public void SetRowArrayWrongRank() { DoubleMatrix a = new DoubleMatrix(2,2); double[] b = {1,2,3}; a.SetRow(1,b); }
public void SetRowArray() { DoubleMatrix a = new DoubleMatrix(2,2); double[] b = {1,2}; a.SetRow(0,b); Assert.AreEqual(b[0], a[0,0]); Assert.AreEqual(b[1], a[0,1]); }
public void SetRowArrayOutOfRange() { DoubleMatrix a = new DoubleMatrix(2,2); double[] b = {1,2}; a.SetRow(2,b); }
public void SetRowWrongRank() { DoubleMatrix a = new DoubleMatrix(2,2); DoubleVector b = new DoubleVector(3); a.SetRow(1,b); }
public void SetRowOutOfRange() { DoubleMatrix a = new DoubleMatrix(2,2); DoubleVector b = new DoubleVector(2); a.SetRow(2,b); }
public void SetRow() { DoubleMatrix a = new DoubleMatrix(2,2); DoubleVector b = new DoubleVector(2); b[0] = 1; b[1] = 2; a.SetRow(0,b); Assert.AreEqual(b[0], a[0,0]); Assert.AreEqual(b[1], a[0,1]); }
/// <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; }
/// <summary> /// Get a copy of the Toeplitz matrix. /// </summary> public DoubleMatrix GetMatrix() { int i, j; // allocate memory for the matrix DoubleMatrix tm = new DoubleMatrix(m_Order); #if MANAGED // fill top row double[] top = tm.data[0]; Array.Copy(m_LeftColumn.data, 0, top, 0, m_Order); if (m_Order > 1) { // fill bottom row (reverse order) double[] bottom = tm.data[m_Order - 1]; for (i = 0, j = m_Order - 1; i < m_Order; i++, j--) { bottom[i] = m_LeftColumn[j]; } // fill rows in-between for (i = 1, j = m_Order - 1 ; j > 1; i++) { Array.Copy(top, 0, tm.data[i], i, j--); Array.Copy(bottom, j, tm.data[i], 0, i); } } #else if (m_Order > 1) { double[] top = new double[m_Order]; Array.Copy(m_LeftColumn.data, 0, top, 0, m_Order); tm.SetRow(0, top); // fill bottom row (reverse order) double[] bottom = new double[m_Order]; for (i = 0, j = m_Order - 1; i < m_Order; i++, j--) { bottom[i] = m_LeftColumn[j]; } // fill rows in-between for (i = 1, j = m_Order - 1 ; j > 0; i++) { double[] temp = new double[m_Order]; Array.Copy(top, 0, temp, i, j--); Array.Copy(bottom, j, temp, 0, i); tm.SetRow(i, temp); } } else { Array.Copy(m_LeftColumn.data, 0, tm.data, 0, m_Order); } #endif return tm; }