public VectorF64(VectorF64 other) { this.components = null; if (null == other) { return; } if (null == other.components) { return; } int dimensions = other.Dimensions(); this.components = new double[dimensions]; for (int i = 0; i < dimensions; i++) { this.components[i] = other.components[i]; } }
public static void LUBacksubstitution( MatrixF64 LUFactorsMatrix, int[] rowPermutationOfOriginalMatrix, VectorF64 givenProductVector, ref VectorF64 solutionVector ) { // This implementation is based on pseudo-code appearing in // ''Introduction to Algorithms'' (Cormen; Lieserson; Rivest; // 24th printing, 2000; MIT Press; ISBN 0-262-03141-8). // See the section named ''Overview of LUP decomposition'', in // chapter 31 (''Matrix Operations''). The implementation here // follows the ''LUP-Solve'' pseudo-code appearing in a // section named ''forward and back substitution''. solutionVector = null; if (null == LUFactorsMatrix) { return; // No matrix specified. } if (null == rowPermutationOfOriginalMatrix) { return; // No permutation specified. } if (null == givenProductVector) { return; // No product vector specified. } if ( (null == LUFactorsMatrix.entries) || (LUFactorsMatrix.totalRows <= 0) || (LUFactorsMatrix.totalColumns <= 0) ) { return; // Matrix is empty. } if (LUFactorsMatrix.totalRows != LUFactorsMatrix.totalColumns) { return; // Matrix is not square. } if (givenProductVector.Dimensions() != LUFactorsMatrix.totalRows) { return; // Product vector size not equal to matrix row count. } // Copy the product vector in to the result. solutionVector = new VectorF64(givenProductVector); // (See LUP-Solve, lines 2-3) for (int i = 0; i < LUFactorsMatrix.totalRows; i++) { double sum = givenProductVector[rowPermutationOfOriginalMatrix[i]]; for (int j = 0; j < i; j++) { sum -= (LUFactorsMatrix[i, j] * solutionVector[j]); } solutionVector[i] = sum; } // (See LUP-Solve, lines 4-5) for (int i = (LUFactorsMatrix.totalRows - 1); i >= 0; i--) { double sum = solutionVector[i]; for ( int j = (i + 1); j < LUFactorsMatrix.totalColumns; j++ ) { sum -= (LUFactorsMatrix[i, j] * solutionVector[j]); } double diagonalElement = LUFactorsMatrix[i, i]; if (diagonalElement != 0.0) { solutionVector[i] = (sum / diagonalElement); } } }
public static MatrixF64 FormHomogeneousTranslationMatrix(VectorF64 v) { // This method assumes the specified vector is a homogeneous // vector, where the final component is not relevant to the // translation. Thus, we form a square homogeneous matrix // with a total number of rows equal to the number of // components of the specified vector. We form an identity // matrix of the required size, and copy all but the final // component of the specified vector to the final column of // the matrix. if (null == v) { return (MatrixF64.Zero(1, 1)); // Vector is not specified. } if (v.Dimensions() <= 0) { return (MatrixF64.Zero(1, 1)); // Vector is empty. } MatrixF64 result = MatrixF64.Identity(v.Dimensions()); // Add all but the final component of the specified vector // to the final column of the result matrix. The final // entry of the final column of the matrix will remain one (1). for (int i = 0; i < (result.totalRows - 1); i++) { result[i, (result.totalColumns - 1)] = v[i]; } return (result); }
public MatrixF64 TranslateByAHomogeneousVector(VectorF64 v) { // This function assumes a square matrix that represents a // homogeneous transformation (with a final row that is all // zero except for a final entry of one), and the specification // of a homogeneous vector (with a final component of one). // All but the final component of the vector will contribute // to the final column vector of the matrix. if (null == v) { return (MatrixF64.Zero(1, 1)); // Vector is not specified. } if ( (this.totalRows <= 0) || (this.totalColumns <= 0) || (null == this.entries) ) { return (MatrixF64.Zero(1, 1)); // Matrix is empty. } if (v.Dimensions() != this.totalRows) { // The vector size is not equal to the matrix total rows. return (MatrixF64.Zero(this.totalRows, this.totalColumns)); } // Add all but the final component of the specified vector // to the final column of this matrix. The final entry // of the final column of the matrix will remain one (1). MatrixF64 result = new MatrixF64(this); for (int i = 0; i < (result.totalRows - 1); i++) { result[i, (result.totalColumns - 1)] += v[i]; } return (result); }
public static bool Perpendicular(VectorF64 a, VectorF64 b) { // Smallest normalized float : 1.1754943e-38 // Smallest normalized double: 2.2250738585072020e-308 double nonZeroThreshold = 1.0e-38; // conservative for double // double: (52+1)-bit mantissa; log10(2^53)=15.95 decimal digits double fractionalDifferenceThreshold = 1.0e-14; // conservative if ((null == a) || (null == b)) { return (false); // Vector is not specified. } if ((null == a.components) || (null == b.components)) { return (false); // Vector is empty. } if (a.Dimensions() != b.Dimensions()) { return (false); // Vectors not the same size. } double lengthA = a.Length(); if (lengthA <= nonZeroThreshold) { return (false); } double lengthB = b.Length(); if (lengthB <= nonZeroThreshold) { return (false); } double zeroImpliesPerpendicular = Math.Abs(VectorF64.Dot(a, b)) / (lengthA * lengthB); double absoluteDifferenceFromZero = Math.Abs(zeroImpliesPerpendicular); if (absoluteDifferenceFromZero <= fractionalDifferenceThreshold) { return (true); } return (false); }
public static double Dot(VectorF64 a, VectorF64 b) { if ((null == a) || (null == b)) { return (0.0); // Vector not specified. } if ((null == a.components) || (null == b.components)) { return (0.0); // Vector is empty. } if (a.Dimensions() != b.Dimensions()) { return (0.0); // Vectors not the same size. } int dimensions = a.Dimensions(); double dotProduct = 0.0; for (int i = 0; i < dimensions; i++) { dotProduct += (a[i] * b[i]); } return (dotProduct); }