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