Exemplo n.º 1
0
        public static IFloatMatrix AU(IFloatMatrix A, IROFloatVector u, int r1, int r2, int c1, int c2, IFloatVector 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] = 0.0f;
                for (int j = c1; j <= c2; j++)
                {
                    v[i - r1] = v[i - r1] + A[i, j] * u[j - c1];
                }
            }
            for (int i = r1; i <= r2; i++)
            {
                for (int j = c1; j <= c2; j++)
                {
                    A[i, j] = A[i, j] - v[i - r1] * u[j - c1];
                }
            }
            return(A);
        }
Exemplo n.º 2
0
 public static IROFloatMatrix UA(IROFloatVector u, IFloatMatrix A, int r1, int r2, int c1, int c2)
 {
     if (c1 > c2)
     {
         return(A);
     }
     return(UA(u, A, r1, r2, c1, c2, new FloatVector(c2 - c1 + 1)));
 }
Exemplo n.º 3
0
 public static IFloatMatrix AU(IFloatMatrix A, IROFloatVector u, int r1, int r2, int c1, int c2)
 {
     if (r2 < r1)
     {
         return(A);
     }
     return(AU(A, u, r1, r2, c1, c2, new FloatVector(r2 - r1 + 1)));
 }
Exemplo n.º 4
0
        private FloatVector Pivot(IROFloatVector B)
        {
            FloatVector ret = new FloatVector(B.Length);

            for (int i = 0; i < pivots.Length; i++)
            {
                ret.data[i] = B[pivots[i]];
            }
            return(ret);
        }
Exemplo 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 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 FloatVector Solve(IROFloatVector 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.
                FloatVector X = new FloatVector(B);
                // Solve L*Y = B;
                for (int i = 0; i < order; i++)
                {
                    float 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--)
                {
                    float sum = X.data[i];
                    for (int k = i + 1; k < order; k++)
                    {
                        sum -= l.data[k][i] * X.data[k];
                    }
                    X.data[i] = sum / l.data[i][i];
                }

                return(X);
#else
                float[] rhs = FloatMatrix.ToLinearArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, 1, l.data, order, rhs, B.Length);
                FloatVector ret = new FloatVector(order, B.Length);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
Exemplo n.º 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="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 FloatVector Solve(IROFloatVector 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
                FloatVector 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
                float[] rhs = FloatMatrix.ToLinearArray(B);
                Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, 1, factor, order, pivots, rhs, rhs.Length);
                return(new FloatVector(rhs));
#endif
            }
        }
Exemplo n.º 7
0
 ///<summary>Constructor for <c>FloatVector</c> to deep copy from a <see cref="IROFloatVector" /></summary>
 ///<param name="src"><c>Vector</c> to deep copy into <c>FloatVector</c>.</param>
 ///<exception cref="ArgumentNullException">Exception thrown if null passed as 'src' parameter.</exception>
 public FloatVector(IROFloatVector src)
 {
     if (src == null)
     {
         throw new ArgumentNullException("IROVector cannot be null");
     }
     if (src is FloatVector)
     {
         data = (float[])(((FloatVector)src).data.Clone());
     }
     else
     {
         data = new float[src.Length];
         for (int i = 0; i < src.Length; ++i)
         {
             data[i] = src[i];
         }
     }
 }
Exemplo n.º 8
0
 ///<summary>Constructor for <c>FloatVector</c> to deep copy from a <see cref="IROFloatVector" /></summary>
 ///<param name="src"><c>Vector</c> to deep copy into <c>FloatVector</c>.</param>
 ///<exception cref="ArgumentNullException">Exception thrown if null passed as 'src' parameter.</exception>
 public FloatVector(IROFloatVector src)
 {
   if (src == null)
   {
     throw new ArgumentNullException("IROVector cannot be null");
   }
   if (src is FloatVector)
   {
     data = (float[])(((FloatVector)src).data.Clone());
   }
   else
   {
     data = new float[src.Length];
     for (int i = 0; i < src.Length; ++i)
     {
       data[i] = src[i];
     }
   }
 }
Exemplo n.º 9
0
		public static IFloatMatrix AU(IFloatMatrix A, IROFloatVector u, int r1, int r2, int c1, int c2, IFloatVector 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] = 0.0f;
				for (int j = c1; j <= c2; j++)
				{
					v[i - r1] = v[i - r1] + A[i, j] * u[j - c1];
				}
			}
			for (int i = r1; i <= r2; i++)
			{
				for (int j = c1; j <= c2; j++)
				{
					A[i, j] = A[i, j] - v[i - r1] * u[j - c1];
				}
			}
			return A;
		}
    /// <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 FloatVector Solve(IROFloatVector Y)
    {
      FloatVector 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
      float Inner;      // inner product
      float G;        // scaling constant
      float[] A;        // reference to current order coefficients

      // allocate memory for solution
      X = new FloatVector(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;
    }
    /// <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>FloatVector</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 FloatSymmetricLevinson(IROFloatVector 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 FloatVector(T);
      m_Order = m_LeftColumn.Length;

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

      // allocate memory for diagonal
      m_Diagonal = new float[m_Order];
    }
    /// <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 FloatMatrix Inverse(IROFloatVector T)
    {

      FloatMatrix 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 FloatMatrix(1);
        X[0, 0] = 1.0f / T[0];
      }
      else
      {

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

        // calculate the predictor coefficients
        FloatVector Y = FloatSymmetricLevinson.YuleWalker(T);

        // calculate gamma
        f = T[0];
        for (i = 1, j = 0; i < N; i++, j++)
        {
          f += T[i] * Y[j];
        }
        g = 1.0f / 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;
    }
    /// <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 FloatVector YuleWalker(IROFloatVector R)
    {

      FloatVector 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 FloatVector(N);                    // prediction coefficients
        FloatVector Z = new FloatVector(N);   // temporary storage vector
        float e;                            // predictor error
        float inner;                               // inner product
        float g;                                   // reflection coefficient
        int i, j, l;

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

      FloatMatrix X;

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

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

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

        if (N > 1)
        {

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

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

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

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

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

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

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

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

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

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

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

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

            }

          }

        }

      }

      return X;
    }
    /// <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 FloatVector Solve(IROFloatVector T, IROFloatVector Y)
    {

      FloatVector 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 FloatVector(N);                    // solution vector
        float e;                                   // prediction error

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

        if (N > 1)
        {
          FloatVector a = new FloatVector(N - 1);   // prediction coefficients
          FloatVector Z = new FloatVector(N - 1);   // temporary storage vector
          float g;                                   // reflection coefficient
          float inner;                               // inner product
          float 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 *= (1.0f - g * g);
            if (e == 0.0f)
            {
              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;

    }
Exemplo n.º 16
0
		///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
		///<param name="B">RHS side of the system.</param>
		///<returns>the solution 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 FloatVector Solve(IROFloatVector 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.
				FloatVector X = new FloatVector(B);
				// Solve L*Y = B;
				for (int i = 0; i < order; i++)
				{
					float 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--)
				{
					float sum = X.data[i];
					for (int k = i + 1; k < order; k++)
					{
						sum -= l.data[k][i] * X.data[k];
					}
					X.data[i] = sum / l.data[i][i];
				}

				return X;
#else
                float[] rhs = FloatMatrix.ToLinearArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower,order,1,l.data,order,rhs,B.Length);
                FloatVector ret = new FloatVector(order,B.Length);
                ret.data = rhs;
                return ret;
#endif
			}
		}
Exemplo n.º 17
0
		public static IROFloatMatrix UA(IROFloatVector u, IFloatMatrix A, int r1, int r2, int c1, int c2)
		{
			if (c1 > c2)
			{
				return A;
			}
			return UA(u, A, r1, r2, c1, c2, new FloatVector(c2 - c1 + 1));
		}
Exemplo n.º 18
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 FloatVector Solve(IROFloatVector Y)
    {
      FloatVector X;
      float 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
      float[] A, B;
      X = new FloatVector(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;
    }
Exemplo n.º 19
0
    /// <overloads>
    /// There are two permuations of the constructor, one requires FloatVector parameters
    /// and the other float arrays.
    /// </overloads>
    /// <summary>
    /// Constructor with <c>FloatVector</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 FloatLevinson(IROFloatVector col, IROFloatVector 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 FloatVector(col);
      m_TopRow = new FloatVector(row);
      m_Order = m_LeftColumn.Length;

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

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

      // allocate memory for upper triangular matrix
      m_UpperTriangle = new float[m_Order][];
      for (int i = 0; i < m_Order; i++)
      {
        m_UpperTriangle[i] = new float[i + 1];
      }
    }
Exemplo n.º 20
0
    /// <summary>
    /// Solve a square Toeplitz system with a right-side matrix.
    /// </summary>
    /// <param name="col">The left-most column of the Toeplitz matrix.</param>
    /// <param name="row">The top-most row of the Toeplitz matrix.</param>
    /// <param name="Y">The right-side matrix of the system.</param>
    /// <returns>The solution matrix.</returns>
    /// <exception cref="ArgumentNullException">
    /// <EM>col</EM> is a null reference,
    /// <para>or</para>
    /// <para><EM>row</EM> is a null reference,</para>
    /// <para>or</para>
    /// <para><EM>Y</EM> is a null reference.</para>
    /// </exception>
    /// <exception cref="RankException">
    /// The length of <EM>col</EM> is 0,
    /// <para>or</para>
    /// <para>the lengths of <EM>col</EM> and <EM>row</EM> are not equal,</para>
    /// <para>or</para>
    /// <para>the number of rows in <EM>Y</EM> does not the length of <EM>col</EM> and <EM>row</EM>.</para>
    /// </exception>
    /// <exception cref="SingularMatrixException">
    /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
    /// </exception>
    /// <exception cref="ArithmeticException">
    /// The values of the first element of <EM>col</EM> and <EM>row</EM> are not equal.
    /// </exception>
    /// <remarks>
    /// This method solves the linear system <B>AX</B> = <B>Y</B>. Where
    /// <B>T</B> is a square Toeplitz matrix, <B>X</B> is an unknown
    /// matrix and <B>Y</B> is a known matrix.
    /// <para>
    /// The classic Levinson algorithm is used to solve the system. The algorithm
    /// assumes that all the leading sub-matrices of the Toeplitz matrix are
    /// non-singular. When a sub-matrix is near singular, accuracy will
    /// be degraded. This member requires approximately <B>N</B> squared
    /// FLOPS to calculate a solution, where <B>N</B> is the matrix order.
    /// </para>
    /// <para>
    /// This static method has minimal storage requirements as it combines
    /// the <b>UDL</b> decomposition with the calculation of the solution vector
    /// in a single algorithm.
    /// </para>
    /// </remarks>
    public static FloatMatrix Solve(IROFloatVector col, IROFloatVector row, IROFloatMatrix Y)
    {
      // check parameters
      if (col == null)
      {
        throw new System.ArgumentNullException("col");
      }
      else if (col.Length == 0)
      {
        throw new RankException("The length of col is zero.");
      }
      else if (row == null)
      {
        throw new System.ArgumentNullException("row");
      }
      else if (col.Length != row.Length)
      {
        throw new RankException("The lengths of col and row are not equal.");
      }
      else if (col[0] != row[0])
      {
        throw new ArithmeticException("The values of the first element of col and row are not equal.");
      }
      else if (Y == null)
      {
        throw new System.ArgumentNullException("Y");
      }
      else if (col.Length != Y.Columns)
      {
        throw new RankException("The numer of rows in Y does not match the length of col and row.");
      }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

          X.SetColumn(l, W);
        }

      }

      return X;
    }
Exemplo n.º 21
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 FloatMatrix Inverse(IROFloatVector col, IROFloatVector 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] == 0.0f)
      {
        throw new SingularMatrixException("One of the leading sub-matrices is singular.");
      }

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

      // setup the zero order solution
      A[0] = 1.0f;
      B[0] = 1.0f;
      e = 1.0f / col[0];

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

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

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

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

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

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

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

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

      }

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

#if MANAGED
      float[] 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;

    }
Exemplo n.º 22
0
		public static IFloatMatrix AU(IFloatMatrix A, IROFloatVector u, int r1, int r2, int c1, int c2)
		{
			if (r2 < r1)
			{
				return A;
			}
			return AU(A, u, r1, r2, c1, c2, new FloatVector(r2 - r1 + 1));
		}