public static void GaussianElimination(BGeomMatrix matrix, Vector rhs, ref double[] results)
        {
            // Create augmented matrix
            var augmentedElements = new List<List<double>>();

            for (var i = 0; i < matrix.GetNRows(); i++)
            {
                augmentedElements.Add(new List<double>());

                for (var j = 0; j < matrix.GetNColumns(); j++)
                    augmentedElements[i].Add(matrix.GetElement(i, j));

                augmentedElements[i].Add(rhs.Elements[i]);
            }

            // Create new matrix:
            var augmentedMatrix = new BGeomMatrix(augmentedElements);

            // Divide first row by the first element:
            var pivot = augmentedMatrix.GetElement(0, 0);

            if (TolerantUtilities.EqualWithinTol(pivot, 0.0))
                throw new Exception("Cannot solve this type of matrix yet");

            var row1 = augmentedMatrix.GetRow(0);

            row1.ScalarProduct(1.0 / pivot);

            // Now replace:
            augmentedMatrix.ReplaceRow(0, row1);

            var nRows = augmentedMatrix.GetNRows();

            // Now enter loop
            for (var i = 1; i < nRows; i++)
            {
                for (var j = 0; j < i; j++)
                {
                    // get the jth row and multiply it with the ith row coefficient:
                    row1 = augmentedMatrix.GetRow(j);

                    // get coefficient:
                    var coefficient = augmentedMatrix.GetElement(i, j);

                    // Multiply:
                    row1.ScalarProduct(coefficient);

                    // Get the ith row:
                    var row2 = augmentedMatrix.GetRow(i);

                    // Subtract:
                    var rowSubs = row2 - row1;

                    // Make the first non-zero coeff 1.0:
                    coefficient = rowSubs.Elements[j+1];
                    rowSubs.ScalarProduct(1.0 / coefficient);

                    // Replace
                    augmentedMatrix.ReplaceRow(i, rowSubs);
                }
            }

            // Now back substitution
            var backSubs = new double[nRows];

            // Fill in the last element:
            backSubs[nRows - 1] = augmentedMatrix.GetElement(nRows-1, nRows);

            // Starting from before last, start filling up:
            for (var i = nRows - 2; i >= 0; i--)
            {
                // Get all the factors on the rhs:
                var rhsFactors = 0.0;

                for (var j = nRows - 1; j > i; j--)
                    rhsFactors += augmentedMatrix.GetElement(i, j)*backSubs[j];

                // Now subtract:
                backSubs[i] = augmentedMatrix.GetElement(i, nRows) - rhsFactors;
            }

            results = backSubs;
        }
示例#2
0
        public static void CentripetalMethod_createSplineByInterpolation(
            int degree, Vector[] interpolationPoints, ref BCurve result)
        {
            // NOTE: result is equal to null(ArgumentNullException)

            // Calculate interpolation parameters:
            double[] interpolationParameters = null;
            CentripetalMethod_calculateInterpolationParameters(interpolationPoints, ref interpolationParameters);

            // Calculate knots:
            double[] knots = null;
            CentripetalMethod_calculateKnots(degree, interpolationParameters, ref knots);

            // Create basis function:
            var basis = new BasisFunction(knots);

            // Number of control points:
            var nControlPoints = interpolationPoints.Length;

            // Create set of linearly independent equations:
            var matrixElements = new double[nControlPoints][];

            for (var i = 0; i < nControlPoints; i++)
            {
                matrixElements[i] = new double[nControlPoints];

                for (var j = 0; j < nControlPoints; j++)
                    matrixElements[i][j] = basis.Evaluate(j, degree, interpolationParameters[i]);
            }

            // Create matrix:
            var matrix = new BGeomMatrix(matrixElements);

            var dimension = interpolationPoints[0].VectorDimension();

            // Solve using Gaussian Elimination:
            var rhs = new Vector(nControlPoints);
            var controlPoints = new Vector[nControlPoints];

            for (var i = 0; i < dimension; i++)
            {
                // Fill the elements of the rhs:
                for (var j = 0; j < nControlPoints; j++)
                    rhs.Elements[j] = interpolationPoints[j].Elements[i];

                double[] gaussResult = null;

                LinearAlgebra.GaussianElimination(matrix, rhs, ref gaussResult);

                // Fill the control points
                for (var k = 0; k < nControlPoints; k++)
                {
                    if ( i == 0)
                        controlPoints[k] = new Vector(dimension);

                    controlPoints[k].Elements[i] = gaussResult[k];
                }
            }

            // Create spline:
            result = new BCurve(degree, controlPoints, basis);
        }
示例#3
0
        private void button1_Click(object sender, EventArgs e)
        {
            var knots = new List<double>
            {
                0.0,
                0.0,
                0.0,
                1.0,
                2.0,
                3.0,
                4.0,
                4.0,
                5.0,
                5.0,
                5.0
            };

            var controlPoints = new List<Vector>
            {
                new Vector(new[] {0.0, 0.0}),
                new Vector(new[] {1.0, 1.0}),
                new Vector(new[] {2.0, 0.0}),
                new Vector(new[] {3.0, -1.0}),
                new Vector(new[] {4.0, 0.0}),
                new Vector(new[] {5.0, 1.0}),
                new Vector(new[] {6.0, 0.0}),
                new Vector(new[] {7.0, -1.0})
            };

            var basis = new BasisFunction(knots);
            var curve = new BCurve(2, controlPoints, basis);

            _sessionCurve = curve;

            curve.Evaluate(2.5);

            // Testing gaussian elimination:
            var matrixElements = new List<List<double>>
            {
                new List<double>
                {
                    1,
                    -3,
                    1
                },

                new List<double>
                {
                    2,
                    -8,
                    8
                },

                new List<double>
                {
                    -6,
                    3,
                    -15
                }
            };

            var rhs = new Vector(new double[] { 4, -2, 9 });
            var matrix = new BGeomMatrix(matrixElements);

            double[] results = null;

            LinearAlgebra.GaussianElimination(matrix, rhs, ref results);

            // make straight line with points:
            var straightLine0 = new List<Vector>();

            for (var i = 0; i < 5; i++)
                straightLine0.Add(new Vector(new[] { i, i % 2.0 }));

            // Interpolate straight line
            var straightLine1 = new BCurve();

            GeomUtils.CentripetalMethod_createSplineByInterpolation(3, straightLine0.ToArray(), ref straightLine1);

            _sessionCurve = straightLine1;
        }