Ejemplo n.º 1
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 ComplexDoubleMatrix Solve(IROComplexDoubleMatrix Y)
        {
            ComplexDoubleMatrix X;
            Complex             Inner;

            Complex[] 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 ComplexDoubleMatrix(m_Order, Y.Rows);
            x = new Complex[m_Order];

            for (l = 0; l < Y.Rows; l++)
            {
                // get right-side column
                y = ComplexDoubleVector.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);
        }
Ejemplo n.º 2
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 ComplexDoubleQRDecomp(IROComplexDoubleMatrix matrix)
 {
     if (matrix == null)
     {
         throw new System.ArgumentNullException("matrix cannot be null.");
     }
     this.matrix = matrix;
 }
Ejemplo n.º 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="SingularMatrixException">Ais singular.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and B must be the same.</exception>
        public ComplexDoubleMatrix Solve(IROComplexDoubleMatrix 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;
                ComplexDoubleMatrix 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
                Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B);
                Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, B.Columns, factor, order, pivots, rhs, B.Rows);
                ComplexDoubleMatrix ret = new ComplexDoubleMatrix(order, B.Columns);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
Ejemplo n.º 4
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 ComplexDoubleSVDDecomp(IROComplexDoubleMatrix matrix, bool computeVectors)
 {
     if (matrix == null)
     {
         throw new System.ArgumentNullException("matrix cannot be null.");
     }
     this.matrix         = new ComplexDoubleMatrix(matrix);
     this.computeVectors = computeVectors;
 }
Ejemplo n.º 5
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 ComplexDoubleMatrix Solve(IROComplexDoubleMatrix 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 ComplexDoubleMatrix(B);
                for (int c = 0; c < cols; c++)
                {
                    // Solve L*Y = B;
                    for (int i = 0; i < order; i++)
                    {
                        Complex 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--)
                    {
                        Complex 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
                Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, B.Columns, l.data, order, rhs, B.Rows);
                ComplexDoubleMatrix ret = new ComplexDoubleMatrix(order, B.Columns);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Returns the column of a <see cref="IROComplexDoubleMatrix" /> 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>Complex</c> with the same elements as the column of the given matrix.</returns>
        public static Complex[] GetColumnAsArray(IROComplexDoubleMatrix mat, int col)
        {
            Complex[] result = new Complex[mat.Rows];
            for (int i = 0; i < result.Length; ++i)
            {
                result[i] = mat[i, col];
            }

            return(result);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Returns the row of a <see cref="IROComplexDoubleMatrix" /> as a new <c>ComplexDoubleVector.</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>ComplexDoubleVector</c> with the same elements as the row of the given matrix.</returns>
        public static ComplexDoubleVector GetRow(IROComplexDoubleMatrix mat, int row)
        {
            ComplexDoubleVector result = new ComplexDoubleVector(mat.Columns);

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

            return(result);
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Returns the column of a <see cref="IROComplexDoubleMatrix" /> as a new <c>ComplexDoubleVector.</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>ComplexDoubleVector</c> with the same elements as the column of the given matrix.</returns>
        public static ComplexDoubleVector GetColumn(IROComplexDoubleMatrix mat, int col)
        {
            ComplexDoubleVector result = new ComplexDoubleVector(mat.Rows);

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

            return(result);
        }
Ejemplo n.º 9
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 ComplexDoubleCholeskyDecomp(IROComplexDoubleMatrix 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 ComplexDoubleMatrix(matrix);
        }
    ///<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 ComplexDoubleCholeskyDecomp(IROComplexDoubleMatrix 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 ComplexDoubleMatrix(matrix);
    }
Ejemplo n.º 11
0
        private ComplexDoubleMatrix Pivot(IROComplexDoubleMatrix B)
        {
            int m = B.Rows;
            int n = B.Columns;

            ComplexDoubleMatrix ret = new ComplexDoubleMatrix(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);
        }
    ///<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 ComplexDoubleMatrix Solve (IROComplexDoubleMatrix 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;
        ComplexDoubleMatrix X = new ComplexDoubleMatrix(B);
        for (int c = 0; c < cols; c++ ) 
        {
          // Solve L*Y = B;
          for (int i = 0; i < order; i++) 
          {
            Complex 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--) 
          {
            Complex 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
                Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower,order,B.Columns,l.data,order,rhs,B.Rows);
                ComplexDoubleMatrix ret = new ComplexDoubleMatrix(order,B.Columns);
                ret.data = rhs;
                return ret;
#endif
      }
    }
Ejemplo n.º 13
0
    public static string MatrixToString(string name, IROComplexDoubleMatrix 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();
    }
Ejemplo n.º 14
0
    /// <summary>
    /// Returns the column of a <see cref="IROComplexDoubleMatrix" /> 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>Complex</c> with the same elements as the column of the given matrix.</returns>
    public static Complex[] GetColumnAsArray(IROComplexDoubleMatrix mat, int col)
    {
      Complex[] result = new Complex[mat.Rows];
      for(int i=0;i<result.Length;++i)
        result[i] = mat[i,col];

      return result;
    }
 ///<summary>Constructor for SVD decomposition class.</summary>
 ///<param name="matrix">The matrix to decompose.</param>
 ///<exception cref="ArgumentNullException">matrix is null.</exception>
 public ComplexDoubleSVDDecomp(IROComplexDoubleMatrix matrix)
 {
   if ( matrix == null ) 
   {
     throw new System.ArgumentNullException("matrix cannot be null.");
   }
   this.matrix = new ComplexDoubleMatrix(matrix);
 }
Ejemplo n.º 16
0
 /// <summary>
 /// Returns the row of a <see cref="IROComplexDoubleMatrix" /> as a new <c>ComplexDoubleVector.</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>ComplexDoubleVector</c> with the same elements as the row of the given matrix.</returns>
 public static ComplexDoubleVector GetRow(IROComplexDoubleMatrix mat, int row)
 {
   ComplexDoubleVector result = new ComplexDoubleVector(mat.Columns);
   for(int i=0;i<result.data.Length;++i)
     result.data[i] = mat[row,i];
   
   return result;
 }
Ejemplo n.º 17
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 ComplexDoubleMatrix Solve(IROComplexDoubleMatrix Y)
		{
			ComplexDoubleMatrix X;
			Complex Inner;
			Complex[] 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 ComplexDoubleMatrix(m_Order, Y.Rows);
			x = new Complex[m_Order];

			for (l = 0; l < Y.Rows; l++)
			{
				// get right-side column
				y = ComplexDoubleVector.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;
		}
Ejemplo n.º 18
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 ComplexDoubleMatrix Solve(IROComplexDoubleVector col, IROComplexDoubleVector row, IROComplexDoubleMatrix 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] == Complex.Zero)
			{
				throw new SingularMatrixException("One of the leading sub-matrices is singular.");
			}

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

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

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

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

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

				for (l = 0; l < Y.Rows; l++)
				{
					ComplexDoubleVector W = X.GetColumn(l);
					ComplexDoubleVector M = ComplexDoubleVector.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;
		}
Ejemplo n.º 19
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 ComplexDoubleMatrix Solve(IROComplexDoubleVector T, IROComplexDoubleMatrix Y)
        {
            ComplexDoubleMatrix 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 ComplexDoubleMatrix(N, M);                  // solution matrix
                ComplexDoubleVector Z = new ComplexDoubleVector(N); // temporary storage vector
                Complex             e;                              // prediction error
                int i, j, l, m;

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

                        if (e == Complex.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);
        }
Ejemplo n.º 20
0
 /// <summary>
 /// Returns the column of a <see cref="IROComplexDoubleMatrix" /> as a new <c>ComplexDoubleVector.</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>ComplexDoubleVector</c> with the same elements as the column of the given matrix.</returns>
 public static ComplexDoubleVector GetColumn(IROComplexDoubleMatrix mat, int col)
 {
   ComplexDoubleVector result = new ComplexDoubleVector(mat.Rows);
   for(int i=0;i<result.data.Length;++i)
     result.data[i] = mat[i,col];
   
   return result;
 }
    /// <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 ComplexDoubleMatrix Solve(IROComplexDoubleVector T, IROComplexDoubleMatrix Y)
    {

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

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

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

            if (e == Complex.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;
    }
Ejemplo n.º 22
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 ComplexDoubleMatrix Solve(IROComplexDoubleVector col, IROComplexDoubleVector row, IROComplexDoubleMatrix 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] == Complex.Zero)
            {
                throw new SingularMatrixException("One of the leading sub-matrices is singular.");
            }

            // decompose matrix
            int order = col.Length;

            Complex[]           A = new Complex[order];
            Complex[]           B = new Complex[order];
            Complex[]           Z = new Complex[order];
            ComplexDoubleMatrix X = new ComplexDoubleMatrix(order);
            Complex             Q, S, Ke, Kr, e;
            Complex             Inner;
            int i, j, l;

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

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

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

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

                for (l = 0; l < Y.Rows; l++)
                {
                    ComplexDoubleVector W = X.GetColumn(l);
                    ComplexDoubleVector M = ComplexDoubleVector.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);
        }
Ejemplo n.º 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 ComplexDoubleMatrix Solve(IROComplexDoubleMatrix Y)
        {
            ComplexDoubleMatrix 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

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

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

            // setup zero order solution
            scalar = Complex.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);
        }
    /// <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 ComplexDoubleMatrix Solve(IROComplexDoubleMatrix Y)
    {
      ComplexDoubleMatrix 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
      Complex[] Inner;      // inner product
      Complex[] G;        // scaling constant
      Complex[] A;        // reference to current order coefficients
      Complex scalar;

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

      // setup zero order solution
      scalar = Complex.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;
    }
 ///<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 ComplexDoubleQRDecomp(IROComplexDoubleMatrix matrix) 
 {
   if (matrix == null)
     throw new System.ArgumentNullException("matrix cannot be null.");
   this.matrix = matrix;
 }