コード例 #1
0
 ///<summary>Constructor for SVD decomposition class.</summary>
 ///<param name="matrix">The matrix to decompose.</param>
 ///<exception cref="ArgumentNullException">matrix is null.</exception>
 public ComplexFloatSVDDecomp(IROComplexFloatMatrix matrix)
 {
     if (matrix == null)
     {
         throw new System.ArgumentNullException("matrix cannot be null.");
     }
     this.matrix = new ComplexFloatMatrix(matrix);
 }
コード例 #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 ComplexFloatMatrix Solve(IROComplexFloatMatrix 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;
                ComplexFloatMatrix 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
                ComplexFloat[] rhs = ComplexFloatMatrix.ToLinearComplexArray(B);
                Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, B.Columns, factor, order, pivots, rhs, B.Rows);
                ComplexFloatMatrix ret = new ComplexFloatMatrix(order, B.Columns);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
コード例 #3
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 ComplexFloatMatrix Solve(IROComplexFloatMatrix 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;
                var X    = new ComplexFloatMatrix(B);
                for (int c = 0; c < cols; c++)
                {
                    // Solve L*Y = B;
                    for (int i = 0; i < order; i++)
                    {
                        ComplexFloat 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--)
                    {
                        ComplexFloat sum = X.data[i][c];
                        for (int k = i + 1; k < order; k++)
                        {
                            sum -= ComplexMath.Conjugate(l.data[k][i]) * X.data[k][c];
                        }
                        X.data[i][c] = sum / ComplexMath.Conjugate(l.data[i][i]);
                    }
                }

                return(X);
#else
                ComplexFloat[] rhs = ComplexFloatMatrix.ToLinearComplexArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, B.Columns, l.data, order, rhs, B.Rows);
                ComplexFloatMatrix ret = new ComplexFloatMatrix(order, B.Columns);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
コード例 #4
0
        /// <summary>
        /// Returns the column of a <see cref="IROComplexFloatMatrix" /> as a new <c>Complex[]</c> array.
        /// </summary>
        /// <param name="mat">The matrix to copy the column from.</param>
        /// <param name="col">Number of column to copy from the matrix.</param>
        /// <returns>A new array of <c>ComplexFloat</c> with the same elements as the column of the given matrix.</returns>
        public static ComplexFloat[] GetColumnAsArray(IROComplexFloatMatrix mat, int col)
        {
            ComplexFloat[] result = new ComplexFloat[mat.Rows];
            for (int i = 0; i < result.Length; ++i)
            {
                result[i] = mat[i, col];
            }

            return(result);
        }
コード例 #5
0
        /// <summary>
        /// Returns the column of a <see cref="IROComplexFloatMatrix" /> as a new <c>ComplexFloatVector.</c>
        /// </summary>
        /// <param name="mat">The matrix to copy the column from.</param>
        /// <param name="col">Number of column to copy from the matrix.</param>
        /// <returns>A new <c>ComplexFloatVector</c> with the same elements as the column of the given matrix.</returns>
        public static ComplexFloatVector GetColumn(IROComplexFloatMatrix mat, int col)
        {
            ComplexFloatVector result = new ComplexFloatVector(mat.Rows);

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

            return(result);
        }
コード例 #6
0
        /// <summary>
        /// Returns the row of a <see cref="IROComplexFloatMatrix" /> as a new <c>ComplexFloatVector.</c>
        /// </summary>
        /// <param name="mat">The matrix to copy the column from.</param>
        /// <param name="row">Number of row to copy from the matrix.</param>
        /// <returns>A new <c>ComplexFloatVector</c> with the same elements as the row of the given matrix.</returns>
        public static ComplexFloatVector GetRow(IROComplexFloatMatrix mat, int row)
        {
            ComplexFloatVector result = new ComplexFloatVector(mat.Columns);

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

            return(result);
        }
コード例 #7
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 ComplexFloatLUDecomp(IROComplexFloatMatrix 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 ComplexFloatMatrix(matrix);
        }
コード例 #8
0
    ///<summary>Constructor for Cholesky decomposition class. The constructor performs the factorization of a Hermitian 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 ComplexFloatCholeskyDecomp(IROComplexFloatMatrix 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 ComplexFloatMatrix(matrix);
    }
コード例 #9
0
        private ComplexFloatMatrix Pivot(IROComplexFloatMatrix B)
        {
            int m = B.Rows;
            int n = B.Columns;

            ComplexFloatMatrix ret = new ComplexFloatMatrix(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);
        }
コード例 #10
0
ファイル: ComplexFloatLevinson.cs プロジェクト: Altaxo/Altaxo
		/// <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 ComplexFloatMatrix Solve(IROComplexFloatVector col, IROComplexFloatVector row, IROComplexFloatMatrix 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] == ComplexFloat.Zero)
			{
				throw new SingularMatrixException("One of the leading sub-matrices is singular.");
			}

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

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

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

				S = ComplexFloat.Zero;
				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] = ComplexFloat.Zero;
				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] = ComplexFloat.Zero;
				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 == ComplexFloat.One)
				{
					throw new SingularMatrixException("One of the leading sub-matrices is singular.");
				}

				// update diagonal
				e = e / (ComplexFloat.One - Ke * Kr);

				for (l = 0; l < Y.Rows; l++)
				{
					ComplexFloatVector W = X.GetColumn(l);
					ComplexFloatVector M = ComplexFloatVector.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;
		}
コード例 #11
0
ファイル: ComplexFloatLevinson.cs プロジェクト: Altaxo/Altaxo
		/// <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 ComplexFloatMatrix Solve(IROComplexFloatMatrix Y)
		{
			ComplexFloatMatrix X;
			ComplexFloat Inner;
			ComplexFloat[] 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 ComplexFloatMatrix(m_Order, Y.Rows);
			x = new ComplexFloat[m_Order];

			for (l = 0; l < Y.Rows; l++)
			{
				// get right-side column
				y = ComplexFloatVector.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;
		}
コード例 #12
0
    /// <summary>
    /// Returns the column of a <see cref="IROComplexFloatMatrix" /> as a new <c>ComplexFloatVector.</c>
    /// </summary>
    /// <param name="mat">The matrix to copy the column from.</param>
    /// <param name="col">Number of column to copy from the matrix.</param>
    /// <returns>A new <c>ComplexFloatVector</c> with the same elements as the column of the given matrix.</returns>
    public static ComplexFloatVector GetColumn(IROComplexFloatMatrix mat, int col)
    {
      ComplexFloatVector result = new ComplexFloatVector(mat.Rows);
      for (int i = 0; i < result.data.Length; ++i)
        result.data[i] = mat[i, col];

      return result;
    }
コード例 #13
0
    /// <summary>
    /// Returns the column of a <see cref="IROComplexFloatMatrix" /> as a new <c>Complex[]</c> array.
    /// </summary>
    /// <param name="mat">The matrix to copy the column from.</param>
    /// <param name="col">Number of column to copy from the matrix.</param>
    /// <returns>A new array of <c>ComplexFloat</c> with the same elements as the column of the given matrix.</returns>
    public static ComplexFloat[] GetColumnAsArray(IROComplexFloatMatrix mat, int col)
    {
      ComplexFloat[] result = new ComplexFloat[mat.Rows];
      for (int i = 0; i < result.Length; ++i)
        result[i] = mat[i, col];

      return result;
    }
コード例 #14
0
 ///<summary>Constructor for SVD decomposition class.</summary>
 ///<param name="matrix">The matrix to decompose.</param>
 ///<exception cref="ArgumentNullException">matrix is null.</exception>
 public ComplexFloatSVDDecomp(IROComplexFloatMatrix matrix)
 {
   if ( matrix == null ) 
   {
     throw new System.ArgumentNullException("matrix cannot be null.");
   }
   this.matrix = new ComplexFloatMatrix(matrix);
 }
コード例 #15
0
    /// <summary>
    /// Returns the row of a <see cref="IROComplexFloatMatrix" /> as a new <c>ComplexFloatVector.</c>
    /// </summary>
    /// <param name="mat">The matrix to copy the column from.</param>
    /// <param name="row">Number of row to copy from the matrix.</param>
    /// <returns>A new <c>ComplexFloatVector</c> with the same elements as the row of the given matrix.</returns>
    public static ComplexFloatVector GetRow(IROComplexFloatMatrix mat, int row)
    {
      ComplexFloatVector result = new ComplexFloatVector(mat.Columns);
      for (int i = 0; i < result.data.Length; ++i)
        result.data[i] = mat[row, i];

      return result;
    }
コード例 #16
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 ComplexFloatMatrix Solve (IROComplexFloatMatrix 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;
        ComplexFloatMatrix X = new ComplexFloatMatrix(B);
        for (int c = 0; c < cols; c++ ) 
        {
          // Solve L*Y = B;
          for (int i = 0; i < order; i++) 
          {
            ComplexFloat 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--) 
          {
            ComplexFloat sum = X.data[i][c];
            for (int k = i+1; k < order; k++) 
            {
              sum -= ComplexMath.Conjugate(l.data[k][i]) * X.data[k][c];
            }
            X.data[i][c] = sum / ComplexMath.Conjugate(l.data[i][i]);
          }
        }

        return X;
#else
                ComplexFloat[] rhs = ComplexFloatMatrix.ToLinearComplexArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower,order,B.Columns,l.data,order,rhs,B.Rows);
                ComplexFloatMatrix ret = new ComplexFloatMatrix(order,B.Columns);
                ret.data = rhs;
                return ret;
#endif
      }
    }
コード例 #17
0
ファイル: ComplexFloatQRDecomp.cs プロジェクト: olesar/Altaxo
        /// <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 ComplexFloatMatrix Solve(IROComplexFloatMatrix B)
        {
            if (B.Rows != matrix.Rows)
            {
                throw new ArgumentException("Matrix row dimensions must agree.");
            }
            if (matrix.Rows < matrix.Columns)
            {
                throw new System.InvalidOperationException("A must have at lest as a many rows as columns.");
            }
            Compute();
            if (!isFullRank)
            {
                throw new System.InvalidOperationException("Matrix is rank deficient.");
            }

            // Copy right hand side
            int m   = matrix.Rows;
            int n   = matrix.Columns;
            int nx  = B.Columns;
            var ret = new ComplexFloatMatrix(n, nx);

#if MANAGED
            var X = new ComplexFloatMatrix(B);
            // Compute Y = transpose(Q)*B
            var column = new ComplexFloat[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++)
                {
                    ComplexFloat s = ComplexFloat.Zero;
                    for (int k = 0; k < m; k++)
                    {
                        s += ComplexMath.Conjugate(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
            ComplexFloat[] c = ComplexFloatMatrix.ToLinearComplexArray(B);
            Lapack.Unmqr.Compute(Lapack.Side.Left, Lapack.Transpose.ConjTrans, 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);
        }
コード例 #18
0
ファイル: MatrixMath.cs プロジェクト: xuchuansheng/GenXSource
    public static string MatrixToString(string name, IROComplexFloatMatrix 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();
    }
コード例 #19
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 ComplexFloatQRDecomp(IROComplexFloatMatrix matrix) 
 {
   if (matrix == null)
     throw new System.ArgumentNullException("matrix cannot be null.");
   this.matrix = matrix;
 }
コード例 #20
0
    /// <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 ComplexFloatMatrix Solve(IROComplexFloatVector T, IROComplexFloatMatrix Y)
    {

      ComplexFloatMatrix 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 ComplexFloatMatrix(N, M);                 // solution matrix
        ComplexFloatVector Z = new ComplexFloatVector(N);       // temporary storage vector
        ComplexFloat e;                                   // prediction error
        int i, j, l, m;

        // setup zero order solution
        e = T[0];
        if (e == ComplexFloat.Zero)
        {
          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)
        {

          ComplexFloatVector a = new ComplexFloatVector(N - 1);   // prediction coefficients
          ComplexFloat p;                                   // reflection coefficient
          ComplexFloat inner;                               // inner product
          ComplexFloat 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 *= (ComplexFloat.One - p * p);

            if (e == ComplexFloat.Zero)
            {
              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;
    }
コード例 #21
0
        /// <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 ComplexFloatMatrix Solve(IROComplexFloatVector T, IROComplexFloatMatrix Y)
        {
            ComplexFloatMatrix 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 ComplexFloatMatrix(N, M);                 // solution matrix
                ComplexFloatVector Z = new ComplexFloatVector(N); // temporary storage vector
                ComplexFloat       e;                             // prediction error
                int i, j, l, m;

                // setup zero order solution
                e = T[0];
                if (e == ComplexFloat.Zero)
                {
                    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)
                {
                    ComplexFloatVector a = new ComplexFloatVector(N - 1); // prediction coefficients
                    ComplexFloat       p;                                 // reflection coefficient
                    ComplexFloat       inner;                             // inner product
                    ComplexFloat       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       *= (ComplexFloat.One - p * p);

                        if (e == ComplexFloat.Zero)
                        {
                            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);
        }
コード例 #22
0
        /// <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 ComplexFloatMatrix Solve(IROComplexFloatMatrix Y)
        {
            ComplexFloatMatrix 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

            ComplexFloat[] Inner; // inner product
            ComplexFloat[] G;     // scaling constant
            ComplexFloat[] A;     // reference to current order coefficients
            ComplexFloat   scalar;

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

            // setup zero order solution
            scalar = ComplexFloat.One / 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);
        }
コード例 #23
0
    /// <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 ComplexFloatMatrix Solve(IROComplexFloatMatrix Y)
    {
      ComplexFloatMatrix 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
      ComplexFloat[] Inner;     // inner product
      ComplexFloat[] G;       // scaling constant
      ComplexFloat[] A;       // reference to current order coefficients
      ComplexFloat scalar;

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

      // setup zero order solution
      scalar = ComplexFloat.One / 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;
    }
コード例 #24
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 ComplexFloatMatrix Solve (IROComplexFloatMatrix B) 
    {
      if (B.Rows != matrix.Rows) 
      {
        throw new ArgumentException("Matrix row dimensions must agree.");
      }
      if (matrix.Rows < matrix.Columns) 
      {
        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.Rows;
      int n = matrix.Columns;
      int nx = B.Columns;
      ComplexFloatMatrix ret = new ComplexFloatMatrix(n,nx);
#if MANAGED
      ComplexFloatMatrix X = new ComplexFloatMatrix(B);
      // Compute Y = transpose(Q)*B
      ComplexFloat[] column = new ComplexFloat[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++) 
        {
          ComplexFloat s = ComplexFloat.Zero;
          for (int k = 0; k < m; k++) 
          {
            s += ComplexMath.Conjugate(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
      ComplexFloat[] c = ComplexFloatMatrix.ToLinearComplexArray(B);
      Lapack.Unmqr.Compute(Lapack.Side.Left, Lapack.Transpose.ConjTrans, 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;   
    }