matrix_sparse/Matrix_Conversions.cxx

00001 // Copyright (C) 2003-2009 Marc Duruflé
00002 // Copyright (C) 2001-2009 Vivien Mallet
00003 //
00004 // This file is part of the linear-algebra library Seldon,
00005 // http://seldon.sourceforge.net/.
00006 //
00007 // Seldon is free software; you can redistribute it and/or modify it under the
00008 // terms of the GNU Lesser General Public License as published by the Free
00009 // Software Foundation; either version 2.1 of the License, or (at your option)
00010 // any later version.
00011 //
00012 // Seldon is distributed in the hope that it will be useful, but WITHOUT ANY
00013 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
00015 // more details.
00016 //
00017 // You should have received a copy of the GNU Lesser General Public License
00018 // along with Seldon. If not, see http://www.gnu.org/licenses/.
00019 
00020 
00021 #ifndef SELDON_FILE_MATRIX_CONVERSIONS_CXX
00022 
00023 
00024 #include "Matrix_Conversions.hxx"
00025 
00026 
00027 namespace Seldon
00028 {
00029 
00030   /*
00031     From CSR formats to "Matlab" coordinate format.
00032   */
00033 
00034 
00036   template<class T, class Prop, class Allocator1, class Allocator2,
00037            class Tint, class Allocator3, class Allocator4>
00038   void
00039   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, RowSparse,
00040                                Allocator1>& A,
00041                                Vector<Tint, VectFull, Allocator2>& IndRow,
00042                                Vector<Tint, VectFull, Allocator3>& IndCol,
00043                                Vector<T, VectFull, Allocator4>& Val,
00044                                int index, bool sym)
00045   {
00046     int i, j;
00047     int m = A.GetM();
00048     int nnz = A.GetDataSize();
00049     IndRow.Reallocate(nnz);
00050     IndCol.Reallocate(nnz);
00051     Val.Reallocate(nnz);
00052     int* ptr = A.GetPtr();
00053     int* ind = A.GetInd();
00054     T* val = A.GetData();
00055     for (i = 0; i < m; i++)
00056       for (j = ptr[i]; j< ptr[i+1]; j++)
00057         {
00058           IndRow(j) = i + index;
00059           IndCol(j) = ind[j] + index;
00060           Val(j) = val[j];
00061         }
00062   }
00063 
00064 
00066   template<class T, class Prop, class Allocator1, class Allocator2,
00067            class Tint, class Allocator3, class Allocator4>
00068   void
00069   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ColSparse,
00070                                Allocator1>& A,
00071                                Vector<Tint, VectFull, Allocator2>& IndRow,
00072                                Vector<Tint, VectFull, Allocator3>& IndCol,
00073                                Vector<T, VectFull, Allocator4>& Val,
00074                                int index, bool sym)
00075   {
00076     int i, j;
00077     int n = A.GetN();
00078     int nnz = A.GetDataSize();
00079     IndCol.Reallocate(nnz);
00080     IndRow.Reallocate(nnz);
00081     Val.Reallocate(nnz);
00082     int* ptr = A.GetPtr();
00083     int* ind = A.GetInd();
00084     T* val = A.GetData();
00085     for (i = 0; i< n; i++)
00086       for (j = ptr[i]; j< ptr[i+1]; j++)
00087         {
00088           IndCol(j) = i + index;
00089           IndRow(j) = ind[j] + index;
00090           Val(j) = val[j];
00091         }
00092   }
00093 
00094 
00096   template<class T, class Prop, class Allocator1, class Allocator2,
00097            class Tint, class Allocator3, class Allocator4>
00098   void
00099   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, RowSymSparse,
00100                                Allocator1>& A,
00101                                Vector<Tint, VectFull, Allocator2>& IndRow,
00102                                Vector<Tint, VectFull, Allocator3>& IndCol,
00103                                Vector<T, VectFull, Allocator4>& Val,
00104                                int index, bool sym)
00105   {
00106     int i, j;
00107     int m = A.GetM();
00108     int nnz = A.GetDataSize();
00109     int* ptr = A.GetPtr();
00110     int* ind = A.GetInd();
00111     T* val = A.GetData();
00112     if (sym)
00113       {
00114         nnz *= 2;
00115         for (i = 0; i < m; i++)
00116           if (ind[ptr[i]] == i)
00117             nnz--;
00118 
00119         IndRow.Reallocate(nnz);
00120         IndCol.Reallocate(nnz);
00121         Val.Reallocate(nnz);
00122         Vector<int> Ptr(m);
00123         Ptr.Zero();
00124         int nb = 0;
00125         for (i = 0; i < m; i++)
00126           for (j = ptr[i]; j < ptr[i + 1]; j++)
00127             {
00128               IndRow(nb) = i + index;
00129               IndCol(nb) = ind[j] + index;
00130               Val(nb) = val[j];
00131               Ptr(ind[j])++;
00132               nb++;
00133 
00134               if (ind[j] != i)
00135                 {
00136                   IndRow(nb) = ind[j] + index;
00137                   IndCol(nb) = i + index;
00138                   Val(nb) = val[j];
00139                   Ptr(i)++;
00140                   nb++;
00141                 }
00142             }
00143 
00144         // Sorting the row numbers...
00145         Sort(IndRow, IndCol, Val);
00146 
00147         // ... and the column numbers.
00148         int offset = 0;
00149         for (i = 0; i < m; i++)
00150           {
00151             Sort(offset, offset + Ptr(i) - 1, IndCol, Val);
00152             offset += Ptr(i);
00153           }
00154 
00155       }
00156     else
00157       {
00158         IndRow.Reallocate(nnz);
00159         IndCol.Reallocate(nnz);
00160         Val.Reallocate(nnz);
00161         for (i = 0; i < m; i++)
00162           for (j = ptr[i]; j< ptr[i + 1]; j++)
00163             {
00164               IndRow(j) = i + index;
00165               IndCol(j) = ind[j] + index;
00166               Val(j) = val[j];
00167             }
00168       }
00169   }
00170 
00171 
00173   template<class T, class Prop, class Allocator1, class Allocator2,
00174            class Tint, class Allocator3, class Allocator4>
00175   void
00176   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ColSymSparse,
00177                                Allocator1>& A,
00178                                Vector<Tint, VectFull, Allocator2>& IndRow,
00179                                Vector<Tint, VectFull, Allocator3>& IndCol,
00180                                Vector<T, VectFull, Allocator4>& Val,
00181                                int index, bool sym)
00182   {
00183     int i, j;
00184     int m = A.GetM();
00185     int nnz = A.GetDataSize();
00186     int* ptr = A.GetPtr();
00187     int* ind = A.GetInd();
00188     T* val = A.GetData();
00189     if (sym)
00190       {
00191         nnz *= 2;
00192         for (i = 0; i < m; i++)
00193           for (j = ptr[i]; j < ptr[i + 1]; j++)
00194             if (ind[j] == i)
00195               nnz--;
00196 
00197         IndRow.Reallocate(nnz);
00198         IndCol.Reallocate(nnz);
00199         Val.Reallocate(nnz);
00200         Vector<int> Ptr(m);
00201         Ptr.Zero();
00202         int nb = 0;
00203         for (i = 0; i < m; i++)
00204           for (j = ptr[i]; j < ptr[i + 1]; j++)
00205             {
00206               IndRow(nb) = i + index;
00207               IndCol(nb) = ind[j] + index;
00208               Val(nb) = val[j];
00209               Ptr(ind[j])++;
00210               nb++;
00211 
00212               if (ind[j] != i)
00213                 {
00214                   IndRow(nb) = ind[j] + index;
00215                   IndCol(nb) = i + index;
00216                   Val(nb) = val[j];
00217                   Ptr(i)++;
00218                   nb++;
00219                 }
00220             }
00221 
00222         // Sorting the row numbers...
00223         Sort(IndRow, IndCol, Val);
00224 
00225         // ...and the column numbers.
00226         int offset = 0;
00227         for (i = 0; i < m; i++)
00228           {
00229             Sort(offset, offset + Ptr(i) - 1, IndCol, Val);
00230             offset += Ptr(i);
00231           }
00232 
00233       }
00234     else
00235       {
00236         IndRow.Reallocate(nnz);
00237         IndCol.Reallocate(nnz);
00238         Val.Reallocate(nnz);
00239         for (i = 0; i < m; i++)
00240           for (j = ptr[i]; j< ptr[i + 1]; j++)
00241             {
00242               IndRow(j) = i + index;
00243               IndCol(j) = ind[j] + index;
00244               Val(j) = val[j];
00245             }
00246       }
00247   }
00248 
00249 
00250   /*
00251     From Sparse Array formats to "Matlab" coordinate format.
00252   */
00253 
00254 
00256   template<class T, class Prop, class Allocator1, class Allocator2,
00257            class Tint, class Allocator3, class Allocator4>
00258   void
00259   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayRowSparse,
00260                                Allocator1>& A,
00261                                Vector<Tint, VectFull, Allocator2>& IndRow,
00262                                Vector<Tint, VectFull, Allocator3>& IndCol,
00263                                Vector<T, VectFull, Allocator4>& Val,
00264                                int index, bool sym)
00265   {
00266     int i, j;
00267     int m = A.GetM();
00268     int nnz = A.GetDataSize();
00269     // Allocating arrays.
00270     IndRow.Reallocate(nnz);
00271     IndCol.Reallocate(nnz);
00272     Val.Reallocate(nnz);
00273     int nb = 0;
00274     for (i = 0; i < m; i++)
00275       for (j = 0; j < A.GetRowSize(i); j++)
00276         {
00277           IndRow(nb) = i + index;
00278           IndCol(nb) = A.Index(i, j) + index;
00279           Val(nb) = A.Value(i, j);
00280           nb++;
00281         }
00282   }
00283 
00284 
00286   template<class T, class Prop, class Allocator1, class Allocator2,
00287            class Tint, class Allocator3, class Allocator4>
00288   void
00289   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayRowComplexSparse,
00290                                Allocator1>& A,
00291                                Vector<Tint, VectFull, Allocator2>& IndRow,
00292                                Vector<Tint, VectFull, Allocator3>& IndCol,
00293                                Vector<complex<T>, VectFull, Allocator4>& Val,
00294                                int index, bool sym)
00295   {
00296     int m = A.GetM();
00297     int nnz = A.GetRealDataSize() + A.GetImagDataSize();
00298     // Allocating arrays.
00299     IndRow.Reallocate(nnz);
00300     IndCol.Reallocate(nnz);
00301     Val.Reallocate(nnz);
00302     int nb = 0;
00303     for (int i = 0; i < m; i++)
00304       {
00305         for (int j = 0; j < A.GetRealRowSize(i); j++)
00306           {
00307             IndRow(nb) = i + index;
00308             IndCol(nb) = A.IndexReal(i, j) + index;
00309             Val(nb) = complex<T>(A.ValueReal(i, j), 0);
00310             nb++;
00311           }
00312 
00313         for (int j = 0; j < A.GetImagRowSize(i); j++)
00314           {
00315             IndRow(nb) = i + index;
00316             IndCol(nb) = A.IndexImag(i, j) + index;
00317             Val(nb) = complex<T>(0, A.ValueImag(i, j));
00318             nb++;
00319           }
00320       }
00321   }
00322 
00323 
00325   template<class T, class Prop, class Allocator1, class Allocator2,
00326            class Tint, class Allocator3, class Allocator4>
00327   void
00328   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayColSparse,
00329                                Allocator1>& A,
00330                                Vector<Tint, VectFull, Allocator2>& IndRow,
00331                                Vector<Tint, VectFull, Allocator3>& IndCol,
00332                                Vector<T, VectFull, Allocator4>& Val,
00333                                int index, bool sym)
00334   {
00335     int i, j;
00336     int n = A.GetN();
00337     int nnz = A.GetDataSize();
00338     // Allocating arrays.
00339     IndRow.Reallocate(nnz);
00340     IndCol.Reallocate(nnz);
00341     Val.Reallocate(nnz);
00342     int nb = 0;
00343     for (i = 0; i < n; i++)
00344       for (j = 0; j < A.GetColumnSize(i); j++)
00345         {
00346           IndRow(nb) = A.Index(i, j) + index;
00347           IndCol(nb) = i + index;
00348           Val(nb) = A.Value(i, j);
00349           nb++;
00350         }
00351   }
00352 
00353 
00355   template<class T, class Prop, class Allocator1, class Allocator2,
00356            class Tint, class Allocator3, class Allocator4>
00357   void
00358   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayRowSymSparse,
00359                                Allocator1>& A,
00360                                Vector<Tint, VectFull, Allocator2>& IndRow,
00361                                Vector<Tint, VectFull, Allocator3>& IndCol,
00362                                Vector<T, VectFull, Allocator4>& Val,
00363                                int index, bool sym)
00364   {
00365     int i, j;
00366     int m = A.GetM();
00367     int nnz = A.GetDataSize();
00368     if (sym)
00369       {
00370         nnz *= 2;
00371         for (i = 0; i < m; i++)
00372           for (j = 0; j < A.GetRowSize(i); j++)
00373             if (A.Index(i, j) == i)
00374               nnz--;
00375 
00376         IndRow.Reallocate(nnz);
00377         IndCol.Reallocate(nnz);
00378         Val.Reallocate(nnz);
00379         Vector<int> Ptr(m);
00380         Ptr.Zero();
00381         int nb = 0;
00382         for (i = 0; i < m; i++)
00383           for (j = 0; j < A.GetRowSize(i); j++)
00384             {
00385               IndRow(nb) = i + index;
00386               IndCol(nb) = A.Index(i, j) + index;
00387               Val(nb) = A.Value(i, j);
00388               Ptr(A.Index(i, j))++;
00389               nb++;
00390 
00391               if (A.Index(i, j) != i)
00392                 {
00393                   IndRow(nb) = A.Index(i, j) + index;
00394                   IndCol(nb) = i + index;
00395                   Val(nb) = A.Value(i, j);
00396                   Ptr(i)++;
00397                   nb++;
00398                 }
00399             }
00400 
00401         // Sorting the row numbers...
00402         Sort(IndRow, IndCol, Val);
00403 
00404         // ...and the column numbers.
00405         int offset = 0;
00406         for (i = 0; i < m; i++)
00407           {
00408             Sort(offset, offset + Ptr(i) - 1, IndCol, Val);
00409             offset += Ptr(i);
00410           }
00411       }
00412     else
00413       {
00414         // Allocating arrays.
00415         IndRow.Reallocate(nnz);
00416         IndCol.Reallocate(nnz);
00417         Val.Reallocate(nnz);
00418         int nb = 0;
00419         for (i = 0; i < m; i++)
00420           for (j = 0; j < A.GetRowSize(i); j++)
00421             {
00422               IndRow(nb) = i + index;
00423               IndCol(nb) = A.Index(i, j) + index;
00424               Val(nb) = A.Value(i, j);
00425               nb++;
00426             }
00427       }
00428   }
00429 
00430 
00432   template<class T, class Prop, class Allocator1, class Allocator2,
00433            class Tint, class Allocator3, class Allocator4>
00434   void
00435   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayColSymSparse,
00436                                Allocator1>& A,
00437                                Vector<Tint, VectFull, Allocator2>& IndRow,
00438                                Vector<Tint, VectFull, Allocator3>& IndCol,
00439                                Vector<T, VectFull, Allocator4>& Val,
00440                                int index, bool sym)
00441   {
00442     int i, j;
00443     int m = A.GetM();
00444     int nnz = A.GetDataSize();
00445     if (sym)
00446       {
00447         nnz *= 2;
00448         for (i = 0; i < m; i++)
00449           for (j = 0; j < A.GetRowSize(i); j++)
00450             if (A.Index(i, j) == i)
00451               nnz--;
00452 
00453         IndRow.Reallocate(nnz);
00454         IndCol.Reallocate(nnz);
00455         Val.Reallocate(nnz);
00456         Vector<int> Ptr(m);
00457         Ptr.Zero();
00458         int nb = 0;
00459         for (i = 0; i < m; i++)
00460           for (j = 0; j < A.GetRowSize(i); j++)
00461             {
00462               IndRow(nb) = i + index;
00463               IndCol(nb) = A.Index(i, j) + index;
00464               Val(nb) = A.Value(i, j);
00465               Ptr(A.Index(i, j))++;
00466               nb++;
00467 
00468               if (A.Index(i, j) != i)
00469                 {
00470                   IndRow(nb) = A.Index(i, j) + index;
00471                   IndCol(nb) = i + index;
00472                   Val(nb) = A.Value(i, j);
00473                   Ptr(i)++;
00474                   nb++;
00475                 }
00476             }
00477 
00478         // Sorting the row numbers...
00479         Sort(IndRow, IndCol, Val);
00480 
00481         // ...and the column numbers.
00482         int offset = 0;
00483         for (i = 0; i < m; i++)
00484           {
00485             Sort(offset, offset + Ptr(i) - 1, IndCol, Val);
00486             offset += Ptr(i);
00487           }
00488       }
00489     else
00490       {
00491         // Allocating arrays.
00492         IndRow.Reallocate(nnz);
00493         IndCol.Reallocate(nnz);
00494         Val.Reallocate(nnz);
00495         int nb = 0;
00496         for (i = 0; i < m; i++)
00497           for (j = 0; j < A.GetColumnSize(i); j++)
00498             {
00499               IndRow(nb) = A.Index(i, j) + index;
00500               IndCol(nb) = i + index;
00501               Val(nb) = A.Value(i, j);
00502               nb++;
00503             }
00504       }
00505   }
00506 
00507 
00508   /*
00509     From "Matlab" coordinate format to CSR formats.
00510   */
00511 
00512 
00514 
00522   template<class T, class Prop, class Allocator1,
00523            class Allocator2, class Allocator3>
00524   void
00525   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
00526                                  Vector<int, VectFull, Allocator2>& IndCol_,
00527                                  Vector<T, VectFull, Allocator3>& Val,
00528                                  Matrix<T, Prop, RowSparse, Allocator3>& A,
00529                                  int index)
00530   {
00531     int i, j;
00532 
00533     int Nelement = IndRow_.GetLength();
00534 
00535     Vector<int, VectFull, CallocAlloc<int> > IndRow(Nelement),
00536       IndCol(Nelement);
00537     for (int i = 0; i < Nelement; i++)
00538       {
00539         IndRow(i) = IndRow_(i) - index;
00540         IndCol(i) = IndCol_(i) - index;
00541       }
00542     IndRow_.Clear();
00543     IndCol_.Clear();
00544 
00545     Sort(IndRow, IndCol, Val);
00546 
00547     Vector<int, VectFull, CallocAlloc<int> > ptr(A.GetM() + 1);
00548     for (i = 0; i <= IndRow(0); i++)
00549       ptr(i) = 0;
00550 
00551     int row = IndRow(0);
00552     int previous_i = 0;
00553 
00554     for (i = 1; i < Nelement; i++)
00555       if (IndRow(i) != row)
00556         {
00557           for (j = row + 1; j <= IndRow(i); j++)
00558             ptr(j) = i;
00559 
00560           Sort(previous_i, i-1, IndCol, Val);
00561           row = IndRow(i);
00562           previous_i = i;
00563         }
00564 
00565     Sort(previous_i, Nelement - 1, IndCol, Val);
00566     for (i = IndRow(Nelement - 1); i < A.GetM(); i++)
00567       ptr(i + 1) = Nelement;
00568 
00569     A.SetData(A.GetM(), A.GetN(), Val, ptr, IndCol);
00570   }
00571 
00572 
00574   template<class T, class Prop, class Allocator1,
00575            class Allocator2, class Allocator3>
00576   void
00577   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
00578                                  Vector<int, VectFull, Allocator2>& IndCol_,
00579                                  Vector<T, VectFull, Allocator3>& Val,
00580                                  Matrix<T, Prop, ColSparse, Allocator3>& A,
00581                                  int index)
00582   {
00583     // Assuming that there is no duplicate value.
00584     if (IndRow_.GetM() <= 0)
00585       return;
00586 
00587     int nnz = IndRow_.GetM();
00588     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
00589     for (int i = 0; i < nnz; i++)
00590       {
00591         IndRow(i) = IndRow_(i);
00592         IndCol(i) = IndCol_(i);
00593       }
00594     IndRow_.Clear();
00595     IndCol_.Clear();
00596 
00597     int row_max = IndRow.GetNormInf();
00598     int col_max = IndCol.GetNormInf();
00599     int m = row_max - index + 1;
00600     int n = col_max - index + 1;
00601 
00602     // Sorts the array 'IndCol'.
00603     Sort(IndCol, IndRow, Val);
00604 
00605     // Construction of array 'Ptr'.
00606     Vector<int, VectFull, CallocAlloc<int> > Ptr(n + 1);
00607     Ptr.Zero();
00608     for (int i = 0; i < nnz; i++)
00609       {
00610         IndRow(i) -= index;
00611         IndCol(i) -= index;
00612         Ptr(IndCol(i) + 1)++;
00613       }
00614 
00615     for (int i = 0; i < n; i++)
00616       Ptr(i + 1) += Ptr(i);
00617 
00618     // Sorts 'IndRow'
00619     for (int i = 0; i < n; i++)
00620       Sort(Ptr(i), Ptr(i + 1) - 1, IndRow, Val);
00621 
00622     A.SetData(m, n, Val, Ptr, IndRow);
00623   }
00624 
00625 
00627   template<class T, class Prop, class Allocator1,
00628            class Allocator2, class Allocator3>
00629   void
00630   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
00631                                  Vector<int, VectFull, Allocator2>& IndCol_,
00632                                  Vector<T, VectFull, Allocator3>& Val,
00633                                  Matrix<T, Prop, RowSymSparse, Allocator3>& A,
00634                                  int index)
00635   {
00636     // Assuming there is no duplicate value.
00637     if (IndRow_.GetM() <= 0)
00638       return;
00639 
00640     int nnz = IndRow_.GetM();
00641     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
00642     for (int i = 0; i < nnz; i++)
00643       {
00644         IndRow(i) = IndRow_(i);
00645         IndCol(i) = IndCol_(i);
00646       }
00647     IndRow_.Clear();
00648     IndCol_.Clear();
00649 
00650     int row_max = IndRow.GetNormInf();
00651     int col_max = IndCol.GetNormInf();
00652     int m = row_max - index + 1;
00653     int n = col_max - index + 1;
00654 
00655     // First, removing the lower part of the matrix (if present).
00656     int nb_low = 0;
00657     for (int i = 0; i < nnz; i++)
00658       if (IndRow(i) > IndCol(i))
00659         nb_low++;
00660 
00661     if (nb_low > 0)
00662       {
00663         int nb = 0;
00664         for (int i = 0; i < nnz; i++)
00665           if (IndRow(i) <= IndCol(i))
00666             {
00667               IndRow(nb) = IndRow(i);
00668               IndCol(nb) = IndCol(i);
00669               Val(nb) = Val(i);
00670               nb++;
00671             }
00672 
00673         IndRow.Resize(nb);
00674         IndCol.Resize(nb);
00675         Val.Resize(nb);
00676         nnz = nb;
00677       }
00678 
00679     // Sorts the array 'IndRow'.
00680     Sort(IndRow, IndCol, Val);
00681 
00682     // Construction of array 'Ptr'.
00683     Vector<int, VectFull, CallocAlloc<int> > Ptr(m + 1);
00684     Ptr.Zero();
00685     for (int i = 0; i < nnz; i++)
00686       {
00687         IndRow(i) -= index;
00688         IndCol(i) -= index;
00689         Ptr(IndRow(i) + 1)++;
00690       }
00691 
00692     for (int i = 0; i < m; i++)
00693       Ptr(i + 1) += Ptr(i);
00694 
00695     // Sorts 'IndCol'.
00696     for (int i = 0; i < m; i++)
00697       Sort(Ptr(i), Ptr(i + 1) - 1, IndCol, Val);
00698 
00699     A.SetData(m, n, Val, Ptr, IndCol);
00700   }
00701 
00702 
00704   template<class T, class Prop, class Allocator1,
00705            class Allocator2, class Allocator3>
00706   void
00707   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
00708                                  Vector<int, VectFull, Allocator2>& IndCol_,
00709                                  Vector<T, VectFull, Allocator3>& Val,
00710                                  Matrix<T, Prop, ColSymSparse, Allocator3>& A,
00711                                  int index)
00712   {
00713     // Assuming there is no duplicate value.
00714     if (IndRow_.GetM() <= 0)
00715       return;
00716 
00717     int nnz = IndRow_.GetM();
00718     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
00719     for (int i = 0; i < nnz; i++)
00720       {
00721         IndRow(i) = IndRow_(i);
00722         IndCol(i) = IndCol_(i);
00723       }
00724     IndRow_.Clear();
00725     IndCol_.Clear();
00726 
00727     int row_max = IndRow.GetNormInf();
00728     int col_max = IndCol.GetNormInf();
00729     int m = row_max - index + 1;
00730     int n = col_max - index + 1;
00731 
00732     // First, removing the lower part of the matrix (if present).
00733     int nb_low = 0;
00734     for (int i = 0; i < nnz; i++)
00735       if (IndRow(i) > IndCol(i))
00736         nb_low++;
00737 
00738     if (nb_low > 0)
00739       {
00740         int nb = 0;
00741         for (int i = 0; i < nnz; i++)
00742           if (IndRow(i) <= IndCol(i))
00743             {
00744               IndRow(nb) = IndRow(i);
00745               IndCol(nb) = IndCol(i);
00746               Val(nb) = Val(i);
00747               nb++;
00748             }
00749 
00750         IndRow.Resize(nb);
00751         IndCol.Resize(nb);
00752         Val.Resize(nb);
00753         nnz = nb;
00754       }
00755 
00756     // Sorts the array 'IndRow'.
00757     Sort(IndRow, IndCol, Val);
00758 
00759     // Construction of array 'Ptr'.
00760     Vector<int, VectFull, CallocAlloc<int> > Ptr(m + 1);
00761     Ptr.Zero();
00762     for (int i = 0; i < nnz; i++)
00763       {
00764         IndRow(i) -= index;
00765         IndCol(i) -= index;
00766         Ptr(IndRow(i) + 1)++;
00767       }
00768 
00769     for (int i = 0; i < m; i++)
00770       Ptr(i + 1) += Ptr(i);
00771 
00772     // Sorts 'IndCol'.
00773     for (int i = 0; i < m; i++)
00774       Sort(Ptr(i), Ptr(i + 1) - 1, IndCol, Val);
00775 
00776     A.SetData(m, n, Val, Ptr, IndCol);
00777   }
00778 
00779 
00780   /*
00781     From Sparse Array formats to "Matlab" coordinate format.
00782   */
00783 
00784 
00786   template<class T, class Prop, class Allocator1,
00787            class Allocator2, class Allocator3>
00788   void
00789   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
00790                                  Vector<int, VectFull, Allocator2>& IndCol_,
00791                                  Vector<T, VectFull, Allocator3>& Val,
00792                                  Matrix<T, Prop, ArrayRowSparse,
00793                                  Allocator3>& A,
00794                                  int index)
00795   {
00796     if (IndRow_.GetM() <= 0)
00797       return;
00798 
00799     int nnz = IndRow_.GetM();
00800     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
00801     for (int i = 0; i < nnz; i++)
00802       {
00803         IndRow(i) = IndRow_(i);
00804         IndCol(i) = IndCol_(i);
00805       }
00806     IndRow_.Clear();
00807     IndCol_.Clear();
00808 
00809     int row_max = IndRow.GetNormInf();
00810     int col_max = IndCol.GetNormInf();
00811     int m = row_max - index + 1;
00812     int n = col_max - index + 1;
00813 
00814     // Sorts the array 'IndRow'.
00815     Sort(IndRow, IndCol, Val);
00816 
00817     // Number of elements per row.
00818     Vector<int, VectFull, CallocAlloc<int> > Ptr(m);
00819     Ptr.Zero();
00820     for (int i = 0; i < nnz; i++)
00821       {
00822         IndRow(i) -= index;
00823         IndCol(i) -= index;
00824         Ptr(IndRow(i))++;
00825       }
00826 
00827     // Fills matrix 'A'.
00828     A.Reallocate(m, n);
00829     int offset = 0;
00830     for (int i = 0; i < m; i++)
00831       if (Ptr(i) > 0)
00832         {
00833           A.ReallocateRow(i, Ptr(i));
00834           for (int j = 0; j < Ptr(i); j++)
00835             {
00836               A.Index(i, j) = IndCol(offset + j);
00837               A.Value(i, j) = Val(offset + j);
00838             }
00839           offset += Ptr(i);
00840         }
00841 
00842     // Assembles 'A' to sort column numbers.
00843     A.Assemble();
00844   }
00845 
00846 
00848   template<class T, class Prop, class Allocator1,
00849            class Allocator2, class Allocator3>
00850   void
00851   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
00852                                  Vector<int, VectFull, Allocator2>& IndCol_,
00853                                  Vector<T, VectFull, Allocator3>& Val,
00854                                  Matrix<T, Prop, ArrayColSparse,
00855                                  Allocator3>& A,
00856                                  int index)
00857   {
00858     // Assuming there is no duplicate value.
00859     if (IndRow_.GetM() <= 0)
00860       return;
00861 
00862     int nnz = IndRow_.GetM();
00863     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
00864     for (int i = 0; i < nnz; i++)
00865       {
00866         IndRow(i) = IndRow_(i);
00867         IndCol(i) = IndCol_(i);
00868       }
00869     IndRow_.Clear();
00870     IndCol_.Clear();
00871 
00872     int row_max = IndRow.GetNormInf();
00873     int col_max = IndCol.GetNormInf();
00874     int m = row_max - index + 1;
00875     int n = col_max - index + 1;
00876 
00877     // Sorts array 'IndCol'.
00878     Sort(IndCol, IndRow, Val);
00879 
00880     // Construction of array 'Ptr'.
00881     Vector<int, VectFull, CallocAlloc<int> > Ptr(n);
00882     Ptr.Zero();
00883     for (int i = 0; i < nnz; i++)
00884       {
00885         IndRow(i) -= index;
00886         IndCol(i) -= index;
00887         Ptr(IndCol(i))++;
00888       }
00889 
00890     // Fills matrix 'A'.
00891     A.Reallocate(m, n);
00892     int offset = 0;
00893     for (int i = 0; i < n; i++)
00894       if (Ptr(i) > 0)
00895         {
00896           A.ReallocateColumn(i, Ptr(i));
00897           for (int j = 0; j < Ptr(i); j++)
00898             {
00899               A.Index(i, j) = IndRow(offset + j);
00900               A.Value(i, j) = Val(offset + j);
00901             }
00902           offset += Ptr(i);
00903         }
00904 
00905     // Assembles 'A' to sort row numbers.
00906     A.Assemble();
00907   }
00908 
00909 
00911   template<class T, class Prop, class Allocator1,
00912            class Allocator2, class Allocator3>
00913   void
00914   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
00915                                  Vector<int, VectFull, Allocator2>& IndCol_,
00916                                  Vector<T, VectFull, Allocator3>& Val,
00917                                  Matrix<T, Prop, ArrayRowSymSparse,
00918                                  Allocator3>& A,
00919                                  int index)
00920   {
00921     // Assuming that there is no duplicate value.
00922     if (IndRow_.GetM() <= 0)
00923       return;
00924 
00925     int nnz = IndRow_.GetM();
00926     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
00927     for (int i = 0; i < nnz; i++)
00928       {
00929         IndRow(i) = IndRow_(i);
00930         IndCol(i) = IndCol_(i);
00931       }
00932     IndRow_.Clear();
00933     IndCol_.Clear();
00934 
00935     int row_max = IndRow.GetNormInf();
00936     int col_max = IndCol.GetNormInf();
00937     int m = row_max - index + 1;
00938     int n = col_max - index + 1;
00939 
00940     // First, removing the lower part of the matrix (if present).
00941     int nb_low = 0;
00942     for (int i = 0; i < nnz; i++)
00943       if (IndRow(i) > IndCol(i))
00944         nb_low++;
00945 
00946     if (nb_low > 0)
00947       {
00948         int nb = 0;
00949         for (int i = 0; i < nnz; i++)
00950           if (IndRow(i) <= IndCol(i))
00951             {
00952               IndRow(nb) = IndRow(i);
00953               IndCol(nb) = IndCol(i);
00954               Val(nb) = Val(i);
00955               nb++;
00956             }
00957 
00958         IndRow.Resize(nb);
00959         IndCol.Resize(nb);
00960         Val.Resize(nb);
00961         nnz = nb;
00962       }
00963 
00964     // Sorts the array 'IndRow'.
00965     Sort(IndRow, IndCol, Val);
00966 
00967     // Construction of array 'Ptr'.
00968     Vector<int, VectFull, CallocAlloc<int> > Ptr(m);
00969     Ptr.Zero();
00970     for (int i = 0; i < nnz; i++)
00971       {
00972         IndRow(i) -= index;
00973         IndCol(i) -= index;
00974         Ptr(IndRow(i))++;
00975       }
00976 
00977     // Fills matrix 'A'.
00978     A.Clear(); A.Reallocate(m, n);
00979     int offset = 0;
00980     for (int i = 0; i < m; i++)
00981       if (Ptr(i) > 0)
00982         {
00983           // sorting column numbers
00984           Sort(offset, offset+Ptr(i)-1, IndCol, Val);
00985 
00986           // putting values in A
00987           A.ReallocateRow(i, Ptr(i));
00988           for (int j = 0; j < Ptr(i); j++)
00989             {
00990               A.Index(i, j) = IndCol(offset + j);
00991               A.Value(i, j) = Val(offset + j);
00992             }
00993 
00994           offset += Ptr(i);
00995         }
00996   }
00997 
00998 
01000   template<class T, class Prop, class Allocator1,
01001            class Allocator2, class Allocator3>
01002   void
01003   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
01004                                  Vector<int, VectFull, Allocator2>& IndCol_,
01005                                  Vector<T, VectFull, Allocator3>& Val,
01006                                  Matrix<T, Prop, ArrayColSymSparse,
01007                                  Allocator3>& A,
01008                                  int index)
01009   {
01010     // Assuming that there is no duplicate value.
01011     if (IndRow_.GetM() <= 0)
01012       return;
01013 
01014     int nnz = IndRow_.GetM();
01015     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
01016     for (int i = 0; i < nnz; i++)
01017       {
01018         IndRow(i) = IndRow_(i);
01019         IndCol(i) = IndCol_(i);
01020       }
01021     IndRow_.Clear();
01022     IndCol_.Clear();
01023 
01024     int row_max = IndRow.GetNormInf();
01025     int col_max = IndCol.GetNormInf();
01026     int m = row_max - index + 1;
01027     int n = col_max - index + 1;
01028 
01029     // First, removing the lower part of the matrix (if present).
01030     int nb_low = 0;
01031     for (int i = 0; i < nnz; i++)
01032       if (IndRow(i) > IndCol(i))
01033         nb_low++;
01034 
01035     if (nb_low > 0)
01036       {
01037         int nb = 0;
01038         for (int i = 0; i < nnz; i++)
01039           if (IndRow(i) <= IndCol(i))
01040             {
01041               IndRow(nb) = IndRow(i);
01042               IndCol(nb) = IndCol(i);
01043               Val(nb) = Val(i);
01044               nb++;
01045             }
01046 
01047         IndRow.Resize(nb);
01048         IndCol.Resize(nb);
01049         Val.Resize(nb);
01050         nnz = nb;
01051       }
01052 
01053     // Sorts the array 'IndRow'.
01054     Sort(IndRow, IndCol, Val);
01055 
01056     // Construction of array 'Ptr'.
01057     Vector<int, VectFull, CallocAlloc<int> > Ptr(m);
01058     Ptr.Zero();
01059     for (int i = 0; i < nnz; i++)
01060       {
01061         IndRow(i) -= index;
01062         IndCol(i) -= index;
01063         Ptr(IndRow(i))++;
01064       }
01065 
01066     // Fills matrix 'A'.
01067     A.Reallocate(m, n);
01068     int offset = 0;
01069     for (int i = 0; i < m; i++)
01070       if (Ptr(i) > 0)
01071         {
01072           A.ReallocateColumn(i, Ptr(i));
01073           for (int j = 0; j < Ptr(i); j++)
01074             {
01075               A.Index(i, j) = IndCol(offset + j);
01076               A.Value(i, j) = Val(offset + j);
01077             }
01078           offset += Ptr(i);
01079         }
01080 
01081     // Assembles 'A' to sort column numbers.
01082     A.Assemble();
01083   }
01084 
01085 
01086   /*
01087     From CSR to other CSR formats.
01088   */
01089 
01090 
01092   template<class T, class Prop, class Storage, class Allocator>
01093   void Copy(const Matrix<T, Prop, Storage, Allocator>& A,
01094             Matrix<T, Prop, Storage, Allocator>& B)
01095   {
01096     B = A;
01097   }
01098 
01099 
01100   template<class T, class Prop, class Alloc1,
01101            class Tint, class Alloc2, class Alloc3, class Alloc4>
01102   void ConvertToCSC(const Matrix<T, Prop, RowSparse, Alloc1>& A,
01103                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
01104                     Vector<Tint, VectFull, Alloc3>& Ind,
01105                     Vector<T, VectFull, Alloc4>& Val, bool sym_pat)
01106   {
01107     if (sym_pat)
01108       throw WrongArgument("ConvertToCSC(Matrix<RowSparse>, ...)",
01109                           "Option 'sym_pat' is not supported.");
01110 
01111     int i, j;
01112 
01113     int m = A.GetM(), n = A.GetN(), nnz = A.GetDataSize();
01114     int* ptr_ = A.GetPtr();
01115     int* ind_ = A.GetInd();
01116     T* data_ = A.GetData();
01117 
01118     // Computation of the indices of the beginning of columns.
01119     Ptr.Reallocate(n + 1);
01120     Ptr.Fill(0);
01121     // Counting the number of entries per column.
01122     for (i = 0; i < nnz; i++)
01123       Ptr(ind_[i])++;
01124 
01125     // Incrementing in order to get indices.
01126     int increment = 0, size, num_col;
01127     for (i = 0; i < n; i++)
01128       {
01129         size = Ptr(i);
01130         Ptr(i) = increment;
01131         increment += size;
01132       }
01133 
01134     // Last index.
01135     Ptr(n) = increment;
01136 
01137     // 'Offset' will be used to get current positions of new entries.
01138     Vector<int, VectFull, CallocAlloc<int> > Offset = Ptr;
01139     Ind.Reallocate(nnz);
01140     Val.Reallocate(nnz);
01141 
01142     // Loop over rows.
01143     for (i = 0; i < m; i++)
01144       for (j = ptr_[i]; j < ptr_[i + 1]; j++)
01145         {
01146           num_col = ind_[j];
01147           Ind(Offset(num_col)) = i;
01148           Val(Offset(num_col)) = data_[j];
01149           Offset(num_col)++;
01150         }
01151   }
01152 
01153 
01155   template<class T, class Prop, class Alloc1, class Alloc2>
01156   void Copy(const Matrix<T, Prop, RowSparse, Alloc1>& A,
01157             Matrix<T, Prop, ColSparse, Alloc2>& B)
01158   {
01159     Vector<int, VectFull, CallocAlloc<int> > Ptr;
01160     Vector<int, VectFull, CallocAlloc<int> > Ind;
01161     Vector<T, VectFull, Alloc2> Val;
01162 
01163     int m = A.GetM(), n = A.GetN();
01164     General sym;
01165     ConvertToCSC(A, sym, Ptr, Ind, Val);
01166 
01167     B.SetData(m, n, Val, Ptr, Ind);
01168   }
01169 
01170 
01171   template<class T, class Prop, class Alloc1,
01172            class Tint, class Alloc2, class Alloc3, class Alloc4>
01173   void ConvertToCSR(const Matrix<T, Prop, ColSymSparse, Alloc1>& A,
01174                     Symmetric& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
01175                     Vector<Tint, VectFull, Alloc3>& Ind,
01176                     Vector<T, VectFull, Alloc4>& Value)
01177   {
01178     IVect IndRow, IndCol;
01179     Vector<T> Val;
01180 
01181     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Val, 0, true);
01182 
01183     int m = A.GetM();
01184     int n = A.GetM();
01185     Ptr.Reallocate(m+1);
01186     Ptr.Zero();
01187     // counting number of non-zero entries
01188     int nnz = 0;
01189     for (int i = 0; i < IndCol.GetM(); i++)
01190       if (IndRow(i) <= IndCol(i))
01191         {
01192           Ptr(IndRow(i) + 1)++;
01193           nnz++;
01194         }
01195 
01196     // incrementing Ptr
01197     for (int i = 2; i <= m; i++)
01198       Ptr(i) += Ptr(i-1);
01199 
01200     // filling Ind and Value
01201     Ind.Reallocate(nnz);
01202     Value.Reallocate(nnz);
01203     nnz = 0;
01204     for (int i = 0; i < IndCol.GetM(); i++)
01205       if (IndRow(i) <= IndCol(i))
01206         {
01207           Ind(nnz) = IndCol(i);
01208           Value(nnz) = Val(i);
01209           nnz++;
01210         }
01211   }
01212 
01213 
01215   template<class T, class Prop, class Alloc1, class Alloc2>
01216   void Copy(const Matrix<T, Prop, ColSymSparse, Alloc1>& A,
01217             Matrix<T, Prop, RowSymSparse, Alloc2>& B)
01218   {
01219     Vector<int, VectFull, CallocAlloc<int> > Ptr, Ind;
01220     Vector<T, VectFull, Alloc2> Value;
01221 
01222     Symmetric sym;
01223     ConvertToCSR(A, sym, Ptr, Ind, Value);
01224 
01225     // creating the matrix
01226     int m = A.GetM();
01227     int n = A.GetN();
01228     B.SetData(m, n, Value, Ptr, Ind);
01229   }
01230 
01231 
01233   template<class T, class Prop1, class Storage, class Tint,
01234            class Alloc1, class Alloc2, class Alloc3, class Alloc4>
01235   void
01236   ConvertSymmetricToCSC(const Matrix<T, Prop1, Storage, Alloc1>& A,
01237                         General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
01238                         Vector<Tint, VectFull, Alloc3>& Ind,
01239                         Vector<T, VectFull, Alloc4>& Val, bool sym_pat)
01240   {
01241     int i, j;
01242 
01243     int m = A.GetM(), n = A.GetN();
01244     int* ptr_ = A.GetPtr();
01245     int* ind_ = A.GetInd();
01246     T* data_ = A.GetData();
01247 
01248     // Computation of the indices of the beginning of columns.
01249     Ptr.Reallocate(n + 1);
01250     Ptr.Fill(0);
01251     // Counting the number of entries per column.
01252     for (i = 0; i < m; i++)
01253       for (j = ptr_[i]; j < ptr_[i + 1]; j++)
01254         {
01255           Ptr(ind_[j])++;
01256           if (i != ind_[j])
01257             Ptr(i)++;
01258         }
01259 
01260     // Incrementing in order to get indices.
01261     int nnz = 0, size, num_col;
01262     for (i = 0; i < n; i++)
01263       {
01264         size = Ptr(i);
01265         Ptr(i) = nnz;
01266         nnz += size;
01267       }
01268     // Last index.
01269     Ptr(n) = nnz;
01270 
01271     // 'Offset' will be used to get current positions of new entries.
01272     Vector<int, VectFull, CallocAlloc<int> > Offset = Ptr;
01273     Ind.Reallocate(nnz);
01274     Val.Reallocate(nnz);
01275 
01276     // Loop over rows.
01277     for (i = 0; i < m; i++)
01278       for (j = ptr_[i]; j < ptr_[i + 1]; j++)
01279         {
01280           num_col = ind_[j];
01281           Ind(Offset(num_col)) = i;
01282           Val(Offset(num_col)) = data_[j];
01283           Offset(num_col)++;
01284           if (i != ind_[j])
01285             {
01286               Ind(Offset(i)) = num_col;
01287               Val(Offset(i)) = data_[j];
01288               Offset(i)++;
01289             }
01290         }
01291   }
01292 
01293 
01294   template<class T, class Prop1, class Tint,
01295            class Alloc1, class Alloc2, class Alloc3, class Alloc4>
01296   void
01297   ConvertToCSC(const Matrix<T, Prop1, RowSymSparse, Alloc1>& A,
01298                General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
01299                Vector<Tint, VectFull, Alloc3>& Ind,
01300                Vector<T, VectFull, Alloc4>& Val, bool sym_pat)
01301   {
01302     ConvertSymmetricToCSC(A, sym, Ptr, Ind, Val, sym_pat);
01303   }
01304 
01305 
01306   template<class T, class Prop1, class Tint,
01307            class Alloc1, class Alloc2, class Alloc3, class Alloc4>
01308   void
01309   ConvertToCSC(const Matrix<T, Prop1, ColSymSparse, Alloc1>& A,
01310                General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
01311                Vector<Tint, VectFull, Alloc3>& Ind,
01312                Vector<T, VectFull, Alloc4>& Val, bool sym_pat = false)
01313   {
01314     ConvertSymmetricToCSC(A, sym, Ptr, Ind, Val, sym_pat);
01315   }
01316 
01317 
01319 
01323   template<class T1, class T2, class Prop1, class Prop2,
01324            class Alloc1, class Alloc2>
01325   void Copy(const Matrix<T1, Prop1, ColSparse, Alloc1>& A,
01326             Matrix<T2, Prop2, RowSparse, Alloc2>& B)
01327   {
01328     int i, j;
01329 
01330     int m = A.GetM();
01331     int n = A.GetN();
01332     int  nnz = A.GetDataSize();
01333 
01334     int* ptr = A.GetPtr();
01335     int* ind = A.GetInd();
01336     T1* data = A.GetData();
01337 
01338     // Computation of the indexes of the beginning of rows.
01339     Vector<int, VectFull, CallocAlloc<int> > Ptr(n + 1);
01340     Ptr.Fill(0);
01341     // Counting the number of entries per row.
01342     for (i = 0; i < nnz; i++)
01343       Ptr(ind[i])++;
01344 
01345     // Incrementing in order to get the row indexes.
01346     int increment = 0, size, num_row;
01347     for (i = 0; i < n; i++)
01348       {
01349         size = Ptr(i);
01350         Ptr(i) = increment;
01351         increment += size;
01352       }
01353     // Last index.
01354     Ptr(n) = increment;
01355 
01356     // 'Offset' will be used to get current positions of new entries.
01357     Vector<int, VectFull, CallocAlloc<int> > Offset = Ptr;
01358     Vector<int, VectFull, CallocAlloc<int> > Ind(nnz);
01359     Vector<T2, VectFull, Alloc2> Val(nnz);
01360 
01361     // Loop over the columns.
01362     for (j = 0; j < n; j++)
01363       for (i = ptr[j]; i < ptr[j + 1]; i++)
01364         {
01365           num_row = ind[i];
01366           Ind(Offset(num_row)) = j;
01367           Val(Offset(num_row)) = data[i];
01368           Offset(num_row)++;
01369         }
01370 
01371     B.SetData(m, n, Val, Ptr, Ind);
01372   }
01373 
01374 
01376   template<class T, class Prop1, class Prop2, class Alloc1, class Alloc2>
01377   void Copy(const Matrix<T, Prop1, RowSymSparse, Alloc1>& A,
01378             Matrix<T, Prop2, ColSparse, Alloc2>& B)
01379   {
01380     Vector<int, VectFull, CallocAlloc<int> > Ptr;
01381     Vector<int, VectFull, CallocAlloc<int> > Ind;
01382     Vector<T, VectFull, Alloc2> Val;
01383 
01384     int m = A.GetM(), n = A.GetN();
01385     General sym;
01386     ConvertToCSC(A, sym, Ptr, Ind, Val);
01387 
01388     B.SetData(m, n, Val, Ptr, Ind);
01389   }
01390 
01391 
01393   template<class T, class Prop1, class Prop2, class Alloc1, class Alloc2>
01394   void Copy(const Matrix<T, Prop1, ColSymSparse, Alloc1>& A,
01395             Matrix<T, Prop2, ColSparse, Alloc2>& B)
01396   {
01397     Vector<int, VectFull, CallocAlloc<int> > Ptr;
01398     Vector<int, VectFull, CallocAlloc<int> > Ind;
01399     Vector<T, VectFull, Alloc2> Val;
01400 
01401     int m = A.GetM(), n = A.GetN();
01402     General sym;
01403     ConvertToCSC(A, sym, Ptr, Ind, Val);
01404 
01405     B.SetData(m, n, Val, Ptr, Ind);
01406   }
01407 
01408 
01409   /*
01410     From ArraySparse matrices to CSR matrices.
01411   */
01412 
01413 
01414   template<class T, class Prop, class Alloc1,
01415            class Tint, class Alloc2, class Alloc3, class Alloc4>
01416   void ConvertToCSR(const Matrix<T, Prop, ArrayRowSparse, Alloc1>& A,
01417                     General& sym, Vector<Tint, VectFull, Alloc2>& IndRow,
01418                     Vector<Tint, VectFull, Alloc3>& IndCol,
01419                     Vector<T, VectFull, Alloc4>& Val)
01420   {
01421     // Matrix (m,n) with 'nnz' entries.
01422     int nnz = A.GetDataSize();
01423     int m = A.GetM();
01424 
01425     // Allocating arrays needed for CSR format.
01426     Val.Reallocate(nnz);
01427     IndRow.Reallocate(m + 1);
01428     IndCol.Reallocate(nnz);
01429 
01430     // Filling the arrays.
01431     int ind = 0;
01432     IndRow(0) = 0;
01433     for (int i = 0; i < m; i++)
01434       {
01435         for (int k = 0; k < A.GetRowSize(i); k++)
01436           {
01437             IndCol(ind) = A.Index(i, k);
01438             Val(ind) = A.Value(i, k);
01439             ind++;
01440           }
01441         IndRow(i + 1) = ind;
01442       }
01443   }
01444 
01445 
01447   template<class T0, class Prop0, class Allocator0,
01448            class T1, class Prop1, class Allocator1>
01449   void Copy(const Matrix<T0, Prop0, ArrayRowSparse,Allocator0>& mat_array,
01450             Matrix<T1, Prop1, RowSparse, Allocator1>& mat_csr)
01451   {
01452     Vector<T1, VectFull, Allocator1> Val;
01453     Vector<int, VectFull, CallocAlloc<int> > IndRow;
01454     Vector<int, VectFull, CallocAlloc<int> > IndCol;
01455 
01456     General sym;
01457     ConvertToCSR(mat_array, sym, IndRow, IndCol, Val);
01458 
01459     int m = mat_array.GetM();
01460     int n = mat_array.GetN();
01461     mat_csr.SetData(m, n, Val, IndRow, IndCol);
01462   }
01463 
01464 
01465   template<class T, class Prop, class Alloc1,
01466            class Tint, class Alloc2, class Alloc3, class Alloc4>
01467   void ConvertToCSC(const Matrix<T, Prop, ArrayRowSparse, Alloc1>& A,
01468                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
01469                     Vector<Tint, VectFull, Alloc3>& IndRow,
01470                     Vector<T, VectFull, Alloc4>& Val, bool sym_pat)
01471   {
01472     // Matrix (m,n) with nnz entries.
01473     int nnz = A.GetDataSize();
01474     int n = A.GetN();
01475 
01476     // Conversion in coordinate format.
01477     Vector<Tint, VectFull, CallocAlloc<Tint> > IndCol;
01478     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Val);
01479 
01480     // Sorting with respect to column numbers.
01481     Sort(IndCol, IndRow, Val);
01482 
01483     // Constructing pointer array 'Ptr'.
01484     Ptr.Reallocate(n + 1);
01485     Ptr.Fill(0);
01486 
01487     // Counting non-zero entries per column.
01488     for (int i = 0; i < nnz; i++)
01489       Ptr(IndCol(i) + 1)++;
01490 
01491     int nb_new_val = 0;
01492 
01493     if (sym_pat)
01494       {
01495         // Counting entries that are on the symmetrized pattern without being
01496         // in the original pattern.
01497         int k = 0;
01498         for (int i = 0; i < n; i++)
01499           {
01500             while (k < IndCol.GetM() && IndCol(k) < i)
01501               k++;
01502 
01503             for (int j = 0; j < A.GetRowSize(i); j++)
01504               {
01505                 int irow = A.Index(i, j);
01506                 while (k < IndCol.GetM() && IndCol(k) == i
01507                        && IndRow(k) < irow)
01508                   k++;
01509 
01510                 if (k < IndCol.GetM() && IndCol(k) == i && IndRow(k) == irow)
01511                   // Already existing entry.
01512                   k++;
01513                 else
01514                   {
01515                     // New entry.
01516                     Ptr(i + 1)++;
01517                     nb_new_val++;
01518                   }
01519               }
01520           }
01521       }
01522 
01523     // Accumulation to get pointer array.
01524     Ptr(0) = 0;
01525     for (int i = 0; i < n; i++)
01526       Ptr(i + 1) += Ptr(i);
01527 
01528     if (sym_pat && (nb_new_val > 0))
01529       {
01530         // Changing 'IndRow' and 'Val', and assembling the pattern.
01531         Vector<Tint, VectFull, Alloc3> OldInd(IndRow);
01532         Vector<T, VectFull, Alloc4> OldVal(Val);
01533         IndRow.Reallocate(nnz + nb_new_val);
01534         Val.Reallocate(nnz + nb_new_val);
01535         int k = 0, nb = 0;
01536         for (int i = 0; i < n; i++)
01537           {
01538             while (k < IndCol.GetM() && IndCol(k) < i)
01539               {
01540                 IndRow(nb) = OldInd(k);
01541                 Val(nb) = OldVal(k);
01542                 nb++;
01543                 k++;
01544               }
01545 
01546             for (int j = 0; j < A.GetRowSize(i); j++)
01547               {
01548                 int irow = A.Index(i, j);
01549                 while (k < IndCol.GetM() && IndCol(k) == i
01550                        && OldInd(k) < irow)
01551                   {
01552                     IndRow(nb) = OldInd(k);
01553                     Val(nb) = OldVal(k);
01554                     nb++;
01555                     k++;
01556                   }
01557 
01558                 if (k < IndCol.GetM() && IndCol(k) == i && OldInd(k) == irow)
01559                   {
01560                     // Already existing entry.
01561                     IndRow(nb) = OldInd(k);
01562                     Val(nb) = OldVal(k);
01563                     nb++;
01564                     k++;
01565                   }
01566                 else
01567                   {
01568                     // New entry (null).
01569                     IndRow(nb) = irow;
01570                     Val(nb) = 0;
01571                     nb++;
01572                   }
01573               }
01574           }
01575       }
01576   }
01577 
01578 
01580   template<class T0, class Prop0, class Allocator0,
01581            class T1, class Prop1, class Allocator1>
01582   void Copy(const Matrix<T0, Prop0, ArrayRowSparse,Allocator0>& mat_array,
01583             Matrix<T1, Prop1, ColSparse, Allocator1>& mat_csr)
01584   {
01585     Vector<int, VectFull, CallocAlloc<int> > Ptr, IndRow;
01586     Vector<T1, VectFull, Allocator1> Val;
01587 
01588     int m = mat_array.GetM();
01589     int n = mat_array.GetN();
01590     General sym;
01591     ConvertToCSC(mat_array, sym, Ptr, IndRow, Val);
01592 
01593     mat_csr.SetData(m, n, Val, Ptr, IndRow);
01594   }
01595 
01596 
01597   template<class T, class Prop, class Alloc1,
01598            class Tint, class Alloc2, class Alloc3, class Alloc4>
01599   void ConvertToCSR(const Matrix<T, Prop, ArrayRowSymSparse, Alloc1>& A,
01600                     Symmetric& sym, Vector<Tint, VectFull, Alloc2>& IndRow,
01601                     Vector<Tint, VectFull, Alloc3>& IndCol,
01602                     Vector<T, VectFull, Alloc4>& Val)
01603   {
01604     // Number of rows and non-zero entries.
01605     int nnz = A.GetDataSize();
01606     int m = A.GetM();
01607 
01608     // Allocation of arrays for CSR format.
01609     Val.Reallocate(nnz);
01610     IndRow.Reallocate(m + 1);
01611     IndCol.Reallocate(nnz);
01612 
01613     int ind = 0;
01614     IndRow(0) = 0;
01615     for (int i = 0; i < m; i++)
01616       {
01617         for (int k = 0; k < A.GetRowSize(i); k++)
01618           {
01619             IndCol(ind) = A.Index(i, k);
01620             Val(ind) = A.Value(i, k);
01621             ind++;
01622           }
01623         IndRow(i + 1) = ind;
01624       }
01625   }
01626 
01627 
01629   template<class T0, class Prop0, class Allocator0,
01630            class T1, class Prop1, class Allocator1>
01631   void Copy(const Matrix<T0, Prop0, ArrayRowSymSparse,Allocator0>& mat_array,
01632             Matrix<T1, Prop1, RowSymSparse, Allocator1>& mat_csr)
01633   {
01634     Vector<T1, VectFull, Allocator1> Val;
01635     Vector<int, VectFull, CallocAlloc<int> > IndRow;
01636     Vector<int, VectFull, CallocAlloc<int> > IndCol;
01637 
01638     Symmetric sym;
01639     ConvertToCSR(mat_array, sym, IndRow, IndCol, Val);
01640 
01641     int m = mat_array.GetM();
01642     mat_csr.SetData(m, m, Val, IndRow, IndCol);
01643   }
01644 
01645 
01646   template<class T, class Prop, class Alloc1,
01647            class Tint, class Alloc2, class Alloc3, class Alloc4>
01648   void ConvertToCSC(const Matrix<T, Prop, ArrayRowSymSparse, Alloc1>& A,
01649                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
01650                     Vector<Tint, VectFull, Alloc3>& Ind,
01651                     Vector<T, VectFull, Alloc4>& AllVal, bool sym_pat)
01652   {
01653     int i, j;
01654 
01655     int nnz = A.GetDataSize();
01656     int n = A.GetM();
01657     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
01658     Vector<T> Val(nnz);
01659     int ind = 0;
01660     for (i = 0; i < n; i++)
01661       for (j = 0; j < A.GetRowSize(i); j++)
01662         if (A.Index(i, j) != i)
01663           {
01664             IndRow(ind) = i;
01665             IndCol(ind) = A.Index(i, j);
01666             Val(ind) = A.Value(i, j);
01667             ind++;
01668           }
01669 
01670     Sort(ind, IndCol, IndRow, Val);
01671 
01672     Ptr.Reallocate(n+1);
01673     Ind.Reallocate(nnz + ind);
01674     AllVal.Reallocate(nnz+ind);
01675     nnz = ind;
01676     ind = 0;
01677 
01678     int offset = 0; Ptr(0) = 0;
01679     for (i = 0; i < n; i++)
01680       {
01681         int first_index = ind;
01682         while (ind < nnz && IndCol(ind) <= i)
01683           ind++;
01684 
01685         int size_lower = ind - first_index;
01686         int size_upper = A.GetRowSize(i);
01687         int size_row = size_lower + size_upper;
01688 
01689         ind = first_index;
01690         for (j = 0; j < size_lower; j++)
01691           {
01692             Ind(offset+j) = IndRow(ind);
01693             AllVal(offset+j) = Val(ind);
01694             ind++;
01695           }
01696 
01697         for (j = 0; j < size_upper; j++)
01698           {
01699             Ind(offset + size_lower + j) = A.Index(i, j);
01700             AllVal(offset + size_lower + j) = A.Value(i, j);
01701           }
01702 
01703         offset += size_row; Ptr(i+1) = offset;
01704       }
01705   }
01706 
01707 
01708   template<class T0, class Prop0, class Allocator0,
01709            class T1, class Prop1, class Allocator1>
01710   void Copy(const Matrix<T0, Prop0, ArrayRowSymSparse, Allocator0>& A,
01711             Matrix<T1, Prop1, ColSparse, Allocator1>& B)
01712   {
01713     Vector<int, VectFull, CallocAlloc<int> > Ptr, Ind;
01714     Vector<T1> AllVal;
01715 
01716     int n = A.GetM();
01717     General sym;
01718     ConvertToCSC(A, sym, Ptr, Ind, AllVal);
01719 
01720     B.SetData(n, n, AllVal, Ptr, Ind);
01721   }
01722 
01723 
01725   template<class T0, class Prop0, class Allocator0,
01726            class T1, class Prop1, class Allocator1>
01727   void
01728   Copy(const Matrix<T0, Prop0, ArrayRowComplexSparse, Allocator0>& mat_array,
01729        Matrix<T1, Prop1, RowComplexSparse, Allocator1>& mat_csr)
01730   {
01731     int i, k;
01732 
01733     // Non-zero entries (real and imaginary part).
01734     int nnz_real = mat_array.GetRealDataSize();
01735     int nnz_imag = mat_array.GetImagDataSize();
01736     int m = mat_array.GetM();
01737 
01738     // Allocation of arrays for CSR.
01739     Vector<T0, VectFull, Allocator1> Val_real(nnz_real), Val_imag(nnz_imag);
01740     Vector<int, VectFull, CallocAlloc<int> > IndRow_real(m + 1);
01741     Vector<int, VectFull, CallocAlloc<int> > IndRow_imag(m + 1);
01742     Vector<int, VectFull, CallocAlloc<int> > IndCol_real(nnz_real);
01743     Vector<int, VectFull, CallocAlloc<int> > IndCol_imag(nnz_imag);
01744 
01745     int ind_real = 0, ind_imag = 0;
01746     IndRow_real(0) = 0;
01747     IndRow_imag(0) = 0;
01748     // Loop over rows.
01749     for (i = 0; i < m; i++)
01750       {
01751         for (k = 0; k < mat_array.GetRealRowSize(i); k++)
01752           {
01753             IndCol_real(ind_real) = mat_array.IndexReal(i, k);
01754             Val_real(ind_real) = mat_array.ValueReal(i, k);
01755             ind_real++;
01756           }
01757 
01758         IndRow_real(i + 1) = ind_real;
01759         for (k = 0; k < mat_array.GetImagRowSize(i); k++)
01760           {
01761             IndCol_imag(ind_imag) = mat_array.IndexImag(i, k);
01762             Val_imag(ind_imag) = mat_array.ValueImag(i, k);
01763             ind_imag++;
01764           }
01765 
01766         IndRow_imag(i + 1) = ind_imag;
01767       }
01768 
01769     mat_csr.SetData(m, m, Val_real, IndRow_real, IndCol_real,
01770                     Val_imag, IndRow_imag, IndCol_imag);
01771   }
01772 
01773 
01775   template<class T0, class Prop0, class Allocator0,
01776            class T1, class Prop1, class Allocator1>
01777   void
01778   Copy(const Matrix<T0, Prop0,
01779        ArrayRowSymComplexSparse, Allocator0>& mat_array,
01780        Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>& mat_csr)
01781   {
01782     int i, k;
01783 
01784     // Non-zero entries (real and imaginary part).
01785     int nnz_real = mat_array.GetRealDataSize();
01786     int nnz_imag = mat_array.GetImagDataSize();
01787     int m = mat_array.GetM();
01788 
01789     // Allocation of arrays for CSR.
01790     Vector<T0, VectFull, Allocator1> Val_real(nnz_real), Val_imag(nnz_imag);
01791     Vector<int, VectFull, CallocAlloc<int> > IndRow_real(m + 1);
01792     Vector<int, VectFull, CallocAlloc<int> > IndRow_imag(m + 1);
01793     Vector<int, VectFull, CallocAlloc<int> > IndCol_real(nnz_real);
01794     Vector<int, VectFull, CallocAlloc<int> > IndCol_imag(nnz_imag);
01795 
01796     int ind_real = 0, ind_imag = 0;
01797     IndRow_real(0) = 0;
01798     IndRow_imag(0) = 0;
01799     // Loop over rows.
01800     for (i = 0; i < m; i++)
01801       {
01802         for (k = 0; k < mat_array.GetRealRowSize(i); k++)
01803           {
01804             IndCol_real(ind_real) = mat_array.IndexReal(i, k);
01805             Val_real(ind_real) = mat_array.ValueReal(i, k);
01806             ind_real++;
01807           }
01808 
01809         IndRow_real(i + 1) = ind_real;
01810         for (int k = 0; k < mat_array.GetImagRowSize(i); k++)
01811           {
01812             IndCol_imag(ind_imag) = mat_array.IndexImag(i, k);
01813             Val_imag(ind_imag) = mat_array.ValueImag(i, k);
01814             ind_imag++;
01815           }
01816 
01817         IndRow_imag(i + 1) = ind_imag;
01818       }
01819 
01820     mat_csr.SetData(m, m, Val_real, IndRow_real, IndCol_real,
01821                     Val_imag, IndRow_imag, IndCol_imag);
01822   }
01823 
01824 
01825   template<class T0, class Prop0, class Allocator0,
01826            class T1, class Prop1, class Allocator1>
01827   void Copy(const Matrix<T0, Prop0, ArrayRowSymSparse, Allocator0>& A,
01828             Matrix<T1, Prop1, ArrayRowSparse, Allocator1>& B)
01829   {
01830     int i, j;
01831 
01832     int nnz = A.GetDataSize();
01833     int n = A.GetM();
01834     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz),IndCol(nnz);
01835     Vector<T1, VectFull, Allocator1> Val(nnz);
01836     int ind = 0;
01837     for (i = 0; i < n; i++)
01838       for (j = 0; j < A.GetRowSize(i); j++)
01839         if (A.Index(i, j) != i)
01840           {
01841             IndRow(ind) = i;
01842             IndCol(ind) = A.Index(i, j);
01843             Val(ind) = A.Value(i, j);
01844             ind++;
01845           }
01846     Sort(ind, IndCol, IndRow, Val);
01847     nnz = ind;
01848     ind = 0;
01849 
01850     B.Reallocate(n, n);
01851     for (i = 0; i < n; i++)
01852       {
01853         int first_index = ind;
01854         while (ind < nnz && IndCol(ind) <= i)
01855           ind++;
01856         int size_lower = ind - first_index;
01857         int size_upper = A.GetRowSize(i);
01858         int size_row = size_lower + size_upper;
01859         B.ResizeRow(i, size_row);
01860         ind = first_index;
01861         for (j = 0; j < size_lower; j++)
01862           {
01863             B.Index(i, j) = IndRow(ind);
01864             B.Value(i, j) = Val(ind);
01865             ind++;
01866           }
01867         for (j = 0; j < size_upper; j++)
01868           {
01869             B.Index(i, size_lower + j) = A.Index(i, j);
01870             B.Value(i, size_lower + j) = A.Value(i, j);
01871           }
01872         B.AssembleRow(i);
01873       }
01874   }
01875 
01876 
01877   template<class T0, class Prop0, class Allocator0,
01878            class T1, class Prop1, class Allocator1>
01879   void Copy(const Matrix<T0, Prop0, ArrayRowSymSparse, Allocator0>& A,
01880             Matrix<T1, Prop1, ArrayColSparse, Allocator1>& B)
01881   {
01882     int i, j;
01883 
01884     int nnz = A.GetDataSize();
01885     int n = A.GetM();
01886     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
01887     Vector<T1> Val(nnz);
01888     int ind = 0;
01889     for (i = 0; i < n; i++)
01890       for (j = 0; j < A.GetRowSize(i); j++)
01891         if (A.Index(i, j) != i)
01892           {
01893             IndRow(ind) = i;
01894             IndCol(ind) = A.Index(i, j);
01895             Val(ind) = A.Value(i, j);
01896             ind++;
01897           }
01898     Sort(ind, IndCol, IndRow, Val);
01899     nnz = ind;
01900     ind = 0;
01901 
01902     B.Reallocate(n, n);
01903     for (i = 0; i < n; i++)
01904       {
01905         int first_index = ind;
01906         while (ind < nnz && IndCol(ind) <= i)
01907           ind++;
01908         int size_lower = ind - first_index;
01909         int size_upper = A.GetRowSize(i);
01910         int size_row = size_lower + size_upper;
01911         B.ResizeColumn(i, size_row);
01912         ind = first_index;
01913         for (j = 0; j < size_lower; j++)
01914           {
01915             B.Index(i, j) = IndRow(ind);
01916             B.Value(i, j) = Val(ind);
01917             ind++;
01918           }
01919         for (j = 0; j < size_upper; j++)
01920           {
01921             B.Index(i, size_lower + j) = A.Index(i, j);
01922             B.Value(i, size_lower + j) = A.Value(i, j);
01923           }
01924         B.AssembleColumn(i);
01925       }
01926   }
01927 
01928 
01929   template<class T, class Prop, class Alloc1,
01930            class Tint, class Alloc2, class Alloc3, class Alloc4>
01931   void ConvertToCSC(const Matrix<T, Prop, ArrayColSparse, Alloc1>& A,
01932                     General& sym, Vector<Tint, VectFull, Alloc2>& IndCol,
01933                     Vector<Tint, VectFull, Alloc3>& IndRow,
01934                     Vector<T, VectFull, Alloc4>& Val, bool sym_pat)
01935   {
01936     if (sym_pat)
01937       throw WrongArgument("ConvertToCSC(Matrix<ArrayColSparse>, ...)",
01938                           "Option 'sym_pat' is not supported.");
01939 
01940     int i, k;
01941 
01942     // Matrix (m,n) with 'nnz' entries.
01943     int nnz = A.GetDataSize();
01944     int m = A.GetM();
01945     int n = A.GetN();
01946 
01947     // Allocating arrays needed for CSC format.
01948     Val.Reallocate(nnz);
01949     IndRow.Reallocate(nnz);
01950     IndCol.Reallocate(n+1);
01951 
01952     // Filling the arrays.
01953     int ind = 0;
01954     IndCol(0) = 0;
01955     for (i = 0; i < n; i++)
01956       {
01957         for (k = 0; k < A.GetColumnSize(i); k++)
01958           {
01959             IndRow(ind) = A.Index(i, k);
01960             Val(ind) = A.Value(i, k);
01961             ind++;
01962           }
01963 
01964         IndCol(i + 1) = ind;
01965       }
01966   }
01967 
01968 
01970   template<class T0, class Prop0, class Allocator0,
01971            class T1, class Prop1, class Allocator1>
01972   void Copy(const Matrix<T0, Prop0, ArrayColSparse, Allocator0>& mat_array,
01973             Matrix<T1, Prop1, ColSparse, Allocator1>& mat_csc)
01974   {
01975     Vector<T1, VectFull, Allocator1> Val;
01976     Vector<int, VectFull, CallocAlloc<int> > IndRow;
01977     Vector<int, VectFull, CallocAlloc<int> > IndCol;
01978 
01979     General sym;
01980     ConvertToCSC(mat_array, sym, IndCol, IndRow, Val);
01981 
01982     int m = mat_array.GetM();
01983     int n = mat_array.GetN();
01984 
01985     mat_csc.SetData(m, n, Val, IndCol, IndRow);
01986   }
01987 
01988 
01990   template<class T0, class Prop0, class Allocator0,
01991            class T1, class Prop1, class Allocator1>
01992   void Copy(const Matrix<T0, Prop0, ArrayRowSparse,Allocator0>& A,
01993             Matrix<T1, Prop1, ArrayColSparse, Allocator1>& B)
01994   {
01995     int i;
01996 
01997     // Matrix (m,n) with nnz entries.
01998     int nnz = A.GetDataSize();
01999     int n = A.GetN();
02000 
02001     // Conversion in coordinate format.
02002     Vector<T1> Val;
02003     Vector<int, VectFull, CallocAlloc<int> > IndRow, IndCol;
02004     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Val);
02005 
02006     // Sorting with respect to column numbers.
02007     Sort(IndCol, IndRow, Val);
02008 
02009     // Constructing pointer array 'Ptr'.
02010     Vector<int, VectFull, CallocAlloc<int> > Ptr(n + 1);
02011 
02012     // Counting non-zero entries per column.
02013     for (i = 0; i < nnz; i++)
02014       Ptr(IndCol(i) + 1)++;
02015 
02016     // Accumulation to get pointer array.
02017     Ptr(0) = 0;
02018     for (i = 0; i < n; i++)
02019       Ptr(i + 1) += Ptr(i);
02020 
02021     // we fill matrix B
02022     for (int i = 0; i < n; i++)
02023       {
02024         int size_col = Ptr(i+1) - Ptr(i);
02025         if (size_col > 0)
02026           {
02027             B.ReallocateColumn(i, size_col);
02028             for (int j = Ptr(i); j < Ptr(i+1); j++)
02029               {
02030                 B.Index(i, j-Ptr(i)) = IndRow(j);
02031                 B.Value(i, j-Ptr(i)) = Val(j);
02032               }
02033           }
02034       }
02035   }
02036 
02037 
02038   /***********************
02039    * GetSymmetricPattern *
02040    ***********************/
02041 
02042 
02043   template<class T, class Prop, class Storage, class Allocator,
02044            class Tint, class Allocator2, class Allocator3>
02045   void GetSymmetricPattern(const Matrix<T, Prop, Storage, Allocator>& A,
02046                            Vector<Tint, VectFull, Allocator2>& Ptr,
02047                            Vector<Tint, VectFull, Allocator3>& Ind)
02048   {
02049     int n = A.GetM();
02050 
02051     // Converting to coordinates.
02052     Vector<int, VectFull, CallocAlloc<int> > IndRow, IndCol;
02053     Vector<T> Value;
02054     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Value);
02055 
02056     // clearing values
02057     Value.Clear();
02058 
02059     // Sorting columns too.
02060     Vector<int, VectFull, CallocAlloc<int> > IndRow2, IndCol2, Index(n);
02061     IndRow2 = IndRow;
02062     IndCol2 = IndCol;
02063     Sort(IndCol2.GetM(), IndCol2, IndRow2);
02064 
02065     Tint max_nnz = 0;
02066     for (int i = 0; i < IndRow.GetM(); i++)
02067       if (IndRow(i) <= IndCol(i))
02068         max_nnz++;
02069 
02070     for (int i = 0; i < IndRow.GetM(); i++)
02071       if (IndCol2(i) <= IndRow2(i))
02072         max_nnz++;
02073 
02074     // then symmetrization of pattern and conversion to csr.
02075     Ptr.Reallocate(n+1);
02076     Ind.Reallocate(max_nnz);
02077     Tint j_begin = 0, j_end = 0, size_row = 0;
02078     Tint j2_begin = 0, j2_end = 0;
02079     Ptr(0) = 0;
02080     for (int i = 0; i < A.GetM(); i++)
02081       {
02082         j_begin = j_end;
02083         size_row = 0;
02084         // We retrieve column numbers.
02085         while ( (j_end < IndRow.GetM()) && (IndRow(j_end) == i))
02086           {
02087             if (IndRow(j_end) <= IndCol(j_end))
02088               {
02089                 Index(size_row) = IndCol(j_end);
02090                 size_row++;
02091               }
02092 
02093             j_end++;
02094           }
02095 
02096         j2_begin = j2_end;
02097         while ( (j2_end < IndCol2.GetM()) && (IndCol2(j2_end) == i))
02098           {
02099             if (IndCol2(j2_end) <= IndRow2(j2_end))
02100               {
02101                 Index(size_row) = IndRow2(j2_end);
02102                 size_row++;
02103               }
02104 
02105             j2_end++;
02106           }
02107 
02108         // Sorting indexes.
02109         Assemble(size_row, Index);
02110 
02111         // Updating Ptr, Ind.
02112         for (int j = 0; j < size_row; j++)
02113           Ind(Ptr(i) + j) = Index(j);
02114 
02115         Ptr(i+1) = Ptr(i) + size_row;
02116       }
02117 
02118     IndRow2.Clear(); IndCol2.Clear();
02119     IndRow.Clear(); IndCol.Clear();
02120     Ind.Resize(Ptr(n));
02121   }
02122 
02123 
02124   template<class T, class Prop, class Storage, class Allocator, class AllocI>
02125   void GetSymmetricPattern(const Matrix<T, Prop, Storage, Allocator>& A,
02126                            Matrix<int, Symmetric, RowSymSparse, AllocI>& B)
02127   {
02128     Vector<int, VectFull, CallocAlloc<int> > Ptr, Ind;
02129 
02130     GetSymmetricPattern(A, Ptr, Ind);
02131 
02132     int n = A.GetM();
02133     Vector<int, VectFull, CallocAlloc<int> > Val(Ptr(n));
02134     // We put Ptr and Ind into the matrix B.
02135     B.SetData(n, n, Val, Ptr, Ind);
02136   }
02137 
02138 
02139 } // namespace Seldon.
02140 
02141 #define SELDON_FILE_MATRIX_CONVERSIONS_CXX
02142 #endif