public void GetInverseSingularTest()
        {
            ComplexDoubleMatrix   a   = new ComplexDoubleMatrix(3, 3);
            ComplexDoubleLUDecomp dlu = new ComplexDoubleLUDecomp(a);

            dlu.GetInverse();
        }
        public void NonSymmFactorTest()
        {
            ComplexDoubleMatrix b = new ComplexDoubleMatrix(3);

            b[0, 0] = 2;
            b[0, 1] = 1;
            b[0, 2] = 1;
            b[1, 0] = 1;
            b[1, 1] = 2;
            b[1, 2] = 0;
            b[2, 0] = 0;
            b[2, 1] = 0;
            b[2, 2] = 3;
            ComplexDoubleCholeskyDecomp dcd = new ComplexDoubleCholeskyDecomp(b);

            Assert.AreEqual(dcd.Factor[0, 0].Real, 1.414, TOLERENCE);
            Assert.AreEqual(dcd.Factor[0, 1].Real, 0.000, TOLERENCE);
            Assert.AreEqual(dcd.Factor[0, 2].Real, 0.000, TOLERENCE);
            Assert.AreEqual(dcd.Factor[1, 0].Real, 0.707, TOLERENCE);
            Assert.AreEqual(dcd.Factor[1, 1].Real, 1.225, TOLERENCE);
            Assert.AreEqual(dcd.Factor[1, 2].Real, 0.000, TOLERENCE);
            Assert.AreEqual(dcd.Factor[2, 0].Real, 0.000, TOLERENCE);
            Assert.AreEqual(dcd.Factor[2, 1].Real, 0.000, TOLERENCE);
            Assert.AreEqual(dcd.Factor[2, 2].Real, 1.732, TOLERENCE);
        }
        public void Current()
        {
            var test = new ComplexDoubleMatrix(new Complex[2, 2] {
                { 1, 2 }, { 3, 4 }
            });
            IEnumerator enumerator = test.GetEnumerator();
            bool        movenextresult;

            movenextresult = enumerator.MoveNext();
            Assert.IsTrue(movenextresult);
            Assert.AreEqual(enumerator.Current, test[0, 0]);

            movenextresult = enumerator.MoveNext();
            Assert.IsTrue(movenextresult);
            Assert.AreEqual(enumerator.Current, test[1, 0]);

            movenextresult = enumerator.MoveNext();
            Assert.IsTrue(movenextresult);
            Assert.AreEqual(enumerator.Current, test[0, 1]);

            movenextresult = enumerator.MoveNext();
            Assert.IsTrue(movenextresult);
            Assert.AreEqual(enumerator.Current, test[1, 1]);

            movenextresult = enumerator.MoveNext();
            Assert.IsFalse(movenextresult);
        }
예제 #4
0
        ///<summary>Calculates the inverse of the matrix.</summary>
        ///<returns>the inverse of the matrix.</returns>
        ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception>
        public ComplexDoubleMatrix GetInverse()
        {
            Compute();
            if (!ispd)
            {
                throw new NotPositiveDefiniteException();
            }
            else
            {
#if MANAGED
                var ret = ComplexDoubleMatrix.CreateIdentity(order);
                ret = Solve(ret);
                return(ret);
#else
                Complex[] inverse = new Complex[l.data.Length];
                Array.Copy(l.data, inverse, l.data.Length);
                Lapack.Potri.Compute(Lapack.UpLo.Lower, order, inverse, order);
                ComplexDoubleMatrix ret = new ComplexDoubleMatrix(order, order);
                ret.data = inverse;
                for (int i = 0; i < order; i++)
                {
                    for (int j = 0; j < order; j++)
                    {
                        if (j > i)
                        {
                            ret.data[j * order + i] = ComplexMath.Conjugate(ret.data[i * order + j]);
                        }
                    }
                }
                return(ret);
#endif
            }
        }
        public void GetInverseNotPositiveDefiniteTest()
        {
            ComplexDoubleMatrix         a   = new ComplexDoubleMatrix(3);
            ComplexDoubleCholeskyDecomp dcd = new ComplexDoubleCholeskyDecomp(a);

            dcd.GetInverse();
        }
		public void Current()
		{
			ComplexDoubleMatrix test = new ComplexDoubleMatrix(new Complex[2, 2] { { 1, 2 }, { 3, 4 } });
			IEnumerator enumerator = test.GetEnumerator();
			bool movenextresult;

			movenextresult = enumerator.MoveNext();
			Assert.IsTrue(movenextresult);
			Assert.AreEqual(enumerator.Current, test[0, 0]);

			movenextresult = enumerator.MoveNext();
			Assert.IsTrue(movenextresult);
			Assert.AreEqual(enumerator.Current, test[1, 0]);

			movenextresult = enumerator.MoveNext();
			Assert.IsTrue(movenextresult);
			Assert.AreEqual(enumerator.Current, test[0, 1]);

			movenextresult = enumerator.MoveNext();
			Assert.IsTrue(movenextresult);
			Assert.AreEqual(enumerator.Current, test[1, 1]);

			movenextresult = enumerator.MoveNext();
			Assert.IsFalse(movenextresult);
		}
예제 #7
0
        /// <summary>
        /// Solve a square Toeplitz system with a right-side matrix.
        /// </summary>
        /// <param name="Y">The right-side matrix</param>
        /// <returns>The solution matrix.</returns>
        /// <exception cref="ArgumentNullException">
        /// Parameter <B>Y</B> is a null reference.
        /// </exception>
        /// <exception cref="RankException">
        /// The number of rows in <B>Y</B> is not equal to the number of rows in the Toeplitz matrix.
        /// </exception>
        /// <exception cref="SingularMatrixException">
        /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
        /// </exception>
        /// <remarks>
        /// This member solves the linear system <B>TX</B> = <B>Y</B>, where <B>T</B> is
        /// a square Toeplitz matrix, <B>X</B> is the unknown solution matrix
        /// and <B>Y</B> is a known matrix.
        /// <para>
        /// The class implicitly decomposes the inverse Toeplitz matrix into a <b>UDL</b> factorisation
        /// using the Levinson algorithm, before calculating the solution vector.
        /// </para>
        /// </remarks>
        public ComplexDoubleMatrix Solve(IROComplexDoubleMatrix Y)
        {
            ComplexDoubleMatrix X;
            Complex             Inner;

            Complex[] a, b, x, y;
            int       i, j, l;

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

            Compute();

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

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

            for (l = 0; l < Y.Rows; l++)
            {
                // get right-side column
                y = ComplexDoubleVector.GetColumnAsArray(Y, l);

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

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

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

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

            return(X);
        }
        public void IsSingularTest()
        {
            Assert.IsFalse(lu.IsSingular);
            ComplexDoubleMatrix   b   = new ComplexDoubleMatrix(3);
            ComplexDoubleLUDecomp dlu = new ComplexDoubleLUDecomp(b);

            Assert.IsTrue(dlu.IsSingular);
        }
예제 #9
0
 ///<summary>Constructor for SVD decomposition class.</summary>
 ///<param name="matrix">The matrix to decompose.</param>
 ///<exception cref="ArgumentNullException">matrix is null.</exception>
 public ComplexDoubleSVDDecomp(IROComplexDoubleMatrix matrix)
 {
     if (matrix == null)
     {
         throw new System.ArgumentNullException("matrix cannot be null.");
     }
     this.matrix = new ComplexDoubleMatrix(matrix);
 }
예제 #10
0
 private static void zscalColumn(ComplexDoubleMatrix A, int Col, int Start, Complex z)
 {
     // A part of column Col of matrix A from row Start to end multiply by z
     for (int i = Start; i < A.RowLength; i++)
     {
         A[i, Col] = A[i, Col] * z;
     }
 }
 public void CurrentException()
 {
     ComplexDoubleMatrix test = new ComplexDoubleMatrix(new Complex[2, 2] {
         { 1, 2 }, { 3, 4 }
     });
     IEnumerator enumerator = test.GetEnumerator();
     object      value      = enumerator.Current;
 }
예제 #12
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution matrix, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="SingularMatrixException">Ais singular.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and B must be the same.</exception>
        public ComplexDoubleMatrix Solve(IROComplexDoubleMatrix B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (singular)
            {
                throw new SingularMatrixException();
            }
            else
            {
                if (B.Rows != order)
                {
                    throw new System.ArgumentException("Matrix row dimensions must agree.");
                }
#if MANAGED
                // Copy right hand side with pivoting
                int nx = B.Columns;
                ComplexDoubleMatrix X = Pivot(B);

                // Solve L*Y = B(piv,:)
                for (int k = 0; k < order; k++)
                {
                    for (int i = k + 1; i < order; i++)
                    {
                        for (int j = 0; j < nx; j++)
                        {
                            X.data[i][j] -= X.data[k][j] * factor[i][k];
                        }
                    }
                }
                // Solve U*X = Y;
                for (int k = order - 1; k >= 0; k--)
                {
                    for (int j = 0; j < nx; j++)
                    {
                        X.data[k][j] /= factor[k][k];
                    }
                    for (int i = 0; i < k; i++)
                    {
                        for (int j = 0; j < nx; j++)
                        {
                            X.data[i][j] -= X.data[k][j] * factor[i][k];
                        }
                    }
                }
                return(X);
#else
                Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B);
                Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, B.Columns, factor, order, pivots, rhs, B.Rows);
                ComplexDoubleMatrix ret = new ComplexDoubleMatrix(order, B.Columns);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
    /// <summary>Performs the QR factorization.</summary>
    protected override void InternalCompute() 
    {
      int m = matrix.Rows;
      int n = matrix.Columns;
#if MANAGED
      int minmn = m < n ? m : n;
      r_ = new ComplexDoubleMatrix(matrix); // create a copy
      ComplexDoubleVector[] u = new ComplexDoubleVector[minmn];
      for (int i = 0; i < minmn; i++) 
      {
        u[i] = Householder.GenerateColumn(r_, i, m - 1, i);
        Householder.UA(u[i], r_, i, m - 1, i + 1, n - 1);
      }
      q_ = ComplexDoubleMatrix.CreateIdentity(m);
      for (int i = minmn - 1; i >= 0; i--) 
      {
        Householder.UA(u[i], q_, i, m - 1, i, m - 1);
      }
#else
      qr = ComplexDoubleMatrix.ToLinearComplexArray(matrix);
      jpvt = new int[n];
      jpvt[0] = 1;
      Lapack.Geqp3.Compute(m, n, qr, m, jpvt, out tau);
      r_ = new ComplexDoubleMatrix(m, n);
      // Populate R

      for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
          if (i <= j) {
            r_.data[j * m + i] = qr[(jpvt[j]-1) * m + i];
          }
          else {
            r_.data[j * m + i] = Complex.Zero;
          }
        }
      }

      q_ = new ComplexDoubleMatrix(m, m);
      for (int i = 0; i < m; i++) {
        for (int j = 0; j < m; j++) {
          if (j < n)
            q_.data[j * m + i] = qr[j * m + i];
          else
            q_.data[j * m + i] = Complex.Zero;
        }
      }
      if( m < n ){
        Lapack.Ungqr.Compute(m, m, m, q_.data, m, tau);
      } else{
        Lapack.Ungqr.Compute(m, m, n, q_.data, m, tau);
      }
#endif
      for (int i = 0; i < m; i++) 
      {
        if (q_[i, i] == 0)
          isFullRank = false;
      }
    }
예제 #14
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution matrix, X.</returns>
        ///<exception cref="ArgumentNullException">B is null.</exception>
        ///<exception cref="NotPositiveDefiniteException">A is not positive definite.</exception>
        ///<exception cref="ArgumentException">The number of rows of A and B must be the same.</exception>
        public ComplexDoubleMatrix Solve(IROComplexDoubleMatrix B)
        {
            if (B == null)
            {
                throw new System.ArgumentNullException("B cannot be null.");
            }
            Compute();
            if (!ispd)
            {
                throw new NotPositiveDefiniteException();
            }
            else
            {
                if (B.Rows != order)
                {
                    throw new System.ArgumentException("Matrix row dimensions must agree.");
                }
#if MANAGED
                // Copy right hand side.
                int cols = B.Columns;
                var X    = new ComplexDoubleMatrix(B);
                for (int c = 0; c < cols; c++)
                {
                    // Solve L*Y = B;
                    for (int i = 0; i < order; i++)
                    {
                        Complex sum = B[i, c];
                        for (int k = i - 1; k >= 0; k--)
                        {
                            sum -= l.data[i][k] * X.data[k][c];
                        }
                        X.data[i][c] = sum / l.data[i][i];
                    }

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

                return(X);
#else
                Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, B.Columns, l.data, order, rhs, B.Rows);
                ComplexDoubleMatrix ret = new ComplexDoubleMatrix(order, B.Columns);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
예제 #15
0
        private static Complex zdotc(ComplexDoubleMatrix A, int Col1, int Col2, int Start)
        {
            Complex z = Complex.Zero;

            for (int i = Start; i < A.RowLength; i++)
            {
                z += A[i, Col2] * ComplexMath.Conjugate(A[i, Col1]);
            }
            return(z);
        }
 public void CurrentException()
 {
     Assert.Throws(typeof(InvalidOperationException), () =>
     {
         var test = new ComplexDoubleMatrix(new Complex[2, 2] {
             { 1, 2 }, { 3, 4 }
         });
         IEnumerator enumerator = test.GetEnumerator();
         object value           = enumerator.Current;
     });
 }
        public void ForEach()
        {
            var test = new ComplexDoubleMatrix(new Complex[2, 2] {
                { 1, 2 }, { 3, 4 }
            });

            foreach (Complex f in test)
            {
                Assert.IsTrue(test.Contains(f));
            }
        }
예제 #18
0
		public void CtorDimensions()
		{
			ComplexDoubleMatrix test = new ComplexDoubleMatrix(2, 2);

			Assert.AreEqual(test.RowLength, 2);
			Assert.AreEqual(test.ColumnLength, 2);
			Assert.AreEqual(test[0, 0], Complex.Zero);
			Assert.AreEqual(test[0, 1], Complex.Zero);
			Assert.AreEqual(test[1, 0], Complex.Zero);
			Assert.AreEqual(test[1, 1], Complex.Zero);
		}
예제 #19
0
        private static void zswap(ComplexDoubleMatrix A, int Col1, int Col2)
        {
            // swap columns Col1,Col2
            Complex z;

            for (int i = 0; i < A.RowLength; i++)
            {
                z          = A[i, Col1];
                A[i, Col1] = A[i, Col2];
                A[i, Col2] = z;
            }
        }
예제 #20
0
		public void CtorInitialValues()
		{
			ComplexDoubleMatrix test = new ComplexDoubleMatrix(2, 2, new Complex(1, 1));

			Assert.AreEqual(test.RowLength, 2);
			Assert.AreEqual(test.ColumnLength, 2);
			Complex value = new Complex(1, 1);
			Assert.AreEqual(test[0, 0], value);
			Assert.AreEqual(test[0, 1], value);
			Assert.AreEqual(test[1, 0], value);
			Assert.AreEqual(test[1, 1], value);
		}
예제 #21
0
        ///<summary>Computes the algorithm.</summary>
        protected override void InternalCompute()
        {
#if MANAGED
            l = new ComplexDoubleMatrix(matrix);
            for (int j = 0; j < order; j++)
            {
                Complex[] rowj = l.data[j];
                double    d    = 0.0;
                for (int k = 0; k < j; k++)
                {
                    Complex[] rowk = l.data[k];
                    Complex   s    = Complex.Zero;
                    for (int i = 0; i < k; i++)
                    {
                        s += rowk[i] * rowj[i];
                    }
                    rowj[k] = s = (matrix.data[j][k] - s) / l.data[k][k];
                    d       = d + (s * ComplexMath.Conjugate(s)).Real;
                }
                d = matrix.data[j][j].Real - d;
                if (d <= 0.0)
                {
                    ispd = false;
                    return;
                }
                l.data[j][j] = new Complex(System.Math.Sqrt(d));
                for (int k = j + 1; k < order; k++)
                {
                    l.data[j][k] = Complex.Zero;
                }
            }
#else
            Complex[] factor = new Complex[matrix.data.Length];
            Array.Copy(matrix.data, factor, matrix.data.Length);
            int status = Lapack.Potrf.Compute(Lapack.UpLo.Lower, order, factor, order);
            if (status != 0)
            {
                ispd = false;
            }
            l      = new ComplexDoubleMatrix(order);
            l.data = factor;
            for (int i = 0; i < order; i++)
            {
                for (int j = 0; j < order; j++)
                {
                    if (j > i)
                    {
                        l.data[j * order + i] = 0;
                    }
                }
            }
#endif
        }
예제 #22
0
        private static double dznrm2Column(ComplexDoubleMatrix A, int Col, int Start)
        {
            //  dznrm2Column returns the euclidean norm of a vector,
            // which is a part of column Col in matrix A, beginning from Start to end of column
            // so that dznrm2Column := sqrt( conjg( matrix' )*matrix )
            double s = 0;

            for (int i = Start; i < A.RowLength; i++)
            {
                s += (A[i, Col] * ComplexMath.Conjugate(A[i, Col])).Real;
            }
            return(System.Math.Sqrt(s));
        }
예제 #23
0
        ///<summary>Solves a system on linear equations, AX=B, where A is the factored matrixed.</summary>
        ///<param name="B">RHS side of the system.</param>
        ///<returns>the solution 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 ComplexDoubleVector Solve(IROComplexDoubleVector 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 ComplexDoubleVector(B);
                // Solve L*Y = B;
                for (int i = 0; i < order; i++)
                {
                    Complex 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--)
                {
                    Complex 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
                Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B);
                Lapack.Potrs.Compute(Lapack.UpLo.Lower, order, 1, l.data, order, rhs, B.Length);
                ComplexDoubleVector ret = new ComplexDoubleVector(order, B.Length);
                ret.data = rhs;
                return(ret);
#endif
            }
        }
예제 #24
0
        private static void zdrot(ComplexDoubleMatrix A, int Col1, int Col2, double c, double s)
        {
            // applies a plane rotation, where the c=cos and s=sin
            // Col1, Col2 - rotated columns of A

            Complex z;

            for (int i = 0; i < A.RowLength; i++)
            {
                z          = c * A[i, Col1] + s * A[i, Col2];
                A[i, Col2] = c * A[i, Col2] - s * A[i, Col1];
                A[i, Col1] = z;
            }
        }
 static ComplexDoubleLUDecompTest() 
 {
   ComplexDoubleMatrix a = new ComplexDoubleMatrix(3);
   a[0,0] = new Complex(-1,1);
   a[0,1] = 5;
   a[0,2] = 6;
   a[1,0] = 3;
   a[1,1] = -6;
   a[1,2] = 1;
   a[2,0] = 6;
   a[2,1] = 8;
   a[2,2] = 9;
   lu = new ComplexDoubleLUDecomp(a);
 }
예제 #26
0
 public static bool AreEqual(ComplexDoubleMatrix f1, ComplexDoubleMatrix f2, float delta) 
 {
   if (f1.RowLength != f2.RowLength) return false;
   if (f1.ColumnLength != f2.ColumnLength) return false;
   for (int i = 0; i < f1.RowLength; i++) 
   {
     for (int j = 0; j < f1.ColumnLength; j++) 
     {
       if (!AreEqual(f1[i, j], f2[i, j], delta))
         return false;
     }
   }
   return true;
 }
 static ComplexDoubleCholeskyDecompTest()
 {
   ComplexDoubleMatrix a = new ComplexDoubleMatrix(3);
   a[0,0] = 2;
   a[0,1] = new Complex(1,-1);
   a[0,2] = 0;
   a[1,0] = new Complex(1,-1);
   a[1,1] = 2;
   a[1,2] = 0;
   a[2,0] = 0;
   a[2,1] = 0;
   a[2,2] = 3;
   cd = new ComplexDoubleCholeskyDecomp(a);
 }
        public void SquareDecomp()
        {
            ComplexDoubleMatrix a = new ComplexDoubleMatrix(3);

            a[0, 0] = new Complex(1.1, 1.1);
            a[0, 1] = new Complex(2.2, -2.2);
            a[0, 2] = new Complex(3.3, 3.3);
            a[1, 0] = new Complex(4.4, -4.4);
            a[1, 1] = new Complex(5.5, 5.5);
            a[1, 2] = new Complex(6.6, -6.6);
            a[2, 0] = new Complex(7.7, 7.7);
            a[2, 1] = new Complex(8.8, -8.8);
            a[2, 2] = new Complex(9.9, 9.9);

            ComplexDoubleQRDecomp qrd = new ComplexDoubleQRDecomp(a);
            ComplexDoubleMatrix   qq  = qrd.Q.GetConjugateTranspose() * qrd.Q;
            ComplexDoubleMatrix   qr  = qrd.Q * qrd.R;
            ComplexDoubleMatrix   I   = ComplexDoubleMatrix.CreateIdentity(3);

            // determine the maximum relative error
            double MaxError = 0.0;

            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; i < 3; i++)
                {
                    double E = ComplexMath.Absolute((qq[i, j] - I[i, j]));
                    if (E > MaxError)
                    {
                        MaxError = E;
                    }
                }
            }
            Assert.IsTrue(MaxError < 1.0E-14);

            MaxError = 0.0;
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; i < 3; i++)
                {
                    double E = ComplexMath.Absolute((qr[i, j] - a[i, j]) / a[i, j]);
                    if (E > MaxError)
                    {
                        MaxError = E;
                    }
                }
            }
            Assert.IsTrue(MaxError < 1.0E-14);
        }
    ///<summary>Computes the algorithm.</summary>
    protected override void InternalCompute()
    {  
#if MANAGED
      l = new ComplexDoubleMatrix(matrix);
      for (int j = 0; j < order; j++) 
      {
        Complex[] rowj = l.data[j];
        double d = 0.0;
        for (int k = 0; k < j; k++) 
        {
          Complex[] rowk = l.data[k];
          Complex s = Complex.Zero;
          for (int i = 0; i < k; i++) 
          {
            s += rowk[i]*rowj[i];
          }
          rowj[k] = s = (matrix.data[j][k] - s)/l.data[k][k];
          d = d + (s*ComplexMath.Conjugate(s)).Real;
        }
        d = matrix.data[j][j].Real - d;
        if ( d <= 0.0 ) 
        {
          ispd = false;
          return;
        }
        l.data[j][j] = new Complex(System.Math.Sqrt(d));
        for (int k = j+1; k < order; k++) 
        {
          l.data[j][k] = Complex.Zero;
        }
      }
#else
            Complex[] factor = new Complex[matrix.data.Length];
            Array.Copy(matrix.data, factor, matrix.data.Length);
            int status = Lapack.Potrf.Compute(Lapack.UpLo.Lower, order, factor, order);
            if (status != 0 ) {
                ispd = false;
            }
            l = new ComplexDoubleMatrix(order);
            l.data = factor;
            for (int i = 0; i < order; i++) {
                for (int j = 0; j < order; j++) {
                    if ( j > i) {
                        l.data[j*order+i] = 0;
                    }
                }
            }
#endif    
    }
        static ComplexDoubleLUDecompTest()
        {
            ComplexDoubleMatrix a = new ComplexDoubleMatrix(3);

            a[0, 0] = new Complex(-1, 1);
            a[0, 1] = 5;
            a[0, 2] = 6;
            a[1, 0] = 3;
            a[1, 1] = -6;
            a[1, 2] = 1;
            a[2, 0] = 6;
            a[2, 1] = 8;
            a[2, 2] = 9;
            lu      = new ComplexDoubleLUDecomp(a);
        }
        static ComplexDoubleCholeskyDecompTest()
        {
            ComplexDoubleMatrix a = new ComplexDoubleMatrix(3);

            a[0, 0] = 2;
            a[0, 1] = new Complex(1, -1);
            a[0, 2] = 0;
            a[1, 0] = new Complex(1, -1);
            a[1, 1] = 2;
            a[1, 2] = 0;
            a[2, 0] = 0;
            a[2, 1] = 0;
            a[2, 2] = 3;
            cd      = new ComplexDoubleCholeskyDecomp(a);
        }
예제 #32
0
        ///<summary>Constructor for Cholesky decomposition class. The constructor performs the factorization of a Hermitian positive
        ///definite matrax and the Cholesky factored matrix is accessible by the <c>Factor</c> property. The factor is the lower
        ///triangular factor.</summary>
        ///<param name="matrix">The matrix to factor.</param>
        ///<exception cref="ArgumentNullException">matrix is null.</exception>
        ///<exception cref="NotSquareMatrixException">matrix is not square.</exception>
        ///<remarks>This class only uses the lower triangle of the input matrix. It ignores the
        ///upper triangle.</remarks>
        public ComplexDoubleCholeskyDecomp(IROComplexDoubleMatrix matrix)
        {
            if (matrix == null)
            {
                throw new System.ArgumentNullException("matrix cannot be null.");
            }

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

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

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

      order = matrix.Columns;
      this.matrix = new ComplexDoubleMatrix(matrix);
    }
예제 #34
0
        public void Multiply()
        {
            ComplexFloatVector a = new ComplexFloatVector(new float[4] {
                0, 1, 2, 3
            });
            ComplexFloatVector b = new ComplexFloatVector(new float[4] {
                4, 5, 6, 7
            });
            ComplexDoubleMatrix c = new ComplexDoubleMatrix(a.Length, b.Length);
            ComplexDoubleMatrix d = new ComplexDoubleMatrix(a.Length, b.Length);

            c = a * b;
            d = ComplexFloatVector.Multiply(a, b);

            Assert.AreEqual(c[0, 0], a[0] * b[0]);
            Assert.AreEqual(c[0, 1], a[0] * b[1]);
            Assert.AreEqual(c[0, 2], a[0] * b[2]);
            Assert.AreEqual(c[0, 3], a[0] * b[3]);
            Assert.AreEqual(c[1, 0], a[1] * b[0]);
            Assert.AreEqual(c[1, 1], a[1] * b[1]);
            Assert.AreEqual(c[1, 2], a[1] * b[2]);
            Assert.AreEqual(c[1, 3], a[1] * b[3]);
            Assert.AreEqual(c[2, 0], a[2] * b[0]);
            Assert.AreEqual(c[2, 1], a[2] * b[1]);
            Assert.AreEqual(c[2, 2], a[2] * b[2]);
            Assert.AreEqual(c[2, 3], a[2] * b[3]);
            Assert.AreEqual(c[3, 0], a[3] * b[0]);
            Assert.AreEqual(c[3, 1], a[3] * b[1]);
            Assert.AreEqual(c[3, 2], a[3] * b[2]);
            Assert.AreEqual(c[3, 3], a[3] * b[3]);

            Assert.AreEqual(d[0, 0], a[0] * b[0]);
            Assert.AreEqual(d[0, 1], a[0] * b[1]);
            Assert.AreEqual(d[0, 2], a[0] * b[2]);
            Assert.AreEqual(d[0, 3], a[0] * b[3]);
            Assert.AreEqual(d[1, 0], a[1] * b[0]);
            Assert.AreEqual(d[1, 1], a[1] * b[1]);
            Assert.AreEqual(d[1, 2], a[1] * b[2]);
            Assert.AreEqual(d[1, 3], a[1] * b[3]);
            Assert.AreEqual(d[2, 0], a[2] * b[0]);
            Assert.AreEqual(d[2, 1], a[2] * b[1]);
            Assert.AreEqual(d[2, 2], a[2] * b[2]);
            Assert.AreEqual(d[2, 3], a[2] * b[3]);
            Assert.AreEqual(d[3, 0], a[3] * b[0]);
            Assert.AreEqual(d[3, 1], a[3] * b[1]);
            Assert.AreEqual(d[3, 2], a[3] * b[2]);
            Assert.AreEqual(d[3, 3], a[3] * b[3]);
        }
예제 #35
0
        private ComplexDoubleMatrix Pivot(IROComplexDoubleMatrix B)
        {
            int m = B.Rows;
            int n = B.Columns;

            ComplexDoubleMatrix ret = new ComplexDoubleMatrix(m, n);

            for (int i = 0; i < pivots.Length; i++)
            {
                for (int j = 0; j < n; j++)
                {
                    ret.data[i][j] = B[pivots[i], j];
                }
            }
            return(ret);
        }
예제 #36
0
		public void SquareDecomp()
		{
			ComplexDoubleMatrix a = new ComplexDoubleMatrix(3);
			a[0, 0] = new Complex(1.1, 1.1);
			a[0, 1] = new Complex(2.2, -2.2);
			a[0, 2] = new Complex(3.3, 3.3);
			a[1, 0] = new Complex(4.4, -4.4);
			a[1, 1] = new Complex(5.5, 5.5);
			a[1, 2] = new Complex(6.6, -6.6);
			a[2, 0] = new Complex(7.7, 7.7);
			a[2, 1] = new Complex(8.8, -8.8);
			a[2, 2] = new Complex(9.9, 9.9);

			ComplexDoubleQRDecomp qrd = new ComplexDoubleQRDecomp(a);
			ComplexDoubleMatrix qq = qrd.Q.GetConjugateTranspose() * qrd.Q;
			ComplexDoubleMatrix qr = qrd.Q * qrd.R;
			ComplexDoubleMatrix I = ComplexDoubleMatrix.CreateIdentity(3);

			// determine the maximum relative error
			double MaxError = 0.0;
			for (int i = 0; i < 3; i++)
			{
				for (int j = 0; i < 3; i++)
				{
					double E = ComplexMath.Absolute((qq[i, j] - I[i, j]));
					if (E > MaxError)
					{
						MaxError = E;
					}
				}
			}
			Assert.IsTrue(MaxError < 1.0E-14);

			MaxError = 0.0;
			for (int i = 0; i < 3; i++)
			{
				for (int j = 0; i < 3; i++)
				{
					double E = ComplexMath.Absolute((qr[i, j] - a[i, j]) / a[i, j]);
					if (E > MaxError)
					{
						MaxError = E;
					}
				}
			}
			Assert.IsTrue(MaxError < 1.0E-14);
		}
예제 #37
0
        ///<summary>Multiply a <c>ComplexDoubleVector</c> with another <c>ComplexDoubleVector</c> as x*y^T</summary>
        ///<param name="lhs"><c>ComplexDoubleVector</c> as left hand operand.</param>
        ///<param name="rhs"><c>ComplexDoubleVector</c> as right hand operand.</param>
        ///<returns><c>ComplexDoubleVector</c> with results.</returns>
        public static ComplexDoubleMatrix operator *(ComplexDoubleVector lhs, ComplexDoubleVector rhs)
        {
            ComplexDoubleMatrix ret = new ComplexDoubleMatrix(lhs.data.Length, rhs.data.Length);

#if MANAGED
            for (int i = 0; i < lhs.data.Length; i++)
            {
                for (int j = 0; j < rhs.data.Length; j++)
                {
                    ret[i, j] = lhs.data[i] * rhs.data[j];
                }
            }
#else
            Blas.Geru.Compute(Blas.Order.ColumnMajor, lhs.data.Length, rhs.data.Length, 1, lhs.data, 1, rhs.data, 1, ret.data, lhs.data.Length);
#endif
            return(ret);
        }
예제 #38
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 ComplexDoubleVector Solve(IROComplexDoubleVector 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
                ComplexDoubleVector 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
                Complex[] rhs = ComplexDoubleMatrix.ToLinearComplexArray(B);
                Lapack.Getrs.Compute(Lapack.Transpose.NoTrans, order, 1, factor, order, pivots, rhs, rhs.Length);
                return(new ComplexDoubleVector(rhs));
#endif
            }
        }
예제 #39
0
		public void CtorCopy()
		{
			ComplexDoubleMatrix a = new ComplexDoubleMatrix(2, 2);
			a[0, 0] = new Complex(1, 1);
			a[0, 1] = new Complex(2, 2);
			a[1, 0] = new Complex(3, 3);
			a[1, 1] = new Complex(4, 4);

			ComplexDoubleMatrix b = new ComplexDoubleMatrix(a);

			Assert.AreEqual(a.RowLength, b.RowLength);
			Assert.AreEqual(a.ColumnLength, b.ColumnLength);
			Assert.AreEqual(a[0, 0], b[0, 0]);
			Assert.AreEqual(a[0, 1], b[0, 1]);
			Assert.AreEqual(a[1, 0], b[1, 0]);
			Assert.AreEqual(a[1, 1], b[1, 1]);
		}
        public void IsPositiveDefiniteTest()
        {
            Assert.IsTrue(cd.IsPositiveDefinite);
            ComplexDoubleMatrix b = new ComplexDoubleMatrix(3);

            b[0, 0] = -2;
            b[0, 1] = 1;
            b[0, 2] = 0;
            b[1, 0] = 1;
            b[1, 1] = 2;
            b[1, 2] = 0;
            b[2, 0] = 0;
            b[2, 1] = 0;
            b[2, 2] = 3;
            ComplexDoubleCholeskyDecomp dcd = new ComplexDoubleCholeskyDecomp(b);

            Assert.IsFalse(dcd.IsPositiveDefinite);
        }
예제 #41
0
        /// <summary>
        /// Get a copy of the Toeplitz matrix.
        /// </summary>
        /// <returns>
        /// The Toeplitz matrix
        /// </returns>
        public ComplexDoubleMatrix GetMatrix()
        {
            int i;

            // allocate memory for the matrix
            ComplexDoubleMatrix tm = new ComplexDoubleMatrix(m_Order);

#if MANAGED
            // fill lower triangle
            for (i = 0; i < m_Order; i++)
            {
                Array.Copy(m_LeftColumn.data, 0, tm.data[i], i, m_Order - i);
            }

            tm = tm.GetTranspose();

            // fill upper triangle
            for (i = 0; i < m_Order - 1; i++)
            {
                Array.Copy(m_TopRow.data, 1, tm.data[i], i + 1, m_Order - i - 1);
            }
#else
            int j, k;

            // fill lower triangle
            for (i = 0; i < m_Order; i++)
            {
                for (j = i, k = 0; j < m_Order; j++, k++)
                {
                    tm[j, i] = m_LeftColumn[k];
                }
            }
            // fill upper triangle
            for (i = 0; i < m_Order; i++)
            {
                for (j = i + 1, k = 1; j < m_Order; j++, k++)
                {
                    tm[i, j] = m_TopRow[k];
                }
            }
#endif
            return(tm);
        }
 public void NonSymmFactorTest()
 {
   ComplexDoubleMatrix b = new ComplexDoubleMatrix(3);
   b[0,0] = 2;
   b[0,1] = 1;
   b[0,2] = 1;
   b[1,0] = 1;
   b[1,1] = 2;
   b[1,2] = 0;
   b[2,0] = 0;
   b[2,1] = 0;
   b[2,2] = 3;
   ComplexDoubleCholeskyDecomp dcd = new ComplexDoubleCholeskyDecomp(b);
   Assert.AreEqual(dcd.Factor[0,0].Real,1.414,TOLERENCE);
   Assert.AreEqual(dcd.Factor[0,1].Real,0.000,TOLERENCE);
   Assert.AreEqual(dcd.Factor[0,2].Real,0.000,TOLERENCE);
   Assert.AreEqual(dcd.Factor[1,0].Real,0.707,TOLERENCE);
   Assert.AreEqual(dcd.Factor[1,1].Real,1.225,TOLERENCE);
   Assert.AreEqual(dcd.Factor[1,2].Real,0.000,TOLERENCE);
   Assert.AreEqual(dcd.Factor[2,0].Real,0.000,TOLERENCE);
   Assert.AreEqual(dcd.Factor[2,1].Real,0.000,TOLERENCE);
   Assert.AreEqual(dcd.Factor[2,2].Real,1.732,TOLERENCE);
 }
예제 #43
0
		public void SetupTestCases()
		{
			a = new ComplexDoubleMatrix(3);
			a[0, 0] = new Complex(1.1, 1.1);
			a[0, 1] = new Complex(2.2, -2.2);
			a[0, 2] = new Complex(3.3, 3.3);
			a[1, 0] = new Complex(4.4, -4.4);
			a[1, 1] = new Complex(5.5, 5.5);
			a[1, 2] = new Complex(6.6, -6.6);
			a[2, 0] = new Complex(7.7, 7.7);
			a[2, 1] = new Complex(8.8, -8.8);
			a[2, 2] = new Complex(9.9, 9.9);
			svd = new ComplexDoubleSVDDecomp(a, true);

			wa = new ComplexDoubleMatrix(2, 4);
			wa[0, 0] = new Complex(1.1, 1.1);
			wa[0, 1] = new Complex(2.2, -2.2);
			wa[0, 2] = new Complex(3.3, 3.3);
			wa[0, 3] = new Complex(4.4, -4.4);
			wa[1, 0] = new Complex(5.5, 5.5);
			wa[1, 1] = new Complex(6.6, -6.6);
			wa[1, 2] = new Complex(7.7, 7.7);
			wa[1, 3] = new Complex(8.8, -8.8);
			wsvd = new ComplexDoubleSVDDecomp(wa, true);

			la = new ComplexDoubleMatrix(4, 2);
			la[0, 0] = new Complex(1.1, 1.1);
			la[0, 1] = new Complex(2.2, -2.2);
			la[1, 0] = new Complex(3.3, 3.3);
			la[1, 1] = new Complex(4.4, -4.4);
			la[2, 0] = new Complex(5.5, 5.5);
			la[2, 1] = new Complex(6.6, -6.6);
			la[3, 0] = new Complex(7.7, 7.7);
			la[3, 1] = new Complex(8.8, -8.8);
			lsvd = new ComplexDoubleSVDDecomp(la, true);
		}
    /// <summary>
    /// Solve a symmetric square Toeplitz system with a right-side matrix.
    /// </summary>
    /// <param name="Y">The right-hand side of the system.</param>
    /// <returns>The solution matrix.</returns>
    /// <exception cref="ArgumentNullException">
    /// Parameter <B>Y</B> is a null reference.
    /// </exception>
    /// <exception cref="RankException">
    /// The number of rows in <B>Y</B> is not equal to the number of rows in the Toeplitz matrix.
    /// </exception>
    /// <exception cref="SingularMatrixException">
    /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
    /// </exception>
    /// <remarks>
    /// This member solves the linear system <B>TX</B> = <B>Y</B>, where <B>T</B> is
    /// a symmetric square Toeplitz matrix, <B>X</B> is the unknown solution matrix
    /// and <B>Y</B> is a known matrix.
    /// <para>
    /// The class implicitly decomposes the inverse Toeplitz matrix into a <b>UDL</b> factorisation
    /// using the Levinson algorithm, and then calculates the solution matrix.
    /// </para>
    /// </remarks>
    public ComplexDoubleMatrix Solve(IROComplexDoubleMatrix Y)
    {
      ComplexDoubleMatrix X;

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

      Compute();

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

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

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

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

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

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

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

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

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

      return X;
    }
    /// <summary>
    /// Get a copy of the Toeplitz matrix.
    /// </summary>
    public ComplexDoubleMatrix GetMatrix()
    {
      int i, j;

      // allocate memory for the matrix
      ComplexDoubleMatrix tm = new ComplexDoubleMatrix(m_Order);

#if MANAGED
      // fill top row
      Complex[] top = tm.data[0];
      Array.Copy(m_LeftColumn.data, 0, top, 0, m_Order);

      if (m_Order > 1)
      {
        // fill bottom row (reverse order)
        Complex[] bottom = tm.data[m_Order - 1];

        for (i = 0, j = m_Order - 1; i < m_Order; i++, j--)
        {
          bottom[i] = m_LeftColumn[j];
        }

        // fill rows in-between
        for (i = 1, j = m_Order - 1 ; j > 1; i++)
        {
          Array.Copy(top, 0, tm.data[i], i, j--);
          Array.Copy(bottom, j, tm.data[i], 0, i);
        }
      }
#else
      if (m_Order > 1)
      {
        Complex[] top = new Complex[m_Order];
        Array.Copy(m_LeftColumn.data, 0, top, 0, m_Order);
        tm.SetRow(0, top);

        // fill bottom row (reverse order)
        Complex[] bottom = new Complex[m_Order];

        for (i = 0, j = m_Order - 1; i < m_Order; i++, j--)
        {
          bottom[i] = m_LeftColumn[j];
        }

        // fill rows in-between
        for (i = 1, j = m_Order - 1 ; j > 0; i++)
        {
          Complex[] temp = new Complex[m_Order];
          Array.Copy(top, 0, temp, i, j--);
          Array.Copy(bottom, j, temp, 0, i);
          tm.SetRow(i, temp);
        }
      }
      else
      {
        Array.Copy(m_LeftColumn.data, 0, tm.data, 0, m_Order);
      }
#endif

      return tm;
    }
    /// <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 ComplexDoubleMatrix Inverse(IROComplexDoubleVector T)
    {

      ComplexDoubleMatrix 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 ComplexDoubleMatrix(1);
        X[0, 0] = Complex.One / T[0];
      }
      else
      {

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

        // calculate the predictor coefficients
        ComplexDoubleVector Y = ComplexDoubleSymmetricLevinson.YuleWalker(T);

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

      ComplexDoubleMatrix X;

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

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

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

        if (N > 1)
        {

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

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

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

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

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

            a[i - 1] = p;
            e *= (Complex.One - p * p);

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

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

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

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

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

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

            }

          }

        }

      }

      return X;
    }
 ///<summary> Constructor </summary>
 public ComplexDoubleMatrixEnumerator (ComplexDoubleMatrix matrix) 
 {
   m=matrix;
   index=-1;
   length=m.RowLength*m.ColumnLength;
 }
 private static void zscalColumn(ComplexDoubleMatrix A, int Col, int Start, Complex z) 
 {
   // A part of column Col of matrix A from row Start to end multiply by z
   for(int i=Start; i<A.RowLength; i++) 
   {
     A[i,Col]=A[i,Col]*z;
   }
 }
    ///<summary>Computes the algorithm.</summary>
    protected override void InternalCompute()
    {
      rows = matrix.RowLength;
      cols = matrix.ColumnLength;
      int mm=System.Math.Min(rows+1,cols);
      s = new ComplexDoubleVector(mm); // singular values
#if MANAGED
      // Derived from LINPACK code.
      // Initialize.
      u=new ComplexDoubleMatrix(rows,rows); // left vectors
      v=new ComplexDoubleMatrix(cols,cols); // right vectors
      ComplexDoubleVector e=new ComplexDoubleVector(cols);
      ComplexDoubleVector work=new ComplexDoubleVector(rows);

      int  i, iter, j, k, kase, l, lp1, ls=0, lu, m, nct, nctp1, ncu, nrt, nrtp1;
      double b, c, cs=0.0, el, emm1, f, g, scale, shift, sl,
        sm, sn=0.0, smm1, t1, test, ztest, xnorm, enorm;
      Complex t,r;

      ncu = rows;

      //   reduce matrix to bidiagonal form, storing the diagonal elements
      //   in s and the super-diagonal elements in e.
      int info = 0;
      nct = System.Math.Min(rows-1,cols);
      nrt = System.Math.Max(0,System.Math.Min(cols-2,rows));
      lu = System.Math.Max(nct,nrt);

      for(l=0; l<lu; l++) 
      { 
        lp1 = l + 1;
        if (l  <  nct) 
        { 
          // compute the transformation for the l-th column and
          // place the l-th diagonal in s[l].
          xnorm=dznrm2Column(matrix, l, l); 
          s[l]=new Complex(xnorm,(double)0.0);
          if (dcabs1(s[l])  !=  0.0) 
          { 
            if (dcabs1(matrix[l,l])  !=  0.0) 
            {
              s[l] = csign(s[l],matrix[l,l]);
            }
            zscalColumn(matrix, l, l, 1.0/s[l]); 
            matrix[l,l] = Complex.One + matrix[l,l];
          } 

          s[l] = -s[l];
        }  

        for(j=lp1; j<cols; j++) 
        { 
          if (l  <  nct) 
          { 
            if (dcabs1(s[l]) !=  0.0) 
            { 
              // apply the transformation.
              t = -zdotc(matrix, l, j, l)/matrix[l,l]; 
              for(int ii=l; ii < matrix.RowLength; ii++) 
              {
                matrix[ii,j]+=t*matrix[ii,l];
              }
            } 
          }

          //place the l-th row of matrix into  e for the
          //subsequent calculation of the row transformation.
          e[j] = ComplexMath.Conjugate(matrix[l,j]);
        } 
       
        if (computeVectors && l < nct) 
        { 
          // place the transformation in u for subsequent back multiplication.
          for(i=l; i < rows; i++) 
          { 
            u[i,l] = matrix[i,l];
          } 
        } 

        if (l < nrt) 
        {    
          // compute the l-th row transformation and place the l-th super-diagonal in e(l).
          enorm=dznrm2Vector(e,lp1);
          e[l]=new Complex(enorm, 0.0); 
          if (dcabs1(e[l])  !=  0.0) 
          { 
            if (dcabs1(e[lp1])  !=  0.0) 
            { 
              e[l] = csign(e[l],e[lp1]);
            }
            zscalVector(e, lp1, 1.0/e[l]); 
            e[lp1] = Complex.One + e[lp1];
          }  
          e[l] = ComplexMath.Conjugate(-e[l]);

          if (lp1  <  rows  &&  dcabs1(e[l])  !=  0.0) 
          { 
            // apply the transformation.
            for(i=lp1; i<rows; i++) 
            { 
              work[i] = Complex.Zero;
            } 

            for(j=lp1; j<cols; j++) 
            {  
              for(int ii=lp1; ii < matrix.RowLength; ii++) 
              {
                work[ii]+=e[j]*matrix[ii,j];
              }
            }  

            for(j=lp1; j<cols; j++) 
            { 
              Complex ww=ComplexMath.Conjugate(-e[j]/e[lp1]);
              for(int ii=lp1; ii < matrix.RowLength; ii++) 
              {
                matrix[ii,j]+=ww*work[ii];
              }
            } 
          } 

          if (computeVectors) 
          { 
            // place the transformation in v for subsequent back multiplication.
            for(i=lp1; i < cols; i++) 
            { 
              v[i,l] = e[i];
            } 
          } 
        } 
      }

      //   set up the final bidiagonal matrix or order m.
      m = System.Math.Min(cols,rows+1);
      nctp1 = nct + 1;
      nrtp1 = nrt + 1;
      if (nct  <  cols) 
      {
        s[nctp1-1] = matrix[nctp1-1,nctp1-1];
      }
      if (rows  <  m) 
      {
        s[m-1] = Complex.Zero;
      }
      if (nrtp1  <  m) 
      {
        e[nrtp1-1] = matrix[nrtp1-1,m-1];
      }
      e[m-1] = Complex.Zero;

      //   if required, generate u.
      if (computeVectors) 
      {
        for(j=nctp1-1; j<ncu; j++) 
        { 
          for(i=0; i < rows; i++) 
          {
            u[i,j] = Complex.Zero;
          } 
          u[j,j] = Complex.One;
        } 
 
        for(l=nct-1; l>=0; l--) 
        { 
          if (dcabs1(s[l])  !=  0.0) 
          {  
            for(j=l+1; j < ncu; j++) 
            {  
              t = -zdotc(u, l, j, l)/u[l,l]; 
              for(int ii=l; ii < u.RowLength; ii++) 
              {
                u[ii,j]+=t*u[ii,l];
              }
            }
            zscalColumn(u, l, l, -Complex.One);
            u[l,l] = Complex.One + u[l,l];
            for(i=0; i<l; i++) 
            {
              u[i,l] = Complex.Zero;
            }
          } 
          else 
          {   
            for(i=0; i<rows; i++) 
            {
              u[i,l] = Complex.Zero;
            }
            u[l,l] = Complex.One;
          } 
        }
      }  

      //   if it is required, generate v.
      if (computeVectors) 
      { 
        for(l=cols-1; l>=0; l--) 
        {
          lp1 = l + 1;
          if (l  <  nrt) 
          { 
            if (dcabs1(e[l])  !=  0.0) 
            {
              for(j=lp1; j < cols; j++) 
              {
                t = -zdotc(v, l, j, lp1)/v[lp1,l];
                for(int ii=l; ii < v.RowLength; ii++) 
                {
                  v[ii,j]+=t*v[ii,l];
                }
              } 
            }
          } 
          for(i=0; i < cols; i++) 
          { 
            v[i,l] = Complex.Zero;
          }
          v[l,l] = Complex.One;
        }
      }

      //   transform s and e so that they are  double .
      for(i=0; i < m; i++) 
      {
        if (dcabs1(s[i])  !=  0.0) 
        { 
          t = new Complex(ComplexMath.Absolute(s[i]),0.0);
          r = s[i]/t;
          s[i] = t;
          if (i  <  m-1) 
          {
            e[i] = e[i]/r;
          }
          if (computeVectors) 
          {
            zscalColumn(u, i, 0, r);
          }
        }
        //   ...exit
        if (i  ==  m-1) 
        {
          break;  
        }
        if (dcabs1(e[i])  !=  0.0) 
        { 
          t = new Complex(ComplexMath.Absolute(e[i]),0.0);
          r = t/e[i];
          e[i] = t;
          s[i+1] = s[i+1]*r;
          if (computeVectors) 
          {
            zscalColumn(v, i+1, 0, r); 
          }
        } 
      }

      //   main iteration loop for the singular values.
      mm = m;
      iter = 0;

      while(m > 0) 
      { // quit if all the singular values have been found.
        // if too many iterations have been performed, set
        //      flag and return.
        if (iter  >=  MAXITER) 
        {
          info = m;
          //   ......exit
          break;
        }

        //      this section of the program inspects for
        //      negligible elements in the s and e arrays.  on
        //      completion the variables kase and l are set as follows.

        //         kase = 1     if s[m] and e[l-1] are negligible and l < m
        //         kase = 2     if s[l] is negligible and l < m
        //         kase = 3     if e[l-1] is negligible, l < m, and
        //                      s[l, ..., s[m] are not negligible (qr step).
        //         kase = 4     if e[m-1] is negligible (convergence).

        for(l=m-2; l>=0; l--) 
        { 
          test = ComplexMath.Absolute(s[l]) + ComplexMath.Absolute(s[l+1]);
          ztest = test + ComplexMath.Absolute(e[l]);
          if (ztest  ==  test) 
          { 
            e[l] = Complex.Zero;
            break;
          } 
        }
          
        if (l  ==  m - 2) 
        {
          kase = 4;
        } 
        else
        {
          for(ls=m-1; ls > l; ls--) 
          { 
            test = 0.0;
            if (ls  !=  m-1) 
            {
              test = test + ComplexMath.Absolute(e[ls]);
            }
            if (ls  !=  l + 1) 
            {
              test = test + ComplexMath.Absolute(e[ls-1]);
            }
            ztest = test + ComplexMath.Absolute(s[ls]);
            if (ztest ==  test) 
            { 
              s[ls] = Complex.Zero;
              break; 
            } 
          } 

          if (ls  ==  l) 
          {
            kase = 3;
          } 
          else if (ls  ==  m-1) 
          { 
            kase = 1;
          } 
          else
          {
            kase = 2;
            l = ls;
          }
        }
  
        l = l + 1;

        //      perform the task indicated by kase.
        switch(kase) 
        {
            // deflate negligible s[m].
          case 1:
            f = e[m-2].Real;
            e[m-2] = Complex.Zero;
            for(k=m-2; k>=0; k--) 
            { 
              t1 = s[k].Real;
              drotg(ref t1,ref f,ref cs,ref sn);
              s[k] = new Complex(t1, 0.0);
              if (k  !=  l) 
              { 
                f = -sn*e[k-1].Real;
                e[k-1] = cs*e[k-1];
              } 
              if (computeVectors) 
              {
                zdrot (v, k, m-1, cs, sn); 
              }
            } 
            break; 

            // split at negligible s[l].
          case 2:
            f = e[l-1].Real;
            e[l-1] = Complex.Zero;
            for(k=l; k <m; k++) 
            {
              t1 = s[k].Real;
              drotg(ref t1, ref f, ref cs, ref sn);
              s[k] = new Complex(t1,0.0);
              f = -sn*e[k].Real;
              e[k] = cs*e[k];
              if (computeVectors) 
              {
                zdrot (u, k, l-1, cs, sn); 
              }
            } 
            break;
         
            // perform one qr step.
          case 3:
            // calculate the shift.
            scale=0.0;
            scale=System.Math.Max(scale,ComplexMath.Absolute(s[m-1]));
            scale=System.Math.Max(scale,ComplexMath.Absolute(s[m-2]));
            scale=System.Math.Max(scale,ComplexMath.Absolute(e[m-2]));
            scale=System.Math.Max(scale,ComplexMath.Absolute(s[l]));
            scale=System.Math.Max(scale,ComplexMath.Absolute(e[l]));
            sm = s[m-1].Real/scale; 
            smm1 = s[m-2].Real/scale;
            emm1 = e[m-2].Real/scale;
            sl = s[l].Real/scale;
            el = e[l].Real/scale;
            b = ((smm1 + sm)*(smm1 - sm) + emm1*emm1)/2.0;
            c = (sm*emm1)*(sm*emm1); 
            shift = 0.0;
            if (b  !=  0.0  ||  c  !=  0.0) 
            { 
              shift = System.Math.Sqrt(b*b+c);
              if (b  <  0.0) 
              {
                shift = -shift;
              }
              shift = c/(b + shift);
            } 
            f = (sl + sm)*(sl - sm) + shift;
            g = sl*el;

            // chase zeros.
            for(k=l; k < m-1; k++) 
            {
              drotg(ref f, ref g, ref cs, ref sn);
              if (k  !=  l) 
              {
                e[k-1] = new Complex(f,0.0);
              }
              f = cs*s[k].Real + sn*e[k].Real;
              e[k] = cs*e[k] - sn*s[k];
              g = sn*s[k+1].Real;
              s[k+1] = cs*s[k+1];
              if (computeVectors) 
              {
                zdrot (v, k, k+1, cs, sn); 
              }
              drotg(ref f, ref g, ref cs, ref sn);
              s[k] = new Complex(f,0.0);
              f = cs*e[k].Real + sn*s[k+1].Real;
              s[k+1] = -sn*e[k] + cs*s[k+1];
              g = sn*e[k+1].Real;
              e[k+1] = cs*e[k+1];
              if (computeVectors  &&  k < rows) 
              {
                zdrot(u, k, k+1, cs, sn); 
              }
            } 
            e[m-2] =new  Complex(f,0.0);
            iter = iter + 1;
            break; 

            // convergence.
          case 4: 
            // make the singular value  positive
            if (s[l].Real  < 0.0) 
            {
              s[l] = -s[l];
              if (computeVectors) 
              {
                zscalColumn(v, l, 0, -Complex.One); 
              }
            }

            // order the singular value.
            while (l != mm-1) 
            {
              if (s[l].Real  >= s[l+1].Real) 
              {
                break;
              }
              t = s[l];
              s[l] = s[l+1];
              s[l+1] = t;
              if (computeVectors && l < cols) 
              {
                zswap(v,l,l+1); 
              }
              if (computeVectors && l < rows) 
              {
                zswap(u,l,l+1); 
              }
              l = l + 1;
            } 
            iter = 0;
            m = m - 1;
            break;
        } 
      }

      // make matrix w from vector s
      // there is no constructor, creating diagonal matrix from vector
      // doing it ourselves
      mm=System.Math.Min(matrix.RowLength,matrix.ColumnLength);
      
#else
      double[] d = new double[mm];
      u = new ComplexDoubleMatrix(rows);
      v = new ComplexDoubleMatrix(cols);
      Complex[] a = new Complex[matrix.data.Length];
      Array.Copy(matrix.data, a, matrix.data.Length);
      Lapack.Gesvd.Compute(rows, cols, a, d, u.data, v.data );
      v.ConjugateTranspose();
      for( int i = 0; i < d.Length; i++){
        s[i] = d[i];
      }
#endif    
      w=new ComplexDoubleMatrix(matrix.RowLength,matrix.ColumnLength);
      for(int ii=0; ii<matrix.RowLength; ii++) 
      {
        for(int jj=0; jj<matrix.ColumnLength; jj++) 
        {
          if(ii==jj) 
          {
            w[ii,ii]=s[ii];
          } 
        }
      }
      
      double eps = System.Math.Pow(2.0,-52.0);
      double tol = System.Math.Max(matrix.RowLength,matrix.ColumnLength)*s[0].Real*eps;
      rank = 0;
      
      for (int h = 0; h < mm; h++) 
      {
        if (s[h].Real > tol) 
        {
          rank++;
        }
      }

      if( !computeVectors )
      {
        u = null;
        v = null;
      }
      matrix = null;
    }
 private static void zswap(ComplexDoubleMatrix A, int Col1, int Col2) 
 {
   // swap columns Col1,Col2
   Complex z;
   for(int i=0; i < A.RowLength; i++) 
   {
     z=A[i,Col1];
     A[i,Col1]=A[i,Col2];
     A[i,Col2]=z;
   } 
 }
 public void ExplicitToComplexDoubleMatrix()
 {
   ComplexDoubleMatrix a = new ComplexDoubleMatrix(2,2);
   a[0,0] = 1;
   a[0,1] = 2;
   a[1,0] = 3;
   a[1,1] = 4;
   
   ComplexFloatMatrix b = ComplexFloatMatrix.ToComplexFloatMatrix(a);
   Assert.AreEqual(a.RowLength, b.RowLength);
   Assert.AreEqual(a.ColumnLength, b.ColumnLength);
   Assert.AreEqual(b[0,0], a[0,0]);
   Assert.AreEqual(b[0,1], a[0,1]);
   Assert.AreEqual(b[1,0], a[1,0]);
   Assert.AreEqual(b[1,1], a[1,1]);
 }
 public void Multiply()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new double[4]{0,1,2,3});
   ComplexDoubleVector b = new ComplexDoubleVector(new double[4]{4,5,6,7});
   ComplexDoubleMatrix c = new ComplexDoubleMatrix(a.Length,b.Length);
   ComplexDoubleMatrix d = new ComplexDoubleMatrix(a.Length,b.Length);
   
   c = a*b;
   d = ComplexDoubleVector.Multiply(a,b);
   
   Assert.AreEqual(c[0,0],a[0]*b[0]);
   Assert.AreEqual(c[0,1],a[0]*b[1]);
   Assert.AreEqual(c[0,2],a[0]*b[2]);
   Assert.AreEqual(c[0,3],a[0]*b[3]);
   Assert.AreEqual(c[1,0],a[1]*b[0]);
   Assert.AreEqual(c[1,1],a[1]*b[1]);
   Assert.AreEqual(c[1,2],a[1]*b[2]);
   Assert.AreEqual(c[1,3],a[1]*b[3]);
   Assert.AreEqual(c[2,0],a[2]*b[0]);
   Assert.AreEqual(c[2,1],a[2]*b[1]);
   Assert.AreEqual(c[2,2],a[2]*b[2]);
   Assert.AreEqual(c[2,3],a[2]*b[3]);
   Assert.AreEqual(c[3,0],a[3]*b[0]);
   Assert.AreEqual(c[3,1],a[3]*b[1]);
   Assert.AreEqual(c[3,2],a[3]*b[2]);
   Assert.AreEqual(c[3,3],a[3]*b[3]);
   
   Assert.AreEqual(d[0,0],a[0]*b[0]);
   Assert.AreEqual(d[0,1],a[0]*b[1]);
   Assert.AreEqual(d[0,2],a[0]*b[2]);
   Assert.AreEqual(d[0,3],a[0]*b[3]);
   Assert.AreEqual(d[1,0],a[1]*b[0]);
   Assert.AreEqual(d[1,1],a[1]*b[1]);
   Assert.AreEqual(d[1,2],a[1]*b[2]);
   Assert.AreEqual(d[1,3],a[1]*b[3]);
   Assert.AreEqual(d[2,0],a[2]*b[0]);
   Assert.AreEqual(d[2,1],a[2]*b[1]);
   Assert.AreEqual(d[2,2],a[2]*b[2]);
   Assert.AreEqual(d[2,3],a[2]*b[3]);
   Assert.AreEqual(d[3,0],a[3]*b[0]);
   Assert.AreEqual(d[3,1],a[3]*b[1]);
   Assert.AreEqual(d[3,2],a[3]*b[2]);
   Assert.AreEqual(d[3,3],a[3]*b[3]);
 }
    private static void zdrot (ComplexDoubleMatrix A, int Col1, int Col2, double c, double s)
    {
      // applies a plane rotation, where the c=cos and s=sin
      // Col1, Col2 - rotated columns of A

      Complex z;
      for(int i=0; i < A.RowLength; i++)
      {
        z=c*A[i,Col1]+s*A[i,Col2];
        A[i,Col2]=c*A[i,Col2]-s*A[i,Col1];
        A[i,Col1]=z;
      }
    }
    /// <summary>
    /// Get the inverse of the Toeplitz matrix.
    /// </summary>
    /// <returns>The inverse matrix.</returns>
    /// <exception cref="SingularMatrixException">
    /// The Toeplitz matrix or one of the the leading sub-matrices is singular.
    /// </exception>
    /// <remarks>
    /// The class implicitly decomposes the inverse Toeplitz matrix into a <b>UDL</b> factorisation
    /// using the Levinson algorithm, before using Trench's algorithm to complete
    /// the calculation of the inverse.
    /// <para>
    /// Trench's algorithm requires approximately <b>N</b> squared FLOPS, compared to <b>N</b> cubed FLOPS
    /// if we simply multiplied the <b>UDL</b> factors (<b>N</b> is the matrix order).
    /// </para>
    /// </remarks>
    public ComplexDoubleMatrix GetInverse()
    {
      Compute();

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

      ComplexDoubleMatrix I = new ComplexDoubleMatrix(m_Order);           // the solution matrix
      Complex[] A = m_LowerTriangle[m_Order-1];
      Complex A1, A2, scale;

#if MANAGED

      Complex[] current, previous;                    // references to rows in the solution
      int i, j, k, l;

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

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

#else

      int i, j, k, l;

      // setup the first row in wedge
      scale = m_Diagonal[m_Order-1];
      for (i = 0, j = m_Order - 1; i < m_Order; i++, j--)
      {
        I[0, i] = scale* A[j];
      }

      // calculate values in the rest of the wedge
      for (i = 1; i < (1 + m_Order) / 2; i++)
      {
        A1 = A[m_Order - i - 1];
        A2 = A[i - 1];
        for (j = i, k = i - 1, l = m_Order - i - 1; j < m_Order - i; j++, k++, l--)
        {
          I[i, j] = I[i - 1, k] + scale * (A1 * A[l] - A2 * A[k]);
        }
      }

#endif

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

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

      return I;
    }
		public void ForEach()
		{
			ComplexDoubleMatrix test = new ComplexDoubleMatrix(new Complex[2, 2] { { 1, 2 }, { 3, 4 } });
			foreach (Complex f in test)
				Assert.IsTrue(test.Contains(f));
		}
 private static Complex zdotc(ComplexDoubleMatrix A, int Col1, int Col2, int Start)
 {
   Complex z=Complex.Zero;
   for(int i=Start; i < A.RowLength; i++)
   { 
     z+=A[i,Col2]*ComplexMath.Conjugate(A[i,Col1]);
   }
   return z;
 }
 private static double dznrm2Column(ComplexDoubleMatrix A, int Col, int Start) 
 {
   //  dznrm2Column returns the euclidean norm of a vector,
   // which is a part of column Col in matrix A, beginning from Start to end of column
   // so that dznrm2Column := sqrt( conjg( matrix' )*matrix )
   double s=0;
   for(int i=Start; i < A.RowLength; i++) 
   {
     s+=(A[i,Col]*ComplexMath.Conjugate(A[i,Col])).Real;
   }
   return System.Math.Sqrt(s);
 }
		public void CurrentException2()
		{
			ComplexDoubleMatrix test = new ComplexDoubleMatrix(new Complex[2, 2] { { 1, 2 }, { 3, 4 } });
			IEnumerator enumerator = test.GetEnumerator();
			enumerator.MoveNext();
			enumerator.MoveNext();
			enumerator.MoveNext();
			enumerator.MoveNext();
			enumerator.MoveNext();
			object value = enumerator.Current;
		}
 ///<summary>Constructor for SVD decomposition class.</summary>
 ///<param name="matrix">The matrix to decompose.</param>
 ///<exception cref="ArgumentNullException">matrix is null.</exception>
 public ComplexDoubleSVDDecomp(IROComplexDoubleMatrix matrix)
 {
   if ( matrix == null ) 
   {
     throw new System.ArgumentNullException("matrix cannot be null.");
   }
   this.matrix = new ComplexDoubleMatrix(matrix);
 }