示例#1
0
        /// <overloads>
        /// There are two permuations of the constructor, both require a parameter corresponding
        /// to the left-most column of a Toeplitz matrix.
        /// </overloads>
        /// <summary>
        /// Constructor with <c>ComplexFloatVector</c> parameter.
        /// </summary>
        /// <param name="T">The left-most column of the Toeplitz matrix.</param>
        /// <exception cref="ArgumentNullException">
        /// <B>T</B> is a null reference.
        /// </exception>
        /// <exception cref="RankException">
        /// The length of <B>T</B> is zero.
        /// </exception>
        public ComplexFloatSymmetricLevinson(IROComplexFloatVector T)
        {
            // check parameter
            if (T == null)
            {
                throw new System.ArgumentNullException("T");
            }
            else if (T.Length == 0)
            {
                throw new RankException("The length of T is zero.");
            }

            // save the vector
            m_LeftColumn = new ComplexFloatVector(T);
            m_Order      = m_LeftColumn.Length;

            // allocate memory for lower triangular matrix
            m_LowerTriangle = new ComplexFloat[m_Order][];
            for (int i = 0; i < m_Order; i++)
            {
                m_LowerTriangle[i] = new ComplexFloat[i + 1];
            }

            // allocate memory for diagonal
            m_Diagonal = new ComplexFloat[m_Order];
        }
示例#2
0
 public static IComplexFloatMatrix UA(IROComplexFloatVector u, IComplexFloatMatrix A, int r1, int r2, int c1, int c2)
 {
     if (c1 > c2)
     {
         return(A);
     }
     return(UA(u, A, r1, r2, c1, c2, new ComplexFloatVector(c2 - c1 + 1)));
 }
示例#3
0
 public static IComplexFloatMatrix AU(IComplexFloatMatrix A, IROComplexFloatVector u, int r1, int r2, int c1, int c2)
 {
     if (r2 < r1)
     {
         return(A);
     }
     return(AU(A, u, r1, r2, c1, c2, new ComplexFloatVector(r2 - r1 + 1)));
 }
        /// <overloads>
        /// Solve a symmetric square Toeplitz system.
        /// </overloads>
        /// <summary>
        /// Solve a symmetric square Toeplitz system with a right-side vector.
        /// </summary>
        /// <param name="Y">The right-hand side of the system.</param>
        /// <returns>The solution vector.</returns>
        /// <exception cref="ArgumentNullException">
        /// Parameter <B>Y</B> is a null reference.
        /// </exception>
        /// <exception cref="RankException">
        /// The length of <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
        /// the symmetric square Toeplitz matrix, <B>X</B> is the unknown solution vector
        /// and <B>Y</B> is a known vector.
        /// <para>
        /// The class implicitly decomposes the inverse Toeplitz matrix into a <b>UDL</b> factorisation
        /// using the Levinson algorithm, and then calculates the solution vector.
        /// </para>
        /// </remarks>
        public ComplexFloatVector Solve(IROComplexFloatVector Y)
        {
            ComplexFloatVector X;

            // check parameters
            if (Y == null)
            {
                throw new System.ArgumentNullException("Y");
            }
            else if (m_Order != Y.Length)
            {
                throw new RankException("The length of 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          i, j, l; // index/loop variables
            ComplexFloat Inner;   // inner product
            ComplexFloat G;       // scaling constant

            ComplexFloat[] A;     // reference to current order coefficients

            // allocate memory for solution
            X = new ComplexFloatVector(m_Order)
            {
                // setup zero order solution
                [0] = Y[0] / m_LeftColumn[0]
            };

            // solve systems of increasing order
            for (i = 1; i < m_Order; i++)
            {
                // calculate inner product
                Inner = Y[i];
                for (j = 0, l = i; j < i; j++, l--)
                {
                    Inner -= X[j] * m_LeftColumn[l];
                }
                // get the current predictor coefficients row
                A = m_LowerTriangle[i];

                // update the solution vector
                G = Inner * m_Diagonal[i];
                for (j = 0; j <= i; j++)
                {
                    X[j] += G * A[j];
                }
            }

            return(X);
        }
示例#5
0
        private ComplexFloatVector Pivot(IROComplexFloatVector B)
        {
            ComplexFloatVector ret = new ComplexFloatVector(B.Length);

            for (int i = 0; i < pivots.Length; i++)
            {
                ret.data[i] = B[pivots[i]];
            }
            return(ret);
        }
示例#6
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 vector, 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 the length of B must be the same.</exception>
        public ComplexFloatVector Solve(IROComplexFloatVector B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (!ispd)
            {
                throw new NotPositiveDefiniteException();
            }
            else
            {
                if (B.Length != order)
                {
                    throw new System.ArgumentException("The length of B must be the same as the order of the matrix.");
                }
#if MANAGED
                // Copy right hand side.
                var X = new ComplexFloatVector(B);
                // Solve L*Y = B;
                for (int i = 0; i < order; i++)
                {
                    ComplexFloat sum = B[i];
                    for (int k = i - 1; k >= 0; k--)
                    {
                        sum -= l.data[i][k] * X.data[k];
                    }
                    X.data[i] = sum / l.data[i][i];
                }
                // Solve L'*X = Y;
                for (int i = order - 1; i >= 0; i--)
                {
                    ComplexFloat sum = X.data[i];
                    for (int k = i + 1; k < order; k++)
                    {
                        sum -= ComplexMath.Conjugate(l.data[k][i]) * X.data[k];
                    }
                    X.data[i] = sum / ComplexMath.Conjugate(l.data[i][i]);
                }

                return(X);
#else
                ComplexFloat[] rhs = ComplexFloatMatrix.ToLinearComplexArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, 1, l.data, order, rhs, B.Length);
                ComplexFloatVector ret = new ComplexFloatVector(order, B.Length);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
        /// <summary>
        /// Invert a symmetric square Toeplitz matrix.
        /// </summary>
        /// <param name="T">The left-most column of the symmetric Toeplitz matrix.</param>
        /// <returns>The inverse matrix.</returns>
        /// <exception cref="ArgumentNullException">
        /// <B>T</B> is a null reference.
        /// </exception>
        /// <exception cref="RankException">
        /// The length of <B>T</B> must be greater than zero.
        /// </exception>
        /// <exception cref="SingularMatrixException">
        /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
        /// </exception>
        /// <remarks>
        /// This static member combines the <b>UDL</b> decomposition and Trench's algorithm into a
        /// single algorithm. When compared to the non-static member it requires minimal data storage
        /// and suffers from no speed penalty.
        /// <para>
        /// Trench's algorithm requires <b>N</b> squared FLOPS, compared to <b>N</b> cubed FLOPS
        /// if we simply solved a linear Toeplitz system with a right-side identity matrix (<b>N</b> is the matrix order).
        /// </para>
        /// </remarks>
        public static ComplexFloatMatrix Inverse(IROComplexFloatVector T)
        {
            ComplexFloatMatrix X;

            // check parameters
            if (T == null)
            {
                throw new System.ArgumentNullException("T");
            }
            else if (T.Length < 1)
            {
                throw new System.RankException("The length of T must be greater than zero.");
            }
            else if (T.Length == 1)
            {
                X = new ComplexFloatMatrix(1)
                {
示例#8
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 vector, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="SingularMatrixException">A is singular.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and the length of B must be the same.</exception>
        public ComplexFloatVector Solve(IROComplexFloatVector B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (singular)
            {
                throw new SingularMatrixException();
            }
            else
            {
                if (B.Length != order)
                {
                    throw new System.ArgumentException("The length of B must be the same as the order of the matrix.");
                }
#if MANAGED
                // Copy right hand side with pivoting
                ComplexFloatVector X = Pivot(B);

                // Solve L*Y = B(piv,:)
                for (int k = 0; k < order; k++)
                {
                    for (int i = k + 1; i < order; i++)
                    {
                        X[i] -= X[k] * factor[i][k];
                    }
                }
                // Solve U*X = Y;
                for (int k = order - 1; k >= 0; k--)
                {
                    X[k] /= factor[k][k];
                    for (int i = 0; i < k; i++)
                    {
                        X[i] -= X[k] * factor[i][k];
                    }
                }
                return(X);
#else
                ComplexFloat[] rhs = ComplexFloatMatrix.ToLinearComplexArray(B);
                Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, 1, factor, order, pivots, rhs, rhs.Length);
                return(new ComplexFloatVector(rhs));
#endif
            }
        }
示例#9
0
 ///<summary>Constructor for <c>ComplexDoubleVector</c> to deep copy from a <see cref="IROComplexDoubleVector" /></summary>
 ///<param name="src"><c>ComplexDoubleVector</c> to deep copy into <c>ComplexDoubleVector</c>.</param>
 ///<exception cref="ArgumentNullException">Exception thrown if null passed as 'src' parameter.</exception>
 public ComplexFloatVector(IROComplexFloatVector src)
 {
     if (src == null)
     {
         throw new ArgumentNullException("IROComplexFloatVector cannot be null");
     }
     if (src is ComplexFloatVector)
     {
         data = (ComplexFloat[])(((ComplexFloatVector)src).data.Clone());
     }
     else
     {
         data = new ComplexFloat[src.Length];
         for (int i = 0; i < src.Length; ++i)
         {
             data[i] = src[i];
         }
     }
 }
示例#10
0
        public static IComplexFloatMatrix UA(IROComplexFloatVector u, IComplexFloatMatrix A, int r1, int r2, int c1, int c2, IComplexFloatVector v)
        {
            if (r2 < r1 || c2 < c1)
            {
                return(A);
            }

            if (r2 - r1 + 1 > u.Length)
            {
                throw new ArgumentException("Householder vector too short.", "u");
            }

            if (c2 - c1 + 1 > v.Length)
            {
                throw new ArgumentException("Work vector too short.", "v");
            }

            for (int j = c1; j <= c2; j++)
            {
                v[j - c1] = ComplexFloat.Zero;
            }

            for (int i = r1; i <= r2; i++)
            {
                for (int j = c1; j <= c2; j++)
                {
                    v[j - c1] = new ComplexFloat(v[j - c1].Real + u[i - r1].Real * A[i, j].Real + u[i - r1].Imag * A[i, j].Imag,
                                                 v[j - c1].Imag + u[i - r1].Real * A[i, j].Imag - u[i - r1].Imag * A[i, j].Real);
                }
            }

            for (int i = r1; i <= r2; i++)
            {
                for (int j = c1; j <= c2; j++)
                {
                    A[i, j] = new ComplexFloat(A[i, j].Real - u[i - r1].Real * v[j - c1].Real + u[i - r1].Imag * v[j - c1].Imag,
                                               A[i, j].Imag - u[i - r1].Real * v[j - c1].Imag - u[i - r1].Imag * v[j - c1].Real);
                }
            }
            return(A);
        }
示例#11
0
		/// <summary>
		/// Invert a square Toeplitz 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>
		/// <returns>The inverse matrix.</returns>
		/// <exception cref="ArgumentNullException">
		/// <B>col</B> is a null reference.
		/// <para>or</para>
		/// <para><B>row</B> is a null reference.</para>
		/// </exception>
		/// <exception cref="RankException">
		/// The length of <B>col</B> is 0,
		/// <para>or</para>
		/// <para>the lengths of <B>col</B> and <B>row</B> are not equal.</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 <B>col</B> and <B>row</B> are not equal.
		/// </exception>
		/// <remarks>
		/// This static member combines the <b>UDL</b> decomposition and Trench's algorithm into a
		/// single algorithm. It requires minimal data storage, compared to the non-static member
		/// and suffers from no speed penalty in comparision.
		/// <para>
		/// Trench's algorithm requires <b>N</b> squared FLOPS, compared to <b>N</b> cubed FLOPS
		/// if we simply solved a linear Toeplitz system with a right-side identity matrix (<b>N</b> is the matrix order).
		/// </para>
		/// </remarks>
		public static ComplexFloatMatrix Inverse(IROComplexFloatVector col, IROComplexFloatVector row)
		{
			// 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.");
			}

			// 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];
			ComplexFloat Q, S, Ke, Kr, e;
			int i, j, k, l;

			// setup the zero order solution
			A[0] = ComplexFloat.One;
			B[0] = ComplexFloat.One;
			e = ComplexFloat.One / col[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);
			}

			// calculate the inverse
			ComplexFloatMatrix I = new ComplexFloatMatrix(order);           // the solution matrix
			ComplexFloat A1, B1;

#if MANAGED
			ComplexFloat[] current, previous;                   // references to rows in the solution

			// setup the first row in wedge
			current = I.data[0];
			for (i = 0, j = order - 1; i < order; i++, j--)
			{
				current[i] = e * B[j];
			}

			// calculate values in the rest of the wedge
			for (i = 1; i < order; i++)
			{
				previous = current;
				current = I.data[i];
				A1 = e * A[order - i - 1];
				B1 = e * B[i - 1];
				current[0] = A1;
				for (j = 1, k = 0, l = order - 2; j < order - i; j++, k++, l--)
				{
					current[j] = previous[k] + A1 * B[l] - B1 * A[k];
				}
			}

#else

      // setup the first row in wedge
      for (i = 0, j = order - 1; i < order; i++, j--)
      {
        I[0, i] = e * B[j];
      }

      // calculate values in the rest of the wedge
      for (i = 1; i < order; i++)
      {
        A1 = e * A[order - i - 1];
        B1 = e * B[i - 1];
        I[i, 0] = A1;
        for (j = 1, k = 0, l = order - 2; j < order - i; j++, k++, l--)
        {
          I[i, j] = I[i - 1, k] + A1 * B[l] - B1 * A[k];
        }
      }
#endif

			// inverse is a persymmetric matrix.
			for (i = 0, j = order - 1; i < order; i++, j--)
			{
				for (k = 0, l = order - 1; k < j; k++, l--)
				{
					I[l, j] = I[i, k];
				}
			}

			return I;
		}
示例#12
0
		/// <overloads>
		/// Solve a square Toeplitz system.
		/// </overloads>
		/// <summary>
		/// Solve a square Toeplitz system with a right-side vector.
		/// </summary>
		/// <param name="Y">The right-hand side of the system.</param>
		/// <returns>The solution vector.</returns>
		/// <exception cref="ArgumentNullException">
		/// Parameter <B>Y</B> is a null reference.
		/// </exception>
		/// <exception cref="RankException">
		/// The length of Y 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
		/// the square Toeplitz matrix, <B>X</B> is the unknown solution vector
		/// and <B>Y</B> is a known vector.
		/// <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 ComplexFloatVector Solve(IROComplexFloatVector Y)
		{
			ComplexFloatVector X;
			ComplexFloat Inner;
			int i, j;

			// check parameters
			if (Y == null)
			{
				throw new System.ArgumentNullException("Y");
			}
			else if (m_Order != Y.Length)
			{
				throw new RankException("The length of 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
			ComplexFloat[] A, B;
			X = new ComplexFloatVector(m_Order);

			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];
				}
			}
			return X;
		}
示例#13
0
		/// <summary>
		/// Constructor with <c>ComplexFloatVector</c> parameters.
		/// </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>
		/// <exception cref="ArgumentNullException">
		/// <B>col</B> is a null reference,
		/// <para>or</para>
		/// <para><B>row</B> is a null reference.</para>
		/// </exception>
		/// <exception cref="RankException">
		/// The length col <B>col</B> is zero,
		/// <para>or</para>
		/// <para>the length of <B>col</B> does not match that of <B>row</B>.</para>
		/// </exception>
		/// <exception cref="ArithmeticException">
		/// The values of the first element of <B>col</B> and <B>row</B> are not equal.
		/// </exception>
		public ComplexFloatLevinson(IROComplexFloatVector col, IROComplexFloatVector row)
		{
			// 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.");
			}

			// save the vectors
			m_LeftColumn = new ComplexFloatVector(col);
			m_TopRow = new ComplexFloatVector(row);
			m_Order = m_LeftColumn.Length;

			// allocate memory for lower triangular matrix
			m_LowerTriangle = new ComplexFloat[m_Order][];
			for (int i = 0; i < m_Order; i++)
			{
				m_LowerTriangle[i] = new ComplexFloat[i + 1];
			}

			// allocate memory for diagonal
			m_Diagonal = new ComplexFloat[m_Order];

			// allocate memory for upper triangular matrix
			m_UpperTriangle = new ComplexFloat[m_Order][];
			for (int i = 0; i < m_Order; i++)
			{
				m_UpperTriangle[i] = new ComplexFloat[i + 1];
			}
		}
示例#14
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 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;
		}
示例#15
0
        /// <summary>
        /// Invert a symmetric square Toeplitz matrix.
        /// </summary>
        /// <param name="T">The left-most column of the symmetric Toeplitz matrix.</param>
        /// <returns>The inverse matrix.</returns>
        /// <exception cref="ArgumentNullException">
        /// <B>T</B> is a null reference.
        /// </exception>
        /// <exception cref="RankException">
        /// The length of <B>T</B> must be greater than zero.
        /// </exception>
        /// <exception cref="SingularMatrixException">
        /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
        /// </exception>
        /// <remarks>
        /// This static member combines the <b>UDL</b> decomposition and Trench's algorithm into a
        /// single algorithm. When compared to the non-static member it requires minimal data storage
        /// and suffers from no speed penalty.
        /// <para>
        /// Trench's algorithm requires <b>N</b> squared FLOPS, compared to <b>N</b> cubed FLOPS
        /// if we simply solved a linear Toeplitz system with a right-side identity matrix (<b>N</b> is the matrix order).
        /// </para>
        /// </remarks>
        public static ComplexFloatMatrix Inverse(IROComplexFloatVector T)
        {
            ComplexFloatMatrix X;

            // check parameters
            if (T == null)
            {
                throw new System.ArgumentNullException("T");
            }
            else if (T.Length < 1)
            {
                throw new System.RankException("The length of T must be greater than zero.");
            }
            else if (T.Length == 1)
            {
                X       = new ComplexFloatMatrix(1);
                X[0, 0] = ComplexFloat.One / T[0];
            }
            else
            {
                int          N = T.Length;
                ComplexFloat f, g;
                int          i, j, l, k, m, n;
                X = new ComplexFloatMatrix(N);

                // calculate the predictor coefficients
                ComplexFloatVector Y = ComplexFloatSymmetricLevinson.YuleWalker(T);

                // calculate gamma
                f = T[0];
                for (i = 1, j = 0; i < N; i++, j++)
                {
                    f += T[i] * Y[j];
                }
                g = ComplexFloat.One / f;

                // calculate first row of inverse
                X[0, 0] = g;
                for (i = 1, j = 0; i < N; i++, j++)
                {
                    X[0, i] = g * Y[j];
                }

                // calculate successive rows of upper wedge
                for (i = 0, j = 1, k = N - 2; i < N / 2; i++, j++, k--)
                {
                    for (l = j, m = i, n = N - 1 - j; l < N - j; l++, m++, n--)
                    {
                        X[j, l] = X[i, m] + g * (Y[i] * Y[m] - Y[k] * Y[n]);
                    }
                }

                // this is symmetric matrix ...
                for (i = 0; i <= N / 2; i++)
                {
                    for (j = i + 1; j < N - i; j++)
                    {
                        X[j, i] = X[i, j];
                    }
                }

                // and a persymmetric matrix.
                for (i = 0, j = N - 1; i < N; i++, j--)
                {
                    for (k = 0, l = N - 1; k < j; k++, l--)
                    {
                        X[l, j] = X[i, k];
                    }
                }
            }

            return(X);
        }
    /// <overloads>
    /// Solve a symmetric square Toeplitz system.
    /// </overloads>
    /// <summary>
    /// Solve a symmetric square Toeplitz system with a right-side vector.
    /// </summary>
    /// <param name="Y">The right-hand side of the system.</param>
    /// <returns>The solution vector.</returns>
    /// <exception cref="ArgumentNullException">
    /// Parameter <B>Y</B> is a null reference.
    /// </exception>
    /// <exception cref="RankException">
    /// The length of <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
    /// the symmetric square Toeplitz matrix, <B>X</B> is the unknown solution vector
    /// and <B>Y</B> is a known vector.
    /// <para>
    /// The class implicitly decomposes the inverse Toeplitz matrix into a <b>UDL</b> factorisation
    /// using the Levinson algorithm, and then calculates the solution vector.
    /// </para>
    /// </remarks>
    public ComplexFloatVector Solve(IROComplexFloatVector Y)
    {
      ComplexFloatVector X;

      // check parameters
      if (Y == null)
      {
        throw new System.ArgumentNullException("Y");
      }
      else if (m_Order != Y.Length)
      {
        throw new RankException("The length of 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 i, j, l;      // index/loop variables
      ComplexFloat Inner;     // inner product
      ComplexFloat G;       // scaling constant
      ComplexFloat[] A;       // reference to current order coefficients

      // allocate memory for solution
      X = new ComplexFloatVector(m_Order);

      // setup zero order solution
      X[0] = Y[0] / m_LeftColumn[0];

      // solve systems of increasing order
      for (i = 1; i < m_Order; i++)
      {
        // calculate inner product
        Inner = Y[i];
        for (j = 0, l = i; j < i; j++, l--)
        {
          Inner -= X[j] * m_LeftColumn[l];
        }
        // get the current predictor coefficients row
        A = m_LowerTriangle[i];

        // update the solution vector
        G = Inner * m_Diagonal[i];
        for (j = 0; j <= i; j++)
        {
          X[j] += G * A[j];
        }

      }

      return X;
    }
    /// <summary>
    /// Invert a symmetric square Toeplitz matrix.
    /// </summary>
    /// <param name="T">The left-most column of the symmetric Toeplitz matrix.</param>
    /// <returns>The inverse matrix.</returns>
    /// <exception cref="ArgumentNullException">
    /// <B>T</B> is a null reference.
    /// </exception>
    /// <exception cref="RankException">
    /// The length of <B>T</B> must be greater than zero.
    /// </exception>
    /// <exception cref="SingularMatrixException">
    /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
    /// </exception>
    /// <remarks>
    /// This static member combines the <b>UDL</b> decomposition and Trench's algorithm into a
    /// single algorithm. When compared to the non-static member it requires minimal data storage
    /// and suffers from no speed penalty.
    /// <para>
    /// Trench's algorithm requires <b>N</b> squared FLOPS, compared to <b>N</b> cubed FLOPS
    /// if we simply solved a linear Toeplitz system with a right-side identity matrix (<b>N</b> is the matrix order).
    /// </para>
    /// </remarks>
    public static ComplexFloatMatrix Inverse(IROComplexFloatVector T)
    {

      ComplexFloatMatrix X;

      // check parameters
      if (T == null)
      {
        throw new System.ArgumentNullException("T");
      }
      else if (T.Length < 1)
      {
        throw new System.RankException("The length of T must be greater than zero.");
      }
      else if (T.Length == 1)
      {
        X = new ComplexFloatMatrix(1);
        X[0, 0] = ComplexFloat.One / T[0];
      }
      else
      {

        int N = T.Length;
        ComplexFloat f, g;
        int i, j, l, k, m, n;
        X = new ComplexFloatMatrix(N);

        // calculate the predictor coefficients
        ComplexFloatVector Y = ComplexFloatSymmetricLevinson.YuleWalker(T);

        // calculate gamma
        f = T[0];
        for (i = 1, j = 0; i < N; i++, j++)
        {
          f += T[i] * Y[j];
        }
        g = ComplexFloat.One / f;

        // calculate first row of inverse
        X[0, 0] = g;
        for (i = 1, j = 0; i < N; i++, j++)
        {
          X[0, i] = g * Y[j];
        }

        // calculate successive rows of upper wedge
        for (i = 0, j = 1, k = N - 2; i < N / 2; i++, j++, k--)
        {
          for (l = j, m = i, n = N-1-j; l < N - j; l++, m++, n--)
          {
            X[j, l] = X[i, m] + g * (Y[i] * Y[m] - Y[k] * Y[n]);
          }
        }

        // this is symmetric matrix ...
        for (i = 0; i <= N / 2; i++)
        {
          for (j = i + 1; j < N - i; j++)
          {
            X[j, i] = X[i, j];
          }
        }

        // and a persymmetric matrix.
        for (i = 0, j = N - 1; i < N; i++, j--)
        {
          for (k = 0, l = N - 1; k < j; k++, l--)
          {
            X[l, j] = X[i, k];
          }
        }

      }

      return X;
    }
示例#18
0
		public static IComplexFloatMatrix UA(IROComplexFloatVector u, IComplexFloatMatrix A, int r1, int r2, int c1, int c2)
		{
			if (c1 > c2)
			{
				return A;
			}
			return UA(u, A, r1, r2, c1, c2, new ComplexFloatVector(c2 - c1 + 1));
		}
示例#19
0
		public static IComplexFloatMatrix AU(IComplexFloatMatrix A, IROComplexFloatVector u, int r1, int r2, int c1, int c2, IComplexFloatVector v)
		{
			if (r2 < r1 || c2 < c1)
			{
				return A;
			}

			if (c2 - c1 + 1 > u.Length)
			{
				throw new ArgumentException("Householder vector too short.", "u");
			}

			if (r2 - r1 + 1 > v.Length)
			{
				throw new ArgumentException("Work vector too short.", "v");
			}

			for (int i = r1; i <= r2; i++)
			{
				v[i - r1] = ComplexFloat.Zero;
				for (int j = c1; j <= c2; j++)
				{
					v[i - r1] = new ComplexFloat(v[i - r1].Real + A[i, j].Real * u[j - c1].Real - A[i, j].Imag * u[j - c1].Imag,
						v[i - r1].Imag + A[i, j].Real * u[j - c1].Imag + A[i, j].Imag * u[j - c1].Real);
				}
			}
			for (int i = r1; i <= r2; i++)
			{
				for (int j = c1; j <= c2; j++)
				{
					A[i, j] = new ComplexFloat(A[i, j].Real - v[i - r1].Real * u[j - c1].Real - v[i - r1].Imag * u[j - c1].Imag,
						A[i, j].Imag + v[i - r1].Real * u[j - c1].Imag - v[i - r1].Imag * u[j - c1].Real);
				}
			}
			return A;
		}
示例#20
0
		public static IComplexFloatMatrix AU(IComplexFloatMatrix A, IROComplexFloatVector u, int r1, int r2, int c1, int c2)
		{
			if (r2 < r1)
			{
				return A;
			}
			return AU(A, u, r1, r2, c1, c2, new ComplexFloatVector(r2 - r1 + 1));
		}
示例#21
0
        /// <overloads>
        /// Solve a symmetric square Toeplitz system.
        /// </overloads>
        /// <summary>
        /// Solve a symmetric square Toeplitz system with a right-side vector.
        /// </summary>
        /// <param name="T">The left-most column of the Toeplitz matrix.</param>
        /// <param name="Y">The right-side vector of the system.</param>
        /// <returns>The solution vector.</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 length of <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
        /// vector and <B>Y</B> is a known vector.
        /// <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 ComplexFloatVector Solve(IROComplexFloatVector T, IROComplexFloatVector Y)
        {
            ComplexFloatVector 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.Length)
            {
                throw new RankException("The length of T and Y are not equal.");
            }
            else
            {
                // allocate memory
                int N = T.Length;
                X = new ComplexFloatVector(N);            // solution vector
                ComplexFloat e;                           // prediction error

                // 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.");
                }
                X[0] = Y[0] / T[0];

                if (N > 1)
                {
                    ComplexFloatVector a = new ComplexFloatVector(N - 1); // prediction coefficients
                    ComplexFloatVector Z = new ComplexFloatVector(N - 1); // temporary storage vector
                    ComplexFloat       g;                                 // reflection coefficient
                    ComplexFloat       inner;                             // inner product
                    ComplexFloat       k;
                    int i, j, l;

                    // 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
                        g = -(inner / e);
                        for (j = 0, l = i - 2; j < i - 1; j++, l--)
                        {
                            Z[j] = a[j] + g * a[l];
                        }

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

                        a[i - 1] = g;

                        e *= (ComplexFloat.One - g * g);
                        if (e == ComplexFloat.Zero)
                        {
                            throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular.");
                        }

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

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

            return(X);
        }
示例#22
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);
        }
    /// <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;
    }
    /// <summary>
    /// Solve the Yule-Walker equations for a symmetric square Toeplitz system
    /// </summary>
    /// <param name="R">The left-most column of the Toeplitz matrix.</param>
    /// <returns>The solution vector.</returns>
    /// <exception cref="ArgumentNullException">
    /// <B>R</B> is a null reference.
    /// </exception>
    /// <exception cref="ArgumentOutOfRangeException">
    /// The length of <B>R</B> must be greater than one.
    /// </exception>
    /// <exception cref="SingularMatrixException">
    /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
    /// </exception>
    /// <remarks>
    /// This member is used to solve the Yule-Walker system <B>AX</B> = -<B>a</B>,
    /// where <B>A</B> is a symmetric square Toeplitz matrix, constructed
    /// from the elements <B>R[0]</B>, ..., <B>R[N-2]</B> and
    /// the vector <B>a</B> is constructed from the elements
    /// <B>R[1]</B>, ..., <B>R[N-1]</B>.
    /// <para>
    /// Durbin's algorithm is used to solve the linear system. It requires
    /// approximately the <b>N</b> squared FLOPS to calculate the
    /// solution (<b>N</b> is the matrix order).
    /// </para>
    /// </remarks>
    public static ComplexFloatVector YuleWalker(IROComplexFloatVector R)
    {

      ComplexFloatVector a;

      // check parameters
      if (R == null)
      {
        throw new System.ArgumentNullException("R");
      }
      else if (R.Length < 2)
      {
        throw new System.ArgumentOutOfRangeException("R", "The length of R must be greater than 1.");
      }
      else
      {

        int N = R.Length - 1;
        a = new ComplexFloatVector(N);              // prediction coefficients
        ComplexFloatVector Z = new ComplexFloatVector(N);   // temporary storage vector
        ComplexFloat e;                   // predictor error
        ComplexFloat inner;                 // inner product
        ComplexFloat g;                   // reflection coefficient
        int i, j, l;

        // setup first order solution
        e = R[0];
        if (e == ComplexFloat.Zero)
        {
          throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular.");
        }
        g = -R[1] / R[0];
        a[0] = g;

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

          e *= (ComplexFloat.One - g * g);
          if (e == ComplexFloat.Zero)
          {
            throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular.");
          }

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

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

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

          a[i] = g;

        }
      }

      return a;
    }
    ///<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 vector, 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 the length of B must be the same.</exception>
    public ComplexFloatVector Solve (IROComplexFloatVector B) 
    {
      if ( B == null ) 
      {
        throw new System.ArgumentNullException("B cannot be null.");
      }
      Compute();
      if ( !ispd ) 
      {
        throw new NotPositiveDefiniteException();
      } 
      else 
      {
        if ( B.Length != order ) 
        {
          throw new System.ArgumentException("The length of B must be the same as the order of the matrix." );
        }
#if MANAGED
        // Copy right hand side.
        ComplexFloatVector X = new ComplexFloatVector(B);
        // Solve L*Y = B;
        for (int i = 0; i < order; i++) 
        {
          ComplexFloat sum = B[i];
          for (int k = i-1; k >= 0; k--) 
          {
            sum -= l.data[i][k] * X.data[k];
          }
          X.data[i] = sum / l.data[i][i];
        }
        // Solve L'*X = Y;
        for (int i =order-1; i >= 0; i--) 
        {
          ComplexFloat sum = X.data[i];
          for (int k = i+1; k < order; k++) 
          {
            sum -= ComplexMath.Conjugate(l.data[k][i]) * X.data[k];
          }
          X.data[i] = sum / ComplexMath.Conjugate(l.data[i][i]);
        }

        return X;

#else
                ComplexFloat[] rhs = ComplexFloatMatrix.ToLinearComplexArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower,order,1,l.data,order,rhs,B.Length);
                ComplexFloatVector ret = new ComplexFloatVector(order,B.Length);
                ret.data = rhs;
                return ret;
#endif
      }
    }
    /// <overloads>
    /// There are two permuations of the constructor, both require a parameter corresponding
    /// to the left-most column of a Toeplitz matrix.
    /// </overloads>
    /// <summary>
    /// Constructor with <c>ComplexFloatVector</c> parameter.
    /// </summary>
    /// <param name="T">The left-most column of the Toeplitz matrix.</param>
    /// <exception cref="ArgumentNullException">
    /// <B>T</B> is a null reference.
    /// </exception>
    /// <exception cref="RankException">
    /// The length of <B>T</B> is zero.
    /// </exception>
    public ComplexFloatSymmetricLevinson(IROComplexFloatVector T)
    {
      // check parameter
      if (T == null)
      {
        throw new System.ArgumentNullException("T");
      }
      else if (T.Length == 0)
      {
        throw new RankException("The length of T is zero.");
      }

      // save the vector
      m_LeftColumn = new ComplexFloatVector(T);
      m_Order = m_LeftColumn.Length;

      // allocate memory for lower triangular matrix
      m_LowerTriangle = new ComplexFloat[m_Order][];
      for (int i = 0; i < m_Order; i++)
      {
        m_LowerTriangle[i] = new ComplexFloat[i+1];
      }

      // allocate memory for diagonal
      m_Diagonal = new ComplexFloat[m_Order];

    }
 ///<summary>Constructor for <c>ComplexDoubleVector</c> to deep copy from a <see cref="IROComplexDoubleVector" /></summary>
 ///<param name="src"><c>ComplexDoubleVector</c> to deep copy into <c>ComplexDoubleVector</c>.</param>
 ///<exception cref="ArgumentNullException">Exception thrown if null passed as 'src' parameter.</exception>
 public ComplexFloatVector(IROComplexFloatVector src)
 {
   if (src == null)
   {
     throw new ArgumentNullException("IROComplexFloatVector cannot be null");
   }
   if (src is ComplexFloatVector)
   {
     data = (ComplexFloat[]) (((ComplexFloatVector)src).data.Clone());
   }
   else
   {
     data = new ComplexFloat[src.Length];
     for (int i = 0; i < src.Length; ++i)
     {
       data[i] = src[i];
     }
   }
 }
    /// <overloads>
    /// Solve a symmetric square Toeplitz system.
    /// </overloads>
    /// <summary>
    /// Solve a symmetric square Toeplitz system with a right-side vector.
    /// </summary>
    /// <param name="T">The left-most column of the Toeplitz matrix.</param>
    /// <param name="Y">The right-side vector of the system.</param>
    /// <returns>The solution vector.</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 length of <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
    /// vector and <B>Y</B> is a known vector.
    /// <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 ComplexFloatVector Solve(IROComplexFloatVector T, IROComplexFloatVector Y)
    {

      ComplexFloatVector 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.Length)
      {
        throw new RankException("The length of T and Y are not equal.");
      }
      else
      {

        // allocate memory
        int N = T.Length;
        X = new ComplexFloatVector(N);                    // solution vector
        ComplexFloat e;                                   // prediction error

        // 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.");
        }
        X[0] = Y[0] / T[0];

        if (N > 1)
        {
          ComplexFloatVector a = new ComplexFloatVector(N - 1);   // prediction coefficients
          ComplexFloatVector Z = new ComplexFloatVector(N - 1);   // temporary storage vector
          ComplexFloat g;                                   // reflection coefficient
          ComplexFloat inner;                               // inner product
          ComplexFloat k;
          int i, j, l;

          // 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
            g = -(inner / e);
            for (j = 0, l = i - 2; j < i - 1; j++, l--)
            {
              Z[j] = a[j] + g * a[l];
            }

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

            a[i - 1] = g;

            e *= (ComplexFloat.One - g * g);
            if (e == ComplexFloat.Zero)
            {
              throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular.");
            }

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

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

          }

        }

      }

      return X;

    }
示例#29
0
        /// <summary>
        /// Solve the Yule-Walker equations for a symmetric square Toeplitz system
        /// </summary>
        /// <param name="R">The left-most column of the Toeplitz matrix.</param>
        /// <returns>The solution vector.</returns>
        /// <exception cref="ArgumentNullException">
        /// <B>R</B> is a null reference.
        /// </exception>
        /// <exception cref="ArgumentOutOfRangeException">
        /// The length of <B>R</B> must be greater than one.
        /// </exception>
        /// <exception cref="SingularMatrixException">
        /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
        /// </exception>
        /// <remarks>
        /// This member is used to solve the Yule-Walker system <B>AX</B> = -<B>a</B>,
        /// where <B>A</B> is a symmetric square Toeplitz matrix, constructed
        /// from the elements <B>R[0]</B>, ..., <B>R[N-2]</B> and
        /// the vector <B>a</B> is constructed from the elements
        /// <B>R[1]</B>, ..., <B>R[N-1]</B>.
        /// <para>
        /// Durbin's algorithm is used to solve the linear system. It requires
        /// approximately the <b>N</b> squared FLOPS to calculate the
        /// solution (<b>N</b> is the matrix order).
        /// </para>
        /// </remarks>
        public static ComplexFloatVector YuleWalker(IROComplexFloatVector R)
        {
            ComplexFloatVector a;

            // check parameters
            if (R == null)
            {
                throw new System.ArgumentNullException("R");
            }
            else if (R.Length < 2)
            {
                throw new System.ArgumentOutOfRangeException("R", "The length of R must be greater than 1.");
            }
            else
            {
                int N = R.Length - 1;
                a = new ComplexFloatVector(N);                    // prediction coefficients
                ComplexFloatVector Z = new ComplexFloatVector(N); // temporary storage vector
                ComplexFloat       e;                             // predictor error
                ComplexFloat       inner;                         // inner product
                ComplexFloat       g;                             // reflection coefficient
                int i, j, l;

                // setup first order solution
                e = R[0];
                if (e == ComplexFloat.Zero)
                {
                    throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular.");
                }
                g    = -R[1] / R[0];
                a[0] = g;

                // calculate solution for successive orders
                for (i = 1; i < N; i++)
                {
                    e *= (ComplexFloat.One - g * g);
                    if (e == ComplexFloat.Zero)
                    {
                        throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular.");
                    }

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

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

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

                    a[i] = g;
                }
            }

            return(a);
        }