///<summary>Add a <c>ComplexDoubleVector</c> to another <c>ComplexDoubleVector</c></summary>
        ///<param name="lhs"><c>ComplexDoubleVector</c> to add to.</param>
        ///<param name="rhs"><c>ComplexDoubleVector</c> to add.</param>
        ///<returns><c>ComplexDoubleVector</c> with results.</returns>
        public static ComplexDoubleVector operator +(ComplexDoubleVector lhs, ComplexDoubleVector rhs)
        {
            ComplexDoubleVector ret = new ComplexDoubleVector(lhs);

            Blas.Axpy.Compute(ret.Length, 1, rhs.data, 1, ret.data, 1);
            return(ret);
        }
        ///<summary>Negate operator for <c>ComplexDoubleVector</c></summary>
        ///<returns><c>ComplexDoubleVector</c> with values to negate.</returns>
        public static ComplexDoubleVector operator -(ComplexDoubleVector rhs)
        {
            ComplexDoubleVector ret = new ComplexDoubleVector(rhs);

            Blas.Scal.Compute(ret.Length, -1, ret.data, 1);
            return(ret);
        }
Example #3
0
        ///<summary>Multiply a <c>Complex</c> x with a <c>ComplexDoubleVector</c> y as x*y</summary>
        ///<param name="lhs"><c>Complex</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 ComplexDoubleVector operator *(Complex lhs, ComplexDoubleVector rhs)
        {
            var ret = new ComplexDoubleVector(rhs);

            Blas.Scal.Compute(ret.Length, lhs, ret.data, 1);
            return(ret);
        }
        ///<summary>Divide a <c>ComplexDoubleVector</c> x with a <c>Complex</c> y as x/y</summary>
        ///<param name="lhs"><c>ComplexDoubleVector</c> as left hand operand.</param>
        ///<param name="rhs"><c>Complex</c> as right hand operand.</param>
        ///<returns><c>ComplexDoubleVector</c> with results.</returns>
        public static ComplexDoubleVector operator /(ComplexDoubleVector lhs, Complex rhs)
        {
            ComplexDoubleVector ret = new ComplexDoubleVector(lhs);

            Blas.Scal.Compute(ret.Length, 1 / rhs, ret.data, 1);
            return(ret);
        }
Example #5
0
        /// <overloads>
        /// There are two permuations of the constructor, both require a parameter corresponding
        /// to the left-most column of a Toeplitz matrix.
        /// </overloads>
        /// <summary>
        /// Constructor with <c>ComplexDoubleVector</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 ComplexDoubleSymmetricLevinson(IROComplexDoubleVector 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 ComplexDoubleVector(T);
            m_Order      = m_LeftColumn.Length;

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

            // allocate memory for diagonal
            m_Diagonal = new Complex[m_Order];
        }
        /// <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);
        }
Example #7
0
 ///<summary>Add a <c>ComplexDoubleVector</c> to this<c>ComplexDoubleVector</c></summary>
 ///<param name="vector"><c>ComplexDoubleVector</c> to add.</param>
 ///<exception cref="ArgumentNullException">Exception thrown if null given as argument.</exception>
 public void Add(ComplexDoubleVector vector)
 {
     if (vector == null)
     {
         throw new System.ArgumentNullException("ComplexDoubleVector cannot be null.");
     }
     Blas.Axpy.Compute(Length, 1, vector.data, 1, data, 1);
 }
 public void CtorInitialValues()
 {
   ComplexDoubleVector test = new ComplexDoubleVector(2, new Complex(1,-1));
   
   Assert.AreEqual(test.Length, 2);
   Assert.AreEqual(test[0],new Complex(1,-1));
   Assert.AreEqual(test[1],new Complex(1,-1));
 }
 public void CtorDimensions()
 {
   ComplexDoubleVector test = new ComplexDoubleVector(2);
   
   Assert.AreEqual(test.Length, 2);
   Assert.AreEqual(test[0],new Complex(0));
   Assert.AreEqual(test[1],new Complex(0));
 }
 ///<summary>Compute the sum y = alpha * x + y where y is this <c>ComplexDoubleVector</c></summary>
 ///<param name="alpha"><c>Complex</c> value to scale this <c>ComplexDoubleVector</c></param>
 ///<param name="X"><c>ComplexDoubleVector</c> to add to alpha * this <c>ComplexDoubleVector</c></param>
 ///<remarks>Results of computation replace data in this variable</remarks>
 public void Axpy(Complex alpha, ComplexDoubleVector X)
 {
     if (X == null)
     {
         throw new System.ArgumentNullException("ComplexDoubleVector cannot be null.");
     }
     Blas.Axpy.Compute(data.Length, alpha, X.data, 1, this.data, 1);
 }
 ///<summary>Compute the complex conjugate scalar product x^Hy and return as <c>Complex</c></summary>
 ///<param name="Y"><c>ComplexDoubleVector</c> to act as y operand in x^Hy.</param>
 ///<returns><c>Complex</c> results from x^Hy.</returns>
 public Complex GetConjugateDotProduct(ComplexDoubleVector Y)
 {
     if (Y == null)
     {
         throw new System.ArgumentNullException("ComplexDoubleVector cannot be null.");
     }
     return(Blas.Dotc.Compute(this.Length, this.data, 1, Y.data, 1));
 }
 ///<summary>Swap data in this <c>ComplexDoubleVector</c> with another <c>ComplexDoubleVector</c></summary>
 ///<param name="src"><c>ComplexDoubleVector</c> to swap data with.</param>
 public void Swap(ComplexDoubleVector src)
 {
     if (src == null)
     {
         throw new System.ArgumentNullException("ComplexDoubleVector cannot be null.");
     }
     Blas.Swap.Compute(src.Length, src.data, 1, this.data, 1);
 }
 private static void zscalVector(ComplexDoubleVector A, int Start, Complex z)
 {
     // A part of vector  A from Start to end multiply by z
     for (int i = Start; i < A.Length; i++)
     {
         A[i] = A[i] * z;
     }
 }
 ///<summary>Subtract a <c>ComplexDoubleVector</c> from this<c>ComplexDoubleVector</c></summary>
 ///<param name="vector"><c>ComplexDoubleVector</c> to add.</param>
 ///<exception cref="ArgumentNullException">Exception thrown if null given as argument.</exception>
 public void Subtract(ComplexDoubleVector vector)
 {
     if (vector == null)
     {
         throw new System.ArgumentNullException("ComplexDoubleVector cannot be null.");
     }
     Blas.Axpy.Compute(this.Length, -1, vector.data, 1, this.data, 1);
 }
 ///<summary>Negate operator for <c>ComplexDoubleVector</c></summary>
 ///<returns><c>ComplexDoubleVector</c> with values to negate.</returns>
 public static ComplexDoubleVector Negate(ComplexDoubleVector rhs)
 {
     if (rhs == null)
     {
         throw new ArgumentNullException("rhs", "rhs cannot be null");
     }
     return(-rhs);
 }
    /// <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;
      }
    }
 public void CtorArray()
 {
   double[] testvector = new double[2]{0,1};
   
   ComplexDoubleVector test = new ComplexDoubleVector(testvector);
   Assert.AreEqual(test.Length,testvector.Length);
   Assert.AreEqual(test[0],new Complex(testvector[0]));
   Assert.AreEqual(test[1],new Complex(testvector[1]));
 }
		public void CurrentException2()
		{
			ComplexDoubleVector test = new ComplexDoubleVector(new Complex[2] { 1, 2 });
			IEnumerator enumerator = test.GetEnumerator();
			enumerator.MoveNext();
			enumerator.MoveNext();
			enumerator.MoveNext();
			object value = enumerator.Current;
		}
 ///<summary>Constructor for <c>ComplexDoubleVector</c> to deep copy another <c>ComplexDoubleVector</c></summary>
 ///<param name="src"><c>ComplexDoubleVector</c> to deep copy into <c>ComplexDoubleVector</c>.</param>
 ///<exception cref="ArgumentNullException">Exception thrown if null passed as 'src' parameter.</exception>
 public ComplexDoubleVector(ComplexDoubleVector src)
 {
     if (src == null)
     {
         throw new ArgumentNullException("ComplexDoubleVector cannot be null");
     }
     data = new Complex[src.data.Length];
     Array.Copy(src.data, 0, data, 0, data.Length);
 }
        /// <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 ComplexDoubleVector Solve(IROComplexDoubleVector Y)
        {
            ComplexDoubleVector 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
            Complex Inner;   // inner product
            Complex G;       // scaling constant

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

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

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

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

            return(X);
        }
        ///<summary>Sum the components in this <c>ComplexDoubleVector</c></summary>
        ///<returns><c>Complex</c> results from the summary of <c>ComplexDoubleVector</c> components.</returns>
        public Complex GetSum()
        {
            Complex ret = 0;

            for (int i = 0; i < data.Length; ++i)
            {
                ret += data[i];
            }
            return(ret);
        }
        private ComplexDoubleVector Pivot(IROComplexDoubleVector B)
        {
            ComplexDoubleVector ret = new ComplexDoubleVector(B.Length);

            for (int i = 0; i < pivots.Length; i++)
            {
                ret.data[i] = B[pivots[i]];
            }
            return(ret);
        }
        /// <summary>
        /// Returns the column of a <see cref="IROComplexDoubleMatrix" /> as a new <c>ComplexDoubleVector.</c>
        /// </summary>
        /// <param name="mat">The matrix to copy the column from.</param>
        /// <param name="col">Number of column to copy from the matrix.</param>
        /// <returns>A new <c>ComplexDoubleVector</c> with the same elements as the column of the given matrix.</returns>
        public static ComplexDoubleVector GetColumn(IROComplexDoubleMatrix mat, int col)
        {
            ComplexDoubleVector result = new ComplexDoubleVector(mat.Rows);

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

            return(result);
        }
        ///<summary>Implicit cast conversion to <c>ComplexDoubleVector</c> from <c>ComplexFloatVector</c></summary>
        static public ComplexDoubleVector ToComplexDoubleVector(ComplexFloatVector src)
        {
            ComplexFloat[]      temp = src.ToArray();
            ComplexDoubleVector ret  = new ComplexDoubleVector(temp.Length);

            for (int i = 0; i < temp.Length; ++i)
            {
                ret.data[i] = temp[i];
            }
            return(ret);
        }
        /// <summary>
        /// Returns the row of a <see cref="IROComplexDoubleMatrix" /> as a new <c>ComplexDoubleVector.</c>
        /// </summary>
        /// <param name="mat">The matrix to copy the column from.</param>
        /// <param name="row">Number of row to copy from the matrix.</param>
        /// <returns>A new <c>ComplexDoubleVector</c> with the same elements as the row of the given matrix.</returns>
        public static ComplexDoubleVector GetRow(IROComplexDoubleMatrix mat, int row)
        {
            ComplexDoubleVector result = new ComplexDoubleVector(mat.Columns);

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

            return(result);
        }
Example #26
0
        ///<summary>Implicit cast conversion to <c>ComplexDoubleVector</c> from <c>DoubleVector</c></summary>
        public static ComplexDoubleVector ToComplexDoubleVector(DoubleVector src)
        {
            double[] temp = src.ToArray();
            var      ret  = new ComplexDoubleVector(temp.Length);

            for (int i = 0; i < temp.Length; ++i)
            {
                ret.data[i] = temp[i];
            }
            return(ret);
        }
        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));
        }
        private static double dznrm2Vector(ComplexDoubleVector A, int Start)
        {
            //  dznrm2Vector returns the euclidean norm of a vector,
            // which is a part of A, beginning from Start to end of vector
            // so that dznrm2Vector := sqrt( conjg( matrix' )*matrix )
            double s = 0;

            for (int i = Start; i < A.Length; i++)
            {
                s += (A[i] * ComplexMath.Conjugate(A[i])).Real;
            }
            return(System.Math.Sqrt(s));
        }
Example #29
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
            }
        }
Example #30
0
        ///<summary>Explicit cast conversion to <c>ComplexFloatVector</c> from <c>double</c> array</summary>
        static public ComplexFloatVector ToComplexFloatVector(ComplexDoubleVector src)
        {
            if (src == null)
            {
                return(null);
            }
            ComplexFloatVector ret = new ComplexFloatVector(src.Length);

            for (int i = 0; i < src.Length; ++i)
            {
                ret.data[i] = (ComplexFloat)src[i];
            }
            return(ret);
        }
Example #31
0
        ///<summary>Implicit cast conversion to <c>ComplexDoubleVector</c> from <c>double</c> array</summary>
        public static ComplexDoubleVector ToComplexDoubleVector(double[] src)
        {
            if (src == null)
            {
                return(null);
            }
            var ret = new ComplexDoubleVector(src.Length);

            for (int i = 0; i < src.Length; ++i)
            {
                ret.data[i] = src[i];
            }
            return(ret);
        }
        ///<summary>Compute the Infinity Norm of this <c>ComplexDoubleVector</c></summary>
        ///<returns><c>double</c> results from norm.</returns>
        public double GetInfinityNorm()
        {
            double ret = 0;

            for (int i = 0; i < data.Length; i++)
            {
                double tmp = ComplexMath.Absolute(data[i]);
                if (tmp > ret)
                {
                    ret = tmp;
                }
            }
            return(ret);
        }
Example #33
0
        public static ComplexDoubleVector GenerateRow(IComplexDoubleMatrix A, int r, int c1, int c2)
        {
            int cu = c2 - c1 + 1;
            ComplexDoubleVector u = new ComplexDoubleVector(cu);

            for (int j = c1; j <= c2; j++)
            {
                u[j - c1] = A[r, j];
                A[r, j]   = Complex.Zero;
            }

            double norm = u.GetNorm();

            if (c1 == c2 || norm == 0)
            {
                A[r, c1] = new Complex(-u[0].Real, -u[0].Imag);
                u[0]     = System.Math.Sqrt(2);
                return(u);
            }

            Complex scale = new Complex(1 / norm);

            Complex t  = Complex.Zero;
            Complex t1 = Complex.Zero;

            if (u[0].Real != 0 || u[0].Imag != 0)
            {
                t     = u[0];
                t1    = ComplexMath.Conjugate(u[0]);
                t     = ComplexMath.Absolute(t);
                t     = t1 / t;
                scale = scale * t;
            }

            A[r, c1] = -Complex.One / scale;

            for (int j = 0; j < cu; j++)
            {
                u[j] *= scale;
            }

            u[0] = new Complex(u[0].Real + 1);
            double s = System.Math.Sqrt(1 / u[0].Real);

            for (int j = 0; j < cu; j++)
            {
                u[j] = new Complex(s * u[j].Real, -s * u[j].Imag);
            }
            return(u);
        }
Example #34
0
        public static ComplexDoubleVector GenerateColumn(IComplexDoubleMatrix A, int r1, int r2, int c)
        {
            int ru = r2 - r1 + 1;
            ComplexDoubleVector u = new ComplexDoubleVector(r2 - r1 + 1);

            for (int i = r1; i <= r2; i++)
            {
                u[i - r1] = A[i, c];
                A[i, c]   = Complex.Zero;
            }

            double norm = u.GetNorm();

            if (r1 == r2 || norm == 0)
            {
                A[r1, c] = new Complex(-u[0]);
                u[0]     = System.Math.Sqrt(2);
                return(u);
            }

            Complex scale = new Complex(1 / norm, 0);

            Complex t  = Complex.Zero;
            Complex t1 = Complex.Zero;

            if (u[0].Real != 0 || u[0].Imag != 0)
            {
                t     = u[0];
                t1    = ComplexMath.Conjugate(u[0]);
                t     = ComplexMath.Absolute(t);
                t     = t1 / t;
                scale = scale * t;
            }
            A[r1, c] = -Complex.One / scale;

            for (int i = 0; i < ru; i++)
            {
                u[i] = u[i] * scale;
            }

            u[0] = new Complex(u[0].Real + 1, 0);
            double s = System.Math.Sqrt(1 / u[0].Real);

            for (int i = 0; i < ru; i++)
            {
                u[i] = new Complex(s * u[i].Real, s * u[i].Imag);
            }
            return(u);
        }
Example #35
0
		public static ComplexDoubleVector GenerateColumn(IComplexDoubleMatrix A, int r1, int r2, int c)
		{
			int ru = r2 - r1 + 1;
			ComplexDoubleVector u = new ComplexDoubleVector(r2 - r1 + 1);

			for (int i = r1; i <= r2; i++)
			{
				u[i - r1] = A[i, c];
				A[i, c] = Complex.Zero;
			}

			double norm = u.GetNorm();

			if (r1 == r2 || norm == 0)
			{
				A[r1, c] = new Complex(-u[0]);
				u[0] = System.Math.Sqrt(2);
				return u;
			}

			Complex scale = new Complex(1 / norm, 0);

			Complex t = Complex.Zero;
			Complex t1 = Complex.Zero;
			if (u[0].Real != 0 || u[0].Imag != 0)
			{
				t = u[0];
				t1 = ComplexMath.Conjugate(u[0]);
				t = ComplexMath.Absolute(t);
				t = t1 / t;
				scale = scale * t;
			}
			A[r1, c] = -Complex.One / scale;

			for (int i = 0; i < ru; i++)
			{
				u[i] = u[i] * scale;
			}

			u[0] = new Complex(u[0].Real + 1, 0);
			double s = System.Math.Sqrt(1 / u[0].Real);

			for (int i = 0; i < ru; i++)
			{
				u[i] = new Complex(s * u[i].Real, s * u[i].Imag);
			}
			return u;
		}
        /// <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 ComplexDoubleVector Solve(IROComplexDoubleVector Y)
        {
            ComplexDoubleVector X;
            Complex             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
            Complex[] A, B;
            X = new ComplexDoubleVector(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);
        }
		public void Current()
		{
			ComplexDoubleVector test = new ComplexDoubleVector(new Complex[2] { 1, 2 });
			IEnumerator enumerator = test.GetEnumerator();
			bool movenextresult;

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

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

			movenextresult = enumerator.MoveNext();
			Assert.IsFalse(movenextresult);
		}
 public void GetNorm()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new double[4]{0,1,2,3});
   ComplexDoubleVector b = new ComplexDoubleVector(new double[4]{4,5,6,7});
   
   Assert.AreEqual(a.GetNorm(),System.Math.Sqrt(14));
   Assert.AreEqual(a.GetNorm(),a.GetNorm(2));
   Assert.AreEqual(a.GetNorm(0),3);
   
   Assert.AreEqual(b.GetNorm(),3*System.Math.Sqrt(14));
   Assert.AreEqual(b.GetNorm(),b.GetNorm(2));
   Assert.AreEqual(b.GetNorm(0),7);  
 }
    /// <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 ComplexDoubleVector Solve(IROComplexDoubleVector Y)
    {
      ComplexDoubleVector 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
      Complex Inner;      // inner product
      Complex G;        // scaling constant
      Complex[] A;        // reference to current order coefficients

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

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

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

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

      }

      return X;
    }
    /// <summary>
    /// 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 ComplexDoubleVector YuleWalker(IROComplexDoubleVector R)
    {

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

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

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

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

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

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

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

          a[i] = g;

        }
      }

      return a;
    }
 public void GetDotProduct()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new double[4]{0,1,2,3});
   ComplexDoubleVector b = new ComplexDoubleVector(new double[4]{4,5,6,7});
   
   Assert.AreEqual(a.GetDotProduct(),(Complex)14);
   Assert.AreEqual(b.GetDotProduct(),(Complex)126);
   Assert.AreEqual(a.GetDotProduct(b),(Complex)38);
   Assert.AreEqual(a.GetDotProduct(b),b.GetDotProduct(a));
   
 }
 public void ICollection()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new Complex[4]{0,1,2,3});
   Complex[] b = new Complex[5];
   
   Assert.AreEqual(a.Count,a.Length);
   
   a.CopyTo(b,1);
   Assert.AreEqual(b[0],(Complex)0);
   Assert.AreEqual(b[1],(Complex)0); 
   Assert.AreEqual(b[2],(Complex)1);
   Assert.AreEqual(b[3],(Complex)2);
   Assert.AreEqual(b[4],(Complex)3); 
 }
 public void CtorDimensionsNegative() 
 {
   ComplexDoubleVector test = new ComplexDoubleVector(-1);
 }
 public void Clone()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new double[4]{0,1,2,3});
   ComplexDoubleVector b = a.Clone();
   
   Assert.AreEqual(a[0],b[0]);
   Assert.AreEqual(a[1],b[1]);
   Assert.AreEqual(a[2],b[2]);
   Assert.AreEqual(a[3],b[3]);
   
   a=a*2;
   
   Assert.AreEqual(a[0],b[0]*2);
   Assert.AreEqual(a[1],b[1]*2);
   Assert.AreEqual(a[2],b[2]*2);
   Assert.AreEqual(a[3],b[3]*2);
 }
 public void Divide()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new double[4]{0,1,2,3});
   ComplexDoubleVector c = new ComplexDoubleVector(a);
   ComplexDoubleVector d = new ComplexDoubleVector(a);
   double scal = -4;
     
   c = a/scal;
   d = ComplexDoubleVector.Divide(a,scal);
     
   Assert.AreEqual(c[0],a[0]/scal);
   Assert.AreEqual(c[1],a[1]/scal);
   Assert.AreEqual(c[2],a[2]/scal);
   Assert.AreEqual(c[3],a[3]/scal);  
   
   Assert.AreEqual(d[0],a[0]/scal);
   Assert.AreEqual(d[1],a[1]/scal);
   Assert.AreEqual(d[2],a[2]/scal);
   Assert.AreEqual(d[3],a[3]/scal);
 }
 public void GetSum()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new double[4]{0,1,2,3});
   ComplexDoubleVector b = new ComplexDoubleVector(new double[4]{4,5,6,7});
   
   Assert.AreEqual(a.GetSum(),(Complex)6);
   Assert.AreEqual(a.GetSumMagnitudes(),6);
   
   Assert.AreEqual(b.GetSum(),(Complex)22);
   Assert.AreEqual(b.GetSumMagnitudes(),22);
 }
 public void GetEnumeratorException()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new Complex[4]{0,1,2,3});
   IEnumerator dve = a.GetEnumerator();
   
   Complex b = (Complex)dve.Current;
 }
 public void Axpy()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new double[4]{0,1,2,3});
   Double scal = 3;
   ComplexDoubleVector b = new ComplexDoubleVector(4);
   
   b.Axpy(scal,a);
   a.Scale(scal);
   
   Assert.AreEqual(a[0],b[0]);
   Assert.AreEqual(a[1],b[1]);
   Assert.AreEqual(a[2],b[2]);
   Assert.AreEqual(a[3],b[3]);
 }
 public void GetEnumerator()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new Complex[4]{0,1,2,3});
   IEnumerator dve = a.GetEnumerator();
   Complex b;
   bool c;
   
   c = dve.MoveNext();
   b = (Complex)dve.Current;
   Assert.AreEqual(c,true);
   Assert.AreEqual(b,(Complex)0);
   
   c = dve.MoveNext();
   b = (Complex)dve.Current;
   Assert.AreEqual(c,true);
   Assert.AreEqual(b,(Complex)1);
   
   c = dve.MoveNext();
   b = (Complex)dve.Current;
   Assert.AreEqual(c,true);
   Assert.AreEqual(b,(Complex)2);
   
   c = dve.MoveNext();
   b = (Complex)dve.Current;
   Assert.AreEqual(c,true);
   Assert.AreEqual(b,(Complex)3);
   
   c = dve.MoveNext();
   Assert.AreEqual(c,false);
 }
 public void Negate()
 {
   double[] vec = new double[4]{0,1,2,3};
   ComplexDoubleVector a = new ComplexDoubleVector(vec);
   ComplexDoubleVector b = -a;
   
   a = ComplexDoubleVector.Negate(a);
   
   Assert.AreEqual(-(Complex)vec[0],a[0]);
   Assert.AreEqual(-(Complex)vec[1],a[1]);
   Assert.AreEqual(-(Complex)vec[2],a[2]);
   Assert.AreEqual(-(Complex)vec[3],a[3]);
   
   Assert.AreEqual(-(Complex)vec[0],b[0]);
   Assert.AreEqual(-(Complex)vec[1],b[1]);
   Assert.AreEqual(-(Complex)vec[2],b[2]);
   Assert.AreEqual(-(Complex)vec[3],b[3]);
 }
 public void IList()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new Complex[4]{0,1,2,3});
   
   Assert.AreEqual(a.IsFixedSize,false);
   Assert.AreEqual(a.IsReadOnly,false);
   
   a.Add((Complex)4.0);
   Assert.AreEqual(a.Length,5);
   Assert.AreEqual(a[4],(Complex)4);
   Assert.AreEqual(a.Contains((Complex)4.0),true);
   
   a.Insert(1,(Complex)5.0);
   Assert.AreEqual(a.Length,6);
   Assert.AreEqual(a.Contains((Complex)5.0),true);
   Assert.AreEqual(a[0],(Complex)0);
   Assert.AreEqual(a[1],(Complex)5);
   Assert.AreEqual(a[2],(Complex)1);
   Assert.AreEqual(a[3],(Complex)2);
   Assert.AreEqual(a[4],(Complex)3);
   Assert.AreEqual(a[5],(Complex)4);
   
   a.Remove((Complex)5.0);
   Assert.AreEqual(a.Length,5);
   Assert.AreEqual(a.Contains((Complex)5.0),false);
   Assert.AreEqual(a[0],(Complex)0);
   Assert.AreEqual(a[1],(Complex)1);
   Assert.AreEqual(a[2],(Complex)2);
   Assert.AreEqual(a[3],(Complex)3);
   Assert.AreEqual(a[4],(Complex)4);
   
   a.RemoveAt(2);
   Assert.AreEqual(a.Length,4);
   Assert.AreEqual(a.Contains((Complex)2.0),false);
   Assert.AreEqual(a[0],(Complex)0);
   Assert.AreEqual(a[1],(Complex)1);
   Assert.AreEqual(a[2],(Complex)3);
   Assert.AreEqual(a[3],(Complex)4);
 }
 public void Subtract()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new double[4]{0,1,2,3});
   ComplexDoubleVector b = new ComplexDoubleVector(new double[4]{4,5,6,7});
   ComplexDoubleVector c = new ComplexDoubleVector(a.Length);
   ComplexDoubleVector d = new ComplexDoubleVector(b.Length);
   
   c = a-b;
   d = ComplexDoubleVector.Subtract(a,b);
   
   Assert.AreEqual(c[0],a[0]-b[0]);
   Assert.AreEqual(c[1],a[1]-b[1]);
   Assert.AreEqual(c[2],a[2]-b[2]);
   Assert.AreEqual(c[3],a[3]-b[3]);
   
   Assert.AreEqual(d[0],c[0]);
   Assert.AreEqual(d[1],c[1]);
   Assert.AreEqual(d[2],c[2]);
   Assert.AreEqual(d[3],c[3]);
   
   a.Subtract(b);
   
   Assert.AreEqual(c[0],a[0]);
   Assert.AreEqual(c[1],a[1]);
   Assert.AreEqual(c[2],a[2]);
   Assert.AreEqual(c[3],a[3]);
 }
 public void CtorCopy()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new double[2]{0,1});
   ComplexDoubleVector b = new ComplexDoubleVector(a);
   
   Assert.AreEqual(b.Length,a.Length);
   Assert.AreEqual(b[0],a[0]);
   Assert.AreEqual(b[1],a[1]);
 }
 public void Add()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new double[4]{0,1,2,3});
   ComplexDoubleVector b = new ComplexDoubleVector(new double[4]{4,5,6,7});
   ComplexDoubleVector c = new ComplexDoubleVector(a.Length);
   ComplexDoubleVector d = new ComplexDoubleVector(b.Length);
   
   c = a+b;
   d = ComplexDoubleVector.Add(a,b);
   
   Assert.AreEqual(c[0],a[0]+b[0]);
   Assert.AreEqual(c[1],a[1]+b[1]);
   Assert.AreEqual(c[2],a[2]+b[2]);
   Assert.AreEqual(c[3],a[3]+b[3]);
   
   Assert.AreEqual(d[0],c[0]);
   Assert.AreEqual(d[1],c[1]);
   Assert.AreEqual(d[2],c[2]);
   Assert.AreEqual(d[3],c[3]);
   
   a.Add(b);
   
   Assert.AreEqual(c[0],a[0]);
   Assert.AreEqual(c[1],a[1]);
   Assert.AreEqual(c[2],a[2]);
   Assert.AreEqual(c[3],a[3]);
 }
    /// <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;
    }
 public void CtorDimensionsZero() 
 {
   ComplexDoubleVector test = new ComplexDoubleVector(0);
 }
    /// <overloads>
    /// There are two permuations of the constructor, both require a parameter corresponding
    /// to the left-most column of a Toeplitz matrix.
    /// </overloads>
    /// <summary>
    /// Constructor with <c>ComplexDoubleVector</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 ComplexDoubleSymmetricLevinson(IROComplexDoubleVector 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 ComplexDoubleVector(T);
      m_Order = m_LeftColumn.Length;

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

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

    }
 public void ScalarMultiplyAndDivide()
 {
   ComplexDoubleVector a = new ComplexDoubleVector(new double[4]{0,1,2,3});
   ComplexDoubleVector c = new ComplexDoubleVector(a);
   ComplexDoubleVector d = new ComplexDoubleVector(a);
   double scal = -4;
     
   c.Multiply(scal);
   d.Divide(scal);
     
   Assert.AreEqual(c[0],a[0]*scal);
   Assert.AreEqual(c[1],a[1]*scal);
   Assert.AreEqual(c[2],a[2]*scal);
   Assert.AreEqual(c[3],a[3]*scal);  
   
   Assert.AreEqual(d[0],a[0]/scal);
   Assert.AreEqual(d[1],a[1]/scal);
   Assert.AreEqual(d[2],a[2]/scal);
   Assert.AreEqual(d[3],a[3]/scal);
   
   c = a*scal;
   
   Assert.AreEqual(c[0],a[0]*scal);
   Assert.AreEqual(c[1],a[1]*scal);
   Assert.AreEqual(c[2],a[2]*scal);
   Assert.AreEqual(c[3],a[3]*scal);  
   
   c = scal*a;
   
   Assert.AreEqual(c[0],a[0]*scal);
   Assert.AreEqual(c[1],a[1]*scal);
   Assert.AreEqual(c[2],a[2]*scal);
   Assert.AreEqual(c[3],a[3]*scal);
 }
    /// <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 ComplexDoubleVector Solve(IROComplexDoubleVector T, IROComplexDoubleVector Y)
    {

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

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

        if (N > 1)
        {
          ComplexDoubleVector a = new ComplexDoubleVector(N - 1);   // prediction coefficients
          ComplexDoubleVector Z = new ComplexDoubleVector(N - 1);   // temporary storage vector
          Complex g;                                   // reflection coefficient
          Complex inner;                               // inner product
          Complex 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 *= (Complex.One - g * g);
            if (e == Complex.Zero)
            {
              throw new SingularMatrixException("The Toeplitz matrix or one of the the leading sub-matrices is singular.");
            }

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

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

          }

        }

      }

      return X;

    }
 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]);
 }