Matrix Library .Net v2.0 By Anas Abidi, 2004. The Matrix Library contains Class Matrix which provides many static methods for making various matrix operations on objects derived from the class or on arrays defined as double. The '+','-','*' operators are overloaded to work with the objects derived from the matrix class.
Ejemplo n.º 1
0
 /// <summary>
 /// Returns the dot product of two vectors whose
 /// dimensions should be [3] or [3,1].
 /// In case of an error the error is raised as an exception.
 /// </summary>
 /// <param name="V1">First Matrix object (dimension [3,1]) in the dot product</param>
 /// <param name="V2">Second Matrix object (dimension [3,1]) in the dot product</param>
 /// <returns>Dot product of V1 and V2</returns>
 public static double DotProduct(NMatrix V1, NMatrix V2)
 {
     return (DotProduct(V1.in_Mat, V2.in_Mat));
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Returns the Eigenvalues and Eigenvectors of a real symmetric
 /// matrix, which is of dimensions [n,n]. In case of an error the
 /// error is raised as an exception.
 /// Note: This method is based on the 'Eigenvalues and Eigenvectors of a TridiagonalMatrix'
 /// section of Numerical Recipes in C by William H. Press,
 /// Saul A. Teukolsky, William T. Vetterling and Brian P. Flannery,
 /// University of Cambridge Press 1992.
 /// </summary>
 /// <param name="Mat">
 /// The Matrix object whose Eigenvalues and Eigenvectors are to be found
 /// </param>
 /// <param name="d">A Matrix object where the eigenvalues are returned</param>
 /// <param name="v">A Matrix object where the eigenvectors are returned</param>
 public static void Eigen(NMatrix Mat, out NMatrix d, out NMatrix v)
 {
     double[,] D, V;
     Eigen(Mat.in_Mat, out D, out V);
     d = new NMatrix(D);
     v = new NMatrix(V);
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Returns a matrix as a string, so it can be viewed
 /// in a multi-text textbox or in a richtextBox (preferred).
 /// In case of an error the error is raised as an exception.
 /// </summary>
 /// <param name="Mat">The Matrix object to be viewed</param>
 /// <returns>The string view of the Matrix object</returns>
 public static string PrintMat(NMatrix Mat)
 {
     return (PrintMat(Mat.in_Mat));
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Returns the determinant of a matrix with [n,n] dimension.
 /// In case of an error the error is raised as an exception. 
 /// </summary>
 /// <param name="Mat">
 /// Matrix object with [n,n] dimension whose determinant is to be found
 /// </param>
 /// <returns>Determinant of the Matrix object</returns>
 public static double Det(NMatrix Mat)
 {
     return Det(Mat.in_Mat);
 }
Ejemplo n.º 5
0
        public static bool TryGaussJordanElimination(NMatrix a, NMatrix b, out NMatrix result)
        {
            if (a.NoRows != b.NoRows)
            {
                throw new ArgumentException();
            }

            result = null;

            NMatrix lhs = a.Copy();
            NMatrix rhs = b.Copy();

            int rowCount = lhs.NoRows;
            int colCount = rhs.NoCols + lhs.NoCols;

            //	augment lhs array with rhs array and store in arr2
            var matrixArray = new double[rowCount, colCount];

            for (int row = 0; row < rowCount; ++row)
            {
                for (int col = 0; col < lhs.NoCols; ++col)
                {
                    matrixArray[row, col] = lhs[row, col];
                }
                for (int col = 0; col < rhs.NoCols; ++col)
                {
                    matrixArray[row, lhs.NoCols + col] = rhs[row, col];
                }
            }

            //	perform forward elimination to get arr2 in row-echelon form
            for (int row = 0; row < rowCount; ++row)
            {
                //	run along diagonal, swapping rows to move zeros in working position
                //	(along the diagonal) downwards
                if (IsZero(matrixArray[row, row]))
                {
                    if (row == (rowCount - 1))
                    {
                        return(false);                        //  no solution
                    }
                }
                for (int insideRow = row + 1; insideRow < rowCount; insideRow++)
                {
                    if (!IsZero(matrixArray[insideRow, row]))
                    {
                        SwapRows(matrixArray, row, insideRow);
                        break;
                    }
                }

                //	divide working row by value of working position to get a 1 on the
                //	diagonal
                if (IsZero(matrixArray[row, row]))
                {
                    return(false);
                }

                double diagonal = matrixArray[row, row];
                for (int col = 0; col < colCount; ++col)
                {
                    matrixArray[row, col] /= diagonal;
                }

                //	eliminate value below working position by subtracting a multiple of
                //	the current row
                for (int insideRow = row + 1; insideRow < rowCount; ++insideRow)
                {
                    double coefficient = matrixArray[insideRow, insideRow];
                    for (int col = 0; col < colCount; ++col)
                    {
                        matrixArray[insideRow, col] -= coefficient * matrixArray[insideRow, col];
                    }
                }
            }

            //	backward substitution steps
            for (int dindex = rowCount - 1; dindex >= 0; --dindex)
            {
                //	eliminate value above working position by subtracting a multiple of
                //	the current row
                for (int row = dindex - 1; row >= 0; --row)
                {
                    double coefficient = matrixArray[row, dindex];
                    for (int col = 0; col < colCount; ++col)
                    {
                        matrixArray[row, col] -= coefficient * matrixArray[dindex, col];
                    }
                }
            }

            result = new NMatrix(matrixArray);
            return(true);
        }
        public Line GetLine(PointUV pointUV)
        {
            var unitMatrix = new NMatrix(new double[,] { { pointUV.U }, { pointUV.V }, { 1 } });
            NMatrix solution;
            if (!NMatrix.TryGaussJordanElimination(Homography, unitMatrix, out solution))
                throw new ArgumentException();

            //a = Vector.Create(solution[0, 3], solution[1, 3], solution[2, 3]);
            //b = Vector.Create(solution[0, 4], solution[1, 4], solution[2, 4]);

            ////var vector = Vector.Create(pointUV.U * a.X, pointUV.V * a.Y, a.Z);
            //return Line.Create(Point.Origin + a, b.Direction);

            return Line.Create(Point.Origin, Direction.Create(
                solution[0, 4] / (solution[0, 3] + 1),
                solution[1, 4] / (solution[1, 3] + 1),
                solution[2, 4] / (solution[2, 3] + 1)
            ));
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Evaluates the Singular Value Decomposition of a matrix, 
 /// returns the  matrices S, U and V. Such that a given
 /// Matrix = U x S x V'.
 /// In case of an error the error is raised as an exception. 
 /// Note: This method is based on the 'Singular Value Decomposition'
 /// section of Numerical Recipes in C by William H. Press,
 /// Saul A. Teukolsky, William T. Vetterling and Brian P. Flannery,
 /// University of Cambridge Press 1992.
 /// </summary>
 /// <param name="Mat">Matrix object whose SVD is to be computed</param>
 /// <param name="S">A Matrix object where the S matrix is returned</param>
 /// <param name="U">A Matrix object where the U matrix is returned</param>
 /// <param name="V">A Matrix object where the V matrix is returned</param>
 public static void SVD(NMatrix Mat, out NMatrix S, out NMatrix U, out NMatrix V)
 {
     double[,] s, u, v;
     SVD(Mat.in_Mat, out s, out u, out v);
     S = new NMatrix(s);
     U = new NMatrix(u);
     V = new NMatrix(v);
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Returns the LU Decomposition of a matrix. 
 /// the output is: lower triangular matrix L, upper
 /// triangular matrix U, and permutation matrix P so that
 ///	P*X = L*U.
 /// In case of an error the error is raised as an exception. 
 /// Note: This method is based on the 'LU Decomposition and Its Applications'
 /// section of Numerical Recipes in C by William H. Press,
 /// Saul A. Teukolsky, William T. Vetterling and Brian P. Flannery,
 /// University of Cambridge Press 1992.  
 /// </summary>
 /// <param name="Mat">Matrix object which will be LU Decomposed</param>
 /// <param name="L">A Matrix object where the lower traingular matrix is returned</param>
 /// <param name="U">A Matrix object where the upper traingular matrix is returned</param>
 /// <param name="P">A Matrix object where the permutation matrix is returned</param>
 public static void LU(NMatrix Mat, out NMatrix L, out NMatrix U, out NMatrix P)
 {
     double[,] l, u, p;
     LU(Mat.in_Mat, out l, out u, out p);
     L = new NMatrix(l);
     U = new NMatrix(u);
     P = new NMatrix(p);
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Solves a set of n linear equations A.X = B, and returns
 /// X, where A is [n,n] and B is [n,1]. 
 /// In the same manner if you need to compute: inverse(A).B, it is
 /// better to use this method instead, as it is much faster.  
 /// In case of an error the error is raised as an exception. 
 /// Note: This method is based on the 'LU Decomposition and Its Applications'
 /// section of Numerical Recipes in C by William H. Press,
 /// Saul A. Teukolsky, William T. Vetterling and Brian P. Flannery,
 /// University of Cambridge Press 1992.
 /// </summary>
 /// <param name="MatA">Matrix object 'A' on the left side of the equations A.X = B</param>
 /// <param name="MatB">Matrix object 'B' on the right side of the equations A.X = B</param>
 /// <returns>Matrix object 'X' in the system of equations A.X = B</returns>
 public static NMatrix SolveLinear(NMatrix MatA, NMatrix MatB)
 {
     return new NMatrix(NMatrix.SolveLinear(MatA.in_Mat, MatB.in_Mat));
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Returns the difference of two matrices with compatible 
 /// dimensions.
 /// In case of an error the error is raised as an exception.
 /// </summary>
 /// <param name="Mat1">First matrix in the subtraction</param>
 /// <param name="Mat2">Second matrix in the subtraction</param>
 /// <returns>Difference of Mat1 and Mat2 as a Matrix object</returns>
 public static NMatrix Subtract(NMatrix Mat1, NMatrix Mat2)
 {
     return new NMatrix(Subtract(Mat1.in_Mat, Mat2.in_Mat));
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Returns the multiplication of a matrix or a vector (i.e 
 /// dimension [3,1]) with a scalar quantity.
 /// In case of an error the error is raised as an exception.
 /// </summary>
 /// <param name="Value">The scalar value to multiply the array</param>
 /// <param name="Mat">Matrix which is to be multiplied by a scalar</param>
 /// <returns>The multiplication of the scalar and the array as an array</returns>
 public static NMatrix ScalarMultiply(double Value, NMatrix Mat)
 {
     return new NMatrix(ScalarMultiply(Value, Mat.in_Mat));
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Returns the division of a matrix or a vector (i.e 
 /// dimension [3,1]) by a scalar quantity.
 /// In case of an error the error is raised as an exception.
 /// </summary>
 /// <param name="Value">The scalar value to divide the array with</param>
 /// <param name="Mat">Matrix which is to be divided by a scalar</param>
 /// <returns>The division of the array and the scalar as an array</returns>
 public static NMatrix ScalarDivide(double Value, NMatrix Mat)
 {
     return new NMatrix(ScalarDivide(Value, Mat.in_Mat));
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Returns the rank of a matrix.
 /// In case of an error the error is raised as an exception. 
 /// </summary>
 /// <param name="Mat">a Matrix object whose rank is to be found</param>
 /// <returns>The rank of the Matrix object</returns>
 public static int Rank(NMatrix Mat)
 {
     return Rank(Mat.in_Mat);
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Returns the inverse of a matrix with [n,n] dimension 
 /// and whose determinant is not zero.
 /// In case of an error the error is raised as an exception. 
 /// </summary>
 /// <param name="Mat">
 /// Matrix object with [n,n] dimension whose inverse is to be found
 /// </param>
 /// <returns>Inverse of the matrix as a Matrix object</returns>
 public static NMatrix Inverse(NMatrix Mat)
 {
     return new NMatrix(Inverse(Mat.in_Mat));
 }
Ejemplo n.º 15
0
 /// <summary>
 /// Returns the transpose of a matrix.
 /// In case of an error the error is raised as an exception. 
 /// </summary>
 /// <param name="Mat">Matrix object whose transpose is to be found</param>
 /// <returns>Transpose of the Matrix object as a Matrix object</returns>
 public static NMatrix Transpose(NMatrix Mat)
 {
     return new NMatrix(Transpose(Mat.in_Mat));
 }
Ejemplo n.º 16
0
 /// <summary>
 /// Checks if two matrices of equal dimensions are equal or not.
 /// In case of an error the error is raised as an exception.
 /// </summary>
 /// <param name="Mat1">First Matrix in equality check</param>
 /// <param name="Mat2">Second Matrix in equality check</param>
 /// <returns>If two matrices are equal or not</returns>
 public static bool IsEqual(NMatrix Mat1, NMatrix Mat2)
 {
     return IsEqual(Mat1.in_Mat, Mat2.in_Mat);
 }
Ejemplo n.º 17
0
 /// <summary>
 ///  Returns the magnitude of a vector whose dimension is [3] or [3,1].
 ///  In case of an error the error is raised as an exception.
 /// </summary>
 /// <param name="V">Matrix object (dimension [3,1]) whose magnitude is to be found</param>
 /// <returns>The magnitude of the Matrix object</returns>
 public static double VectorMagnitude(NMatrix V)
 {
     return (VectorMagnitude(V.in_Mat));
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Returns the multiplication of two matrices with compatible 
 /// dimensions OR the cross-product of two vectors.
 /// In case of an error the error is raised as an exception. 
 /// </summary>
 /// <param name="Mat1">
 /// First matrix or vector (i.e: dimension [3,1]) object in 
 /// multiplication
 /// </param>
 /// <param name="Mat2">
 /// Second matrix or vector (i.e: dimension [3,1]) object in 
 /// multiplication
 /// </param>
 /// <returns>Mat1 multiplied by Mat2 as a Matrix object</returns>
 public static NMatrix Multiply(NMatrix Mat1, NMatrix Mat2)
 {
     if ((Mat1.NoRows == 3) && (Mat2.NoRows == 3) &&
         (Mat1.NoCols == 1) && (Mat1.NoCols == 1)) { return new NMatrix(CrossProduct(Mat1.in_Mat, Mat2.in_Mat)); }
     else { return new NMatrix(Multiply(Mat1.in_Mat, Mat2.in_Mat)); }
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Returns the summation of two matrices with compatible 
 /// dimensions.
 /// In case of an error the error is raised as an exception.
 /// </summary>
 /// <param name="Mat1">First matrix in the summation</param>
 /// <param name="Mat2">Second matrix in the summation</param>
 /// <returns>Sum of Mat1 and Mat2 as a Matrix object</returns>
 public static NMatrix Add(NMatrix Mat1, NMatrix Mat2)
 {
     return new NMatrix(Add(Mat1.in_Mat, Mat2.in_Mat));
 }
        public void Calibrate()
        {
            //CalibrationPoints.Add(PointUV.Create(-100, -100));
            //CalibrationPoints.Add(PointUV.Create(-100, 100));
            //CalibrationPoints.Add(PointUV.Create(100, -100));
            //CalibrationPoints.Add(PointUV.Create(100, 100));
            //CalibrationPoints.Add(PointUV.Create(-80, -80));
            //CalibrationPoints.Add(PointUV.Create(-80, 80));
            //CalibrationPoints.Add(PointUV.Create(80, -80));
            //CalibrationPoints.Add(PointUV.Create(80, 80));

            double h = (double)imageSize.Height;
            CalibrationPoints.Add(PointUV.Create(0, 0));
            CalibrationPoints.Add(PointUV.Create(0, h));
            CalibrationPoints.Add(PointUV.Create(h, 0));
            CalibrationPoints.Add(PointUV.Create(h, h));
            h *= 2;
            CalibrationPoints.Add(PointUV.Create(0, 0));
            CalibrationPoints.Add(PointUV.Create(0, h));
            CalibrationPoints.Add(PointUV.Create(h, 0));
            CalibrationPoints.Add(PointUV.Create(h, h));

            NMatrix calibrationMatrixA = new NMatrix(2 * CalibrationPoints.Count, 11);
            NMatrix calibrationMatrixB = new NMatrix(2 * CalibrationPoints.Count, 1);
            for (int i = 0; i < CalibrationPoints.Count; i++) {
                double x = controlForm.CalibrationPoints[i].X;
                double y = controlForm.CalibrationPoints[i].Y;
                double z = controlForm.CalibrationPoints[i].Z;
                double u = CalibrationPoints[i].U;
                double v = CalibrationPoints[i].V;

                calibrationMatrixA[2 * i, 0] = x;
                calibrationMatrixA[2 * i, 1] = y;
                calibrationMatrixA[2 * i, 2] = z;
                calibrationMatrixA[2 * i, 3] = 1;
                calibrationMatrixA[2 * i, 8] = -u * x;
                calibrationMatrixA[2 * i, 9] = -u * y;
                calibrationMatrixA[2 * i, 10] = -u * z;

                calibrationMatrixA[2 * i + 1, 4] = x;
                calibrationMatrixA[2 * i + 1, 5] = y;
                calibrationMatrixA[2 * i + 1, 6] = z;
                calibrationMatrixA[2 * i + 1, 7] = 1;
                calibrationMatrixA[2 * i + 1, 8] = -v * x;
                calibrationMatrixA[2 * i + 1, 9] = -v * y;
                calibrationMatrixA[2 * i + 1, 10] = -v * z;

                calibrationMatrixB[2 * i, 0] = u;
                calibrationMatrixB[2 * i + 1, 0] = v;
            }

            NMatrix calibrationMatrixAT = NMatrix.Transpose(calibrationMatrixA);
            NMatrix homographyData = NMatrix.Inverse(calibrationMatrixAT * calibrationMatrixA) * calibrationMatrixAT * calibrationMatrixB;

            Homography = new NMatrix(new double[,]{
                {homographyData[0,0], homographyData[1,0], homographyData[2,0], homographyData[3,0]} ,
                {homographyData[4,0], homographyData[5,0], homographyData[6,0], homographyData[7,0]} ,
                {homographyData[8,0], homographyData[9,0], homographyData[10,0], 1}
            });
        }
Ejemplo n.º 21
0
 /// <summary>
 /// Returns the cross product of two vectors whose
 /// dimensions should be [3] or [3x1].
 /// In case of an error the error is raised as an exception.
 /// </summary>
 /// <param name="V1">First Matrix (dimensions [3,1]) in the cross product</param>
 /// <param name="V2">Second Matrix (dimensions [3,1]) in the cross product</param>
 /// <returns>Cross product of V1 and V2 as a matrix (dimension [3,1])</returns>
 public static NMatrix CrossProduct(NMatrix V1, NMatrix V2)
 {
     return (new NMatrix((CrossProduct(V1.in_Mat, V2.in_Mat))));
 }
        public static bool TryGaussJordanElimination(NMatrix a, NMatrix b, out NMatrix result)
        {
            if (a.NoRows != b.NoRows)
                throw new ArgumentException();

            result = null;

            NMatrix lhs = a.Copy();
            NMatrix rhs = b.Copy();

            int rowCount = lhs.NoRows;
            int colCount = rhs.NoCols + lhs.NoCols;

            //	augment lhs array with rhs array and store in arr2
            var matrixArray = new double[rowCount, colCount];
            for (int row = 0; row < rowCount; ++row) {
                for (int col = 0; col < lhs.NoCols; ++col) {
                    matrixArray[row, col] = lhs[row, col];
                }
                for (int col = 0; col < rhs.NoCols; ++col) {
                    matrixArray[row, lhs.NoCols + col] = rhs[row, col];
                }
            }

            //	perform forward elimination to get arr2 in row-echelon form
            for (int row = 0; row < rowCount; ++row) {
                //	run along diagonal, swapping rows to move zeros in working position
                //	(along the diagonal) downwards
                if (IsZero(matrixArray[row, row]))
                    if (row == (rowCount - 1))
                        return false; //  no solution

                for (int insideRow = row + 1; insideRow < rowCount; insideRow++) {
                    if (!IsZero(matrixArray[insideRow, row])) {
                        SwapRows(matrixArray, row, insideRow);
                        break;
                    }
                }

                //	divide working row by value of working position to get a 1 on the
                //	diagonal
                if (IsZero(matrixArray[row, row]))
                    return false;

                double diagonal = matrixArray[row, row];
                for (int col = 0; col < colCount; ++col)
                    matrixArray[row, col] /= diagonal;

                //	eliminate value below working position by subtracting a multiple of
                //	the current row
                for (int insideRow = row + 1; insideRow < rowCount; ++insideRow) {
                    double coefficient = matrixArray[insideRow, insideRow];
                    for (int col = 0; col < colCount; ++col)
                        matrixArray[insideRow, col] -= coefficient * matrixArray[insideRow, col];
                }
            }

            //	backward substitution steps
            for (int dindex = rowCount - 1; dindex >= 0; --dindex) {
                //	eliminate value above working position by subtracting a multiple of
                //	the current row
                for (int row = dindex - 1; row >= 0; --row) {
                    double coefficient = matrixArray[row, dindex];
                    for (int col = 0; col < colCount; ++col)
                        matrixArray[row, col] -= coefficient * matrixArray[dindex, col];
                }
            }

            result = new NMatrix(matrixArray);
            return true;
        }
Ejemplo n.º 23
0
 /// <summary>
 /// Returns the pseudoinverse of a matrix, such that
 /// X = PINV(A) produces a matrix 'X' of the same dimensions
 /// as A' so that A*X*A = A, X*A*X = X.
 /// In case of an error the error is raised as an exception.
 /// </summary>
 /// <param name="Mat">a Matrix object whose pseudoinverse is to be found</param>
 /// <returns>The pseudoinverse of the Matrix object as a Matrix Object</returns>
 public static NMatrix PINV(NMatrix Mat)
 {
     return new NMatrix(PINV(Mat.in_Mat));
 }