Exemplo n.º 1
0
 ///<summary>Constructor for QR decomposition class. The constructor performs the factorization and the upper and
 ///lower matrices are accessible by the <c>Q</c> and <c>R</c> properties.</summary>
 ///<param name="matrix">The matrix to factor.</param>
 ///<exception cref="ArgumentNullException">matrix is null.</exception>
 public FloatQRDecomp(IROFloatMatrix matrix)
 {
     if (matrix == null)
     {
         throw new System.ArgumentNullException("matrix cannot be null.");
     }
     this.matrix = new FloatMatrix(matrix);
 }
Exemplo n.º 2
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution matrix, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="SingularMatrixException">Ais singular.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and B must be the same.</exception>
        public FloatMatrix Solve(IROFloatMatrix B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (singular)
            {
                throw new SingularMatrixException();
            }
            else
            {
                if (B.Rows != order)
                {
                    throw new System.ArgumentException("Matrix row dimensions must agree.");
                }
#if MANAGED
                // Copy right hand side with pivoting
                int         nx = B.Columns;
                FloatMatrix X  = Pivot(B);

                // Solve L*Y = B(piv,:)
                for (int k = 0; k < order; k++)
                {
                    for (int i = k + 1; i < order; i++)
                    {
                        for (int j = 0; j < nx; j++)
                        {
                            X.data[i][j] -= X.data[k][j] * factor[i][k];
                        }
                    }
                }
                // Solve U*X = Y;
                for (int k = order - 1; k >= 0; k--)
                {
                    for (int j = 0; j < nx; j++)
                    {
                        X.data[k][j] /= factor[k][k];
                    }
                    for (int i = 0; i < k; i++)
                    {
                        for (int j = 0; j < nx; j++)
                        {
                            X.data[i][j] -= X.data[k][j] * factor[i][k];
                        }
                    }
                }
                return(X);
#else
                float[] rhs = FloatMatrix.ToLinearArray(B);
                Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, B.Columns, factor, order, pivots, rhs, B.Rows);
                FloatMatrix ret = new FloatMatrix(order, B.Columns);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
Exemplo n.º 3
0
 ///<summary>Constructor for SVD decomposition class.</summary>
 ///<param name="matrix">The matrix to decompose.</param>
 ///<param name="computeVectors">Whether to compute the singular vectors or not.</param>
 ///<exception cref="ArgumentNullException">matrix is null.</exception>
 public FloatSVDDecomp(IROFloatMatrix matrix, bool computeVectors)
 {
     if (matrix == null)
     {
         throw new System.ArgumentNullException("matrix cannot be null.");
     }
     this.matrix         = new FloatMatrix(matrix);
     this.computeVectors = computeVectors;
 }
Exemplo n.º 4
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution matrix, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and B must be the same.</exception>
        public FloatMatrix Solve(IROFloatMatrix B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (!ispd)
            {
                throw new NotPositiveDefiniteException();
            }
            else
            {
                if (B.Rows != order)
                {
                    throw new System.ArgumentException("Matrix row dimensions must agree.");
                }
#if MANAGED
                // Copy right hand side.
                int         cols = B.Columns;
                FloatMatrix X    = new FloatMatrix(B);
                for (int c = 0; c < cols; c++)
                {
                    // Solve L*Y = B;
                    for (int i = 0; i < order; i++)
                    {
                        float sum = B[i, c];
                        for (int k = i - 1; k >= 0; k--)
                        {
                            sum -= l.data[i][k] * X.data[k][c];
                        }
                        X.data[i][c] = sum / l.data[i][i];
                    }

                    // Solve L'*X = Y;
                    for (int i = order - 1; i >= 0; i--)
                    {
                        float sum = X.data[i][c];
                        for (int k = i + 1; k < order; k++)
                        {
                            sum -= l.data[k][i] * X.data[k][c];
                        }
                        X.data[i][c] = sum / l.data[i][i];
                    }
                }

                return(X);
#else
                float[] rhs = FloatMatrix.ToLinearArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, B.Columns, l.data, order, rhs, B.Rows);
                FloatMatrix ret = new FloatMatrix(order, B.Columns);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
Exemplo n.º 5
0
        /// <summary>
        /// Returns the column of a <see cref="IROFloatMatrix" /> as a new <c>float[]</c> array.
        /// </summary>
        /// <param name="mat">The matrix to copy the column from.</param>
        /// <param name="col">Index of the column to copy from the matrix.</param>
        /// <returns>A new array of <c>float</c> with the same elements as the column of the given matrix.</returns>
        public static float[] GetColumnAsArray(IROFloatMatrix mat, int col)
        {
            float[] result = new float[mat.Rows];
            for (int i = 0; i < result.Length; ++i)
            {
                result[i] = mat[i, col];
            }

            return(result);
        }
Exemplo n.º 6
0
        /// <summary>
        /// Returns the column of a <see cref="IROFloatMatrix" /> as a new <c>FloatVector.</c>
        /// </summary>
        /// <param name="mat">The matrix to copy the column from.</param>
        /// <param name="col">Index of the column to copy from the matrix.</param>
        /// <returns>A new <c>FloatVector</c> with the same elements as the column of the given matrix.</returns>
        public static FloatVector GetColumn(IROFloatMatrix mat, int col)
        {
            FloatVector result = new FloatVector(mat.Rows);

            for (int i = 0; i < result.data.Length; ++i)
            {
                result.data[i] = mat[i, col];
            }

            return(result);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Returns the row of a <see cref="IROFloatMatrix" /> as a new <c>FloatVector.</c>
        /// </summary>
        /// <param name="mat">The matrix to copy the column from.</param>
        /// <param name="row">Index of the row to copy from the matrix.</param>
        /// <returns>A new <c>DoubleVector</c> with the same elements as the row of the given matrix.</returns>
        public static FloatVector GetRow(IROFloatMatrix mat, int row)
        {
            FloatVector result = new FloatVector(mat.Columns);

            for (int i = 0; i < result.data.Length; ++i)
            {
                result.data[i] = mat[row, i];
            }

            return(result);
        }
Exemplo n.º 8
0
        ///<summary>Constructor for LU decomposition class. The constructor performs the factorization and the upper and
        ///lower matrices are accessible by the <c>U</c> and <c>L</c> properties.</summary>
        ///<param name="matrix">The matrix to factor.</param>
        ///<exception cref="ArgumentNullException">matrix is null.</exception>
        ///<exception cref="NotSquareMatrixException">matrix is not square.</exception>
        public FloatLUDecomp(IROFloatMatrix matrix)
        {
            if (matrix == null)
            {
                throw new System.ArgumentNullException("matrix cannot be null.");
            }

            if (matrix.Rows != matrix.Columns)
            {
                throw new NotSquareMatrixException("Matrix must be square.");
            }

            order       = matrix.Columns;
            this.matrix = new FloatMatrix(matrix);
        }
Exemplo n.º 9
0
		///<summary>Constructor for Cholesky decomposition class. The constructor performs the factorization of a symmetric positive
		///definite matrax and the Cholesky factored matrix is accessible by the <c>Factor</c> property. The factor is the lower
		///triangular factor.</summary>
		///<param name="matrix">The matrix to factor.</param>
		///<exception cref="ArgumentNullException">matrix is null.</exception>
		///<exception cref="NotSquareMatrixException">matrix is not square.</exception>
		///<remarks>This class only uses the lower triangle of the input matrix. It ignores the
		///upper triangle.</remarks>
		public FloatCholeskyDecomp(IROFloatMatrix matrix)
		{
			if (matrix == null)
			{
				throw new System.ArgumentNullException("matrix cannot be null.");
			}

			if (matrix.Rows != matrix.Columns)
			{
				throw new NotSquareMatrixException("Matrix must be square.");
			}

			order = matrix.Columns;
			this.matrix = new FloatMatrix(matrix);
		}
Exemplo n.º 10
0
        private FloatMatrix Pivot(IROFloatMatrix B)
        {
            int m = B.Rows;
            int n = B.Columns;

            FloatMatrix ret = new FloatMatrix(m, n);

            for (int i = 0; i < pivots.Length; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    ret.data[i][j] = B[pivots[i], j];
                }
            }
            return(ret);
        }
Exemplo n.º 11
0
 ///<summary>Constructor for QR decomposition class. The constructor performs the factorization and the upper and
 ///lower matrices are accessible by the <c>Q</c> and <c>R</c> properties.</summary>
 ///<param name="matrix">The matrix to factor.</param>
 ///<exception cref="ArgumentNullException">matrix is null.</exception>
 public FloatQRDecomp(IROFloatMatrix matrix) 
 {
   if (matrix == null)
     throw new System.ArgumentNullException("matrix cannot be null.");
   this.matrix = new FloatMatrix(matrix);
 }
Exemplo n.º 12
0
    /// <summary>Finds the least squares solution of <c>A*X = B</c>, where <c>m &gt;= n</c></summary>
    /// <param name="B">A matrix with as many rows as A and any number of columns.</param>
    /// <returns>X that minimizes the two norm of <c>Q*R*X-B</c>.</returns>
    /// <exception cref="ArgumentException">Matrix row dimensions must agree.</exception>
    /// <exception cref="InvalidOperationException">Matrix is rank deficient or <c>m &lt; n</c>.</exception>
    public FloatMatrix Solve (IROFloatMatrix B) 
    {
      if (B.Rows != matrix.RowLength) 
      {
        throw new ArgumentException("Matrix row dimensions must agree.");
      }
      if (matrix.RowLength < matrix.ColumnLength) 
      {
        throw new System.InvalidOperationException("A must have at lest as a many rows as columns.");
      } 
      Compute();
      if (!this.isFullRank) 
      {
        throw new System.InvalidOperationException("Matrix is rank deficient.");
      }
      
      // Copy right hand side
      int m = matrix.RowLength;
      int n = matrix.ColumnLength;
      int nx = B.Columns;
      FloatMatrix ret = new FloatMatrix(n,nx);

#if MANAGED
      FloatMatrix X = new FloatMatrix(B);
      // Compute Y = transpose(Q)*B
      float[] column = new float[q_.RowLength];
      for (int j = 0; j < nx; j++) 
      {
        for (int k = 0; k < m; k++) 
        {
          column[k] = X.data[k][j];
        }
        for (int i = 0; i < m; i++) 
        {
          float s = 0;
          for (int k = 0; k < m; k++) 
          {
            s += q_.data[k][i] * column[k];
          }
          X.data[i][j] = s;
        } 
      }

      // Solve R*X = Y;
      for (int k = n-1; k >= 0; k--) 
      {
        for (int j = 0; j < nx; j++) 
        {
          X.data[k][j] /= r_.data[k][k];
        }
        for (int i = 0; i < k; i++) 
        {
          for (int j = 0; j < nx; j++) 
          {
            X.data[i][j] -= X.data[k][j]*r_.data[i][k];
          }
        }
      }
      for( int i = 0; i < n; i++ )
      {
        for( int j = 0; j < nx; j++ )
        {
          ret.data[i][j] = X.data[i][j];
        }
      }

#else
      float[] c = FloatMatrix.ToLinearArray(B);
      Lapack.Ormqr.Compute(Lapack.Side.Left, Lapack.Transpose.Trans, m, nx, n, qr, m, tau, c, m);
      Blas.Trsm.Compute(Blas.Order.ColumnMajor, Blas.Side.Left, Blas.UpLo.Upper, Blas.Transpose.NoTrans, Blas.Diag.NonUnit,
        n, nx, 1, qr, m, c, m);
      for ( int i = 0; i < n; i++ ) {
        for ( int j = 0; j < nx; j++) {
          ret.data[j*n+i] = c[j*m+(jpvt[i]-1)];
        }
      }

#endif
      return ret;
    }
    /// <summary>
    /// Solve a symmetric square Toeplitz system with a right-side matrix.
    /// </summary>
    /// <param name="Y">The right-hand side of the system.</param>
    /// <returns>The solution matrix.</returns>
    /// <exception cref="ArgumentNullException">
    /// Parameter <B>Y</B> is a null reference.
    /// </exception>
    /// <exception cref="RankException">
    /// The number of rows in <B>Y</B> is not equal to the number of rows in the Toeplitz matrix.
    /// </exception>
    /// <exception cref="SingularMatrixException">
    /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
    /// </exception>
    /// <remarks>
    /// This member solves the linear system <B>TX</B> = <B>Y</B>, where <B>T</B> is
    /// a symmetric square Toeplitz matrix, <B>X</B> is the unknown solution matrix
    /// and <B>Y</B> is a known matrix.
    /// <para>
    /// The class implicitly decomposes the inverse Toeplitz matrix into a <b>UDL</b> factorisation
    /// using the Levinson algorithm, and then calculates the solution matrix.
    /// </para>
    /// </remarks>
    public FloatMatrix Solve(IROFloatMatrix Y)
    {
      FloatMatrix X;

      // check parameters
      if (Y == null)
      {
        throw new System.ArgumentNullException("Y");
      }
      else if (m_Order != Y.Columns)
      {
        throw new RankException("The numer of rows in Y is not equal to the number of rows in the Toeplitz matrix.");
      }

      Compute();

      if (m_IsSingular == true)
      {
        throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular.");
      }

      int M = Y.Rows;
      int i, j, l, m;     // index/loop variables
      float[] Inner;      // inner product
      float[] G;        // scaling constant
      float[] A;        // reference to current order coefficients
      float scalar;

      // allocate memory for solution
      X = new FloatMatrix(m_Order, M);
      Inner = new float[M];
      G = new float[M];

      // setup zero order solution
      scalar = 1.0f / m_LeftColumn[0];
      for (m = 0; m < M; m++)
      {
#if MANAGED
        X.data[0][m] = scalar * Y[0,m];
#else

        X.data[m*m_Order] = scalar * Y[0,m];
#endif
      }

      // solve systems of increasing order
      for (i = 1; i < m_Order; i++)
      {
        // calculate inner product
        for (m = 0; m < M; m++)
        {
#if MANAGED
          Inner[m] = Y[i,m];
#else
          Inner[m] = Y[i,m];
#endif
        }

        for (j = 0, l = i; j < i; j++, l--)
        {
          scalar = m_LeftColumn[l];
          for (m = 0; m < M; m++)
          {
#if MANAGED
            Inner[m] -= scalar * X.data[j][m];
#else
            Inner[m] -= scalar * X.data[m*m_Order+j];
#endif
          }
        }

        // get the current predictor coefficients row
        A = m_LowerTriangle[i];

        // update the solution matrix
        for (m = 0; m < M; m++)
        {
          G[m] = m_Diagonal[i] * Inner[m];
        }
        for (j = 0; j <= i; j++)
        {
          scalar = A[j];
          for (m = 0; m < M; m++)
          {
#if MANAGED
            X.data[j][m] += scalar * G[m];
#else
            X.data[m*m_Order+j] += scalar * G[m];
#endif
          }
        }
      }

      return X;
    }
    /// <summary>
    /// Solve a symmetric square Toeplitz system with a right-side matrix.
    /// </summary>
    /// <param name="T">The left-most column of the Toeplitz matrix.</param>
    /// <param name="Y">The right-side matrix of the system.</param>
    /// <returns>The solution matrix.</returns>
    /// <exception cref="ArgumentNullException">
    /// <B>T</B> and/or <B>Y</B> are null references
    /// </exception>
    /// <exception cref="RankException">
    /// The length of <B>T</B> does not match the number of rows in <B>Y</B>.
    /// </exception>
    /// <exception cref="SingularMatrixException">
    /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
    /// </exception>
    /// <remarks>
    /// This method solves the linear system <B>AX</B> = <B>Y</B>. Where
    /// <B>T</B> is a symmetric square Toeplitz matrix, <B>X</B> is an unknown
    /// matrix and <B>Y</B> is a known matrix.
    /// <para>
    /// This static member combines the <b>UDL</b> decomposition and the calculation of the solution into a
    /// single algorithm. When compared to the non-static member it requires minimal data storage
    /// and suffers from no speed penalty.
    /// </para>
    /// </remarks>
    public static FloatMatrix Solve(IROFloatVector T, IROFloatMatrix Y)
    {

      FloatMatrix X;

      // check parameters
      if (T == null)
      {
        throw new System.ArgumentNullException("T");
      }
      else if (Y == null)
      {
        throw new System.ArgumentNullException("Y");
      }
      else if (T.Length != Y.Columns)
      {
        throw new RankException("The length of T and Y are not equal.");
      }
      else
      {

        // allocate memory
        int N = T.Length;
        int M = Y.Rows;
        X = new FloatMatrix(N, M);                 // solution matrix
        FloatVector Z = new FloatVector(N);       // temporary storage vector
        float e;                                   // prediction error
        int i, j, l, m;

        // setup zero order solution
        e = T[0];
        if (e == 0.0f)
        {
          throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular.");
        }
        for (m = 0; m < M; m++)
        {
          X[0, m] = Y[0, m] / T[0];
        }

        if (N > 1)
        {

          FloatVector a = new FloatVector(N - 1);   // prediction coefficients
          float p;                                   // reflection coefficient
          float inner;                               // inner product
          float k;

          // calculate solution for successive orders
          for (i = 1; i < N; i++)
          {

            // calculate first inner product
            inner = T[i];
            for (j = 0, l = i - 1; j < i - 1; j++, l--)
            {
              inner += a[j] * T[l];
            }

            // update predictor coefficients
            p = -(inner / e);
            for (j = 0, l = i - 2; j < i - 1; j++, l--)
            {
              Z[j] = a[j] + p * a[l];
            }

            // copy vector
            for (j = 0; j < i - 1; j++)
            {
              a[j] = Z[j];
            }

            a[i - 1] = p;
            e *= (1.0f - p * p);

            if (e == 0.0f)
            {
              throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular.");
            }

            // update the solution matrix
            for (m = 0; m < M; m++)
            {

              // retrieve a copy of solution column
              for (j = 0; j < i; j++)
              {
                Z[j] = X[j, m];
              }

              // calculate second inner product
              inner = Y[i, m];
              for (j = 0, l = i; j < i; j++, l--)
              {
                inner -= Z[j] * T[l];
              }

              // update solution vector
              k = inner / e;
              for (j = 0, l = i - 1; j < i; j++, l--)
              {
                Z[j] = Z[j] + k * a[l];
              }
              Z[j] = k;

              // store solution column in matrix
              for (j = 0; j <= i; j++)
              {
                X[j, m] = Z[j];
              }

            }

          }

        }

      }

      return X;
    }
 public static FloatMatrix Solve(AbstractROFloatVector T, IROFloatMatrix Y)
 {
   return Solve((IROFloatVector)T, Y);
 }
Exemplo n.º 16
0
        /// <summary>Finds the least squares solution of <c>A*X = B</c>, where <c>m &gt;= n</c></summary>
        /// <param name="B">A matrix with as many rows as A and any number of columns.</param>
        /// <returns>X that minimizes the two norm of <c>Q*R*X-B</c>.</returns>
        /// <exception cref="ArgumentException">Matrix row dimensions must agree.</exception>
        /// <exception cref="InvalidOperationException">Matrix is rank deficient or <c>m &lt; n</c>.</exception>
        public FloatMatrix Solve(IROFloatMatrix B)
        {
            if (B.Rows != matrix.RowLength)
            {
                throw new ArgumentException("Matrix row dimensions must agree.");
            }
            if (matrix.RowLength < matrix.ColumnLength)
            {
                throw new System.InvalidOperationException("A must have at lest as a many rows as columns.");
            }
            Compute();
            if (!this.isFullRank)
            {
                throw new System.InvalidOperationException("Matrix is rank deficient.");
            }

            // Copy right hand side
            int         m   = matrix.RowLength;
            int         n   = matrix.ColumnLength;
            int         nx  = B.Columns;
            FloatMatrix ret = new FloatMatrix(n, nx);

#if MANAGED
            FloatMatrix X = new FloatMatrix(B);
            // Compute Y = transpose(Q)*B
            float[] column = new float[q_.RowLength];
            for (int j = 0; j < nx; j++)
            {
                for (int k = 0; k < m; k++)
                {
                    column[k] = X.data[k][j];
                }
                for (int i = 0; i < m; i++)
                {
                    float s = 0;
                    for (int k = 0; k < m; k++)
                    {
                        s += q_.data[k][i] * column[k];
                    }
                    X.data[i][j] = s;
                }
            }

            // Solve R*X = Y;
            for (int k = n - 1; k >= 0; k--)
            {
                for (int j = 0; j < nx; j++)
                {
                    X.data[k][j] /= r_.data[k][k];
                }
                for (int i = 0; i < k; i++)
                {
                    for (int j = 0; j < nx; j++)
                    {
                        X.data[i][j] -= X.data[k][j] * r_.data[i][k];
                    }
                }
            }
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < nx; j++)
                {
                    ret.data[i][j] = X.data[i][j];
                }
            }
#else
            float[] c = FloatMatrix.ToLinearArray(B);
            Lapack.Ormqr.Compute(Lapack.Side.Left, Lapack.Transpose.Trans, m, nx, n, qr, m, tau, c, m);
            Blas.Trsm.Compute(Blas.Order.ColumnMajor, Blas.Side.Left, Blas.UpLo.Upper, Blas.Transpose.NoTrans, Blas.Diag.NonUnit,
                              n, nx, 1, qr, m, c, m);
            for (int i = 0; i < n; i++)
            {
                for (int j = 0; j < nx; j++)
                {
                    ret.data[j * n + i] = c[j * m + (jpvt[i] - 1)];
                }
            }
#endif
            return(ret);
        }
Exemplo n.º 17
0
    /// <summary>
    /// Solve a square Toeplitz system with a right-side matrix.
    /// </summary>
    /// <param name="col">The left-most column of the Toeplitz matrix.</param>
    /// <param name="row">The top-most row of the Toeplitz matrix.</param>
    /// <param name="Y">The right-side matrix of the system.</param>
    /// <returns>The solution matrix.</returns>
    /// <exception cref="ArgumentNullException">
    /// <EM>col</EM> is a null reference,
    /// <para>or</para>
    /// <para><EM>row</EM> is a null reference,</para>
    /// <para>or</para>
    /// <para><EM>Y</EM> is a null reference.</para>
    /// </exception>
    /// <exception cref="RankException">
    /// The length of <EM>col</EM> is 0,
    /// <para>or</para>
    /// <para>the lengths of <EM>col</EM> and <EM>row</EM> are not equal,</para>
    /// <para>or</para>
    /// <para>the number of rows in <EM>Y</EM> does not the length of <EM>col</EM> and <EM>row</EM>.</para>
    /// </exception>
    /// <exception cref="SingularMatrixException">
    /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
    /// </exception>
    /// <exception cref="ArithmeticException">
    /// The values of the first element of <EM>col</EM> and <EM>row</EM> are not equal.
    /// </exception>
    /// <remarks>
    /// This method solves the linear system <B>AX</B> = <B>Y</B>. Where
    /// <B>T</B> is a square Toeplitz matrix, <B>X</B> is an unknown
    /// matrix and <B>Y</B> is a known matrix.
    /// <para>
    /// The classic Levinson algorithm is used to solve the system. The algorithm
    /// assumes that all the leading sub-matrices of the Toeplitz matrix are
    /// non-singular. When a sub-matrix is near singular, accuracy will
    /// be degraded. This member requires approximately <B>N</B> squared
    /// FLOPS to calculate a solution, where <B>N</B> is the matrix order.
    /// </para>
    /// <para>
    /// This static method has minimal storage requirements as it combines
    /// the <b>UDL</b> decomposition with the calculation of the solution vector
    /// in a single algorithm.
    /// </para>
    /// </remarks>
    public static FloatMatrix Solve(IROFloatVector col, IROFloatVector row, IROFloatMatrix Y)
    {
      // check parameters
      if (col == null)
      {
        throw new System.ArgumentNullException("col");
      }
      else if (col.Length == 0)
      {
        throw new RankException("The length of col is zero.");
      }
      else if (row == null)
      {
        throw new System.ArgumentNullException("row");
      }
      else if (col.Length != row.Length)
      {
        throw new RankException("The lengths of col and row are not equal.");
      }
      else if (col[0] != row[0])
      {
        throw new ArithmeticException("The values of the first element of col and row are not equal.");
      }
      else if (Y == null)
      {
        throw new System.ArgumentNullException("Y");
      }
      else if (col.Length != Y.Columns)
      {
        throw new RankException("The numer of rows in Y does not match the length of col and row.");
      }

      // check if leading diagonal is zero
      if (col[0] == 0.0f)
      {
        throw new SingularMatrixException("One of the leading sub-matrices is singular.");
      }

      // decompose matrix
      int order = col.Length;
      float[] A = new float[order];
      float[] B = new float[order];
      float[] Z = new float[order];
      FloatMatrix X = new FloatMatrix(order);
      float Q, S, Ke, Kr, e;
      float Inner;
      int i, j, l;

      // setup the zero order solution
      A[0] = 1.0f;
      B[0] = 1.0f;
      e = 1.0f / col[0];
      X.SetRow(0, e * FloatVector.GetRow(Y,0));

      for (i = 1; i < order; i++)
      {
        // calculate inner products
        Q = 0.0f;
        for ( j = 0, l = 1; j < i; j++, l++)
        {
          Q += col[l] * A[j];
        }

        S = 0.0f;
        for ( j = 0, l = 1; j < i; j++, l++)
        {
          S += row[l] * B[j];
        }

        // reflection coefficients
        Kr = -S * e;
        Ke = -Q * e;

        // update lower triangle (in temporary storage)
        Z[0] = 0.0f;
        Array.Copy(A, 0, Z, 1, i);
        for (j = 0, l = i - 1; j < i; j++, l--)
        {
          Z[j] += Ke * B[l];
        }

        // update upper triangle
        for (j = i; j > 0; j--)
        {
          B[j] = B[j-1];
        }

        B[0] = 0.0f;
        for (j = 0, l = i - 1; j < i; j++, l--)
        {
          B[j] += Kr * A[l];
        }

        // copy from temporary storage to lower triangle
        Array.Copy(Z, 0, A, 0, i + 1);

        // check for singular sub-matrix)
        if (Ke * Kr == 1.0f)
        {
          throw new SingularMatrixException("One of the leading sub-matrices is singular.");
        }
      
        // update diagonal
        e = e / (1.0f - Ke * Kr);

        for (l = 0; l < Y.Rows; l++)
        {
          FloatVector W = X.GetColumn(l);
          FloatVector M = FloatVector.GetColumn(Y,l);

          Inner = M[i];
          for (j = 0; j < i; j++)
          {
            Inner += A[j] * M[j];
          }
          Inner *= e;

          W[i] = Inner;
          for (j = 0; j < i; j++)
          {
            W[j] += Inner * B[j];
          }

          X.SetColumn(l, W);
        }

      }

      return X;
    }
Exemplo n.º 18
0
    public static string MatrixToString(string name, IROFloatMatrix a)
    {
      if (null == name)
        name = "";

      if (a.Rows == 0 || a.Columns == 0)
        return string.Format("EmptyMatrix {0}({1},{2})", name, a.Rows, a.Columns);

      System.Text.StringBuilder s = new System.Text.StringBuilder();
      s.Append("Matrix " + name + ":");
      for (int i = 0; i < a.Rows; i++)
      {
        s.Append("\n(");
        for (int j = 0; j < a.Columns; j++)
        {
          s.Append(a[i, j].ToString());
          if (j + 1 < a.Columns)
            s.Append(";");
          else
            s.Append(")");
        }
      }
      return s.ToString();
    }
Exemplo n.º 19
0
    /// <summary>
    /// Solve a square Toeplitz system with a right-side matrix.
    /// </summary>
    /// <param name="Y">The right-side matrix</param>
    /// <returns>The solution matrix.</returns>
    /// <exception cref="ArgumentNullException">
    /// Parameter <B>Y</B> is a null reference.
    /// </exception>
    /// <exception cref="RankException">
    /// The number of rows in <B>Y</B> is not equal to the number of rows in the Toeplitz matrix.
    /// </exception>
    /// <exception cref="SingularMatrixException">
    /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
    /// </exception>
    /// <remarks>
    /// This member solves the linear system <B>TX</B> = <B>Y</B>, where <B>T</B> is
    /// a square Toeplitz matrix, <B>X</B> is the unknown solution matrix
    /// and <B>Y</B> is a known matrix.
    /// <para>
    /// The class implicitly decomposes the inverse Toeplitz matrix into a <b>UDL</b> factorisation
    /// using the Levinson algorithm, before calculating the solution vector.
    /// </para>
    /// </remarks>
    public FloatMatrix Solve(IROFloatMatrix Y)
    {
      FloatMatrix X;
      float Inner;
      float[] a, b, x, y;
      int i, j, l;

      // check parameters
      if (Y == null)
      {
        throw new System.ArgumentNullException("Y");
      }
      else if (m_Order != Y.Columns)
      {
        throw new RankException("The numer of rows in Y is not equal to the number of rows in the Toeplitz matrix.");
      }

      Compute();

      if (m_IsSingular == true)
      {
        throw new SingularMatrixException("One of the leading sub-matrices is singular.");
      }

      // allocate memory for solution
      X = new FloatMatrix(m_Order, Y.Rows);
      x = new float[m_Order];

      for (l = 0; l < Y.Rows; l++)
      {

        // get right-side column
        y = FloatVector.GetColumnAsArray(Y,l);

        // solve left-side column
        for (i = 0; i < m_Order; i++)
        {
          a = m_LowerTriangle[i];
          b = m_UpperTriangle[i];

          Inner = y[i];
          for (j = 0; j < i; j++)
          {
            Inner += a[j] * y[j];
          }
          Inner *= m_Diagonal[i];
  
          x[i] = Inner;
          for (j = 0; j < i; j++)
          {
            x[j] += Inner * b[j];
          }
        }

        // insert left-side column into the matrix
        X.SetColumn(l, x);
      }

      return X;
    }
Exemplo n.º 20
0
    /// <summary>
    /// Returns the row of a <see cref="IROFloatMatrix" /> as a new <c>FloatVector.</c>
    /// </summary>
    /// <param name="mat">The matrix to copy the column from.</param>
    /// <param name="row">Index of the row to copy from the matrix.</param>
    /// <returns>A new <c>DoubleVector</c> with the same elements as the row of the given matrix.</returns>
    public static FloatVector GetRow(IROFloatMatrix mat, int row)
    {
      FloatVector result = new FloatVector(mat.Columns);
      for (int i = 0; i < result.data.Length; ++i)
        result.data[i] = mat[row, i];

      return result;
    }
Exemplo n.º 21
0
    /// <summary>
    /// Returns the column of a <see cref="IROFloatMatrix" /> as a new <c>float[]</c> array.
    /// </summary>
    /// <param name="mat">The matrix to copy the column from.</param>
    /// <param name="col">Index of the column to copy from the matrix.</param>
    /// <returns>A new array of <c>float</c> with the same elements as the column of the given matrix.</returns>
    public static float[] GetColumnAsArray(IROFloatMatrix mat, int col)
    {
      float[] result = new float[mat.Rows];
      for (int i = 0; i < result.Length; ++i)
        result[i] = mat[i, col];

      return result;
    }
Exemplo n.º 22
0
    /// <summary>
    /// Returns the column of a <see cref="IROFloatMatrix" /> as a new <c>FloatVector.</c>
    /// </summary>
    /// <param name="mat">The matrix to copy the column from.</param>
    /// <param name="col">Index of the column to copy from the matrix.</param>
    /// <returns>A new <c>FloatVector</c> with the same elements as the column of the given matrix.</returns>
    public static FloatVector GetColumn(IROFloatMatrix mat, int col)
    {
      FloatVector result = new FloatVector(mat.Rows);
      for (int i = 0; i < result.data.Length; ++i)
        result.data[i] = mat[i, col];

      return result;
    }
Exemplo n.º 23
0
		///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
		///<param name="B">RHS side of the system.</param>
		///<returns>the solution matrix, X.</returns>
		///<exception cref="ArgumentNullException">B is null.</exception>
		///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception>
		///<exception cref="ArgumentException">The number of rows of A and B must be the same.</exception>
		public FloatMatrix Solve(IROFloatMatrix B)
		{
			if (B == null)
			{
				throw new System.ArgumentNullException("B cannot be null.");
			}
			Compute();
			if (!ispd)
			{
				throw new NotPositiveDefiniteException();
			}
			else
			{
				if (B.Rows != order)
				{
					throw new System.ArgumentException("Matrix row dimensions must agree.");
				}
#if MANAGED
				// Copy right hand side.
				int cols = B.Columns;
				FloatMatrix X = new FloatMatrix(B);
				for (int c = 0; c < cols; c++)
				{
					// Solve L*Y = B;
					for (int i = 0; i < order; i++)
					{
						float sum = B[i, c];
						for (int k = i - 1; k >= 0; k--)
						{
							sum -= l.data[i][k] * X.data[k][c];
						}
						X.data[i][c] = sum / l.data[i][i];
					}

					// Solve L'*X = Y;
					for (int i = order - 1; i >= 0; i--)
					{
						float sum = X.data[i][c];
						for (int k = i + 1; k < order; k++)
						{
							sum -= l.data[k][i] * X.data[k][c];
						}
						X.data[i][c] = sum / l.data[i][i];
					}
				}

				return X;
#else
                float[] rhs = FloatMatrix.ToLinearArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower,order,B.Columns,l.data,order,rhs,B.Rows);
                FloatMatrix ret = new FloatMatrix(order,B.Columns);
                ret.data = rhs;
                return ret;
#endif
			}
		}
Exemplo n.º 24
0
		///<summary>Constructor for SVD decomposition class.</summary>
		///<param name="matrix">The matrix to decompose.</param>
		///<param name="computeVectors">Whether to compute the singular vectors or not.</param>
		///<exception cref="ArgumentNullException">matrix is null.</exception>
		public FloatSVDDecomp(IROFloatMatrix matrix, bool computeVectors)
		{
			if (matrix == null)
			{
				throw new System.ArgumentNullException("matrix cannot be null.");
			}
			this.matrix = new FloatMatrix(matrix);
			this.computeVectors = computeVectors;
		}