public static double rhoDinvA(MsrMatrix A, out MsrMatrix DinvA) { double rho; // extract diagonal matrix double[] Diag = A.GetDiagVector(); int n = Diag.Length; // % form (D^-1) A //Diag = spdiags(1./Diag, 0, n, n); //DinvA = Diag*A; DinvA = new MsrMatrix(A.RowPartitioning, A.ColPartition); int i0 = A.RowPartitioning.i0; int Lr; int[] ColumnIdx = null; double[] Values = null; for (int i = 0; i < n; i++) { Lr = A.GetRow(i + i0, ref ColumnIdx, ref Values); for (int k = 0; k < Lr; k++) { Values[k] *= 1.0 / Diag[i]; } DinvA.SetRow(i + i0, ColumnIdx, Values, Lr); } #if DEBUG for (int i = 0; i < n; i++) { Debug.Assert(Math.Abs(1.0 - DinvA[i + i0, i + i0]) < BLAS.MachineEps * 10); } #endif // estimate the largest eigen value from Arnoldi iteration int kk = 20; var rand = new Random(0); double[] v0 = n.ForLoop(i => rand.NextDouble()); double[][] V; double[,] H; int kact; arnoldi(out V, out H, out kact, DinvA, v0, kk, false); kk = Math.Min(H.GetLength(0), H.GetLength(1)); H = H.GetSubMatrix(0, kk, 0, kk); rho = MaxAbsEigen(H); return(rho); }
/// <summary> /// converts an arbitrary mutable matrix to an <see cref="MsrMatrix"/>. /// </summary> /// <param name="M"></param> /// <returns></returns> static public MsrMatrix ToMsrMatrix(this IMutableMatrixEx M) { using (new FuncTrace()) { MsrMatrix R = new MsrMatrix(M.RowPartitioning, M.ColPartition); int[] col = null; double[] val = null; int i0 = (int)R.RowPartitioning.i0, L = R.RowPartitioning.LocalLength; for (int i = 0; i < L; i++) { int iRow = i0 + i; int Lr = M.GetRow(iRow, ref col, ref val); R.SetRow(iRow, col, val, Lr); } return(R); } }