public void SetColumnArrayWrongRank() { DoubleMatrix a = new DoubleMatrix(2,2); double[] b = {1,2,3}; a.SetColumn(1,b); }
public void SetColumnArray() { DoubleMatrix a = new DoubleMatrix(2,2); double[] b = {1,2}; a.SetColumn(0,b); Assert.AreEqual(b[0], a[0,0]); Assert.AreEqual(b[1], a[1,0]); }
public void SetColumnArrayOutOfRange() { DoubleMatrix a = new DoubleMatrix(2,2); double[] b = {1,2}; a.SetColumn(2,b); }
public void SetColumnWrongRank() { DoubleMatrix a = new DoubleMatrix(2,2); DoubleVector b = new DoubleVector(3); a.SetColumn(1,b); }
public void SetColumnOutOfRange() { DoubleMatrix a = new DoubleMatrix(2,2); DoubleVector b = new DoubleVector(2); a.SetColumn(2,b); }
public void SetColumn() { DoubleMatrix a = new DoubleMatrix(2,2); DoubleVector b = new DoubleVector(2); b[0] = 1; b[1] = 2; a.SetColumn(0,b); Assert.AreEqual(b[0], a[0,0]); Assert.AreEqual(b[1], a[1,0]); }
/// <summary> /// Solve a square Toeplitz system with a right-side matrix. /// </summary> /// <param name="Y">The right-side matrix</param> /// <returns>The solution matrix.</returns> /// <exception cref="ArgumentNullException"> /// Parameter <B>Y</B> is a null reference. /// </exception> /// <exception cref="RankException"> /// The number of rows in <B>Y</B> is not equal to the number of rows in the Toeplitz matrix. /// </exception> /// <exception cref="SingularMatrixException"> /// The Toeplitz matrix or one of the the leading sub-matrices is singular. /// </exception> /// <remarks> /// This member solves the linear system <B>TX</B> = <B>Y</B>, where <B>T</B> is /// a square Toeplitz matrix, <B>X</B> is the unknown solution matrix /// and <B>Y</B> is a known matrix. /// <para> /// The class implicitly decomposes the inverse Toeplitz matrix into a <b>UDL</b> factorisation /// using the Levinson algorithm, before calculating the solution vector. /// </para> /// </remarks> public DoubleMatrix Solve(IROMatrix Y) { DoubleMatrix X; double Inner; double[] 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 DoubleMatrix(m_Order, Y.Rows); x = new double[m_Order]; for (l = 0; l < Y.Rows; l++) { // get right-side column y = DoubleVector.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> /// Solve a square Toeplitz system with a right-side matrix. /// </summary> /// <param name="col">The left-most column of the Toeplitz matrix.</param> /// <param name="row">The top-most row of the Toeplitz matrix.</param> /// <param name="Y">The right-side matrix of the system.</param> /// <returns>The solution matrix.</returns> /// <exception cref="ArgumentNullException"> /// <EM>col</EM> is a null reference, /// <para>or</para> /// <para><EM>row</EM> is a null reference,</para> /// <para>or</para> /// <para><EM>Y</EM> is a null reference.</para> /// </exception> /// <exception cref="RankException"> /// The length of <EM>col</EM> is 0, /// <para>or</para> /// <para>the lengths of <EM>col</EM> and <EM>row</EM> are not equal,</para> /// <para>or</para> /// <para>the number of rows in <EM>Y</EM> does not the length of <EM>col</EM> and <EM>row</EM>.</para> /// </exception> /// <exception cref="SingularMatrixException"> /// The Toeplitz matrix or one of the the leading sub-matrices is singular. /// </exception> /// <exception cref="ArithmeticException"> /// The values of the first element of <EM>col</EM> and <EM>row</EM> are not equal. /// </exception> /// <remarks> /// This method solves the linear system <B>AX</B> = <B>Y</B>. Where /// <B>T</B> is a square Toeplitz matrix, <B>X</B> is an unknown /// matrix and <B>Y</B> is a known matrix. /// <para> /// The classic Levinson algorithm is used to solve the system. The algorithm /// assumes that all the leading sub-matrices of the Toeplitz matrix are /// non-singular. When a sub-matrix is near singular, accuracy will /// be degraded. This member requires approximately <B>N</B> squared /// FLOPS to calculate a solution, where <B>N</B> is the matrix order. /// </para> /// <para> /// This static method has minimal storage requirements as it combines /// the <b>UDL</b> decomposition with the calculation of the solution vector /// in a single algorithm. /// </para> /// </remarks> public static DoubleMatrix Solve(IROVector col, IROVector row, IROMatrix Y) { // check parameters if (col == null) { throw new System.ArgumentNullException("col"); } else if (col.Length == 0) { throw new RankException("The length of col is zero."); } else if (row == null) { throw new System.ArgumentNullException("row"); } else if (col.Length != row.Length) { throw new RankException("The lengths of col and row are not equal."); } else if (col[0] != row[0]) { throw new ArithmeticException("The values of the first element of col and row are not equal."); } else if (Y == null) { throw new System.ArgumentNullException("Y"); } else if (col.Length != Y.Columns) { throw new RankException("The numer of rows in Y does not match the length of col and row."); } // check if leading diagonal is zero if (col[0] == 0.0) { throw new SingularMatrixException("One of the leading sub-matrices is singular."); } // decompose matrix int order = col.Length; double[] A = new double[order]; double[] B = new double[order]; double[] Z = new double[order]; DoubleMatrix X = new DoubleMatrix(order); double Q, S, Ke, Kr, e; double Inner; int i, j, l; // setup the zero order solution A[0] = 1.0; B[0] = 1.0; e = 1.0 / col[0]; X.SetRow(0, e * DoubleVector.GetRow(Y,0)); for (i = 1; i < order; i++) { // calculate inner products Q = 0.0; for ( j = 0, l = 1; j < i; j++, l++) { Q += col[l] * A[j]; } S = 0.0; for ( j = 0, l = 1; j < i; j++, l++) { S += row[l] * B[j]; } // reflection coefficients Kr = -S * e; Ke = -Q * e; // update lower triangle (in temporary storage) Z[0] = 0.0; Array.Copy(A, 0, Z, 1, i); for (j = 0, l = i - 1; j < i; j++, l--) { Z[j] += Ke * B[l]; } // update upper triangle for (j = i; j > 0; j--) { B[j] = B[j-1]; } B[0] = 0.0; for (j = 0, l = i - 1; j < i; j++, l--) { B[j] += Kr * A[l]; } // copy from temporary storage to lower triangle Array.Copy(Z, 0, A, 0, i + 1); // check for singular sub-matrix) if (Ke * Kr == 1.0) { throw new SingularMatrixException("One of the leading sub-matrices is singular."); } // update diagonal e = e / (1.0 - Ke * Kr); for (l = 0; l < Y.Rows; l++) { DoubleVector W = X.GetColumn(l); DoubleVector M = DoubleVector.GetColumn(Y,l); Inner = M[i]; for (j = 0; j < i; j++) { Inner += A[j] * M[j]; } Inner *= e; W[i] = Inner; for (j = 0; j < i; j++) { W[j] += Inner * B[j]; } X.SetColumn(l, W); } } return X; }