Esempio n. 1
0
        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];
            }
        }
Esempio n. 2
0
        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);
        }
Esempio n. 3
0
        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);
                }
            }
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
        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);
        }
Esempio n. 6
0
        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);
        }
Esempio n. 7
0
        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);
        }
Esempio n. 8
0
        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);
        }
Esempio n. 9
0
        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());
        }
Esempio n. 10
0
        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());
        }
Esempio n. 11
0
        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);
        }