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 Test() { System.Console.WriteLine(String.Empty.PadRight(78, '#')); System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of MatrixF64"); System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine(String.Empty.PadRight(78, '#')); System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of matrix initialization:"); System.Console.WriteLine(Environment.NewLine); // A 5x3 matrix (5 rows x 3 columns) with // 64-bit floating-point entries: MatrixF64 m = new MatrixF64 ( 5, 3, 0.0, 1.0, 2.0, // row 0 3.0, 4.0, 5.0, // row 1 6.0, 7.0, 8.0, // row 2 9.0, 10.0, 11.0, // row 3 12.0, 13.0, 14.0 // row 4 ); m.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 0, 1, 2 ] // row 0 // [ 3, 4, 5 ] // row 1 // [ 6, 7, 8 ] // row 2 // [ 9, 10, 11 ] // row 3 // [ 12, 13, 14 ] // row 4 // An 8x2 matrix (8 rows x 2 columns) with all 16 // 64-bit floating-point entries set to zero: MatrixF64 z = MatrixF64.Zero(8, 2); z.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 0, 0 ] // row 0 // [ 0, 0 ] // row 1 // [ 0, 0 ] // row 2 // [ 0, 0 ] // row 3 // [ 0, 0 ] // row 4 // [ 0, 0 ] // row 5 // [ 0, 0 ] // row 6 // [ 0, 0 ] // row 7 // Examples of matrix addition, subtraction, and multiplication: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of matrix addition, subtraction, and multiplication:"); System.Console.WriteLine(Environment.NewLine); MatrixF64 a = new MatrixF64 ( 3, 5, 0.0, 1.0, 2.0, 3.0, 4.0, // row 0 5.0, 6.0, 7.0, 8.0, 9.0, // row 1 10.0, 11.0, 12.0, 13.0, 14.0 // row 2 ); MatrixF64 b = new MatrixF64 ( 3, 5, 4.0, -3.0, 2.0, -1.0, 0.0, // row 0 -9.0, 8.0, -7.0, 6.0, -5.0, // row 1 14.0, -13.0, 12.0, -11.0, 10.0 // row 2 ); MatrixF64 c = new MatrixF64 ( 5, 3, 0.0, 1.0, 2.0, // row 0 3.0, 4.0, 5.0, // row 1 6.0, 7.0, 8.0, // row 2 9.0, 10.0, 11.0, // row 3 12.0, 13.0, 14.0 // row 4 ); MatrixF64 result = new MatrixF64(); result = a + b; result.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 4, -2, 4, 2, 4 ] // [ -4, 14, 0, 14, 4 ] // [ 24, -2, 24, 2, 24 ] result = a - b; result.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ -4, 4, 0, 4, 4 ] // [ 14, -2, 14, 2, 14 ] // [ -4, 24, 0, 24, 4 ] result = -a; result.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 0, -1, -2, -3, -4 ] // [ -5, -6, -7, -8, -9 ] // [ -10, -11, -12, -13, -14 ] result = 3.0 * a; result.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 0, 3, 6, 9, 12 ] // [ 15, 18, 21, 24, 27 ] // [ 30, 33, 36, 39, 42 ] result = a * c; // (3x5) * (5x3) = (3x3) result.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 90, 100, 110 ] // [ 240, 275, 310 ] // [ 390, 450, 510 ] result = c * a; // (5x3) * (3x5) = (5x5) result.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 25, 28, 31, 34, 37 ] // [ 70, 82, 94, 106, 118 ] // [ 115, 136, 157, 178, 199 ] // [ 160, 190, 220, 250, 280 ] // [ 205, 244, 283, 322, 361 ] // Examples of multiplying by an identity matrix: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of multiplying by an identity matrix:"); System.Console.WriteLine(Environment.NewLine); MatrixF64 identity3x3 = MatrixF64.Identity(3); identity3x3.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 1, 0, 0 ] // [ 0, 1, 0 ] // [ 0, 0, 1 ] MatrixF64 s3x3 = new MatrixF64 ( 3, 3, 0.0, 1.0, 2.0, // row 0 3.0, 4.0, 5.0, // row 1 6.0, 7.0, 8.0 // row 2 ); result = s3x3 * identity3x3; result.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 0, 1, 2 ] // [ 3, 4, 5 ] // [ 6, 7, 8 ] // (i.e., the same as s3x3) result = identity3x3 * s3x3; result.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 0, 1, 2 ] // [ 3, 4, 5 ] // [ 6, 7, 8 ] // (i.e., the same as s3x3) // Example of LU factoring and back-substitution: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of LU factoring and back-substitution:"); System.Console.WriteLine(Environment.NewLine); MatrixF64 a3x3 = new MatrixF64 ( 3, 3, 0.0, 1.0, 2.0, // row 0 3.0, 4.0, 5.0, // row 1 6.0, 7.0, 8.0 // row 2 ); int[] rowPermutationOfOriginalMatrix = null; bool rowInterchangeParityIsOdd = false; MatrixF64 a3x3LU = null; MatrixF64.FindLUFactorsOfARowPermutedVersionOfAnOriginalMatrix ( a3x3, ref a3x3LU, ref rowPermutationOfOriginalMatrix, ref rowInterchangeParityIsOdd ); a3x3LU.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 6, 7, 8 ] // [ 0, 1, 2 ] // [ 0.5, 0.5, 1e-19 ] // The matrix above is a combination of the L and U // matrices. The L matrix is 0 above the diagonal, // 1 on the diagonal, and the shown values below the // diagonal. The U matrix is 0 below the diagonal, // and the shown values on and above the diagonal. // This LU factoring is of a ROW-PERMUTED version // of the original matrix. // The following L and U matrices are manually formed // by inspecting the LU factoring matrix above. MatrixF64 L3x3 = new MatrixF64 ( 3, 3, 1.0, 0.0, 0.0, // row 0 0.0, 1.0, 0.0, // row 1 0.5, 0.5, 1.0 // row 2 ); MatrixF64 U3x3 = new MatrixF64 ( 3, 3, 6.0, 7.0, 8.0, // row 0 0.0, 1.0, 2.0, // row 1 0.0, 0.0, 0.0 // row 2 ); // The product (L)*(U) produces a ROW-PERMUTED version // of the original matrix: result = L3x3 * U3x3; result.WriteLine(4); System.Console.WriteLine(Environment.NewLine); // [ 6, 7, 8 ] // [ 0, 1, 2 ] // [ 3, 4, 5 ] VectorF64 b3x1 = new VectorF64(1.0, 2.0, 3.0); VectorF64 x3x1 = null; MatrixF64.LUBacksubstitution ( a3x3LU, rowPermutationOfOriginalMatrix, b3x1, ref x3x1 ); // Solution vector x3x1.WriteLine(); System.Console.WriteLine(Environment.NewLine); // ( -0.66666667, 1, 0 ) // Both the given b3x1 and this x3x1 are relative to the // original matrix, a3x3. The a3x3LU for a ROW-PERMUTED // version of a3x3, but LUBacksubstitution accepts a // non-permuted product vector (e.g., b3x1) and produces // a non-permuted solution vector (e.g., x3x1). // Check solution by multiplying the original matrix a3x3 // by the solution vector x3x1, to get a product vector. VectorF64 checkb3x1 = a3x3 * x3x1; checkb3x1.WriteLine(); System.Console.WriteLine(Environment.NewLine); // ( 1, 2, 3 ) // This matches the b3x1 vector we specified above, so // the solution is valid. // Examples of matrix determinants: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of matrix determinants:"); System.Console.WriteLine(Environment.NewLine); MatrixF64 d2x2 = new MatrixF64 ( 2, 2, 2.0, 5.0, // row 0 -4.0, -7.0 // row 1 ); double detd2x2 = d2x2.Determinant(); System.Console.WriteLine(detd2x2); System.Console.WriteLine(Environment.NewLine); // detd2x2 = 6 MatrixF64 d3x3 = new MatrixF64 ( 3, 3, 2.0, 5.0, 7.0, // row 0 -4.0, -1.0, 6.0, // row 1 9.0, 8.0, 3.0 // row 2 ); double detd3x3 = d3x3.Determinant(); System.Console.WriteLine(detd3x3); System.Console.WriteLine(Environment.NewLine); // detd3x3 = 67 MatrixF64 d4x4 = new MatrixF64 ( 4, 4, 7.0, -5.0, 2.0, 4.0, // row 0 3.0, 2.0, 6.0, 3.0, // row 1 -9.0, 8.0, -3.0, 2.0, // row 2 5.0, 3.0, 2.0, 5.0 // row 3 ); double detd4x4 = d4x4.Determinant(); System.Console.WriteLine(detd4x4); System.Console.WriteLine(Environment.NewLine); // detd4x4 = 1457 // Examples of matrix inverses: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of matrix inverses:"); System.Console.WriteLine(Environment.NewLine); MatrixF64 m2x2 = new MatrixF64 ( 2, 2, 2.0, 5.0, // row 0 -4.0, -7.0 // row 1 ); MatrixF64 inversem2x2 = m2x2.Inverse(); inversem2x2.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ -1.1666667, -0.83333333 ] // [ 0.66666667, 0.33333333 ] MatrixF64 prodinvm2x2andm2x2 = inversem2x2 * m2x2; prodinvm2x2andm2x2.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 1, 8.8817842e-16 ] // [ 0, 1 ] // This product is very close to a // 2x2 identity matrix, as it should be. MatrixF64 prodm2x2andinvm2x2 = m2x2 * inversem2x2; prodm2x2andinvm2x2.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 1, 0 ] // [ 0, 1 ] // This product is the 2x2 identity matrix, // as it should be. MatrixF64 m3x3 = new MatrixF64 ( 3, 3, 2.0, 5.0, 7.0, // row 0 -4.0, -1.0, 6.0, // row 1 9.0, 8.0, 3.0 // row 2 ); MatrixF64 inversem3x3 = m3x3.Inverse(); inversem3x3.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ -0.76119403, 0.6119403, 0.55223881 ] // [ 0.98507463, -0.85074627, -0.59701493 ] // [ -0.34328358, 0.43283582, 0.26865672 ] MatrixF64 prodinvm3x3andm3x3 = inversem3x3 * m3x3; prodinvm3x3andm3x3.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 1, 0, 4.4408921e-16 ] // [ 0, 1, 0 ] // [ 0, 0, 1 ] // This product is very close to a 3x3 identity matrix, // as it should be. MatrixF64 prodm3x3andinvm3x3 = m3x3 * inversem3x3; prodm3x3andinvm3x3.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 1, -4.4408921e-16, 4.4408921e-16 ] // [ 0, 1, -2.220446e-16 ] // [ -4.4408921e-16, 0, 1 ] // This product is very close to a 3x3 identity matrix, // as it should be. // Examples of a product of a matrix and a vector: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of a product of a matrix and a vector:"); System.Console.WriteLine(Environment.NewLine); MatrixF64 t3x3 = new MatrixF64 ( 3, 3, 2.0, 5.0, 7.0, // row 0 -4.0, -1.0, 6.0, // row 1 9.0, 8.0, 3.0 // row 2 ); VectorF64 p3x1 = new VectorF64(1.0, 2.0, 3.0); VectorF64 q3x1 = t3x3 * p3x1; q3x1.WriteLine(); System.Console.WriteLine(Environment.NewLine); // ( 33, 12, 34 ) // The multiplicative product of the inverse // of the matrix and the result vector computed // above should produce the original vector. MatrixF64 inverset3x3 = t3x3.Inverse(); VectorF64 prodinvt3x3andq3x1 = inverset3x3 * q3x1; prodinvt3x3andq3x1.WriteLine(); System.Console.WriteLine(Environment.NewLine); // ( 1, 2, 3 ) // This vector is equal to the original vector, // as expected. // Example of using a homogeneous matrix to // translate a homogeneous vector: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of using a homogeneous matrix to translate a homogeneous vector:"); System.Console.WriteLine(Environment.NewLine); // Forming a homogeneous matrix that represents // a translation: VectorF64 homogeneousTranslationVector4x1 = new VectorF64(10.0, 20.0, 30.0, 1.0); MatrixF64 translation4x4 = MatrixF64.FormHomogeneousTranslationMatrix (homogeneousTranslationVector4x1); translation4x4.WriteLine(); System.Console.WriteLine(Environment.NewLine); // [ 1, 0, 0, 10 ] // [ 0, 1, 0, 20 ] // [ 0, 0, 1, 30 ] // [ 0, 0, 0, 1 ] // Using the homogeneous matrix to translate // a homogeneous vector: VectorF64 homogeneousVector = new VectorF64(5.0, 6.0, 7.0, 1.0); VectorF64 translatedVector = translation4x4 * homogeneousVector; translatedVector.WriteLine(); System.Console.WriteLine(Environment.NewLine); // ( 15, 26, 37, 1 ) // The relevant vector components (5,6,7) // were translated by (10,20,30) by the // homogeneous translation matrix. // Example of using a homogeneous matrix // to rotate a homogeneous vector: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of using a homogeneous matrix to rotate a homogeneous vector:"); System.Console.WriteLine(Environment.NewLine); // Forming a homogeneous rotation matrix that // rotates a positive component along coordinate // axis 0 to a positive component along // cooridnate axis 1, in 3-dimensional space. // (The homogeneous matrix must be (3+1)=4 // rows by (3+1)=4 columns.) MatrixF64 rotation4x4 = MatrixF64.Rab(4, 0, 1, (0.5 * Math.PI)); rotation4x4.WriteLine(3); System.Console.WriteLine(Environment.NewLine); // [ 6.12e-17, -1, 0, 0 ] // [ 1, 6.12e-17, 0, 0 ] // [ 0, 0, 1, 0 ] // [ 0, 0, 0, 1 ] // (The entries '6.12e-17' are negligible.) // The upper-left 3x3 part of the matrix represents // a counterclockwise rotation of a quarter-turn // such that a positive component along axis 0 // would be rotated to a positive component along // axis 1, in 3-dimensional space. // Using the homogeneous rotation matrix to // rotate a homogeneous vector: VectorF64 homogeneousVector2 = new VectorF64(5.0, 6.0, 7.0, 1.0); VectorF64 rotatedVector = rotation4x4 * homogeneousVector2; rotatedVector.WriteLine(); System.Console.WriteLine(Environment.NewLine); // ( -6, 5, 7, 1 ) // The relevant vector components (5,6,7) were // rotated to (-6,5,7), which is consistent with // a counterclockwise quarter-turn rotation // with a rotation plane parallel to axes 0 and 1. System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine(String.Empty.PadRight(78, '#')); System.Console.WriteLine(Environment.NewLine); }
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 VectorF64 Zero(int dimensions) { VectorF64 zero = new VectorF64(); zero.components = new double[dimensions]; for (int i = 0; i < dimensions; i++) { zero[i] = 0.0; } return (zero); }
public static void Test() { System.Console.WriteLine(String.Empty.PadRight(78, '#')); System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of VectorF64"); System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine(String.Empty.PadRight(78, '#')); System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of vector initialization:"); System.Console.WriteLine(Environment.NewLine); // A 3-dimensional vector with 64-bit floating-point components: VectorF64 v3 = new VectorF64(0.0, 1.0, 2.0); v3.WriteLine(); // ( 0, 1, 2 ) System.Console.WriteLine(Environment.NewLine); // A 4-dimensional vector with 64-bit floating-point components: VectorF64 v4 = new VectorF64(0.0, 1.0, 2.0, 3.0); v4.WriteLine(); // ( 0, 1, 2, 3 ) System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of zero vector:"); System.Console.WriteLine(Environment.NewLine); // An 8-dimensional vector with all 8 64-bit floating-point // components set to zero: VectorF64 z = VectorF64.Zero(8); z.WriteLine(); // ( 0, 0, 0, 0, 0, 0, 0, 0 ) System.Console.WriteLine(Environment.NewLine); // Examples of vector addition, subtraction, and scaling: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of vector addition, subtraction, and scaling:"); System.Console.WriteLine(Environment.NewLine); VectorF64 a = new VectorF64(0.0, 1.0, 2.0, 3.0); a.WriteLine(); // ( 0, 1, 2, 3 ) System.Console.WriteLine(Environment.NewLine); VectorF64 b = new VectorF64(3.0, 2.0, 1.0, 0.0); b.WriteLine(); // ( 3, 2, 1, 0 ) System.Console.WriteLine(Environment.NewLine); VectorF64 c = new VectorF64(); c.WriteLine(); // ( ) System.Console.WriteLine(Environment.NewLine); c = a + b; c.WriteLine(); // ( 3, 3, 3, 3 ) System.Console.WriteLine(Environment.NewLine); c = a - b; c.WriteLine(); // ( -3, -1, 1, 3 ) System.Console.WriteLine(Environment.NewLine); c = -b; c.WriteLine(); // ( -3, -2, -1, 0 ) System.Console.WriteLine(Environment.NewLine); c = 3.0 * a; c.WriteLine(); // ( 0, 3, 6, 9 ) System.Console.WriteLine(Environment.NewLine); // The 4 basis vectors of 4-dimensional space, // each with 4 64-bit floating-point components: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of unit basis vectors:"); System.Console.WriteLine(Environment.NewLine); VectorF64 b0 = VectorF64.BasisVector(4, 0); b0.WriteLine(); // ( 1, 0, 0, 0 ) System.Console.WriteLine(Environment.NewLine); VectorF64 b1 = VectorF64.BasisVector(4, 1); b1.WriteLine(); // ( 0, 1, 0, 0 ) System.Console.WriteLine(Environment.NewLine); VectorF64 b2 = VectorF64.BasisVector(4, 2); b2.WriteLine(); // ( 0, 0, 1, 0 ) System.Console.WriteLine(Environment.NewLine); VectorF64 b3 = VectorF64.BasisVector(4, 3); b3.WriteLine(); // ( 0, 0, 0, 1 ) System.Console.WriteLine(Environment.NewLine); // The following two vectors are equivalent: // A 4-dimensional vector with 64-bit floating-point components: VectorF64 va = new VectorF64(0.1, 1.1, 2.2, 3.3); va.WriteLine(); // ( 0.1, 1.1, 2.2, 3.3 ) System.Console.WriteLine(Environment.NewLine); // A 4-dimensional vector formed by scaling the 4 independent // basis vectors for 4-dimensional space: VectorF64 vb = 0.1 * VectorF64.BasisVector(4, 0) + 1.1 * VectorF64.BasisVector(4, 1) + 2.2 * VectorF64.BasisVector(4, 2) + 3.3 * VectorF64.BasisVector(4, 3); vb.WriteLine(); // ( 0.1, 1.1, 2.2, 3.3 ) System.Console.WriteLine(Environment.NewLine); // Example of vector length: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of vector length:"); System.Console.WriteLine(Environment.NewLine); // A 6-dimensional vector representing a point (p): VectorF64 p = new VectorF64(0.0, 1.0, 2.0, 3.0, 4.0, 5.0); p.WriteLine(); // ( 0, 1, 2, 3, 4, 5 ) System.Console.WriteLine(Environment.NewLine); // A 6-dimensional vector representing a point (q): VectorF64 q = new VectorF64(-5.0, 4.0, -3.0, 2.0, -1.0, 0.0); q.WriteLine(); // ( -5, 4, -3, 2, -1, 0 ) System.Console.WriteLine(Environment.NewLine); // A 6-dimensional vector representing the displacement // from point (p) to point (q): VectorF64 r = q - p; r.WriteLine(); // ( -5, 3, -5, -1, -5, -5 ) System.Console.WriteLine(Environment.NewLine); // The distance between point (p) and point (q) // in 6-dimensional space: double distance = r.Length(); System.Console.WriteLine(distance); // 10.4880884817015 System.Console.WriteLine(Environment.NewLine); // Example of testing for parallel vectors: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of parallel vectors:"); System.Console.WriteLine(Environment.NewLine); // A 6-dimensional vector: VectorF64 vf = new VectorF64(0.0, 1.0, 2.0, 3.0, 4.0, 5.0); vf.WriteLine(); // ( 0, 1, 2, 3, 4, 5 ) System.Console.WriteLine(Environment.NewLine); // A 6-dimensional vector: VectorF64 vg = new VectorF64(0.0, -2.0, -4.0, -6.0, -8.0, -10.0); vg.WriteLine(); // ( 0, -2, -4, -6, -8, -10 ) System.Console.WriteLine(Environment.NewLine); // Determine if the specified vectors are parallel // (or ""anti-parallel""): bool parallel = VectorF64.Parallel(vf, vg); System.Console.WriteLine(parallel); // True System.Console.WriteLine(Environment.NewLine); // Add a non-negligible displacement to a component of a vector: vf[0] += 1.0e-5; vf.WriteLine(); // ( 1E-05, 1, 2, 3, 4, 5 ) System.Console.WriteLine(Environment.NewLine); // Determine if the specified vectors are parallel // (or ""anti-parallel""): parallel = VectorF64.Parallel(vf, vg); System.Console.WriteLine(parallel); // False System.Console.WriteLine(Environment.NewLine); // Example of testing for perpendicular vectors: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of perpendicular vectors:"); System.Console.WriteLine(Environment.NewLine); // A 6-dimensional vector: VectorF64 vf2 = new VectorF64(0.0, 1.0, 2.0, 0.0, 4.0, 5.0); vf2.WriteLine(); // ( 0, 1, 2, 0, 4, 5 ) System.Console.WriteLine(Environment.NewLine); // A 6-dimensional vector: VectorF64 vg2 = new VectorF64(10.0, 0.0, 0.0, -5.0, 0.0, 0.0); vg2.WriteLine(); // ( 10, 0, 0, -5, 0, 0 ) System.Console.WriteLine(Environment.NewLine); // Determine if the specified vectors are perpendicular bool perpendicular = VectorF64.Perpendicular(vf2, vg2); System.Console.WriteLine(perpendicular); // True System.Console.WriteLine(Environment.NewLine); // Add a non-negligible displacement to a component of a vector: vf2[0] += 1.0e-13; vf2.WriteLine(); // ( 1E-13, 1, 2, 0, 4, 5 ) System.Console.WriteLine(Environment.NewLine); // Determine if the specified vectors are perpendicular perpendicular = VectorF64.Perpendicular(vf2, vg2); System.Console.WriteLine(perpendicular); // False System.Console.WriteLine(Environment.NewLine); // Examples of cross products: System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine("Test of cross products:"); System.Console.WriteLine(Environment.NewLine); // Three-dimensional example: VectorF64 vcp1x3a = new VectorF64(1.0, 2.0, 3.0); VectorF64 vcp1x3b = new VectorF64(3.0, 1.0, 2.0); VectorF64 vcp1x3 = VectorF64.Cross(vcp1x3a, vcp1x3b); vcp1x3.WriteLine(); // ( 1, 7, -5 ) System.Console.WriteLine(Environment.NewLine); // Verify that the result is perpendicular to the original // vectors: System.Console.WriteLine(VectorF64.Perpendicular(vcp1x3, vcp1x3a)); System.Console.WriteLine(VectorF64.Perpendicular(vcp1x3, vcp1x3b)); // True, True // Four-dimensional example: VectorF64 vcp1x4a = new VectorF64(1.0, 2.0, 3.0, 4.0); VectorF64 vcp1x4b = new VectorF64(4.0, 1.0, 2.0, 3.0); VectorF64 vcp1x4c = new VectorF64(3.0, 4.0, 1.0, 2.0); VectorF64 vcp1x4 = VectorF64.Cross(vcp1x4a, vcp1x4b, vcp1x4c); vcp1x4.WriteLine(); // ( 4, 4, 44, -36 ) System.Console.WriteLine(Environment.NewLine); // Verify that the result is perpendicular to the original // vectors: System.Console.WriteLine(VectorF64.Perpendicular(vcp1x4, vcp1x4a)); System.Console.WriteLine(VectorF64.Perpendicular(vcp1x4, vcp1x4b)); System.Console.WriteLine(VectorF64.Perpendicular(vcp1x4, vcp1x4c)); // True, True, True System.Console.WriteLine(Environment.NewLine); System.Console.WriteLine(String.Empty.PadRight(78, '#')); System.Console.WriteLine(Environment.NewLine); }
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 VectorF64 Normalize(VectorF64 v) { if (null == v) { return (new VectorF64()); // Vector not specified. } if (null == v.components) { return (new VectorF64()); // Vector is empty. } return (v.Normalize()); }
public static double Length(VectorF64 a) { if (null == a) { return (0.0); // Vector not specified. } if (null == a.components) { return (0.0); // Vector is empty. } return (a.Length()); }
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); }