示例#1
0
 /// <summary>
 /// Places the values in the this GMatrix into the matrix m1;
 /// m1 should be at least as large as this GMatrix.
 /// </summary>
 /// <remarks>
 /// Places the values in the this GMatrix into the matrix m1;
 /// m1 should be at least as large as this GMatrix.
 /// </remarks>
 /// <param name="m1">The matrix that will hold the new values</param>
 public void Get(GMatrix m1)
 {
     int i;
     int j;
     int nc;
     int nr;
     if (nCol < m1.nCol)
     {
         nc = nCol;
     }
     else
     {
         nc = m1.nCol;
     }
     if (nRow < m1.nRow)
     {
         nr = nRow;
     }
     else
     {
         nr = m1.nRow;
     }
     for (i = 0; i < nr; i++)
     {
         for (j = 0; j < nc; j++)
         {
             m1.values[i][j] = values[i][j];
         }
     }
     for (i = nr; i < m1.nRow; i++)
     {
         for (j = 0; j < m1.nCol; j++)
         {
             m1.values[i][j] = 0.0;
         }
     }
     for (j = nc; j < m1.nCol; j++)
     {
         for (i = 0; i < nr; i++)
         {
             m1.values[i][j] = 0.0;
         }
     }
 }
示例#2
0
 /// <summary>
 /// Sets the value of this matrix to the result of multiplying
 /// the two argument matrices together (this = m1 * m2).
 /// </summary>
 /// <remarks>
 /// Sets the value of this matrix to the result of multiplying
 /// the two argument matrices together (this = m1 * m2).
 /// </remarks>
 /// <param name="m1">the first matrix</param>
 /// <param name="m2">the second matrix</param>
 public void Mul(GMatrix m1, GMatrix m2)
 {
     int i;
     int j;
     int k;
     if (m1.nCol != m2.nRow || nRow != m1.nRow || nCol != m2.nCol)
     {
         throw new MismatchedSizeException("GMatrix.mul(GMatrix, GMatrix) dimension mismatch ");
     }
     //double[][] tmp = new double[nRow][nCol];
     double[][] tmp = new double[][] { new double[7], new double[7], new double[7], new
         double[7], new double[7], new double[7], new double[7] };
     for (i = 0; i < m1.nRow; i++)
     {
         for (j = 0; j < m2.nCol; j++)
         {
             tmp[i][j] = 0.0;
             for (k = 0; k < m1.nCol; k++)
             {
                 tmp[i][j] += m1.values[i][k] * m2.values[k][j];
             }
         }
     }
     values = tmp;
 }
示例#3
0
        private static void Update_u_split(int topr, int bottomr, GMatrix u, double
			[] cosl, double[] sinl, GMatrix t, GMatrix m)
        {
            int j;
            double utemp;
            for (j = 0; j < u.nCol; j++)
            {
                utemp = u.values[topr][j];
                u.values[topr][j] = cosl[0] * utemp - sinl[0] * u.values[bottomr][j];
                u.values[bottomr][j] = sinl[0] * utemp + cosl[0] * u.values[bottomr][j];
            }
            System.Console.Out.WriteLine("\nm=");
            CheckMatrix(m);
            System.Console.Out.WriteLine("\nu=");
            CheckMatrix(t);
            m.Mul(t, m);
            System.Console.Out.WriteLine("\nt*m=");
            CheckMatrix(m);
        }
示例#4
0
        private static void Update_v_split(int topr, int bottomr, GMatrix v, double
			[] cosr, double[] sinr, GMatrix t, GMatrix m)
        {
            int j;
            double vtemp;
            for (j = 0; j < v.nRow; j++)
            {
                vtemp = v.values[j][topr];
                v.values[j][topr] = cosr[0] * vtemp - sinr[0] * v.values[j][bottomr];
                v.values[j][bottomr] = sinr[0] * vtemp + cosr[0] * v.values[j][bottomr];
            }
            System.Console.Out.WriteLine("topr    =" + topr);
            System.Console.Out.WriteLine("bottomr =" + bottomr);
            System.Console.Out.WriteLine("cosr =" + cosr[0]);
            System.Console.Out.WriteLine("sinr =" + sinr[0]);
            System.Console.Out.WriteLine("\nm =");
            CheckMatrix(m);
            System.Console.Out.WriteLine("\nv =");
            CheckMatrix(t);
            m.Mul(m, t);
            System.Console.Out.WriteLine("\nt*m =");
            CheckMatrix(m);
        }
示例#5
0
        private static void Print_m(GMatrix m, GMatrix u, GMatrix
			 v)
        {
            GMatrix mtmp = new GMatrix(m.nCol, m.nRow);
            mtmp.Mul(u, mtmp);
            mtmp.Mul(mtmp, v);
            System.Console.Out.WriteLine("\n m = \n" + GMatrix.ToString(mtmp));
        }
示例#6
0
 private static string ToString(GMatrix m)
 {
     StringBuilder buffer = new StringBuilder(m.nRow * m.nCol * 8);
     int i;
     int j;
     for (i = 0; i < m.nRow; i++)
     {
         for (j = 0; j < m.nCol; j++)
         {
             if (Math.Abs(m.values[i][j]) < .000000001)
             {
                 buffer.Append("0.0000 ");
             }
             else
             {
                 buffer.Append(m.values[i][j]).Append(" ");
             }
         }
         buffer.Append("\n");
     }
     return buffer.ToString();
 }
示例#7
0
 /// <summary>
 /// Sets the value of this matrix to the matrix difference
 /// of matrices m1 and m2 (this = m1 - m2).
 /// </summary>
 /// <remarks>
 /// Sets the value of this matrix to the matrix difference
 /// of matrices m1 and m2 (this = m1 - m2).
 /// </remarks>
 /// <param name="m1">the first matrix</param>
 /// <param name="m2">the second matrix</param>
 public void Sub(GMatrix m1, GMatrix m2)
 {
     int i;
     int j;
     if (m2.nRow != m1.nRow)
     {
         throw new MismatchedSizeException("GMatrix.sub(GMatrix, GMatrix): row dimension mismatch");
     }
     if (m2.nCol != m1.nCol)
     {
         throw new MismatchedSizeException("GMatrix.sub(GMatrix, GMatrix): column dimension mismatch");
     }
     if (nRow != m1.nRow || nCol != m1.nCol)
     {
         throw new MismatchedSizeException("GMatrix.sub(GMatrix, GMatrix): input matrix dimensions do not match dimensions for this matrix");
     }
     for (i = 0; i < nRow; i++)
     {
         for (j = 0; j < nCol; j++)
         {
             values[i][j] = m1.values[i][j] - m2.values[i][j];
         }
     }
 }
示例#8
0
 private static void Chase_up(double[] s, double[] e, int k, GMatrix v)
 {
     double f;
     double g;
     double r;
     double[] cosr = new double[1];
     double[] sinr = new double[1];
     int i;
     GMatrix t = new GMatrix(v.nRow, v.nCol);
     GMatrix m = new GMatrix(v.nRow, v.nCol);
     f = e[k];
     g = s[k];
     for (i = k; i > 0; i--)
     {
         r = Compute_rot(f, g, sinr, cosr);
         f = -e[i - 1] * sinr[0];
         g = s[i - 1];
         s[i] = r;
         e[i - 1] = e[i - 1] * cosr[0];
         Update_v_split(i, k + 1, v, cosr, sinr, t, m);
     }
     s[i + 1] = Compute_rot(f, g, sinr, cosr);
     Update_v_split(i, k + 1, v, cosr, sinr, t, m);
 }
示例#9
0
 /// <summary>Sets the value of this matrix to the values found in matrix m1.</summary>
 /// <remarks>Sets the value of this matrix to the values found in matrix m1.</remarks>
 /// <param name="m1">the source matrix</param>
 public void Set(GMatrix m1)
 {
     int i;
     int j;
     if (nRow < m1.nRow || nCol < m1.nCol)
     {
         nRow = m1.nRow;
         nCol = m1.nCol;
         //values = new double[nRow][nCol];
         values = new double[][] { new double[7], new double[7], new double[7], new double
             [7], new double[7], new double[7], new double[7] };
     }
     for (i = 0; i < Math.Min(nRow, m1.nRow); i++)
     {
         for (j = 0; j < Math.Min(nCol, m1.nCol); j++)
         {
             values[i][j] = m1.values[i][j];
         }
     }
     for (i = m1.nRow; i < nRow; i++)
     {
         // pad rest or matrix with zeros
         for (j = m1.nCol; j < nCol; j++)
         {
             values[i][j] = 0.0;
         }
     }
 }
示例#10
0
 /// <summary>
 /// Sets the value of this matrix to the matrix difference of itself
 /// and matrix m1 (this = this - m1).
 /// </summary>
 /// <remarks>
 /// Sets the value of this matrix to the matrix difference of itself
 /// and matrix m1 (this = this - m1).
 /// </remarks>
 /// <param name="m1">the other matrix</param>
 public void Sub(GMatrix m1)
 {
     int i;
     int j;
     if (nRow != m1.nRow)
     {
         throw new MismatchedSizeException("GMatrix.sub(GMatrix): row dimension mismatch");
     }
     if (nCol != m1.nCol)
     {
         throw new MismatchedSizeException("GMatrix.sub(GMatrix): column dimension mismatch");
     }
     for (i = 0; i < nRow; i++)
     {
         for (j = 0; j < nCol; j++)
         {
             values[i][j] = values[i][j] - m1.values[i][j];
         }
     }
 }
示例#11
0
 /// <summary>
 /// Sets the value of this matrix equal to the negation of
 /// of the GMatrix parameter.
 /// </summary>
 /// <remarks>
 /// Sets the value of this matrix equal to the negation of
 /// of the GMatrix parameter.
 /// </remarks>
 /// <param name="m1">The source matrix</param>
 public void Negate(GMatrix m1)
 {
     int i;
     int j;
     if (nRow != m1.nRow || nCol != m1.nCol)
     {
         throw new MismatchedSizeException("GMatrix.negate(GMatrix, GMatrix): input matrix dimensions do not match dimensions for this matrix");
     }
     for (i = 0; i < nRow; i++)
     {
         for (j = 0; j < nCol; j++)
         {
             values[i][j] = -m1.values[i][j];
         }
     }
 }
示例#12
0
 /// <summary>
 /// Multiplies matrix m1 times the transpose of matrix m2, and
 /// places the result into this.
 /// </summary>
 /// <remarks>
 /// Multiplies matrix m1 times the transpose of matrix m2, and
 /// places the result into this.
 /// </remarks>
 /// <param name="m1">The matrix on the left hand side of the multiplication</param>
 /// <param name="m2">The matrix on the right hand side of the multiplication</param>
 public void MulTransposeRight(GMatrix m1, GMatrix m2)
 {
     int i;
     int j;
     int k;
     if (m1.nCol != m2.nCol || nCol != m2.nRow || nRow != m1.nRow)
     {
         throw new MismatchedSizeException("GMatrix.mulTransposeRight matrix dimension mismatch");
     }
     if (m1 == this || m2 == this)
     {
         //double[][] tmp = new double[nRow][nCol];
         double[][] tmp = new double[][] { new double[7], new double[7], new double[7], new
             double[7], new double[7], new double[7], new double[7] };
         for (i = 0; i < nRow; i++)
         {
             for (j = 0; j < nCol; j++)
             {
                 tmp[i][j] = 0.0;
                 for (k = 0; k < m1.nCol; k++)
                 {
                     tmp[i][j] += m1.values[i][k] * m2.values[j][k];
                 }
             }
         }
         values = tmp;
     }
     else
     {
         for (i = 0; i < nRow; i++)
         {
             for (j = 0; j < nCol; j++)
             {
                 values[i][j] = 0.0;
                 for (k = 0; k < m1.nCol; k++)
                 {
                     values[i][j] += m1.values[i][k] * m2.values[j][k];
                 }
             }
         }
     }
 }
示例#13
0
 /// <summary>
 /// Constructs a new GMatrix and copies the initial values
 /// from the parameter matrix.
 /// </summary>
 /// <remarks>
 /// Constructs a new GMatrix and copies the initial values
 /// from the parameter matrix.
 /// </remarks>
 /// <param name="matrix">the source of the initial values of the new GMatrix</param>
 public GMatrix(GMatrix matrix)
 {
     nRow = matrix.nRow;
     nCol = matrix.nCol;
     //values = new double[nRow][nCol];
     values = new double[][] { new double[7], new double[7], new double[7], new double
         [7], new double[7], new double[7], new double[7] };
     int i;
     int j;
     for (i = 0; i < nRow; i++)
     {
         for (j = 0; j < nCol; j++)
         {
             values[i][j] = matrix.values[i][j];
         }
     }
 }
示例#14
0
 /// <summary>General invert routine.</summary>
 /// <remarks>
 /// General invert routine.  Inverts m1 and places the result in "this".
 /// Note that this routine handles both the "this" version and the
 /// non-"this" version.
 /// Also note that since this routine is slow anyway, we won't worry
 /// about allocating a little bit of garbage.
 /// </remarks>
 internal void InvertGeneral(GMatrix m1)
 {
     int size = m1.nRow * m1.nCol;
     double[] temp = new double[size];
     double[] result = new double[size];
     int[] row_perm = new int[m1.nRow];
     int[] even_row_exchange = new int[1];
     int i;
     int j;
     // Use LU decomposition and backsubstitution code specifically
     // for floating-point nxn matrices.
     if (m1.nRow != m1.nCol)
     {
         // Matrix is either under or over determined
         throw new MismatchedSizeException("cannot invert non square matrix");
     }
     // Copy source matrix to temp
     for (i = 0; i < nRow; i++)
     {
         for (j = 0; j < nCol; j++)
         {
             temp[i * nCol + j] = m1.values[i][j];
         }
     }
     // Calculate LU decomposition: Is the matrix singular?
     if (!LuDecomposition(m1.nRow, temp, row_perm, even_row_exchange))
     {
         // Matrix has no inverse
         throw new SingularMatrixException("cannot invert matrix");
     }
     // Perform back substitution on the identity matrix
     for (i = 0; i < size; i++)
     {
         result[i] = 0.0;
     }
     for (i = 0; i < nCol; i++)
     {
         result[i + i * nCol] = 1.0;
     }
     LuBacksubstitution(m1.nRow, temp, row_perm, result);
     for (i = 0; i < nRow; i++)
     {
         for (j = 0; j < nCol; j++)
         {
             values[i][j] = result[i * nCol + j];
         }
     }
 }
示例#15
0
 /// <summary>
 /// Finds the singular value decomposition (SVD) of this matrix
 /// such that this = U*W*transpose(V); and returns the rank of
 /// this matrix; the values of U,W,V are all overwritten.
 /// </summary>
 /// <remarks>
 /// Finds the singular value decomposition (SVD) of this matrix
 /// such that this = U*W*transpose(V); and returns the rank of
 /// this matrix; the values of U,W,V are all overwritten.  Note
 /// that the matrix V is output as V, and
 /// not transpose(V).  If this matrix is mxn, then U is mxm, W
 /// is a diagonal matrix that is mxn, and V is nxn.  Using the
 /// notation W = diag(w), then the inverse of this matrix is:
 /// inverse(this) = V*diag(1/w)*tranpose(U), where diag(1/w)
 /// is the same matrix as W except that the reciprocal of each
 /// of the diagonal components is used.
 /// </remarks>
 /// <param name="U">The computed U matrix in the equation this = U*W*transpose(V)</param>
 /// <param name="W">The computed W matrix in the equation this = U*W*transpose(V)</param>
 /// <param name="V">The computed V matrix in the equation this = U*W*transpose(V)</param>
 /// <returns>The rank of this matrix.</returns>
 public int Svd(GMatrix U, GMatrix W, GMatrix V)
 {
     // check for consistancy in dimensions
     if (nCol != V.nCol || nCol != V.nRow)
     {
         throw new MismatchedSizeException("GMatrix.SVD: dimension mismatch with V matrix");
     }
     if (nRow != U.nRow || nRow != U.nCol)
     {
         throw new MismatchedSizeException("GMatrix.SVD: dimension mismatch with U matrix");
     }
     if (nRow != W.nRow || nCol != W.nCol)
     {
         throw new MismatchedSizeException("GMatrix.SVD: dimension mismatch with W matrix");
     }
     // Fix ArrayIndexOutOfBounds for 2x2 matrices, which partially
     // addresses bug 4348562 for J3D 1.2.1.
     //
     // Does *not* fix the following problems reported in 4348562,
     // which will wait for J3D 1.3:
     //
     //   1) no output of W
     //   2) wrong transposition of U
     //   3) wrong results for 4x4 matrices
     //   4) slow performance
     if (nRow == 2 && nCol == 2)
     {
         if (values[1][0] == 0.0)
         {
             U.SetIdentity();
             V.SetIdentity();
             if (values[0][1] == 0.0)
             {
                 return 2;
             }
             double[] sinl = new double[1];
             double[] sinr = new double[1];
             double[] cosl = new double[1];
             double[] cosr = new double[1];
             double[] single_values = new double[2];
             single_values[0] = values[0][0];
             single_values[1] = values[1][1];
             Compute_2X2(values[0][0], values[0][1], values[1][1], single_values, sinl, cosl,
                 sinr, cosr, 0);
             Update_u(0, U, cosl, sinl);
             Update_v(0, V, cosr, sinr);
             return 2;
         }
     }
     // else call computeSVD() and check for 2x2 there
     return ComputeSVD(this, U, W, V);
 }
示例#16
0
        private static void Chase_across(double[] s, double[] e, int k, GMatrix u
			)
        {
            double f;
            double g;
            double r;
            double[] cosl = new double[1];
            double[] sinl = new double[1];
            int i;
            GMatrix t = new GMatrix(u.nRow, u.nCol);
            GMatrix m = new GMatrix(u.nRow, u.nCol);
            g = e[k];
            f = s[k + 1];
            for (i = k; i < u.nCol - 2; i++)
            {
                r = Compute_rot(f, g, sinl, cosl);
                g = -e[i + 1] * sinl[0];
                f = s[i + 2];
                s[i + 1] = r;
                e[i + 1] = e[i + 1] * cosl[0];
                Update_u_split(k, i + 1, u, cosl, sinl, t, m);
            }
            s[i + 1] = Compute_rot(f, g, sinl, cosl);
            Update_u_split(k, i + 1, u, cosl, sinl, t, m);
        }
示例#17
0
 /// <summary>Places the matrix values of the transpose of matrix m1 into this matrix.
 /// 	</summary>
 /// <remarks>Places the matrix values of the transpose of matrix m1 into this matrix.
 /// 	</remarks>
 /// <param name="m1">the matrix to be transposed (but not modified)</param>
 public void Transpose(GMatrix m1)
 {
     int i;
     int j;
     if (nRow != m1.nCol || nCol != m1.nRow)
     {
         throw new MismatchedSizeException("GMatrix.transpose(GMatrix) mismatch in matrix dimensions");
     }
     if (m1 != this)
     {
         for (i = 0; i < nRow; i++)
         {
             for (j = 0; j < nCol; j++)
             {
                 values[i][j] = m1.values[j][i];
             }
         }
     }
     else
     {
         Transpose();
     }
 }
示例#18
0
 private static void CheckMatrix(GMatrix m)
 {
     int i;
     int j;
     for (i = 0; i < m.nRow; i++)
     {
         for (j = 0; j < m.nCol; j++)
         {
             if (Math.Abs(m.values[i][j]) < 0.0000000001)
             {
                 System.Console.Out.Write(" 0.0     ");
             }
             else
             {
                 System.Console.Out.Write(" " + m.values[i][j]);
             }
         }
         System.Console.Out.Write("\n");
     }
 }
示例#19
0
        internal static int ComputeSVD(GMatrix mat, GMatrix U, GMatrix
			 W, GMatrix V)
        {
            int i;
            int j;
            int k;
            int nr;
            int nc;
            int si;
            int converged;
            int rank;
            double cs;
            double sn;
            double r;
            double mag;
            double scale;
            double t;
            int eLength;
            int sLength;
            int vecLength;
            GMatrix tmp = new GMatrix(mat.nRow, mat.nCol);
            GMatrix u = new GMatrix(mat.nRow, mat.nCol);
            GMatrix v = new GMatrix(mat.nRow, mat.nCol);
            GMatrix m = new GMatrix(mat);
            // compute the number of singular values
            if (m.nRow >= m.nCol)
            {
                sLength = m.nCol;
                eLength = m.nCol - 1;
            }
            else
            {
                sLength = m.nRow;
                eLength = m.nRow;
            }
            if (m.nRow > m.nCol)
            {
                vecLength = m.nRow;
            }
            else
            {
                vecLength = m.nCol;
            }
            double[] vec = new double[vecLength];
            double[] single_values = new double[sLength];
            double[] e = new double[eLength];
            rank = 0;
            U.SetIdentity();
            V.SetIdentity();
            nr = m.nRow;
            nc = m.nCol;
            // householder reduction
            for (si = 0; si < sLength; si++)
            {
                // for each singular value
                if (nr > 1)
                {
                    // zero out column
                    // compute reflector
                    mag = 0.0;
                    for (i = 0; i < nr; i++)
                    {
                        mag += m.values[i + si][si] * m.values[i + si][si];
                    }
                    mag = Math.Sqrt(mag);
                    if (m.values[si][si] == 0.0)
                    {
                        vec[0] = mag;
                    }
                    else
                    {
                        vec[0] = m.values[si][si] + D_sign(mag, m.values[si][si]);
                    }
                    for (i = 1; i < nr; i++)
                    {
                        vec[i] = m.values[si + i][si];
                    }
                    scale = 0.0;
                    for (i = 0; i < nr; i++)
                    {
                        scale += vec[i] * vec[i];
                    }
                    scale = 2.0 / scale;
                    for (j = si; j < m.nRow; j++)
                    {
                        for (k = si; k < m.nRow; k++)
                        {
                            u.values[j][k] = -scale * vec[j - si] * vec[k - si];
                        }
                    }
                    for (i = si; i < m.nRow; i++)
                    {
                        u.values[i][i] += 1.0;
                    }
                    // compute s
                    t = 0.0;
                    for (i = si; i < m.nRow; i++)
                    {
                        t += u.values[si][i] * m.values[i][si];
                    }
                    m.values[si][si] = t;
                    // apply reflector
                    for (j = si; j < m.nRow; j++)
                    {
                        for (k = si + 1; k < m.nCol; k++)
                        {
                            tmp.values[j][k] = 0.0;
                            for (i = si; i < m.nCol; i++)
                            {
                                tmp.values[j][k] += u.values[j][i] * m.values[i][k];
                            }
                        }
                    }
                    for (j = si; j < m.nRow; j++)
                    {
                        for (k = si + 1; k < m.nCol; k++)
                        {
                            m.values[j][k] = tmp.values[j][k];
                        }
                    }
                    // update U matrix
                    for (j = si; j < m.nRow; j++)
                    {
                        for (k = 0; k < m.nCol; k++)
                        {
                            tmp.values[j][k] = 0.0;
                            for (i = si; i < m.nCol; i++)
                            {
                                tmp.values[j][k] += u.values[j][i] * U.values[i][k];
                            }
                        }
                    }
                    for (j = si; j < m.nRow; j++)
                    {
                        for (k = 0; k < m.nCol; k++)
                        {
                            U.values[j][k] = tmp.values[j][k];
                        }
                    }
                    nr--;
                }
                if (nc > 2)
                {
                    // zero out row
                    mag = 0.0;
                    for (i = 1; i < nc; i++)
                    {
                        mag += m.values[si][si + i] * m.values[si][si + i];
                    }
                    // generate the reflection vector, compute the first entry and
                    // copy the rest from the row to be zeroed
                    mag = Math.Sqrt(mag);
                    if (m.values[si][si + 1] == 0.0)
                    {
                        vec[0] = mag;
                    }
                    else
                    {
                        vec[0] = m.values[si][si + 1] + D_sign(mag, m.values[si][si + 1]);
                    }
                    for (i = 1; i < nc - 1; i++)
                    {
                        vec[i] = m.values[si][si + i + 1];
                    }
                    // use reflection vector to compute v matrix
                    scale = 0.0;
                    for (i = 0; i < nc - 1; i++)
                    {
                        scale += vec[i] * vec[i];
                    }
                    scale = 2.0 / scale;
                    for (j = si + 1; j < nc; j++)
                    {
                        for (k = si + 1; k < m.nCol; k++)
                        {
                            v.values[j][k] = -scale * vec[j - si - 1] * vec[k - si - 1];
                        }
                    }
                    for (i = si + 1; i < m.nCol; i++)
                    {
                        v.values[i][i] += 1.0;
                    }
                    t = 0.0;
                    for (i = si; i < m.nCol; i++)
                    {
                        t += v.values[i][si + 1] * m.values[si][i];
                    }
                    m.values[si][si + 1] = t;
                    // apply reflector
                    for (j = si + 1; j < m.nRow; j++)
                    {
                        for (k = si + 1; k < m.nCol; k++)
                        {
                            tmp.values[j][k] = 0.0;
                            for (i = si + 1; i < m.nCol; i++)
                            {
                                tmp.values[j][k] += v.values[i][k] * m.values[j][i];
                            }
                        }
                    }
                    for (j = si + 1; j < m.nRow; j++)
                    {
                        for (k = si + 1; k < m.nCol; k++)
                        {
                            m.values[j][k] = tmp.values[j][k];
                        }
                    }
                    // update V matrix
                    for (j = 0; j < m.nRow; j++)
                    {
                        for (k = si + 1; k < m.nCol; k++)
                        {
                            tmp.values[j][k] = 0.0;
                            for (i = si + 1; i < m.nCol; i++)
                            {
                                tmp.values[j][k] += v.values[i][k] * V.values[j][i];
                            }
                        }
                    }
                    for (j = 0; j < m.nRow; j++)
                    {
                        for (k = si + 1; k < m.nCol; k++)
                        {
                            V.values[j][k] = tmp.values[j][k];
                        }
                    }
                    nc--;
                }
            }
            for (i = 0; i < sLength; i++)
            {
                single_values[i] = m.values[i][i];
            }
            for (i = 0; i < eLength; i++)
            {
                e[i] = m.values[i][i + 1];
            }
            // Fix ArrayIndexOutOfBounds for 2x2 matrices, which partially
            // addresses bug 4348562 for J3D 1.2.1.
            //
            // Does *not* fix the following problems reported in 4348562,
            // which will wait for J3D 1.3:
            //
            //   1) no output of W
            //   2) wrong transposition of U
            //   3) wrong results for 4x4 matrices
            //   4) slow performance
            if (m.nRow == 2 && m.nCol == 2)
            {
                double[] cosl = new double[1];
                double[] cosr = new double[1];
                double[] sinl = new double[1];
                double[] sinr = new double[1];
                Compute_2X2(single_values[0], e[0], single_values[1], single_values, sinl, cosl,
                    sinr, cosr, 0);
                Update_u(0, U, cosl, sinl);
                Update_v(0, V, cosr, sinr);
                return 2;
            }
            // compute_qr causes ArrayIndexOutOfBounds for 2x2 matrices
            Compute_qr(0, e.Length - 1, single_values, e, U, V);
            // compute rank = number of non zero singular values
            rank = single_values.Length;
            // sort by order of size of single values
            // and check for zero's
            return rank;
        }
示例#20
0
        private static void Print_svd(double[] s, double[] e, GMatrix u, GMatrix
			 v)
        {
            int i;
            GMatrix mtmp = new GMatrix(u.nCol, v.nRow);
            System.Console.Out.WriteLine(" \ns = ");
            for (i = 0; i < s.Length; i++)
            {
                System.Console.Out.WriteLine(" " + s[i]);
            }
            System.Console.Out.WriteLine(" \ne = ");
            for (i = 0; i < e.Length; i++)
            {
                System.Console.Out.WriteLine(" " + e[i]);
            }
            System.Console.Out.WriteLine(" \nu  = \n" + u.ToString());
            System.Console.Out.WriteLine(" \nv  = \n" + v.ToString());
            mtmp.SetIdentity();
            for (i = 0; i < s.Length; i++)
            {
                mtmp.values[i][i] = s[i];
            }
            for (i = 0; i < e.Length; i++)
            {
                mtmp.values[i][i + 1] = e[i];
            }
            System.Console.Out.WriteLine(" \nm  = \n" + mtmp.ToString());
            mtmp.MulTransposeLeft(u, mtmp);
            mtmp.MulTransposeRight(mtmp, v);
            System.Console.Out.WriteLine(" \n u.transpose*m*v.transpose  = \n" + mtmp.ToString
                ());
        }
示例#21
0
        /// <summary>Copies a sub-matrix derived from this matrix into the target matrix.</summary>
        /// <remarks>
        /// Copies a sub-matrix derived from this matrix into the target matrix.
        /// The upper left of the sub-matrix is located at (rowSource, colSource);
        /// the lower right of the sub-matrix is located at
        /// (lastRowSource,lastColSource).  The sub-matrix is copied into the
        /// the target matrix starting at (rowDest, colDest).
        /// </remarks>
        /// <param name="rowSource">the top-most row of the sub-matrix</param>
        /// <param name="colSource">the left-most column of the sub-matrix</param>
        /// <param name="numRow">the number of rows in the sub-matrix</param>
        /// <param name="numCol">the number of columns in the sub-matrix</param>
        /// <param name="rowDest">
        /// the top-most row of the position of the copied
        /// sub-matrix within the target matrix
        /// </param>
        /// <param name="colDest">
        /// the left-most column of the position of the copied
        /// sub-matrix within the target matrix
        /// </param>
        /// <param name="target">the matrix into which the sub-matrix will be copied</param>
        public void CopySubMatrix(int rowSource, int colSource, int numRow, int numCol, int
			 rowDest, int colDest, GMatrix target)
        {
            int i;
            int j;
            if (this != target)
            {
                for (i = 0; i < numRow; i++)
                {
                    for (j = 0; j < numCol; j++)
                    {
                        target.values[rowDest + i][colDest + j] = values[rowSource + i][colSource + j];
                    }
                }
            }
            else
            {
                //double[][] tmp = new double[numRow][numCol];
                double[][] tmp = new double[][] { new double[7], new double[7], new double[7], new
                    double[7], new double[7], new double[7], new double[7] };
                for (i = 0; i < numRow; i++)
                {
                    for (j = 0; j < numCol; j++)
                    {
                        tmp[i][j] = values[rowSource + i][colSource + j];
                    }
                }
                for (i = 0; i < numRow; i++)
                {
                    for (j = 0; j < numCol; j++)
                    {
                        target.values[rowDest + i][colDest + j] = tmp[i][j];
                    }
                }
            }
        }
示例#22
0
        private static void Update_u(int index, GMatrix u, double[] cosl, double[]
			 sinl)
        {
            int j;
            double utemp;
            for (j = 0; j < u.nCol; j++)
            {
                utemp = u.values[index][j];
                u.values[index][j] = cosl[0] * utemp + sinl[0] * u.values[index + 1][j];
                u.values[index + 1][j] = -sinl[0] * utemp + cosl[0] * u.values[index + 1][j];
            }
        }
示例#23
0
        internal static void Compute_qr(int start, int end, double[] s, double[] e, GMatrix
			 u, GMatrix v)
        {
            int i;
            int j;
            int k;
            int n;
            int sl;
            bool converged;
            double shift;
            double r;
            double utemp;
            double vtemp;
            double f;
            double g;
            double[] cosl = new double[1];
            double[] cosr = new double[1];
            double[] sinl = new double[1];
            double[] sinr = new double[1];
            GMatrix m = new GMatrix(u.nCol, v.nRow);
            int MaxInterations = 2;
            double ConvergeTol = 4.89E-15;
            double c_b48 = 1.0;
            double c_b71 = -1.0;
            converged = false;
            f = 0.0;
            g = 0.0;
            for (k = 0; k < MaxInterations && !converged; k++)
            {
                for (i = start; i <= end; i++)
                {
                    // if at start of iterfaction compute shift
                    if (i == start)
                    {
                        if (e.Length == s.Length)
                        {
                            sl = end;
                        }
                        else
                        {
                            sl = end + 1;
                        }
                        shift = Compute_shift(s[sl - 1], e[end], s[sl]);
                        f = (Math.Abs(s[i]) - shift) * (D_sign(c_b48, s[i]) + shift / s[i]);
                        g = e[i];
                    }
                    r = Compute_rot(f, g, sinr, cosr);
                    if (i != start)
                    {
                        e[i - 1] = r;
                    }
                    f = cosr[0] * s[i] + sinr[0] * e[i];
                    e[i] = cosr[0] * e[i] - sinr[0] * s[i];
                    g = sinr[0] * s[i + 1];
                    s[i + 1] = cosr[0] * s[i + 1];
                    // if (debug) print_se(s,e);
                    Update_v(i, v, cosr, sinr);
                    r = Compute_rot(f, g, sinl, cosl);
                    s[i] = r;
                    f = cosl[0] * e[i] + sinl[0] * s[i + 1];
                    s[i + 1] = cosl[0] * s[i + 1] - sinl[0] * e[i];
                    if (i < end)
                    {
                        // if not last
                        g = sinl[0] * e[i + 1];
                        e[i + 1] = cosl[0] * e[i + 1];
                    }
                    //if (debug) print_se(s,e);
                    Update_u(i, u, cosl, sinl);
                }
                // if extra off diagonal perform one more right side rotation
                if (s.Length == e.Length)
                {
                    r = Compute_rot(f, g, sinr, cosr);
                    f = cosr[0] * s[i] + sinr[0] * e[i];
                    e[i] = cosr[0] * e[i] - sinr[0] * s[i];
                    s[i + 1] = cosr[0] * s[i + 1];
                    Update_v(i, v, cosr, sinr);
                }
                // check for convergence on off diagonals and reduce
                while ((end - start > 1) && (Math.Abs(e[end]) < ConvergeTol))
                {
                    end--;
                }
                // check if need to split
                for (n = end - 2; n > start; n--)
                {
                    if (Math.Abs(e[n]) < ConvergeTol)
                    {
                        // split
                        Compute_qr(n + 1, end, s, e, u, v);
                        // do lower matrix
                        end = n - 1;
                        // do upper matrix
                        // check for convergence on off diagonals and reduce
                        while ((end - start > 1) && (Math.Abs(e[end]) < ConvergeTol))
                        {
                            end--;
                        }
                    }
                }
                if ((end - start <= 1) && (Math.Abs(e[start + 1]) < ConvergeTol))
                {
                    converged = true;
                }
            }
            // check if zero on the diagonal
            if (Math.Abs(e[1]) < ConvergeTol)
            {
                Compute_2X2(s[start], e[start], s[start + 1], s, sinl, cosl, sinr, cosr, 0);
                e[start] = 0.0;
                e[start + 1] = 0.0;
            }
            i = start;
            Update_u(i, u, cosl, sinl);
            Update_v(i, v, cosr, sinr);
            return;
        }
示例#24
0
        private static void Update_v(int index, GMatrix v, double[] cosr, double[]
			 sinr)
        {
            int j;
            double vtemp;
            for (j = 0; j < v.nRow; j++)
            {
                vtemp = v.values[j][index];
                v.values[j][index] = cosr[0] * vtemp + sinr[0] * v.values[j][index + 1];
                v.values[j][index + 1] = -sinr[0] * vtemp + cosr[0] * v.values[j][index + 1];
            }
        }
示例#25
0
 public virtual bool EpsilonEquals(GMatrix m1, float epsilon)
 {
     return EpsilonEquals(m1, (double)epsilon);
 }
示例#26
0
 /// <summary>
 /// Returns true if all of the data members of GMatrix m1 are
 /// equal to the corresponding data members in this GMatrix.
 /// </summary>
 /// <remarks>
 /// Returns true if all of the data members of GMatrix m1 are
 /// equal to the corresponding data members in this GMatrix.
 /// </remarks>
 /// <param name="m1">The matrix with which the comparison is made.</param>
 /// <returns>true or false</returns>
 public virtual bool Equals(GMatrix m1)
 {
     try
     {
         int i;
         int j;
         if (nRow != m1.nRow || nCol != m1.nCol)
         {
             return false;
         }
         for (i = 0; i < nRow; i++)
         {
             for (j = 0; j < nCol; j++)
             {
                 if (values[i][j] != m1.values[i][j])
                 {
                     return false;
                 }
             }
         }
         return true;
     }
     catch (ArgumentNullException)
     {
         return false;
     }
 }
示例#27
0
 /// <summary>
 /// Returns true if the L-infinite distance between this matrix
 /// and matrix m1 is less than or equal to the epsilon parameter,
 /// otherwise returns false.
 /// </summary>
 /// <remarks>
 /// Returns true if the L-infinite distance between this matrix
 /// and matrix m1 is less than or equal to the epsilon parameter,
 /// otherwise returns false.  The L-infinite
 /// distance is equal to
 /// MAX[i=0,1,2, . . .n ; j=0,1,2, . . .n ; abs(this.m(i,j) - m1.m(i,j)]
 /// </remarks>
 /// <param name="m1">The matrix to be compared to this matrix</param>
 /// <param name="epsilon">the threshold value</param>
 public virtual bool EpsilonEquals(GMatrix m1, double epsilon)
 {
     int i;
     int j;
     double diff;
     if (nRow != m1.nRow || nCol != m1.nCol)
     {
         return false;
     }
     for (i = 0; i < nRow; i++)
     {
         for (j = 0; j < nCol; j++)
         {
             diff = values[i][j] - m1.values[i][j];
             if ((diff < 0 ? -diff : diff) > epsilon)
             {
                 return false;
             }
         }
     }
     return true;
 }
示例#28
0
 /// <summary>Inverts matrix m1 and places the new values into this matrix.</summary>
 /// <remarks>
 /// Inverts matrix m1 and places the new values into this matrix.  Matrix
 /// m1 is not modified.
 /// </remarks>
 /// <param name="m1">the matrix to be inverted</param>
 public void Invert(GMatrix m1)
 {
     InvertGeneral(m1);
 }
示例#29
0
 /// <summary>
 /// LU Decomposition: this matrix must be a square matrix and the
 /// LU GMatrix parameter must be the same size as this matrix.
 /// </summary>
 /// <remarks>
 /// LU Decomposition: this matrix must be a square matrix and the
 /// LU GMatrix parameter must be the same size as this matrix.
 /// The matrix LU will be overwritten as the combination of a
 /// lower diagonal and upper diagonal matrix decompostion of this
 /// matrix; the diagonal
 /// elements of L (unity) are not stored.  The GVector parameter
 /// records the row permutation effected by the partial pivoting,
 /// and is used as a parameter to the GVector method LUDBackSolve
 /// to solve sets of linear equations.
 /// This method returns +/- 1 depending on whether the number
 /// of row interchanges was even or odd, respectively.
 /// </remarks>
 /// <param name="Lu">
 /// The matrix into which the lower and upper decompositions
 /// will be placed.
 /// </param>
 /// <param name="permutation">
 /// The row permutation effected by the partial
 /// pivoting
 /// </param>
 /// <returns>
 /// +-1 depending on whether the number of row interchanges
 /// was even or odd respectively
 /// </returns>
 public int Lud(GMatrix Lu, GVector permutation)
 {
     int size = Lu.nRow * Lu.nCol;
     double[] temp = new double[size];
     int[] even_row_exchange = new int[1];
     int[] row_perm = new int[Lu.nRow];
     int i;
     int j;
     if (nRow != nCol)
     {
         throw new MismatchedSizeException("cannot perform LU decomposition on a non square matrix");
     }
     if (nRow != Lu.nRow)
     {
         throw new MismatchedSizeException("LU must have same dimensions as this matrix");
     }
     if (nCol != Lu.nCol)
     {
         throw new MismatchedSizeException("LU must have same dimensions as this matrix");
     }
     if (Lu.nRow != permutation.GetSize())
     {
         throw new MismatchedSizeException("row permutation must be same dimension as matrix");
     }
     for (i = 0; i < nRow; i++)
     {
         for (j = 0; j < nCol; j++)
         {
             temp[i * nCol + j] = values[i][j];
         }
     }
     // Calculate LU decomposition: Is the matrix singular?
     if (!LuDecomposition(Lu.nRow, temp, row_perm, even_row_exchange))
     {
         // Matrix has no inverse
         throw new SingularMatrixException("cannot invert matrix");
     }
     for (i = 0; i < nRow; i++)
     {
         for (j = 0; j < nCol; j++)
         {
             Lu.values[i][j] = temp[i * nCol + j];
         }
     }
     for (i = 0; i < Lu.nRow; i++)
     {
         permutation.values[i] = (double)row_perm[i];
     }
     return even_row_exchange[0];
 }