/// <summary> /// returns the maximum and minimum eigenvalues of the matrix /// </summary> /// <returns>Array myeigs =[MaximumEig, MinimumEig]</returns> public double[] Eigenval() { double[] eigenvalues = new double[2]; MultidimensionalArray eigs = MultidimensionalArray.Create(1, 2); MultidimensionalArray output = MultidimensionalArray.Create(2, 1); int[] DepVars = this.VarGroup; double[] DepVars_subvec = this.m_map.GetSubvectorIndices(true, DepVars).Select(i => i + 1.0).ToArray(); using (BatchmodeConnector bmc = new BatchmodeConnector()){ // if Octave should be used instead of Matlab.... //BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave; bmc.PutSparseMatrix(m_OpMtx, "FullMatrix"); bmc.PutVector(DepVars_subvec, "DepVars_subvec"); bmc.Cmd("output = zeros(2,1)"); bmc.Cmd("output(1) = eigs(FullMatrix(DepVars_subvec,DepVars_subvec),1,'lm');"); bmc.Cmd("output(2) = eigs(FullMatrix(DepVars_subvec,DepVars_subvec),1,'sm');"); bmc.GetMatrix(output, "output"); bmc.Execute(false); } double[] myeigs = new double[] { output[0, 0], output[1, 0] }; Debug.Assert(output[0, 0].MPIEquals(), "value does not match on procs"); Debug.Assert(output[1, 0].MPIEquals(), "value does not match on procs"); return(myeigs); }
public static void GetExternalRowsTest( [Values(XDGusage.none, XDGusage.all)] XDGusage UseXdg, [Values(2)] int DGOrder, [Values(4)] int Res) { //Matlabaufruf --> gesamte Matrix nach Matlab schreiben //Teilmatritzen gemäß Globalid extrahieren //Mit ExternalRows vergleichen //Die große Frage: funktioniert der batchmode connector parallel? Beim rausschreiben beachten Utils.TestInit((int)UseXdg, DGOrder); Console.WriteLine("GetExternalRowsTest({0},{1})", UseXdg, DGOrder); //Arrange --- setup mgo and mask MultigridOperator mgo = Utils.CreateTestMGOperator(UseXdg, DGOrder, MatrixShape.laplace, Res); MultigridMapping map = mgo.Mapping; BlockMsrMatrix M = mgo.OperatorMatrix; //Delete this plz ... //M.SaveToTextFileSparse("M"); //int[] A = Utils.GimmeAllBlocksWithSpec(map, 9); //int[] B = Utils.GimmeAllBlocksWithSpec(map, 18); //if (map.MpiRank == 0) { // A.SaveToTextFileDebug("ACells"); // B.SaveToTextFileDebug("BCells"); //} var selector = new SubBlockSelector(map); var dummy = new BlockMsrMatrix(map); // we are only interested in getting indices, so a dummy is sufficient var mask = new BlockMask(selector, dummy); //Arrange --- get stuff to put into matlab int[] GlobalIdx_ext = Utils.GetAllExtCellIdc(map); double[] GlobIdx = GlobalIdx_ext.Length.ForLoop(i => (double)GlobalIdx_ext[i] + 1.0); //Arrange --- get external rows by mask BlockMsrMatrix extrows = BlockMask.GetAllExternalRows(mgo.Mapping, mgo.OperatorMatrix); //Assert --- idc and rows of extrows have to be the same Assert.IsTrue(GlobIdx.Length == extrows._RowPartitioning.LocalLength); //Arrange --- get external rows by matlab var infNorm = MultidimensionalArray.Create(1, 1); using (BatchmodeConnector matlab = new BatchmodeConnector()) { //note: BatchmodeCon maybe working on proc0 but savetotxt file, etc. (I/O) is full mpi parallel //so concider this as full mpi-parallel matlab.PutSparseMatrix(M, "M"); matlab.PutSparseMatrix(extrows, "M_test"); matlab.PutVector(GlobIdx, "Idx"); matlab.Cmd(String.Format("M_ext = M(Idx, :);")); matlab.Cmd("n=norm(M_test-M_ext,inf)"); matlab.GetMatrix(infNorm, "n"); matlab.Execute(); } //Assert --- test if we actually got the right Matrix corresponding to Index Assert.IsTrue(infNorm[0, 0] == 0.0); }
/// <summary> /// returns the condition number of the full matrix /// </summary> public double CondNumMatlab() { int[] DepVars = this.VarGroup; var grd = m_map.GridDat; int NoOfCells = grd.Grid.NumberOfCells; int NoOfBdryCells = grd.GetBoundaryCells().NoOfItemsLocally_WithExternal; var Mtx = m_MultigridOp.OperatorMatrix; // Blocks and selectors // ==================== var InnerCellsMask = grd.GetBoundaryCells().Complement(); var FullSel = new SubBlockSelector(m_MultigridOp.Mapping); FullSel.VariableSelector(this.VarGroup); // Matlab // ====== double[] Full_0Vars = (new BlockMask(FullSel)).GlobalIndices.Select(i => i + 1.0).ToArray(); MultidimensionalArray output = MultidimensionalArray.Create(2, 1); string[] names = new string[] { "Full_0Vars", "Inner_0Vars" }; using (BatchmodeConnector bmc = new BatchmodeConnector()) { // if Octave should be used instead of Matlab.... // BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave; bmc.PutSparseMatrix(Mtx, "FullMatrix"); bmc.PutVector(Full_0Vars, "Full_0Vars"); bmc.Cmd("output = ones(2,1);"); bmc.Cmd("output(1) = condest(FullMatrix(Full_0Vars,Full_0Vars));"); bmc.GetMatrix(output, "output"); bmc.Execute(false); double condestFull = output[0, 0]; Debug.Assert(condestFull.MPIEquals(), "value does not match on procs"); Console.WriteLine($"MATLAB condition number: {condestFull:0.###e-00}"); return(condestFull); } }
public static void SpMVTest( [Values(XDGusage.none, XDGusage.mixed1, XDGusage.mixed2, XDGusage.all)] XDGusage UseXdg, [Values(1, 3)] int DGOrder, [Values(false, true)] bool compressL1, [Values(false, true)] bool compressL2) { unsafe { int[] Params = new int[8], ParamsGlob = new int[8]; fixed(int *pParams = Params, pParamsGlob = ParamsGlob) { pParams[0] = (int)UseXdg; pParams[1] = DGOrder; pParams[2] = compressL1 ? 1 : 0; pParams[3] = compressL2 ? 1 : 0; pParams[4] = -pParams[0]; pParams[5] = -pParams[1]; pParams[6] = -pParams[2]; pParams[7] = -pParams[3]; csMPI.Raw.Allreduce((IntPtr)pParams, (IntPtr)pParamsGlob, 8, csMPI.Raw._DATATYPE.INT, csMPI.Raw._OP.MIN, csMPI.Raw._COMM.WORLD); } int[] ParamsMin = ParamsGlob.GetSubVector(0, 4); int[] ParamsMax = ParamsGlob.GetSubVector(4, 4); for (int i = 0; i < 4; i++) { if (Params[i] != ParamsMin[i]) { throw new ApplicationException(); } if (Params[i] != -ParamsMax[i]) { throw new ApplicationException(); } } Console.WriteLine("SpMVTest({0},{1},{2},{3})", UseXdg, DGOrder, compressL1, compressL2); } using (var solver = new Matrix_MPItestMain() { m_UseXdg = UseXdg, m_DGorder = DGOrder }) { // create the test data // ==================== BoSSS.Solution.Application.CommandLineOptions opts = null; //opts = new BoSSS.Solution.Application.CommandLineOptions(); solver.Init(null, opts); solver.RunSolverMode(); Stopwatch stw = new Stopwatch(); stw.Reset(); BlockMsrMatrix M = solver.OperatorMatrix; double[] B = new double[M.RowPartitioning.LocalLength]; double[] X = new double[M.ColPartition.LocalLength]; Random R = new Random(); for (int i = 0; i < X.Length; i++) { X[i] = R.NextDouble(); } for (int i = 0; i < B.Length; i++) { B[i] = R.NextDouble(); } double[] Bb4 = B.CloneAs(); double RefNorm = B.L2NormPow2().MPISum().Sqrt() * 1e-10; stw.Start(); M.SpMV(1.6, X, 0.5, B); stw.Stop(); //M.SaveToTextFileSparse(@"C:\tmp\M.txt"); //M11.SaveToTextFileSparse(@"C:\tmp\M11.txt"); //M12.SaveToTextFileSparse(@"C:\tmp\M12.txt"); //M21.SaveToTextFileSparse(@"C:\tmp\M21.txt"); //M22.SaveToTextFileSparse(@"C:\tmp\M22.txt"); //M22xM21.SaveToTextFileSparse(@"C:\tmp\M22xM21.txt"); using (var MatlabRef = new BatchmodeConnector()) { MultidimensionalArray CheckRes = MultidimensionalArray.Create(1, 1); MatlabRef.PutSparseMatrix(M, "M"); MatlabRef.PutVector(Bb4, "Bref"); MatlabRef.PutVector(B, "B"); MatlabRef.PutVector(X, "X"); MatlabRef.Cmd("Bref = Bref*0.5 + M*X*1.6;"); MatlabRef.Cmd("errB = norm(B - Bref, 2);"); MatlabRef.Cmd("CheckRes = [errB];"); MatlabRef.GetMatrix(CheckRes, "CheckRes"); MatlabRef.Execute(); Console.WriteLine("Matlab check SpMV: " + CheckRes[0, 0]); Assert.LessOrEqual(CheckRes[0, 0], RefNorm, "Error in SpMV"); } Console.WriteLine("Time spend in matrix operations: " + stw.Elapsed.TotalSeconds + " sec."); TotTime_MatrixOp += stw.Elapsed; } }
public static void SubMatrixTest( [Values(XDGusage.none, XDGusage.mixed1, XDGusage.mixed2, XDGusage.all)] XDGusage UseXdg, [Values(1, 3)] int DGOrder, [Values(false, true)] bool compressL1, [Values(false, true)] bool compressL2) { unsafe { int[] Params = new int[8], ParamsGlob = new int[8]; fixed(int *pParams = Params, pParamsGlob = ParamsGlob) { pParams[0] = (int)UseXdg; pParams[1] = DGOrder; pParams[2] = compressL1 ? 1 : 0; pParams[3] = compressL2 ? 1 : 0; pParams[4] = -pParams[0]; pParams[5] = -pParams[1]; pParams[6] = -pParams[2]; pParams[7] = -pParams[3]; csMPI.Raw.Allreduce((IntPtr)pParams, (IntPtr)pParamsGlob, 8, csMPI.Raw._DATATYPE.INT, csMPI.Raw._OP.MIN, csMPI.Raw._COMM.WORLD); } int[] ParamsMin = ParamsGlob.GetSubVector(0, 4); int[] ParamsMax = ParamsGlob.GetSubVector(4, 4); for (int i = 0; i < 4; i++) { if (Params[i] != ParamsMin[i]) { throw new ApplicationException(); } if (Params[i] != -ParamsMax[i]) { throw new ApplicationException(); } } Console.WriteLine("SubMatrixTest({0},{1},{2},{3})", UseXdg, DGOrder, compressL1, compressL2); } using (var solver = new Matrix_MPItestMain() { m_UseXdg = UseXdg, m_DGorder = DGOrder }) { // create the test data // ==================== BoSSS.Solution.Application.CommandLineOptions opts = null; //opts = new BoSSS.Solution.Application.CommandLineOptions(); solver.Init(null, opts); solver.RunSolverMode(); Stopwatch stw = new Stopwatch(); stw.Reset(); stw.Start(); BlockMsrMatrix M = solver.OperatorMatrix; int[] Ilist1 = solver.ProblemMapping.GetSubvectorIndices(false, 0); int[] Ilist2 = solver.ProblemMapping.GetSubvectorIndices(false, 1); foreach (int i in Ilist1) { Assert.IsTrue(solver.ProblemMapping.IsInLocalRange(i)); } foreach (int i in Ilist2) { Assert.IsTrue(solver.ProblemMapping.IsInLocalRange(i)); } var Blk1 = solver.ProblemMapping.GetSubBlocking(Ilist1, csMPI.Raw._COMM.WORLD, compressL1 ? -1 : 0); var Blk2 = solver.ProblemMapping.GetSubBlocking(Ilist2, csMPI.Raw._COMM.WORLD, compressL2 ? -1 : 0); int[] Tlist1 = compressL1 ? default(int[]) : Blk1.GetOccupiedIndicesList(); int[] Tlist2 = compressL2 ? default(int[]) : Blk2.GetOccupiedIndicesList(); if (Tlist1 != null) { Assert.AreEqual(Tlist1.Length, Ilist1.Length); foreach (int i in Tlist1) { Assert.IsTrue(Blk1.IsInLocalRange(i)); } } if (Tlist2 != null) { Assert.AreEqual(Tlist2.Length, Ilist2.Length); foreach (int i in Tlist2) { Assert.IsTrue(Blk2.IsInLocalRange(i)); } } BlockMsrMatrix M11 = new BlockMsrMatrix(Blk1, Blk1); BlockMsrMatrix M12 = new BlockMsrMatrix(Blk1, Blk2); BlockMsrMatrix M21 = new BlockMsrMatrix(Blk2, Blk1); BlockMsrMatrix M22 = new BlockMsrMatrix(Blk2, Blk2); M.AccSubMatrixTo(1.0, M11, Ilist1, Tlist1, Ilist1, Tlist1); M.AccSubMatrixTo(1.0, M12, Ilist1, Tlist1, Ilist2, Tlist2); M.AccSubMatrixTo(1.0, M21, Ilist2, Tlist2, Ilist1, Tlist1); M.AccSubMatrixTo(1.0, M22, Ilist2, Tlist2, Ilist2, Tlist2); BlockMsrMatrix restored_M = new BlockMsrMatrix(M._RowPartitioning, M._ColPartitioning); int[] Idx1 = compressL1 ? Blk1.LocalLength.ForLoop(i => i + Blk1.i0) : Tlist1; int[] Idx2 = compressL2 ? Blk2.LocalLength.ForLoop(i => i + Blk2.i0) : Tlist2; M11.AccSubMatrixTo(1.0, restored_M, Idx1, Ilist1, Idx1, Ilist1); M12.AccSubMatrixTo(1.0, restored_M, Idx1, Ilist1, Idx2, Ilist2); M21.AccSubMatrixTo(1.0, restored_M, Idx2, Ilist2, Idx1, Ilist1); M22.AccSubMatrixTo(1.0, restored_M, Idx2, Ilist2, Idx2, Ilist2); // test transpose-operator var M_TT = M.Transpose().Transpose(); var M11_TT = M11.Transpose().Transpose(); var M12_TT = M12.Transpose().Transpose(); var M21_TT = M21.Transpose().Transpose(); var M22_TT = M22.Transpose().Transpose(); M_TT.Acc(-1.0, M); M11_TT.Acc(-1.0, M11); M12_TT.Acc(-1.0, M12); M21_TT.Acc(-1.0, M21); M22_TT.Acc(-1.0, M22); double M_TT_norm = M_TT.InfNorm(); double M11_TT_norm = M11_TT.InfNorm(); double M12_TT_norm = M12_TT.InfNorm(); double M21_TT_norm = M21_TT.InfNorm(); double M22_TT_norm = M22_TT.InfNorm(); Assert.IsTrue(M_TT_norm == 0.0, "Transpose^2 is not identity."); Assert.IsTrue(M11_TT_norm == 0.0, "Transpose^2 is not identity."); Assert.IsTrue(M12_TT_norm == 0.0, "Transpose^2 is not identity."); Assert.IsTrue(M21_TT_norm == 0.0, "Transpose^2 is not identity."); Assert.IsTrue(M22_TT_norm == 0.0, "Transpose^2 is not identity."); //M.SaveToTextFileSparse(@"C:\tmp\M.txt"); //M11.SaveToTextFileSparse(@"C:\tmp\M11.txt"); //M12.SaveToTextFileSparse(@"C:\tmp\M12.txt"); //M21.SaveToTextFileSparse(@"C:\tmp\M21.txt"); //M22.SaveToTextFileSparse(@"C:\tmp\M22.txt"); //restored_M.SaveToTextFileSparse(@"C:\tmp\Mr.txt"); stw.Stop(); using (var MatlabRef = new BatchmodeConnector()) { MatlabRef.PutVector(Ilist1.Select(i => (double)i + 1.0).ToArray(), "Ilist1"); MatlabRef.PutVector(Ilist2.Select(i => (double)i + 1.0).ToArray(), "Ilist2"); MatlabRef.PutVector(Tlist1 == null ? Ilist1.Length.ForLoop(i => (double)i + 1.0 + Blk1.i0) : Tlist1.Select(i => (double)i + 1.0).ToArray(), "Tlist1"); MatlabRef.PutVector(Tlist2 == null ? Ilist2.Length.ForLoop(i => (double)i + 1.0 + Blk2.i0) : Tlist2.Select(i => (double)i + 1.0).ToArray(), "Tlist2"); MultidimensionalArray CheckRes = MultidimensionalArray.Create(1, 4); MatlabRef.PutSparseMatrix(M, "M"); MatlabRef.PutSparseMatrix(M11, "M11"); MatlabRef.PutSparseMatrix(M12, "M12"); MatlabRef.PutSparseMatrix(M21, "M21"); MatlabRef.PutSparseMatrix(M22, "M22"); MatlabRef.Cmd("L1 = {0};", Blk1.TotalLength); MatlabRef.Cmd("L2 = {0};", Blk2.TotalLength); MatlabRef.Cmd("refM11 = sparse(L1, L1);"); MatlabRef.Cmd("refM12 = sparse(L1, L2);"); MatlabRef.Cmd("refM21 = sparse(L2, L1);"); MatlabRef.Cmd("refM22 = sparse(L2, L2);"); MatlabRef.Cmd("refM11(Tlist1, Tlist1) = M(Ilist1, Ilist1);"); MatlabRef.Cmd("refM12(Tlist1, Tlist2) = M(Ilist1, Ilist2);"); MatlabRef.Cmd("refM21(Tlist2, Tlist1) = M(Ilist2, Ilist1);"); MatlabRef.Cmd("refM22(Tlist2, Tlist2) = M(Ilist2, Ilist2);"); MatlabRef.Cmd("err11 = norm(refM11 - M11, inf);"); MatlabRef.Cmd("err12 = norm(refM12 - M12, inf);"); MatlabRef.Cmd("err21 = norm(refM21 - M21, inf);"); MatlabRef.Cmd("err22 = norm(refM22 - M22, inf);"); MatlabRef.Cmd("CheckRes = [err11, err12, err21, err22];"); MatlabRef.GetMatrix(CheckRes, "CheckRes"); MatlabRef.Execute(); Console.WriteLine("Matlab check 11: " + CheckRes[0, 0]); Console.WriteLine("Matlab check 12: " + CheckRes[0, 1]); Console.WriteLine("Matlab check 21: " + CheckRes[0, 2]); Console.WriteLine("Matlab check 22: " + CheckRes[0, 3]); Assert.IsTrue(CheckRes[0, 0] == 0.0); Assert.IsTrue(CheckRes[0, 1] == 0.0); Assert.IsTrue(CheckRes[0, 2] == 0.0); Assert.IsTrue(CheckRes[0, 3] == 0.0); } stw.Start(); restored_M.Acc(-1.0, M); double err = restored_M.InfNorm(); Console.WriteLine("Submatrix operations error: " + err); Assert.IsTrue(err == 0.0); restored_M.Clear(); restored_M.Acc(1.0, M); IMutuableMatrixEx_Extensions.Acc(restored_M, -1.0, M); double err2 = restored_M.InfNorm(); Console.WriteLine("Submatrix operations error: " + err2); Assert.IsTrue(err2 == 0.0); stw.Stop(); Console.WriteLine("Time spend in matrix operations: " + stw.Elapsed.TotalSeconds + " sec."); TotTime_MatrixOp += stw.Elapsed; } }
/// <summary> /// According to the Rouché-Capelli theorem, the system is inconsistent if rank(augMatrix) > rank(Matrix). /// If rank(augMatrix) == rank(Matrix), the system has at least one solution. /// Additionally, if the rank is equal to the number of variables, the solution of the system is unique. /// Remark: This requires the whole RHS not only local!!! /// </summary> /// <param name="OpMatrix"></param> /// <param name="RHS"></param> public void rankAnalysis(BlockMsrMatrix OpMatrix, double[] RHS) { int RHSlen = this.localRHS.Length; Debug.Assert(RHSlen == m_OpMtx.RowPartitioning.LocalLength); MultidimensionalArray outputArray = MultidimensionalArray.Create(2, 1); // The two rank values //At this point OpMatrix and RHS are local, they are collected within bmc on proc rank==0 using (var bmc = new BatchmodeConnector()){ bmc.PutSparseMatrix(OpMatrix, "OpMatrix"); bmc.PutVector(RHS, "RHS"); bmc.Cmd("output = zeros(2,1)"); // First value is rank(OpMatrix), second the rank of the augmented matrix = rank([Matrix|RHS]) bmc.Cmd(""); bmc.Cmd("fullMtx = full(OpMatrix);"); bmc.Cmd("augmentedMtx = [fullMtx RHS];"); bmc.Cmd("output(1) = rank(fullMtx)"); bmc.Cmd("output(2) = rank(augmentedMtx)"); bmc.GetMatrix(outputArray, "output"); bmc.Execute(false); } double[] output = new double[2]; output[0] = outputArray[0, 0]; //Rank matrix output[1] = outputArray[1, 0]; //Rank augmented matrix ( [Matrix|RHS]) double rnkMtx = output[0]; double rnkAugmentedMtx = output[1]; // Some tests Console.WriteLine("=================================================================="); //Output { Console.WriteLine("Results of rank analysis:"); if (rnkAugmentedMtx > rnkMtx) { //throw new Exception("The rank of the augmented matrix shouldn't be greater than the one of the original matrix!!"); Console.WriteLine("======================================================"); Console.WriteLine("WARNING!!!!!!! The rank of the augmented matrix shouldn't be greater than the one of the original matrix!!"); Console.WriteLine("This means that the system doesnt have a solution!"); } if (rnkAugmentedMtx == rnkMtx) { Console.WriteLine("The system has at least a solution"); } //RHS and OpMatrix will be collected in Bmc, so total length has to be considered for RHS: RHS.length will lead to errors in parallel execution if (rnkMtx < RHSlen) { Console.WriteLine("The rank of the matrix is smaller than the number of variables. There are {0} free parameters", (RHS.Length - rnkMtx)); } else if (rnkMtx == RHSlen) { Console.WriteLine("The system has a unique solution :) "); } else { throw new Exception("what? should not happen"); } Console.WriteLine("Rank of the matrix : {0} \n" + "Rank of the augmented matrix : {1} \n" + "Number of variables: {2}", output[0], output[1], RHS.Length); Console.WriteLine("=================================================================="); } Debug.Assert(output[0].MPIEquals(), "value does not match on procs"); Debug.Assert(output[1].MPIEquals(), "value does not match on procs"); }
/// <summary> /// returns the condition number of the full matrix and the inner matrix without boundary terms /// </summary> /// <returns>Array condestOut=[ConditionNumberFullOp, ConditionNumberInnerOp]</returns> public double[] CondNum() { int[] DepVars = this.VarGroup; var grd = m_map.GridDat; int NoOfCells = grd.Grid.NumberOfCells; int NoOfBdryCells = grd.GetBoundaryCells().NoOfItemsLocally_WithExternal; // only for full matrix, if there are no inner cells if (NoOfCells == NoOfBdryCells) { Console.WriteLine(""); Console.WriteLine("Since there are only boundary cells, the condest of the non-existing inner matrix is set to zero!"); double[] Full_0Vars = this.m_map.GetSubvectorIndices(true, DepVars).Select(i => i + 1.0).ToArray(); MultidimensionalArray output = MultidimensionalArray.Create(1, 1); using (BatchmodeConnector bmc = new BatchmodeConnector()){ // if Octave should be used instead of Matlab.... //BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave; bmc.PutSparseMatrix(m_OpMtx, "FullMatrix"); bmc.PutVector(Full_0Vars, "Full_0Vars"); bmc.Cmd("output = zeros(1,1)"); bmc.Cmd("output = condest(FullMatrix(Full_0Vars,Full_0Vars));"); bmc.GetMatrix(output, "output"); bmc.Execute(false); } double condestFull = output[0, 0]; double condestInner = 0; double[] condestOut = new double[] { condestFull, condestInner }; return(condestOut); } // for full and inner matrix else { CellMask InnerCellsMask = grd.GetBoundaryCells().Complement(); SubGrid InnerCells = new SubGrid(InnerCellsMask); double[] Full_0Vars = this.m_map.GetSubvectorIndices(true, DepVars).Select(i => i + 1.0).ToArray(); double[] Inner_0Vars = this.m_map.GetSubvectorIndices(InnerCells, true, DepVars).Select(i => i + 1.0).ToArray(); MultidimensionalArray output = MultidimensionalArray.Create(2, 1); string[] names = new string[] { "Full_0Vars", "Inner_0Vars" }; using (BatchmodeConnector bmc = new BatchmodeConnector()){ // if Octave should be used instead of Matlab.... // BatchmodeConnector.Flav = BatchmodeConnector.Flavor.Octave; bmc.PutSparseMatrix(m_OpMtx, "FullMatrix"); bmc.PutVector(Inner_0Vars, "Inner_0Vars"); bmc.PutVector(Full_0Vars, "Full_0Vars"); bmc.Cmd("output = zeros(2,1)"); int k = 1; foreach (var s in names) { bmc.Cmd("output({1}) = condest(FullMatrix({0},{0}));", s, k); k++; } bmc.GetMatrix(output, "output"); bmc.Execute(false); double condestFull = output[0, 0]; double condestInner = output[1, 0]; double[] condestOut = new double[] { condestFull, condestInner }; Debug.Assert(condestOut[0].MPIEquals(), "value does not match on procs"); Debug.Assert(condestOut[1].MPIEquals(), "value does not match on procs"); return(condestOut); } } }