/// <summary> /// Saves the matrix in a custom sparse text format; /// Mainly for importing into MATLAB; /// </summary> /// <param name="path">Path to the text file</param> /// <remarks> /// MATLAB code for importing the matrix (save as file 'ReadMsr.m'): /// <code> /// function Mtx = ReadMsr(filename) /// /// fid = fopen(filename); /// % matrix dimensions /// % ----------------- /// NoOfRows = fscanf(fid,'%d',1); /// NoOfCols = fscanf(fid,'%d',1); /// NonZeros = fscanf(fid,'%d',1); /// cnt = 1; /// % read row and column array /// % ------------------------- /// iCol = zeros(NonZeros,1); /// iRow = zeros(NonZeros,1); /// entries = zeros(NonZeros,1); /// l0 = 0; /// str = char(zeros(1,6)); /// for i = 1:NoOfRows /// NonZerosInRow = fscanf(fid,'%d',1); /// if(l0 ~= NonZerosInRow) /// str = char(zeros(1,NonZerosInRow*6)); /// for j = 1:NonZerosInRow /// i0 = 1+(j-1)*6; /// str(i0:i0+1) = '%f'; /// str(i0+3:i0+4) = '%f'; /// end /// end /// R = fscanf(fid,str,2*NonZerosInRow); /// R2 = reshape(R',2,NonZerosInRow); /// ind = cnt:(cnt+NonZerosInRow-1); /// iCol(ind) = R2(1,:); /// iRow(ind) = i; /// entries(ind) = R2(2,:); /// /// cnt = cnt + NonZerosInRow; /// end /// fclose(fid); /// /// if (cnt-1) < NonZeros /// iCol = iCol(1:(cnt-1),1); /// iRow = iRow(1:(cnt-1),1); /// entries = entries(1:(cnt-1),1); /// end /// /// % create sparse matrix /// % -------------------- /// Mtx = sparse(iRow,iCol+1,entries,NoOfRows,NoOfCols,NonZeros); /// /// </code> /// </remarks> /// <param name="M"> /// this pointer of extension method /// </param> static public void SaveToTextFileSparse(this IMutableMatrixEx M, string path) { using (new FuncTrace()) { int rank, size; csMPI.Raw.Comm_Rank(M.MPI_Comm, out rank); csMPI.Raw.Comm_Size(M.MPI_Comm, out size); SerialisationMessenger sms = new SerialisationMessenger(M.MPI_Comm); int NoOfNonZeros = M.GetTotalNoOfNonZeros(); if (rank == 0) { sms.CommitCommPaths(); // receive data from other processors MsrMatrix.MatrixEntry[][] entries = M.GetAllEntries(); if (size > 1) { Array.Resize(ref entries, (int)(M.RowPartitioning.TotalLength)); } Helper rcvdata; int rcvRank; while (sms.GetNext(out rcvRank, out rcvdata)) { Array.Copy(rcvdata.entries, 0, entries, (int)M.RowPartitioning.GetI0Offest(rcvRank), rcvdata.entries.Length); } // open file StreamWriter stw = new StreamWriter(path); // serialize matrix data stw.WriteLine(M.RowPartitioning.TotalLength); // number of rows stw.WriteLine(M.NoOfCols); // number of columns stw.WriteLine(NoOfNonZeros); // number of non-zero entries in Matrix (over all MPI-processors) for (int i = 0; i < entries.Length; i++) { MsrMatrix.MatrixEntry[] row = entries[i]; int NonZPRow = 0; foreach (MsrMatrix.MatrixEntry e in row) { if (e.ColIndex >= 0 && e.Value != 0.0) { NonZPRow++; } } stw.Write(NonZPRow); stw.Write(" "); foreach (MsrMatrix.MatrixEntry e in row) { if (e.ColIndex >= 0 && e.Value != 0.0) { stw.Write(e.ColIndex); stw.Write(" "); stw.Write(e.Value.ToString("E16", NumberFormatInfo.InvariantInfo)); stw.Write(" "); } } stw.WriteLine(); } // finalize stw.Flush(); stw.Close(); } else { sms.SetCommPath(0); sms.CommitCommPaths(); var entries = M.GetAllEntries(); var c = new Helper(); c.entries = entries; sms.Transmitt(0, c); MsrMatrix.MatrixEntry[][] dummy; int dummy_; if (sms.GetNext <MsrMatrix.MatrixEntry[][]>(out dummy_, out dummy)) { throw new ApplicationException("error in app"); } } sms.Dispose(); } }