public BCurve(int degree, Vector[] controlPoints, BasisFunction basisFunction) { if (controlPoints.Length + degree + 1 != basisFunction.GetNKnots()) throw new Exception("Number of control points + 1 + degree != n_knots"); _mDegree = degree; _mControlPoints = controlPoints; _mBasis = basisFunction; _mDimension = _mControlPoints[0].VectorDimension(); }
public Vector Evaluate(double u) { var result = new Vector(_mDimension); for (var i = 0; i < _mControlPoints.Length; i++) { var temp1 = _mControlPoints[i]; var coeff = _mBasis.Evaluate(i, _mDegree, u); if (TolerantUtilities.EqualWithinTol(coeff, 0.0)) continue; var temp2 = Vector.ScalarProduct(coeff, temp1); result = result+temp2; } return result; }
private static void CentripetalMethod_calculateInterpolationParameters( Vector[] interpolationPoints, ref double[] interpolationParameters) { // NOTE: interpolationParameters is equal to null(ArgumentNullException) // The first element is always 0.0; var parameters = new List<double> {0.0}; var nPoints = interpolationPoints.Length; // Calculate chord length: double[] chordLengthCache = null; var chordLength = CentripetalMethod_getChordLength(interpolationPoints, ref chordLengthCache); for (var k = 1; k < nPoints - 1; k++) { // First term: var firstTerm = parameters[k - 1]; // use cache: var secondTerm = chordLengthCache[k - 1] / chordLength; // Set new parameter: var param = firstTerm + secondTerm; // Save: parameters.Add(param); } // last parameter is always 1.0; // Minus tolerance as a work around for a problem... parameters.Add(1.0 - new TolerantUtilities().GetTolerance()); // Store parameters: interpolationParameters = parameters.ToArray(); }
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); }
private static double CentripetalMethod_getChordLength(Vector[] interpolationPoints, ref double[] cache) { // NOTE: cache is equal to null(ArgumentNullException) var cacheList = new List<double>(); var length = 0.0; for (var i = 1; i < interpolationPoints.Length; i++) { // Q_k - Q_k-1 var vecDiff = interpolationPoints[i] - interpolationPoints[i-1]; // Size of this vector: var vecSize = vecDiff.GetLength(); // Sqrt of this size: vecSize = Math.Sqrt(vecSize); // Store this in cache list: cacheList.Add(vecSize); // Add to length: length += vecSize; } cache = cacheList.ToArray(); return length; }
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; }
public void ReplaceRow(int row, Vector vec) { // Check dimensions: if (_mColumns != vec.VectorDimension()) throw new Exception("wrong dimension"); for (var i = 0; i < _mColumns; i++) SetElement(row, i, vec.Elements[i]); }
public void Subtract(Vector v2) { // Check dimensions if (_nElements != v2.VectorDimension()) throw new Exception("Wrong dimensions"); for (var i = 0; i < _nElements; i++) Elements[i] = Elements[i] - v2.Elements[i]; }
public double DotProduct(Vector v2) { // Check dimensions if (_nElements != v2.VectorDimension()) throw new Exception("Wrong dimension"); var result = 0.0; for (var i = 0; i < _nElements; i++) result += Elements[i]*v2.Elements[i]; return result; }
public static Vector Subtract(Vector v1, Vector v2) { // Check dimensions: if (v1.VectorDimension() != v2.VectorDimension()) throw new Exception("Wrong dimensions"); var resultElements = new double[v1.VectorDimension()]; for (var i = 0; i < v1.VectorDimension(); i++) resultElements[i] = v1.Elements[i] - v2.Elements[i]; return new Vector(resultElements); }
/// <summary> /// Scalar product double a * Vector v1 /// </summary> /// <param name="a"></param> /// <param name="v1"></param> /// <returns></returns> public static Vector ScalarProduct(double a, Vector v1) { var resultElements = new List<double>(); // Multiply each element of v1 with a for (var i = 0; i < v1.VectorDimension(); i++) resultElements.Add(a*v1.Elements[i]); return new Vector(resultElements); }
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; }