Warning: this documentation for the development version is under construction.

/home/vivien/public_html/.src_seldon/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     sym = true => the upper part and lower part are both generated
00033   */
00034 
00035 
00037   template<class T, class Prop, class Allocator1, class Allocator2,
00038            class Tint, class Allocator3, class Allocator4>
00039   void
00040   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, RowSparse,
00041                                Allocator1>& A,
00042                                Vector<Tint, VectFull, Allocator2>& IndRow,
00043                                Vector<Tint, VectFull, Allocator3>& IndCol,
00044                                Vector<T, VectFull, Allocator4>& Val,
00045                                int index, bool sym)
00046   {
00047     int i, j;
00048     int m = A.GetM();
00049     int nnz = A.GetDataSize();
00050     IndRow.Reallocate(nnz);
00051     IndCol.Reallocate(nnz);
00052     Val.Reallocate(nnz);
00053     int* ptr = A.GetPtr();
00054     int* ind = A.GetInd();
00055     T* val = A.GetData();
00056     for (i = 0; i < m; i++)
00057       for (j = ptr[i]; j< ptr[i+1]; j++)
00058         {
00059           IndRow(j) = i + index;
00060           IndCol(j) = ind[j] + index;
00061           Val(j) = val[j];
00062         }
00063   }
00064 
00065 
00067   template<class T, class Prop, class Allocator1, class Allocator2,
00068            class Tint, class Allocator3, class Allocator4>
00069   void
00070   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ColSparse,
00071                                Allocator1>& A,
00072                                Vector<Tint, VectFull, Allocator2>& IndRow,
00073                                Vector<Tint, VectFull, Allocator3>& IndCol,
00074                                Vector<T, VectFull, Allocator4>& Val,
00075                                int index, bool sym)
00076   {
00077     int i, j;
00078     int n = A.GetN();
00079     int nnz = A.GetDataSize();
00080     IndCol.Reallocate(nnz);
00081     IndRow.Reallocate(nnz);
00082     Val.Reallocate(nnz);
00083     int* ptr = A.GetPtr();
00084     int* ind = A.GetInd();
00085     T* val = A.GetData();
00086     for (i = 0; i < n; i++)
00087       for (j = ptr[i]; j< ptr[i+1]; j++)
00088         {
00089           IndCol(j) = i + index;
00090           IndRow(j) = ind[j] + index;
00091           Val(j) = val[j];
00092         }
00093   }
00094 
00095 
00097   template<class T, class Prop, class Allocator1, class Allocator2,
00098            class Tint, class Allocator3, class Allocator4>
00099   void
00100   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, RowSymSparse,
00101                                Allocator1>& A,
00102                                Vector<Tint, VectFull, Allocator2>& IndRow,
00103                                Vector<Tint, VectFull, Allocator3>& IndCol,
00104                                Vector<T, VectFull, Allocator4>& Val,
00105                                int index, bool sym)
00106   {
00107     int i, j;
00108     int m = A.GetM();
00109     int nnz = A.GetDataSize();
00110     int* ptr = A.GetPtr();
00111     int* ind = A.GetInd();
00112     T* val = A.GetData();
00113     if (sym)
00114       {
00115         nnz *= 2;
00116         for (i = 0; i < m; i++)
00117           if (ind[ptr[i]] == i)
00118             nnz--;
00119 
00120         IndRow.Reallocate(nnz);
00121         IndCol.Reallocate(nnz);
00122         Val.Reallocate(nnz);
00123         Vector<int> Ptr(m);
00124         Ptr.Zero();
00125         int nb = 0;
00126         for (i = 0; i < m; i++)
00127           for (j = ptr[i]; j < ptr[i + 1]; j++)
00128             {
00129               IndRow(nb) = i + index;
00130               IndCol(nb) = ind[j] + index;
00131               Val(nb) = val[j];
00132               Ptr(ind[j])++;
00133               nb++;
00134 
00135               if (ind[j] != i)
00136                 {
00137                   IndRow(nb) = ind[j] + index;
00138                   IndCol(nb) = i + index;
00139                   Val(nb) = val[j];
00140                   Ptr(i)++;
00141                   nb++;
00142                 }
00143             }
00144 
00145         // Sorting the row numbers...
00146         Sort(IndRow, IndCol, Val);
00147 
00148         // ... and the column numbers.
00149         int offset = 0;
00150         for (i = 0; i < m; i++)
00151           {
00152             Sort(offset, offset + Ptr(i) - 1, IndCol, Val);
00153             offset += Ptr(i);
00154           }
00155 
00156       }
00157     else
00158       {
00159         IndRow.Reallocate(nnz);
00160         IndCol.Reallocate(nnz);
00161         Val.Reallocate(nnz);
00162         for (i = 0; i < m; i++)
00163           for (j = ptr[i]; j< ptr[i + 1]; j++)
00164             {
00165               IndRow(j) = i + index;
00166               IndCol(j) = ind[j] + index;
00167               Val(j) = val[j];
00168             }
00169       }
00170   }
00171 
00172 
00174   template<class T, class Prop, class Allocator1, class Allocator2,
00175            class Tint, class Allocator3, class Allocator4>
00176   void
00177   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ColSymSparse,
00178                                Allocator1>& A,
00179                                Vector<Tint, VectFull, Allocator2>& IndRow,
00180                                Vector<Tint, VectFull, Allocator3>& IndCol,
00181                                Vector<T, VectFull, Allocator4>& Val,
00182                                int index, bool sym)
00183   {
00184     int i, j;
00185     int m = A.GetM();
00186     int nnz = A.GetDataSize();
00187     int* ptr = A.GetPtr();
00188     int* ind = A.GetInd();
00189     T* val = A.GetData();
00190     if (sym)
00191       {
00192         nnz *= 2;
00193         for (i = 0; i < m; i++)
00194           for (j = ptr[i]; j < ptr[i + 1]; j++)
00195             if (ind[j] == i)
00196               nnz--;
00197 
00198         IndRow.Reallocate(nnz);
00199         IndCol.Reallocate(nnz);
00200         Val.Reallocate(nnz);
00201         Vector<int> Ptr(m);
00202         Ptr.Zero();
00203         int nb = 0;
00204         for (i = 0; i < m; i++)
00205           for (j = ptr[i]; j < ptr[i + 1]; j++)
00206             {
00207               IndRow(nb) = i + index;
00208               IndCol(nb) = ind[j] + index;
00209               Val(nb) = val[j];
00210               Ptr(ind[j])++;
00211               nb++;
00212 
00213               if (ind[j] != i)
00214                 {
00215                   IndRow(nb) = ind[j] + index;
00216                   IndCol(nb) = i + index;
00217                   Val(nb) = val[j];
00218                   Ptr(i)++;
00219                   nb++;
00220                 }
00221             }
00222 
00223         // Sorting the row numbers...
00224         Sort(IndRow, IndCol, Val);
00225 
00226         // ...and the column numbers.
00227         int offset = 0;
00228         for (i = 0; i < m; i++)
00229           {
00230             Sort(offset, offset + Ptr(i) - 1, IndCol, Val);
00231             offset += Ptr(i);
00232           }
00233 
00234       }
00235     else
00236       {
00237         IndRow.Reallocate(nnz);
00238         IndCol.Reallocate(nnz);
00239         Val.Reallocate(nnz);
00240         for (i = 0; i < m; i++)
00241           for (j = ptr[i]; j< ptr[i + 1]; j++)
00242             {
00243               IndRow(j) = i + index;
00244               IndCol(j) = ind[j] + index;
00245               Val(j) = val[j];
00246             }
00247       }
00248   }
00249 
00250 
00252   template<class T, class Prop, class Allocator1, class Allocator2,
00253            class Tint, class Allocator3, class Allocator4>
00254   void
00255   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, RowComplexSparse,
00256                                Allocator1>& A,
00257                                Vector<Tint, VectFull, Allocator2>& IndRow,
00258                                Vector<Tint, VectFull, Allocator3>& IndCol,
00259                                Vector<complex<T>, VectFull, Allocator4>& Val,
00260                                int index, bool sym)
00261   {
00262     int m = A.GetM();
00263     int nnz = A.GetRealDataSize() + A.GetImagDataSize();
00264     // Allocating arrays.
00265     IndRow.Reallocate(nnz);
00266     IndCol.Reallocate(nnz);
00267     Val.Reallocate(nnz);
00268     nnz = 0;
00269     int* real_ptr = A.GetRealPtr();
00270     int* imag_ptr = A.GetImagPtr();
00271     int* real_ind = A.GetRealInd();
00272     int* imag_ind = A.GetImagInd();
00273     T* real_data = A.GetRealData();
00274     T* imag_data = A.GetImagData();
00275     IVect col; Vector<complex<T> > value;
00276     for (int i = 0; i < m; i++)
00277       {
00278         int nb_r = real_ptr[i+1] - real_ptr[i];
00279         int nb_i = imag_ptr[i+1] - imag_ptr[i];
00280         int size_row = nb_r + nb_i;
00281         if (size_row > col.GetM())
00282           {
00283             col.Reallocate(size_row);
00284             value.Reallocate(size_row);
00285           }
00286 
00287         int nb = 0;
00288         for (int j = real_ptr[i]; j < real_ptr[i+1]; j++)
00289           {
00290             col(nb) = real_ind[j] + index;
00291             value(nb) = complex<T>(real_data[j], 0);
00292             nb++;
00293           }
00294 
00295         for (int j = imag_ptr[i]; j < imag_ptr[i+1]; j++)
00296           {
00297             col(nb) = imag_ind[j] + index;
00298             value(nb) = complex<T>(0, imag_data[j]);
00299             nb++;
00300           }
00301 
00302         Assemble(nb, col, value);
00303         for (int j = 0; j < nb; j++)
00304           {
00305             IndRow(nnz + j) = index + i;
00306             IndCol(nnz + j) = col(j);
00307             Val(nnz + j) = value(j);
00308           }
00309 
00310         nnz += nb;
00311       }
00312 
00313     IndRow.Resize(nnz);
00314     IndCol.Resize(nnz);
00315     Val.Resize(nnz);
00316   }
00317 
00318 
00320   template<class T, class Prop, class Allocator1, class Allocator2,
00321            class Tint, class Allocator3, class Allocator4>
00322   void
00323   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ColComplexSparse,
00324                                Allocator1>& A,
00325                                Vector<Tint, VectFull, Allocator2>& IndRow,
00326                                Vector<Tint, VectFull, Allocator3>& IndCol,
00327                                Vector<complex<T>, VectFull, Allocator4>& Val,
00328                                int index, bool sym)
00329   {
00330     int n = A.GetN();
00331     int nnz = A.GetRealDataSize() + A.GetImagDataSize();
00332     // Allocating arrays.
00333     IndRow.Reallocate(nnz);
00334     IndCol.Reallocate(nnz);
00335     Val.Reallocate(nnz);
00336     nnz = 0;
00337     int* real_ptr = A.GetRealPtr();
00338     int* imag_ptr = A.GetImagPtr();
00339     int* real_ind = A.GetRealInd();
00340     int* imag_ind = A.GetImagInd();
00341     T* real_data = A.GetRealData();
00342     T* imag_data = A.GetImagData();
00343     IVect col; Vector<complex<T> > value;
00344     for (int i = 0; i < n; i++)
00345       {
00346         int nb_r = real_ptr[i+1] - real_ptr[i];
00347         int nb_i = imag_ptr[i+1] - imag_ptr[i];
00348         int size_col = nb_r + nb_i;
00349         if (size_col > col.GetM())
00350           {
00351             col.Reallocate(size_col);
00352             value.Reallocate(size_col);
00353           }
00354 
00355         int nb = 0;
00356         for (int j = real_ptr[i]; j < real_ptr[i+1]; j++)
00357           {
00358             col(nb) = real_ind[j] + index;
00359             value(nb) = complex<T>(real_data[j], 0);
00360             nb++;
00361           }
00362 
00363         for (int j = imag_ptr[i]; j < imag_ptr[i+1]; j++)
00364           {
00365             col(nb) = imag_ind[j] + index;
00366             value(nb) = complex<T>(0, imag_data[j]);
00367             nb++;
00368           }
00369 
00370         Assemble(nb, col, value);
00371         for (int j = 0; j < nb; j++)
00372           {
00373             IndRow(nnz + j) = col(j);
00374             IndCol(nnz + j) = index + i;
00375             Val(nnz + j) = value(j);
00376           }
00377 
00378         nnz += nb;
00379       }
00380 
00381     IndRow.Resize(nnz);
00382     IndCol.Resize(nnz);
00383     Val.Resize(nnz);
00384   }
00385 
00386 
00388   template<class T, class Prop, class Allocator1, class Allocator2,
00389            class Tint, class Allocator3, class Allocator4>
00390   void
00391   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, RowSymComplexSparse,
00392                                Allocator1>& A,
00393                                Vector<Tint, VectFull, Allocator2>& IndRow,
00394                                Vector<Tint, VectFull, Allocator3>& IndCol,
00395                                Vector<complex<T>, VectFull, Allocator4>& Val,
00396                                int index, bool sym)
00397   {
00398     int m = A.GetM();
00399     int nnz = A.GetDataSize();
00400     int* real_ptr = A.GetRealPtr();
00401     int* imag_ptr = A.GetImagPtr();
00402     int* real_ind = A.GetRealInd();
00403     int* imag_ind = A.GetImagInd();
00404     T* real_data = A.GetRealData();
00405     T* imag_data = A.GetImagData();
00406 
00407     if (sym)
00408       {
00409         nnz *= 2;
00410         IndRow.Reallocate(nnz);
00411         IndCol.Reallocate(nnz);
00412         Val.Reallocate(nnz);
00413         Vector<int> Ptr(m);
00414         Ptr.Zero();
00415         nnz = 0;
00416         IVect col; Vector<complex<T> > value;
00417         for (int i = 0; i < m; i++)
00418           {
00419             int nb_r = real_ptr[i+1] - real_ptr[i];
00420             int nb_i = imag_ptr[i+1] - imag_ptr[i];
00421             int size_row = nb_r + nb_i;
00422             if (size_row > col.GetM())
00423               {
00424                 col.Reallocate(size_row);
00425                 value.Reallocate(size_row);
00426               }
00427 
00428             int nb = 0;
00429             for (int j = real_ptr[i]; j < real_ptr[i+1]; j++)
00430               {
00431                 col(nb) = real_ind[j];
00432                 value(nb) = complex<T>(real_data[j], 0);
00433                 nb++;
00434               }
00435 
00436             for (int j = imag_ptr[i]; j < imag_ptr[i+1]; j++)
00437               {
00438                 col(nb) = imag_ind[j];
00439                 value(nb) = complex<T>(0, imag_data[j]);
00440                 nb++;
00441               }
00442 
00443             Assemble(nb, col, value);
00444             for (int j = 0; j < nb; j++)
00445               {
00446                 IndRow(nnz) = i + index;
00447                 IndCol(nnz) = col(j) + index;
00448                 Val(nnz) = value(j);
00449                 Ptr(i)++;
00450                 nnz++;
00451 
00452                 if (col(j) != i)
00453                   {
00454                     IndRow(nnz) = col(j) + index;
00455                     IndCol(nnz) = i + index;
00456                     Val(nnz) = value(j);
00457                     Ptr(col(j))++;
00458                     nnz++;
00459                   }
00460               }
00461           }
00462 
00463         IndRow.Resize(nnz);
00464         IndCol.Resize(nnz);
00465         Val.Resize(nnz);
00466 
00467         // Sorting the row numbers...
00468         Sort(IndRow, IndCol, Val);
00469 
00470         // ...and the column numbers.
00471         int offset = 0;
00472         for (int i = 0; i < m; i++)
00473           {
00474             Sort(offset, offset + Ptr(i) - 1, IndCol, Val);
00475             offset += Ptr(i);
00476           }
00477       }
00478     else
00479       {
00480         // Allocating arrays.
00481         IndRow.Reallocate(nnz);
00482         IndCol.Reallocate(nnz);
00483         Val.Reallocate(nnz);
00484         nnz = 0;
00485         IVect col; Vector<complex<T> > value;
00486         for (int i = 0; i < m; i++)
00487           {
00488             int nb_r = real_ptr[i+1] - real_ptr[i];
00489             int nb_i = imag_ptr[i+1] - imag_ptr[i];
00490             int size_row = nb_r + nb_i;
00491             if (size_row > col.GetM())
00492               {
00493                 col.Reallocate(size_row);
00494                 value.Reallocate(size_row);
00495               }
00496 
00497             int nb = 0;
00498             for (int j = real_ptr[i]; j < real_ptr[i+1]; j++)
00499               {
00500                 col(nb) = real_ind[j] + index;
00501                 value(nb) = complex<T>(real_data[j], 0);
00502                 nb++;
00503               }
00504 
00505             for (int j = real_ptr[i]; j < real_ptr[i+1]; j++)
00506               {
00507                 col(nb) = imag_ind[j] + index;
00508                 value(nb) = complex<T>(0, imag_ind[j]);
00509                 nb++;
00510               }
00511 
00512             Assemble(nb, col, value);
00513             for (int j = 0; j < nb; j++)
00514               {
00515                 IndRow(nnz + j) = index + i;
00516                 IndCol(nnz + j) = col(j);
00517                 Val(nnz + j) = value(j);
00518               }
00519 
00520             nnz += nb;
00521           }
00522 
00523         IndRow.Resize(nnz);
00524         IndCol.Resize(nnz);
00525         Val.Resize(nnz);
00526       }
00527   }
00528 
00529 
00531   template<class T, class Prop, class Allocator1, class Allocator2,
00532            class Tint, class Allocator3, class Allocator4>
00533   void
00534   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ColSymComplexSparse,
00535                                Allocator1>& A,
00536                                Vector<Tint, VectFull, Allocator2>& IndRow,
00537                                Vector<Tint, VectFull, Allocator3>& IndCol,
00538                                Vector<complex<T>, VectFull, Allocator4>& Val,
00539                                int index, bool sym)
00540   {
00541     int m = A.GetM();
00542     int nnz = A.GetDataSize();
00543     int* real_ptr = A.GetRealPtr();
00544     int* imag_ptr = A.GetImagPtr();
00545     int* real_ind = A.GetRealInd();
00546     int* imag_ind = A.GetImagInd();
00547     T* real_data = A.GetRealData();
00548     T* imag_data = A.GetImagData();
00549 
00550     if (sym)
00551       {
00552         nnz *= 2;
00553         IndRow.Reallocate(nnz);
00554         IndCol.Reallocate(nnz);
00555         Val.Reallocate(nnz);
00556         Vector<int> Ptr(m);
00557         Ptr.Zero();
00558         nnz = 0;
00559         IVect row; Vector<complex<T> > value;
00560         for (int i = 0; i < m; i++)
00561           {
00562             int nb_r = real_ptr[i+1] - real_ptr[i];
00563             int nb_i = imag_ptr[i+1] - imag_ptr[i];
00564             int size_col = nb_r + nb_i;
00565             if (size_col > row.GetM())
00566               {
00567                 row.Reallocate(size_col);
00568                 value.Reallocate(size_col);
00569               }
00570 
00571             int nb = 0;
00572             for (int j = real_ptr[i]; j < real_ptr[i+1]; j++)
00573               {
00574                 row(nb) = real_ind[j];
00575                 value(nb) = complex<T>(real_data[j], 0);
00576                 nb++;
00577               }
00578 
00579             for (int j = imag_ptr[i]; j < imag_ptr[i+1]; j++)
00580               {
00581                 row(nb) = imag_ind[j];
00582                 value(nb) = complex<T>(0, imag_data[j]);
00583                 nb++;
00584               }
00585 
00586             Assemble(nb, row, value);
00587             for (int j = 0; j < nb; j++)
00588               {
00589                 IndRow(nnz) = i + index;
00590                 IndCol(nnz) = row(j) + index;
00591                 Val(nnz) = value(j);
00592                 Ptr(i)++;
00593                 nnz++;
00594 
00595                 if (row(j) != i)
00596                   {
00597                     IndRow(nnz) = row(j) + index;
00598                     IndCol(nnz) = i + index;
00599                     Val(nnz) = value(j);
00600                     Ptr(row(j))++;
00601                     nnz++;
00602                   }
00603               }
00604           }
00605 
00606         IndRow.Resize(nnz);
00607         IndCol.Resize(nnz);
00608         Val.Resize(nnz);
00609 
00610         // Sorting the column numbers...
00611         Sort(IndCol, IndRow, Val);
00612 
00613         // ...and the row numbers.
00614         int offset = 0;
00615         for (int i = 0; i < m; i++)
00616           {
00617             Sort(offset, offset + Ptr(i) - 1, IndRow, Val);
00618             offset += Ptr(i);
00619           }
00620       }
00621     else
00622       {
00623         // Allocating arrays.
00624         IndRow.Reallocate(nnz);
00625         IndCol.Reallocate(nnz);
00626         Val.Reallocate(nnz);
00627         nnz = 0;
00628         IVect row; Vector<complex<T> > value;
00629         for (int i = 0; i < m; i++)
00630           {
00631             int nb_r = real_ptr[i+1] - real_ptr[i];
00632             int nb_i = imag_ptr[i+1] - imag_ptr[i];
00633             int size_col = nb_r + nb_i;
00634             if (size_col > row.GetM())
00635               {
00636                 row.Reallocate(size_col);
00637                 value.Reallocate(size_col);
00638               }
00639 
00640             int nb = 0;
00641             for (int j = real_ptr[i]; j < real_ptr[i+1]; j++)
00642               {
00643                 row(nb) = real_ind[j] + index;
00644                 value(nb) = complex<T>(real_data[j], 0);
00645                 nb++;
00646               }
00647 
00648             for (int j = imag_ptr[i]; j < imag_ptr[i+1]; j++)
00649               {
00650                 row(nb) = imag_ind[j] + index;
00651                 value(nb) = complex<T>(0, imag_data[j]);
00652                 nb++;
00653               }
00654 
00655             Assemble(nb, row, value);
00656             for (int j = 0; j < nb; j++)
00657               {
00658                 IndCol(nnz + j) = index + i;
00659                 IndRow(nnz + j) = row(j);
00660                 Val(nnz + j) = value(j);
00661               }
00662 
00663             nnz += nb;
00664           }
00665 
00666         IndRow.Resize(nnz);
00667         IndCol.Resize(nnz);
00668         Val.Resize(nnz);
00669       }
00670   }
00671 
00672 
00673   /*
00674     From Sparse Array formats to "Matlab" coordinate format.
00675   */
00676 
00677 
00679   template<class T, class Prop, class Allocator1, class Allocator2,
00680            class Tint, class Allocator3, class Allocator4>
00681   void
00682   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayRowSparse,
00683                                Allocator1>& A,
00684                                Vector<Tint, VectFull, Allocator2>& IndRow,
00685                                Vector<Tint, VectFull, Allocator3>& IndCol,
00686                                Vector<T, VectFull, Allocator4>& Val,
00687                                int index, bool sym)
00688   {
00689     int i, j;
00690     int m = A.GetM();
00691     int nnz = A.GetDataSize();
00692     // Allocating arrays.
00693     IndRow.Reallocate(nnz);
00694     IndCol.Reallocate(nnz);
00695     Val.Reallocate(nnz);
00696     int nb = 0;
00697     for (i = 0; i < m; i++)
00698       for (j = 0; j < A.GetRowSize(i); j++)
00699         {
00700           IndRow(nb) = i + index;
00701           IndCol(nb) = A.Index(i, j) + index;
00702           Val(nb) = A.Value(i, j);
00703           nb++;
00704         }
00705   }
00706 
00707 
00709   template<class T, class Prop, class Allocator1, class Allocator2,
00710            class Tint, class Allocator3, class Allocator4>
00711   void
00712   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayColSparse,
00713                                Allocator1>& A,
00714                                Vector<Tint, VectFull, Allocator2>& IndRow,
00715                                Vector<Tint, VectFull, Allocator3>& IndCol,
00716                                Vector<T, VectFull, Allocator4>& Val,
00717                                int index, bool sym)
00718   {
00719     int i, j;
00720     int n = A.GetN();
00721     int nnz = A.GetDataSize();
00722     // Allocating arrays.
00723     IndRow.Reallocate(nnz);
00724     IndCol.Reallocate(nnz);
00725     Val.Reallocate(nnz);
00726     int nb = 0;
00727     for (i = 0; i < n; i++)
00728       for (j = 0; j < A.GetColumnSize(i); j++)
00729         {
00730           IndRow(nb) = A.Index(i, j) + index;
00731           IndCol(nb) = i + index;
00732           Val(nb) = A.Value(i, j);
00733           nb++;
00734         }
00735   }
00736 
00737 
00739   template<class T, class Prop, class Allocator1, class Allocator2,
00740            class Tint, class Allocator3, class Allocator4>
00741   void
00742   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayRowComplexSparse,
00743                                Allocator1>& A,
00744                                Vector<Tint, VectFull, Allocator2>& IndRow,
00745                                Vector<Tint, VectFull, Allocator3>& IndCol,
00746                                Vector<complex<T>, VectFull, Allocator4>& Val,
00747                                int index, bool sym)
00748   {
00749     int m = A.GetM();
00750     int nnz = A.GetRealDataSize() + A.GetImagDataSize();
00751     // Allocating arrays.
00752     IndRow.Reallocate(nnz);
00753     IndCol.Reallocate(nnz);
00754     Val.Reallocate(nnz);
00755     nnz = 0;
00756     IVect col; Vector<complex<T> > value;
00757     for (int i = 0; i < m; i++)
00758       {
00759         int size_row = A.GetRealRowSize(i) + A.GetImagRowSize(i);
00760         if (size_row > col.GetM())
00761           {
00762             col.Reallocate(size_row);
00763             value.Reallocate(size_row);
00764           }
00765 
00766         int nb = 0;
00767         for (int j = 0; j < A.GetRealRowSize(i); j++)
00768           {
00769             col(nb) = A.IndexReal(i, j) + index;
00770             value(nb) = complex<T>(A.ValueReal(i, j), 0);
00771             nb++;
00772           }
00773 
00774         for (int j = 0; j < A.GetImagRowSize(i); j++)
00775           {
00776             col(nb) = A.IndexImag(i, j) + index;
00777             value(nb) = complex<T>(0, A.ValueImag(i, j));
00778             nb++;
00779           }
00780 
00781         Assemble(nb, col, value);
00782         for (int j = 0; j < nb; j++)
00783           {
00784             IndRow(nnz + j) = index + i;
00785             IndCol(nnz + j) = col(j);
00786             Val(nnz + j) = value(j);
00787           }
00788 
00789         nnz += nb;
00790       }
00791 
00792     IndRow.Resize(nnz);
00793     IndCol.Resize(nnz);
00794     Val.Resize(nnz);
00795   }
00796 
00797 
00799   template<class T, class Prop, class Allocator1, class Allocator2,
00800            class Tint, class Allocator3, class Allocator4>
00801   void
00802   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayColComplexSparse,
00803                                Allocator1>& A,
00804                                Vector<Tint, VectFull, Allocator2>& IndRow,
00805                                Vector<Tint, VectFull, Allocator3>& IndCol,
00806                                Vector<complex<T>, VectFull, Allocator4>& Val,
00807                                int index, bool sym)
00808   {
00809     int nnz = A.GetRealDataSize() + A.GetImagDataSize();
00810     // Allocating arrays.
00811     IndRow.Reallocate(nnz);
00812     IndCol.Reallocate(nnz);
00813     Val.Reallocate(nnz);
00814     nnz = 0;
00815     IVect row; Vector<complex<T> > value;
00816     for (int i = 0; i < A.GetN(); i++)
00817       {
00818         int size_col = A.GetRealColumnSize(i) + A.GetImagColumnSize(i);
00819         if (size_col > row.GetM())
00820           {
00821             row.Reallocate(size_col);
00822             value.Reallocate(size_col);
00823           }
00824 
00825         int nb = 0;
00826         for (int j = 0; j < A.GetRealColumnSize(i); j++)
00827           {
00828             row(nb) = A.IndexReal(i, j) + index;
00829             value(nb) = complex<T>(A.ValueReal(i, j), 0);
00830             nb++;
00831           }
00832 
00833         for (int j = 0; j < A.GetImagColumnSize(i); j++)
00834           {
00835             row(nb) = A.IndexImag(i, j) + index;
00836             value(nb) = complex<T>(0, A.ValueImag(i, j));
00837             nb++;
00838           }
00839 
00840         Assemble(nb, row, value);
00841         for (int j = 0; j < nb; j++)
00842           {
00843             IndRow(nnz + j) = row(j);
00844             IndCol(nnz + j) = index + i;
00845             Val(nnz + j) = value(j);
00846           }
00847 
00848         nnz += nb;
00849       }
00850 
00851     IndRow.Resize(nnz);
00852     IndCol.Resize(nnz);
00853     Val.Resize(nnz);
00854   }
00855 
00856 
00858   template<class T, class Prop, class Allocator1, class Allocator2,
00859            class Tint, class Allocator3, class Allocator4>
00860   void
00861   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayRowSymSparse,
00862                                Allocator1>& A,
00863                                Vector<Tint, VectFull, Allocator2>& IndRow,
00864                                Vector<Tint, VectFull, Allocator3>& IndCol,
00865                                Vector<T, VectFull, Allocator4>& Val,
00866                                int index, bool sym)
00867   {
00868     int i, j;
00869     int m = A.GetM();
00870     int nnz = A.GetDataSize();
00871     if (sym)
00872       {
00873         nnz *= 2;
00874         for (i = 0; i < m; i++)
00875           for (j = 0; j < A.GetRowSize(i); j++)
00876             if (A.Index(i, j) == i)
00877               nnz--;
00878 
00879         IndRow.Reallocate(nnz);
00880         IndCol.Reallocate(nnz);
00881         Val.Reallocate(nnz);
00882         Vector<int> Ptr(m);
00883         Ptr.Zero();
00884         int nb = 0;
00885         for (i = 0; i < m; i++)
00886           for (j = 0; j < A.GetRowSize(i); j++)
00887             {
00888               IndRow(nb) = i + index;
00889               IndCol(nb) = A.Index(i, j) + index;
00890               Val(nb) = A.Value(i, j);
00891               Ptr(A.Index(i, j))++;
00892               nb++;
00893 
00894               if (A.Index(i, j) != i)
00895                 {
00896                   IndRow(nb) = A.Index(i, j) + index;
00897                   IndCol(nb) = i + index;
00898                   Val(nb) = A.Value(i, j);
00899                   Ptr(i)++;
00900                   nb++;
00901                 }
00902             }
00903 
00904         // Sorting the row numbers...
00905         Sort(IndRow, IndCol, Val);
00906 
00907         // ...and the column numbers.
00908         int offset = 0;
00909         for (i = 0; i < m; i++)
00910           {
00911             Sort(offset, offset + Ptr(i) - 1, IndCol, Val);
00912             offset += Ptr(i);
00913           }
00914       }
00915     else
00916       {
00917         // Allocating arrays.
00918         IndRow.Reallocate(nnz);
00919         IndCol.Reallocate(nnz);
00920         Val.Reallocate(nnz);
00921         int nb = 0;
00922         for (i = 0; i < m; i++)
00923           for (j = 0; j < A.GetRowSize(i); j++)
00924             {
00925               IndRow(nb) = i + index;
00926               IndCol(nb) = A.Index(i, j) + index;
00927               Val(nb) = A.Value(i, j);
00928               nb++;
00929             }
00930       }
00931   }
00932 
00933 
00935   template<class T, class Prop, class Allocator1, class Allocator2,
00936            class Tint, class Allocator3, class Allocator4>
00937   void
00938   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayColSymSparse,
00939                                Allocator1>& A,
00940                                Vector<Tint, VectFull, Allocator2>& IndRow,
00941                                Vector<Tint, VectFull, Allocator3>& IndCol,
00942                                Vector<T, VectFull, Allocator4>& Val,
00943                                int index, bool sym)
00944   {
00945     int m = A.GetM();
00946     int nnz = A.GetDataSize();
00947     if (sym)
00948       {
00949         nnz *= 2;
00950         for (int i = 0; i < m; i++)
00951           for (int j = 0; j < A.GetColumnSize(i); j++)
00952             if (A.Index(i, j) == i)
00953               nnz--;
00954 
00955         IndRow.Reallocate(nnz);
00956         IndCol.Reallocate(nnz);
00957         Val.Reallocate(nnz);
00958         Vector<int> Ptr(m);
00959         Ptr.Zero();
00960         int nb = 0;
00961         for (int i = 0; i < m; i++)
00962           for (int j = 0; j < A.GetColumnSize(i); j++)
00963             {
00964               IndCol(nb) = i + index;
00965               IndRow(nb) = A.Index(i, j) + index;
00966               Val(nb) = A.Value(i, j);
00967               Ptr(A.Index(i, j))++;
00968               nb++;
00969 
00970               if (A.Index(i, j) != i)
00971                 {
00972                   IndCol(nb) = A.Index(i, j) + index;
00973                   IndRow(nb) = i + index;
00974                   Val(nb) = A.Value(i, j);
00975                   Ptr(i)++;
00976                   nb++;
00977                 }
00978             }
00979 
00980         // Sorting the row numbers...
00981         Sort(IndRow, IndCol, Val);
00982 
00983         // ...and the column numbers.
00984         int offset = 0;
00985         for (int i = 0; i < m; i++)
00986           {
00987             Sort(offset, offset + Ptr(i) - 1, IndCol, Val);
00988             offset += Ptr(i);
00989           }
00990       }
00991     else
00992       {
00993         // Allocating arrays.
00994         IndRow.Reallocate(nnz);
00995         IndCol.Reallocate(nnz);
00996         Val.Reallocate(nnz);
00997         int nb = 0;
00998         for (int i = 0; i < m; i++)
00999           for (int j = 0; j < A.GetColumnSize(i); j++)
01000             {
01001               IndRow(nb) = A.Index(i, j) + index;
01002               IndCol(nb) = i + index;
01003               Val(nb) = A.Value(i, j);
01004               nb++;
01005             }
01006       }
01007   }
01008 
01009 
01011   template<class T, class Prop, class Allocator1, class Allocator2,
01012            class Tint, class Allocator3, class Allocator4>
01013   void
01014   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayRowSymComplexSparse,
01015                                Allocator1>& A,
01016                                Vector<Tint, VectFull, Allocator2>& IndRow,
01017                                Vector<Tint, VectFull, Allocator3>& IndCol,
01018                                Vector<complex<T>, VectFull, Allocator4>& Val,
01019                                int index, bool sym)
01020   {
01021     int m = A.GetM();
01022     int nnz = A.GetDataSize();
01023     if (sym)
01024       {
01025         nnz *= 2;
01026         IndRow.Reallocate(nnz);
01027         IndCol.Reallocate(nnz);
01028         Val.Reallocate(nnz);
01029         Vector<int> Ptr(m);
01030         Ptr.Zero();
01031         nnz = 0;
01032         IVect col; Vector<complex<T> > value;
01033         for (int i = 0; i < m; i++)
01034           {
01035             int size_row = A.GetRealRowSize(i) + A.GetImagRowSize(i);
01036             if (size_row > col.GetM())
01037               {
01038                 col.Reallocate(size_row);
01039                 value.Reallocate(size_row);
01040               }
01041 
01042             int nb = 0;
01043             for (int j = 0; j < A.GetRealRowSize(i); j++)
01044               {
01045                 col(nb) = A.IndexReal(i, j);
01046                 value(nb) = complex<T>(A.ValueReal(i, j), 0);
01047                 nb++;
01048               }
01049 
01050             for (int j = 0; j < A.GetImagRowSize(i); j++)
01051               {
01052                 col(nb) = A.IndexImag(i, j);
01053                 value(nb) = complex<T>(0, A.ValueImag(i, j));
01054                 nb++;
01055               }
01056 
01057             Assemble(nb, col, value);
01058             for (int j = 0; j < nb; j++)
01059               {
01060                 IndRow(nnz) = i + index;
01061                 IndCol(nnz) = col(j) + index;
01062                 Val(nnz) = value(j);
01063                 Ptr(i)++;
01064                 nnz++;
01065 
01066                 if (col(j) != i)
01067                   {
01068                     IndRow(nnz) = col(j) + index;
01069                     IndCol(nnz) = i + index;
01070                     Val(nnz) = value(j);
01071                     Ptr(col(j))++;
01072                     nnz++;
01073                   }
01074               }
01075           }
01076 
01077         IndRow.Resize(nnz);
01078         IndCol.Resize(nnz);
01079         Val.Resize(nnz);
01080 
01081         // Sorting the row numbers...
01082         Sort(IndRow, IndCol, Val);
01083 
01084         // ...and the column numbers.
01085         int offset = 0;
01086         for (int i = 0; i < m; i++)
01087           {
01088             Sort(offset, offset + Ptr(i) - 1, IndCol, Val);
01089             offset += Ptr(i);
01090           }
01091       }
01092     else
01093       {
01094         // Allocating arrays.
01095         IndRow.Reallocate(nnz);
01096         IndCol.Reallocate(nnz);
01097         Val.Reallocate(nnz);
01098         nnz = 0;
01099         IVect col; Vector<complex<T> > value;
01100         for (int i = 0; i < m; i++)
01101           {
01102             int size_row = A.GetRealRowSize(i) + A.GetImagRowSize(i);
01103             if (size_row > col.GetM())
01104               {
01105                 col.Reallocate(size_row);
01106                 value.Reallocate(size_row);
01107               }
01108 
01109             int nb = 0;
01110             for (int j = 0; j < A.GetRealRowSize(i); j++)
01111               {
01112                 col(nb) = A.IndexReal(i, j) + index;
01113                 value(nb) = complex<T>(A.ValueReal(i, j), 0);
01114                 nb++;
01115               }
01116 
01117             for (int j = 0; j < A.GetImagRowSize(i); j++)
01118               {
01119                 col(nb) = A.IndexImag(i, j) + index;
01120                 value(nb) = complex<T>(0, A.ValueImag(i, j));
01121                 nb++;
01122               }
01123 
01124             Assemble(nb, col, value);
01125             for (int j = 0; j < nb; j++)
01126               {
01127                 IndRow(nnz + j) = index + i;
01128                 IndCol(nnz + j) = col(j);
01129                 Val(nnz + j) = value(j);
01130               }
01131 
01132             nnz += nb;
01133           }
01134 
01135         IndRow.Resize(nnz);
01136         IndCol.Resize(nnz);
01137         Val.Resize(nnz);
01138       }
01139   }
01140 
01141 
01143   template<class T, class Prop, class Allocator1, class Allocator2,
01144            class Tint, class Allocator3, class Allocator4>
01145   void
01146   ConvertMatrix_to_Coordinates(const Matrix<T, Prop, ArrayColSymComplexSparse,
01147                                Allocator1>& A,
01148                                Vector<Tint, VectFull, Allocator2>& IndRow,
01149                                Vector<Tint, VectFull, Allocator3>& IndCol,
01150                                Vector<complex<T>, VectFull, Allocator4>& Val,
01151                                int index, bool sym)
01152   {
01153     int m = A.GetM();
01154     int nnz = A.GetDataSize();
01155     if (sym)
01156       {
01157         nnz *= 2;
01158         IndRow.Reallocate(nnz);
01159         IndCol.Reallocate(nnz);
01160         Val.Reallocate(nnz);
01161         Vector<int> Ptr(m);
01162         Ptr.Zero();
01163         nnz = 0;
01164         IVect row; Vector<complex<T> > value;
01165         for (int i = 0; i < m; i++)
01166           {
01167             int size_col = A.GetRealColumnSize(i) + A.GetImagColumnSize(i);
01168             if (size_col > row.GetM())
01169               {
01170                 row.Reallocate(size_col);
01171                 value.Reallocate(size_col);
01172               }
01173 
01174             int nb = 0;
01175             for (int j = 0; j < A.GetRealColumnSize(i); j++)
01176               {
01177                 row(nb) = A.IndexReal(i, j);
01178                 value(nb) = complex<T>(A.ValueReal(i, j), 0);
01179                 nb++;
01180               }
01181 
01182             for (int j = 0; j < A.GetImagColumnSize(i); j++)
01183               {
01184                 row(nb) = A.IndexImag(i, j);
01185                 value(nb) = complex<T>(0, A.ValueImag(i, j));
01186                 nb++;
01187               }
01188 
01189             Assemble(nb, row, value);
01190             for (int j = 0; j < nb; j++)
01191               {
01192                 IndRow(nnz) = i + index;
01193                 IndCol(nnz) = row(j) + index;
01194                 Val(nnz) = value(j);
01195                 Ptr(i)++;
01196                 nnz++;
01197 
01198                 if (row(j) != i)
01199                   {
01200                     IndRow(nnz) = row(j) + index;
01201                     IndCol(nnz) = i + index;
01202                     Val(nnz) = value(j);
01203                     Ptr(row(j))++;
01204                     nnz++;
01205                   }
01206               }
01207           }
01208 
01209         IndRow.Resize(nnz);
01210         IndCol.Resize(nnz);
01211         Val.Resize(nnz);
01212 
01213         // Sorting the column numbers...
01214         Sort(IndCol, IndRow, Val);
01215 
01216         // ...and the row numbers.
01217         int offset = 0;
01218         for (int i = 0; i < m; i++)
01219           {
01220             Sort(offset, offset + Ptr(i) - 1, IndRow, Val);
01221             offset += Ptr(i);
01222           }
01223       }
01224     else
01225       {
01226         // Allocating arrays.
01227         IndRow.Reallocate(nnz);
01228         IndCol.Reallocate(nnz);
01229         Val.Reallocate(nnz);
01230         nnz = 0;
01231         IVect row; Vector<complex<T> > value;
01232         for (int i = 0; i < m; i++)
01233           {
01234             int size_col = A.GetRealColumnSize(i) + A.GetImagColumnSize(i);
01235             if (size_col > row.GetM())
01236               {
01237                 row.Reallocate(size_col);
01238                 value.Reallocate(size_col);
01239               }
01240 
01241             int nb = 0;
01242             for (int j = 0; j < A.GetRealColumnSize(i); j++)
01243               {
01244                 row(nb) = A.IndexReal(i, j) + index;
01245                 value(nb) = complex<T>(A.ValueReal(i, j), 0);
01246                 nb++;
01247               }
01248 
01249             for (int j = 0; j < A.GetImagColumnSize(i); j++)
01250               {
01251                 row(nb) = A.IndexImag(i, j) + index;
01252                 value(nb) = complex<T>(0, A.ValueImag(i, j));
01253                 nb++;
01254               }
01255 
01256             Assemble(nb, row, value);
01257             for (int j = 0; j < nb; j++)
01258               {
01259                 IndCol(nnz + j) = index + i;
01260                 IndRow(nnz + j) = row(j);
01261                 Val(nnz + j) = value(j);
01262               }
01263 
01264             nnz += nb;
01265           }
01266 
01267         IndRow.Resize(nnz);
01268         IndCol.Resize(nnz);
01269         Val.Resize(nnz);
01270       }
01271   }
01272 
01273 
01274   /*
01275     From "Matlab" coordinate format to CSR formats.
01276   */
01277 
01278 
01280 
01288   template<class T, class Prop, class Allocator1,
01289            class Allocator2, class Allocator3>
01290   void
01291   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
01292                                  Vector<int, VectFull, Allocator2>& IndCol_,
01293                                  Vector<T, VectFull, Allocator3>& Val,
01294                                  Matrix<T, Prop, RowSparse, Allocator3>& A,
01295                                  int index)
01296   {
01297     int Nelement = IndRow_.GetLength();
01298 
01299     Vector<int, VectFull, CallocAlloc<int> > IndRow(Nelement),
01300       IndCol(Nelement);
01301 
01302     for (int i = 0; i < Nelement; i++)
01303       {
01304         IndRow(i) = IndRow_(i) - index;
01305         IndCol(i) = IndCol_(i) - index;
01306       }
01307 
01308     IndRow_.Clear();
01309     IndCol_.Clear();
01310 
01311     int row_max = IndRow.GetNormInf();
01312     int col_max = IndCol.GetNormInf();
01313 
01314     int m = row_max + 1;
01315     int n = col_max + 1;
01316     m = max(m, A.GetM());
01317     n = max(n, A.GetN());
01318 
01319     Sort(IndRow, IndCol, Val);
01320 
01321     // Construction of array 'Ptr'.
01322     Vector<int, VectFull, CallocAlloc<int> > Ptr(m + 1);
01323     Ptr.Zero();
01324     for (int i = 0; i < Nelement; i++)
01325       Ptr(IndRow(i)+1)++;
01326 
01327     for (int i = 0; i < m; i++)
01328       Ptr(i + 1) += Ptr(i);
01329 
01330     // Sorts 'IndCol'
01331     for (int i = 0; i < m; i++)
01332       Sort(Ptr(i), Ptr(i + 1) - 1, IndCol, Val);
01333 
01334     A.SetData(m, n, Val, Ptr, IndCol);
01335   }
01336 
01337 
01339   template<class T, class Prop, class Allocator1,
01340            class Allocator2, class Allocator3>
01341   void
01342   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
01343                                  Vector<int, VectFull, Allocator2>& IndCol_,
01344                                  Vector<T, VectFull, Allocator3>& Val,
01345                                  Matrix<T, Prop, ColSparse, Allocator3>& A,
01346                                  int index)
01347   {
01348     // Assuming that there is no duplicate value.
01349     if (IndRow_.GetM() <= 0)
01350       return;
01351 
01352     int nnz = IndRow_.GetM();
01353     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
01354     for (int i = 0; i < nnz; i++)
01355       {
01356         IndRow(i) = IndRow_(i);
01357         IndCol(i) = IndCol_(i);
01358       }
01359     IndRow_.Clear();
01360     IndCol_.Clear();
01361 
01362     int row_max = IndRow.GetNormInf();
01363     int col_max = IndCol.GetNormInf();
01364     int m = row_max - index + 1;
01365     int n = col_max - index + 1;
01366     m = max(m, A.GetM());
01367     n = max(n, A.GetN());
01368 
01369     // Sorts the array 'IndCol'.
01370     Sort(IndCol, IndRow, Val);
01371 
01372     // Construction of array 'Ptr'.
01373     Vector<int, VectFull, CallocAlloc<int> > Ptr(n + 1);
01374     Ptr.Zero();
01375     for (int i = 0; i < nnz; i++)
01376       {
01377         IndRow(i) -= index;
01378         IndCol(i) -= index;
01379         Ptr(IndCol(i) + 1)++;
01380       }
01381 
01382     for (int i = 0; i < n; i++)
01383       Ptr(i + 1) += Ptr(i);
01384 
01385     // Sorts 'IndRow'
01386     for (int i = 0; i < n; i++)
01387       Sort(Ptr(i), Ptr(i + 1) - 1, IndRow, Val);
01388 
01389     A.SetData(m, n, Val, Ptr, IndRow);
01390   }
01391 
01392 
01394   template<class T, class Prop, class Allocator1,
01395            class Allocator2, class Allocator3>
01396   void
01397   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
01398                                  Vector<int, VectFull, Allocator2>& IndCol_,
01399                                  Vector<T, VectFull, Allocator3>& Val,
01400                                  Matrix<T, Prop, RowSymSparse, Allocator3>& A,
01401                                  int index)
01402   {
01403     // Assuming there is no duplicate value.
01404     if (IndRow_.GetM() <= 0)
01405       return;
01406 
01407     int nnz = IndRow_.GetM();
01408     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
01409     for (int i = 0; i < nnz; i++)
01410       {
01411         IndRow(i) = IndRow_(i);
01412         IndCol(i) = IndCol_(i);
01413       }
01414     IndRow_.Clear();
01415     IndCol_.Clear();
01416 
01417     int row_max = IndRow.GetNormInf();
01418     int col_max = IndCol.GetNormInf();
01419     int m = row_max - index + 1;
01420     int n = col_max - index + 1;
01421 
01422     // First, removing the lower part of the matrix (if present).
01423     int nb_low = 0;
01424     for (int i = 0; i < nnz; i++)
01425       if (IndRow(i) > IndCol(i))
01426         nb_low++;
01427 
01428     if (nb_low > 0)
01429       {
01430         int nb = 0;
01431         for (int i = 0; i < nnz; i++)
01432           if (IndRow(i) <= IndCol(i))
01433             {
01434               IndRow(nb) = IndRow(i);
01435               IndCol(nb) = IndCol(i);
01436               Val(nb) = Val(i);
01437               nb++;
01438             }
01439 
01440         IndRow.Resize(nb);
01441         IndCol.Resize(nb);
01442         Val.Resize(nb);
01443         nnz = nb;
01444       }
01445 
01446     // Sorts the array 'IndRow'.
01447     Sort(IndRow, IndCol, Val);
01448 
01449     // Construction of array 'Ptr'.
01450     Vector<int, VectFull, CallocAlloc<int> > Ptr(m + 1);
01451     Ptr.Zero();
01452     for (int i = 0; i < nnz; i++)
01453       {
01454         IndRow(i) -= index;
01455         IndCol(i) -= index;
01456         Ptr(IndRow(i) + 1)++;
01457       }
01458 
01459     for (int i = 0; i < m; i++)
01460       Ptr(i + 1) += Ptr(i);
01461 
01462     // Sorts 'IndCol'.
01463     for (int i = 0; i < m; i++)
01464       Sort(Ptr(i), Ptr(i + 1) - 1, IndCol, Val);
01465 
01466     A.SetData(m, n, Val, Ptr, IndCol);
01467   }
01468 
01469 
01471   template<class T, class Prop, class Allocator1,
01472            class Allocator2, class Allocator3>
01473   void
01474   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
01475                                  Vector<int, VectFull, Allocator2>& IndCol_,
01476                                  Vector<T, VectFull, Allocator3>& Val,
01477                                  Matrix<T, Prop, ColSymSparse, Allocator3>& A,
01478                                  int index)
01479   {
01480     // Assuming there is no duplicate value.
01481     if (IndRow_.GetM() <= 0)
01482       return;
01483 
01484     int nnz = IndRow_.GetM();
01485     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
01486     for (int i = 0; i < nnz; i++)
01487       {
01488         IndRow(i) = IndRow_(i);
01489         IndCol(i) = IndCol_(i);
01490       }
01491 
01492     IndRow_.Clear();
01493     IndCol_.Clear();
01494 
01495     int row_max = IndRow.GetNormInf();
01496     int col_max = IndCol.GetNormInf();
01497     int m = row_max - index + 1;
01498     int n = col_max - index + 1;
01499 
01500     // First, removing the lower part of the matrix (if present).
01501     int nb_low = 0;
01502     for (int i = 0; i < nnz; i++)
01503       if (IndRow(i) > IndCol(i))
01504         nb_low++;
01505 
01506     if (nb_low > 0)
01507       {
01508         int nb = 0;
01509         for (int i = 0; i < nnz; i++)
01510           if (IndRow(i) <= IndCol(i))
01511             {
01512               IndRow(nb) = IndRow(i);
01513               IndCol(nb) = IndCol(i);
01514               Val(nb) = Val(i);
01515               nb++;
01516             }
01517 
01518         IndRow.Resize(nb);
01519         IndCol.Resize(nb);
01520         Val.Resize(nb);
01521         nnz = nb;
01522       }
01523 
01524     // Sorts the array 'IndCol'.
01525     Sort(IndCol, IndRow, Val);
01526 
01527     // Construction of array 'Ptr'.
01528     Vector<int, VectFull, CallocAlloc<int> > Ptr(m + 1);
01529     Ptr.Zero();
01530     for (int i = 0; i < nnz; i++)
01531       {
01532         IndRow(i) -= index;
01533         IndCol(i) -= index;
01534         Ptr(IndCol(i) + 1)++;
01535       }
01536 
01537     for (int i = 0; i < m; i++)
01538       Ptr(i + 1) += Ptr(i);
01539 
01540     // Sorts 'IndRow'.
01541     for (int i = 0; i < m; i++)
01542       Sort(Ptr(i), Ptr(i + 1) - 1, IndRow, Val);
01543 
01544     A.SetData(m, n, Val, Ptr, IndRow);
01545   }
01546 
01547 
01549   template<class T, class Prop, class Allocator1,
01550            class Allocator2, class Allocator3, class Allocator4>
01551   void
01552   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow,
01553                                  Vector<int, VectFull, Allocator2>& IndCol,
01554                                  Vector<complex<T>, VectFull, Allocator3>& Val,
01555                                  Matrix<T, Prop, RowComplexSparse,
01556                                  Allocator4>& A,
01557                                  int index)
01558   {
01559     if (IndRow.GetM() <= 0)
01560       {
01561         A.Clear();
01562         return;
01563       }
01564 
01565     T zero(0);
01566     int row_max = IndRow.GetNormInf();
01567     int col_max = IndCol.GetNormInf();
01568     int m = row_max - index + 1;
01569     int n = col_max - index + 1;
01570 
01571     // Sorts the array 'IndRow'.
01572     Sort(IndRow, IndCol, Val);
01573 
01574     // Number of elements per row.
01575     Vector<int, VectFull, CallocAlloc<int> > PtrReal(m+1), PtrImag(m+1), Ptr(m);
01576     PtrReal.Zero(); PtrImag.Zero(); Ptr.Zero();
01577     for (int i = 0; i < IndRow.GetM(); i++)
01578       {
01579         IndRow(i) -= index;
01580         IndCol(i) -= index;
01581         Ptr(IndRow(i))++;
01582         if (real(Val(i)) != zero)
01583           PtrReal(IndRow(i)+1)++;
01584 
01585         if (imag(Val(i)) != zero)
01586           PtrImag(IndRow(i)+1)++;
01587       }
01588 
01589     for (int i = 0; i < m; i++)
01590       {
01591         PtrReal(i+1) += PtrReal(i);
01592         PtrImag(i+1) += PtrImag(i);
01593       }
01594     int real_nz = PtrReal(m), imag_nz = PtrImag(m);
01595 
01596     // Fills matrix 'A'.
01597     Vector<int, VectFull, CallocAlloc<int> > IndReal(real_nz), IndImag(imag_nz);
01598     Vector<T, VectFull, Allocator4> ValReal(real_nz), ValImag(imag_nz);
01599     int offset = 0;
01600     for (int i = 0; i < m; i++)
01601       {
01602         int nb = PtrReal(i);
01603         for (int j = 0; j < Ptr(i); j++)
01604           if (real(Val(offset + j)) != zero)
01605             {
01606               IndReal(nb) = IndCol(offset + j);
01607               ValReal(nb) = real(Val(offset + j));
01608               nb++;
01609             }
01610 
01611         nb = PtrImag(i);
01612         for (int j = 0; j < Ptr(i); j++)
01613           if (imag(Val(offset + j)) != zero)
01614             {
01615               IndImag(nb) = IndCol(offset + j);
01616               ValImag(nb) = imag(Val(offset + j));
01617               nb++;
01618             }
01619 
01620         // sorting column numbers
01621         Sort(PtrReal(i), PtrReal(i+1)-1, IndReal, ValReal);
01622         Sort(PtrImag(i), PtrImag(i+1)-1, IndImag, ValImag);
01623 
01624         offset += Ptr(i);
01625       }
01626 
01627     // providing pointers to A
01628     A.SetData(m, n, ValReal, PtrReal, IndReal, ValImag, PtrImag, IndImag);
01629   }
01630 
01631 
01633   template<class T, class Prop, class Allocator1,
01634            class Allocator2, class Allocator3, class Allocator4>
01635   void
01636   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow,
01637                                  Vector<int, VectFull, Allocator2>& IndCol,
01638                                  Vector<complex<T>, VectFull, Allocator3>& Val,
01639                                  Matrix<T, Prop, ColComplexSparse,
01640                                  Allocator4>& A,
01641                                  int index)
01642   {
01643     if (IndRow.GetM() <= 0)
01644       {
01645         A.Clear();
01646         return;
01647       }
01648 
01649     T zero(0);
01650     int row_max = IndRow.GetNormInf();
01651     int col_max = IndCol.GetNormInf();
01652     int m = row_max - index + 1;
01653     int n = col_max - index + 1;
01654 
01655     // Sorts the array 'IndCol'.
01656     Sort(IndCol, IndRow, Val);
01657 
01658     // Number of elements per column.
01659     Vector<int, VectFull, CallocAlloc<int> > PtrReal(n+1), PtrImag(n+1), Ptr(n);
01660     PtrReal.Zero(); PtrImag.Zero(); Ptr.Zero();
01661     for (int i = 0; i < IndCol.GetM(); i++)
01662       {
01663         IndRow(i) -= index;
01664         IndCol(i) -= index;
01665         Ptr(IndCol(i))++;
01666         if (real(Val(i)) != zero)
01667           PtrReal(IndCol(i)+1)++;
01668 
01669         if (imag(Val(i)) != zero)
01670           PtrImag(IndCol(i)+1)++;
01671       }
01672 
01673     for (int i = 0; i < n; i++)
01674       {
01675         PtrReal(i+1) += PtrReal(i);
01676         PtrImag(i+1) += PtrImag(i);
01677       }
01678     int real_nz = PtrReal(n), imag_nz = PtrImag(n);
01679 
01680     // Fills matrix 'A'.
01681     Vector<int, VectFull, CallocAlloc<int> > IndReal(real_nz), IndImag(imag_nz);
01682     Vector<T, VectFull, Allocator4> ValReal(real_nz), ValImag(imag_nz);
01683     int offset = 0;
01684     for (int i = 0; i < n; i++)
01685       {
01686         int nb = PtrReal(i);
01687         for (int j = 0; j < Ptr(i); j++)
01688           if (real(Val(offset + j)) != zero)
01689             {
01690               IndReal(nb) = IndRow(offset + j);
01691               ValReal(nb) = real(Val(offset + j));
01692               nb++;
01693             }
01694 
01695         nb = PtrImag(i);
01696         for (int j = 0; j < Ptr(i); j++)
01697           if (imag(Val(offset + j)) != zero)
01698             {
01699               IndImag(nb) = IndRow(offset + j);
01700               ValImag(nb) = imag(Val(offset + j));
01701               nb++;
01702             }
01703 
01704         // sorting column numbers
01705         Sort(PtrReal(i), PtrReal(i+1)-1, IndReal, ValReal);
01706         Sort(PtrImag(i), PtrImag(i+1)-1, IndImag, ValImag);
01707 
01708         offset += Ptr(i);
01709       }
01710 
01711     // providing pointers to A
01712     A.SetData(m, n, ValReal, PtrReal, IndReal, ValImag, PtrImag, IndImag);
01713   }
01714 
01715 
01717   template<class T, class Prop, class Allocator1,
01718            class Allocator2, class Allocator3, class Allocator4>
01719   void
01720   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow,
01721                                  Vector<int, VectFull, Allocator2>& IndCol,
01722                                  Vector<complex<T>, VectFull, Allocator3>& Val,
01723                                  Matrix<T, Prop, RowSymComplexSparse,
01724                                  Allocator4>& A,
01725                                  int index)
01726   {
01727     if (IndRow.GetM() <= 0)
01728       {
01729         A.Clear();
01730         return;
01731       }
01732 
01733     T zero(0);
01734     int row_max = IndRow.GetNormInf();
01735     int col_max = IndCol.GetNormInf();
01736     int m = row_max - index + 1;
01737     int n = col_max - index + 1;
01738 
01739     // Sorts the array 'IndRow'.
01740     Sort(IndRow, IndCol, Val);
01741 
01742     // Number of elements per row.
01743     Vector<int, VectFull, CallocAlloc<int> > PtrReal(m+1), PtrImag(m+1), Ptr(m);
01744     PtrReal.Zero(); PtrImag.Zero(); Ptr.Zero();
01745     for (int i = 0; i < IndRow.GetM(); i++)
01746       {
01747         IndRow(i) -= index;
01748         IndCol(i) -= index;
01749         Ptr(IndRow(i))++;
01750         if (IndRow(i) <= IndCol(i))
01751           {
01752             if (real(Val(i)) != zero)
01753               PtrReal(IndRow(i)+1)++;
01754 
01755             if (imag(Val(i)) != zero)
01756               PtrImag(IndRow(i)+1)++;
01757           }
01758       }
01759 
01760     for (int i = 0; i < m; i++)
01761       {
01762         PtrReal(i+1) += PtrReal(i);
01763         PtrImag(i+1) += PtrImag(i);
01764       }
01765 
01766     int real_nz = PtrReal(m), imag_nz = PtrImag(m);
01767 
01768     // Fills matrix 'A'.
01769     Vector<int, VectFull, CallocAlloc<int> > IndReal(real_nz), IndImag(imag_nz);
01770     Vector<T, VectFull, Allocator4> ValReal(real_nz), ValImag(imag_nz);
01771     int offset = 0;
01772     for (int i = 0; i < m; i++)
01773       {
01774         int nb = PtrReal(i);
01775         for (int j = 0; j < Ptr(i); j++)
01776           if (i <= IndCol(offset+j))
01777             if (real(Val(offset + j)) != zero)
01778               {
01779                 IndReal(nb) = IndCol(offset + j);
01780                 ValReal(nb) = real(Val(offset + j));
01781                 nb++;
01782               }
01783 
01784         nb = PtrImag(i);
01785         for (int j = 0; j < Ptr(i); j++)
01786           if (i <= IndCol(offset+j))
01787             if (imag(Val(offset + j)) != zero)
01788               {
01789                 IndImag(nb) = IndCol(offset + j);
01790                 ValImag(nb) = imag(Val(offset + j));
01791                 nb++;
01792             }
01793 
01794         // sorting column numbers
01795         Sort(PtrReal(i), PtrReal(i+1)-1, IndReal, ValReal);
01796         Sort(PtrImag(i), PtrImag(i+1)-1, IndImag, ValImag);
01797 
01798         offset += Ptr(i);
01799       }
01800 
01801     // providing pointers to A
01802     A.SetData(m, n, ValReal, PtrReal, IndReal, ValImag, PtrImag, IndImag);
01803   }
01804 
01805 
01807   template<class T, class Prop, class Allocator1,
01808            class Allocator2, class Allocator3, class Allocator4>
01809   void
01810   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow,
01811                                  Vector<int, VectFull, Allocator2>& IndCol,
01812                                  Vector<complex<T>, VectFull, Allocator3>& Val,
01813                                  Matrix<T, Prop, ColSymComplexSparse,
01814                                  Allocator4>& A,
01815                                  int index)
01816   {
01817     if (IndRow.GetM() <= 0)
01818       {
01819         A.Clear();
01820         return;
01821       }
01822 
01823     T zero(0);
01824     int row_max = IndRow.GetNormInf();
01825     int col_max = IndCol.GetNormInf();
01826     int m = row_max - index + 1;
01827     int n = col_max - index + 1;
01828 
01829     // Sorts the array 'IndCol'.
01830     Sort(IndCol, IndRow, Val);
01831 
01832     // Number of elements per column.
01833     Vector<int, VectFull, CallocAlloc<int> > PtrReal(n+1), PtrImag(n+1), Ptr(n);
01834     PtrReal.Zero(); PtrImag.Zero(); Ptr.Zero();
01835     for (int i = 0; i < IndCol.GetM(); i++)
01836       {
01837         IndRow(i) -= index;
01838         IndCol(i) -= index;
01839         Ptr(IndCol(i))++;
01840         if (IndRow(i) <= IndCol(i))
01841           {
01842             if (real(Val(i)) != zero)
01843               PtrReal(IndCol(i)+1)++;
01844 
01845             if (imag(Val(i)) != zero)
01846               PtrImag(IndCol(i)+1)++;
01847           }
01848       }
01849 
01850     for (int i = 0; i < n; i++)
01851       {
01852         PtrReal(i+1) += PtrReal(i);
01853         PtrImag(i+1) += PtrImag(i);
01854       }
01855 
01856     int real_nz = PtrReal(n), imag_nz = PtrImag(n);
01857 
01858     // Fills matrix 'A'.
01859     Vector<int, VectFull, CallocAlloc<int> > IndReal(real_nz), IndImag(imag_nz);
01860     Vector<T, VectFull, Allocator4> ValReal(real_nz), ValImag(imag_nz);
01861     int offset = 0;
01862     for (int i = 0; i < n; i++)
01863       {
01864         int nb = PtrReal(i);
01865         for (int j = 0; j < Ptr(i); j++)
01866           if (IndRow(offset+j) <= i)
01867             if (real(Val(offset + j)) != zero)
01868               {
01869                 IndReal(nb) = IndRow(offset + j);
01870                 ValReal(nb) = real(Val(offset + j));
01871                 nb++;
01872               }
01873 
01874         nb = PtrImag(i);
01875         for (int j = 0; j < Ptr(i); j++)
01876           if (IndRow(offset+j) <= i)
01877             if (imag(Val(offset + j)) != zero)
01878               {
01879                 IndImag(nb) = IndRow(offset + j);
01880                 ValImag(nb) = imag(Val(offset + j));
01881                 nb++;
01882               }
01883 
01884         // sorting column numbers
01885         Sort(PtrReal(i), PtrReal(i+1)-1, IndReal, ValReal);
01886         Sort(PtrImag(i), PtrImag(i+1)-1, IndImag, ValImag);
01887 
01888         offset += Ptr(i);
01889       }
01890 
01891     // providing pointers to A
01892     A.SetData(m, n, ValReal, PtrReal, IndReal, ValImag, PtrImag, IndImag);
01893   }
01894 
01895 
01896   /*
01897     From Sparse Array formats to "Matlab" coordinate format.
01898   */
01899 
01900 
01902   template<class T, class Prop, class Allocator1,
01903            class Allocator2, class Allocator3>
01904   void
01905   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
01906                                  Vector<int, VectFull, Allocator2>& IndCol_,
01907                                  Vector<T, VectFull, Allocator3>& Val,
01908                                  Matrix<T, Prop, ArrayRowSparse,
01909                                  Allocator3>& A,
01910                                  int index)
01911   {
01912     if (IndRow_.GetM() <= 0)
01913       return;
01914 
01915     int nnz = IndRow_.GetM();
01916     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
01917     for (int i = 0; i < nnz; i++)
01918       {
01919         IndRow(i) = IndRow_(i);
01920         IndCol(i) = IndCol_(i);
01921       }
01922     IndRow_.Clear();
01923     IndCol_.Clear();
01924 
01925     int row_max = IndRow.GetNormInf();
01926     int col_max = IndCol.GetNormInf();
01927     int m = row_max - index + 1;
01928     int n = col_max - index + 1;
01929 
01930     // Sorts the array 'IndRow'.
01931     Sort(IndRow, IndCol, Val);
01932 
01933     // Number of elements per row.
01934     Vector<int, VectFull, CallocAlloc<int> > Ptr(m);
01935     Ptr.Zero();
01936     for (int i = 0; i < nnz; i++)
01937       {
01938         IndRow(i) -= index;
01939         IndCol(i) -= index;
01940         Ptr(IndRow(i))++;
01941       }
01942 
01943     // Fills matrix 'A'.
01944     A.Reallocate(m, n);
01945     int offset = 0;
01946     for (int i = 0; i < m; i++)
01947       if (Ptr(i) > 0)
01948         {
01949           A.ReallocateRow(i, Ptr(i));
01950           for (int j = 0; j < Ptr(i); j++)
01951             {
01952               A.Index(i, j) = IndCol(offset + j);
01953               A.Value(i, j) = Val(offset + j);
01954             }
01955           offset += Ptr(i);
01956         }
01957 
01958     // Assembles 'A' to sort column numbers.
01959     A.Assemble();
01960   }
01961 
01962 
01964   template<class T, class Prop, class Allocator1,
01965            class Allocator2, class Allocator3>
01966   void
01967   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
01968                                  Vector<int, VectFull, Allocator2>& IndCol_,
01969                                  Vector<T, VectFull, Allocator3>& Val,
01970                                  Matrix<T, Prop, ArrayColSparse,
01971                                  Allocator3>& A,
01972                                  int index)
01973   {
01974     // Assuming there is no duplicate value.
01975     if (IndRow_.GetM() <= 0)
01976       return;
01977 
01978     int nnz = IndRow_.GetM();
01979     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
01980     for (int i = 0; i < nnz; i++)
01981       {
01982         IndRow(i) = IndRow_(i);
01983         IndCol(i) = IndCol_(i);
01984       }
01985     IndRow_.Clear();
01986     IndCol_.Clear();
01987 
01988     int row_max = IndRow.GetNormInf();
01989     int col_max = IndCol.GetNormInf();
01990     int m = row_max - index + 1;
01991     int n = col_max - index + 1;
01992 
01993     // Sorts array 'IndCol'.
01994     Sort(IndCol, IndRow, Val);
01995 
01996     // Construction of array 'Ptr'.
01997     Vector<int, VectFull, CallocAlloc<int> > Ptr(n);
01998     Ptr.Zero();
01999     for (int i = 0; i < nnz; i++)
02000       {
02001         IndRow(i) -= index;
02002         IndCol(i) -= index;
02003         Ptr(IndCol(i))++;
02004       }
02005 
02006     // Fills matrix 'A'.
02007     A.Reallocate(m, n);
02008     int offset = 0;
02009     for (int i = 0; i < n; i++)
02010       if (Ptr(i) > 0)
02011         {
02012           A.ReallocateColumn(i, Ptr(i));
02013           for (int j = 0; j < Ptr(i); j++)
02014             {
02015               A.Index(i, j) = IndRow(offset + j);
02016               A.Value(i, j) = Val(offset + j);
02017             }
02018           offset += Ptr(i);
02019         }
02020 
02021     // Assembles 'A' to sort row numbers.
02022     A.Assemble();
02023   }
02024 
02025 
02027   template<class T, class Prop, class Allocator1,
02028            class Allocator2, class Allocator3>
02029   void
02030   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
02031                                  Vector<int, VectFull, Allocator2>& IndCol_,
02032                                  Vector<T, VectFull, Allocator3>& Val,
02033                                  Matrix<T, Prop, ArrayRowSymSparse,
02034                                  Allocator3>& A,
02035                                  int index)
02036   {
02037     // Assuming that there is no duplicate value.
02038     if (IndRow_.GetM() <= 0)
02039       return;
02040 
02041     int nnz = IndRow_.GetM();
02042     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
02043     for (int i = 0; i < nnz; i++)
02044       {
02045         IndRow(i) = IndRow_(i);
02046         IndCol(i) = IndCol_(i);
02047       }
02048     IndRow_.Clear();
02049     IndCol_.Clear();
02050 
02051     int row_max = IndRow.GetNormInf();
02052     int col_max = IndCol.GetNormInf();
02053     int m = row_max - index + 1;
02054     int n = col_max - index + 1;
02055 
02056     // First, removing the lower part of the matrix (if present).
02057     int nb_low = 0;
02058     for (int i = 0; i < nnz; i++)
02059       if (IndRow(i) > IndCol(i))
02060         nb_low++;
02061 
02062     if (nb_low > 0)
02063       {
02064         int nb = 0;
02065         for (int i = 0; i < nnz; i++)
02066           if (IndRow(i) <= IndCol(i))
02067             {
02068               IndRow(nb) = IndRow(i);
02069               IndCol(nb) = IndCol(i);
02070               Val(nb) = Val(i);
02071               nb++;
02072             }
02073 
02074         IndRow.Resize(nb);
02075         IndCol.Resize(nb);
02076         Val.Resize(nb);
02077         nnz = nb;
02078       }
02079 
02080     // Sorts the array 'IndRow'.
02081     Sort(IndRow, IndCol, Val);
02082 
02083     // Construction of array 'Ptr'.
02084     Vector<int, VectFull, CallocAlloc<int> > Ptr(m);
02085     Ptr.Zero();
02086     for (int i = 0; i < nnz; i++)
02087       {
02088         IndRow(i) -= index;
02089         IndCol(i) -= index;
02090         Ptr(IndRow(i))++;
02091       }
02092 
02093     // Fills matrix 'A'.
02094     A.Clear(); A.Reallocate(m, n);
02095     int offset = 0;
02096     for (int i = 0; i < m; i++)
02097       if (Ptr(i) > 0)
02098         {
02099           // sorting column numbers
02100           Sort(offset, offset+Ptr(i)-1, IndCol, Val);
02101 
02102           // putting values in A
02103           A.ReallocateRow(i, Ptr(i));
02104           for (int j = 0; j < Ptr(i); j++)
02105             {
02106               A.Index(i, j) = IndCol(offset + j);
02107               A.Value(i, j) = Val(offset + j);
02108             }
02109 
02110           offset += Ptr(i);
02111         }
02112   }
02113 
02114 
02116   template<class T, class Prop, class Allocator1,
02117            class Allocator2, class Allocator3>
02118   void
02119   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow_,
02120                                  Vector<int, VectFull, Allocator2>& IndCol_,
02121                                  Vector<T, VectFull, Allocator3>& Val,
02122                                  Matrix<T, Prop, ArrayColSymSparse,
02123                                  Allocator3>& A,
02124                                  int index)
02125   {
02126     // Assuming that there is no duplicate value.
02127     if (IndRow_.GetM() <= 0)
02128       return;
02129 
02130     int nnz = IndRow_.GetM();
02131     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
02132     for (int i = 0; i < nnz; i++)
02133       {
02134         IndRow(i) = IndRow_(i);
02135         IndCol(i) = IndCol_(i);
02136       }
02137 
02138     IndRow_.Clear();
02139     IndCol_.Clear();
02140 
02141     int row_max = IndRow.GetNormInf();
02142     int col_max = IndCol.GetNormInf();
02143     int m = row_max - index + 1;
02144     int n = col_max - index + 1;
02145 
02146     // First, removing the lower part of the matrix (if present).
02147     int nb_low = 0;
02148     for (int i = 0; i < nnz; i++)
02149       if (IndRow(i) > IndCol(i))
02150         nb_low++;
02151 
02152     if (nb_low > 0)
02153       {
02154         int nb = 0;
02155         for (int i = 0; i < nnz; i++)
02156           if (IndRow(i) <= IndCol(i))
02157             {
02158               IndRow(nb) = IndRow(i);
02159               IndCol(nb) = IndCol(i);
02160               Val(nb) = Val(i);
02161               nb++;
02162             }
02163 
02164         IndRow.Resize(nb);
02165         IndCol.Resize(nb);
02166         Val.Resize(nb);
02167         nnz = nb;
02168       }
02169 
02170     // Sorts the array 'IndRow'.
02171     Sort(IndCol, IndRow, Val);
02172 
02173     // Construction of array 'Ptr'.
02174     Vector<int, VectFull, CallocAlloc<int> > Ptr(m);
02175     Ptr.Zero();
02176     for (int i = 0; i < nnz; i++)
02177       {
02178         IndRow(i) -= index;
02179         IndCol(i) -= index;
02180         Ptr(IndCol(i))++;
02181       }
02182 
02183     // Fills matrix 'A'.
02184     A.Reallocate(m, n);
02185     int offset = 0;
02186     for (int i = 0; i < m; i++)
02187       if (Ptr(i) > 0)
02188         {
02189           A.ReallocateColumn(i, Ptr(i));
02190           for (int j = 0; j < Ptr(i); j++)
02191             {
02192               A.Index(i, j) = IndRow(offset + j);
02193               A.Value(i, j) = Val(offset + j);
02194             }
02195           offset += Ptr(i);
02196         }
02197 
02198     // Assembles 'A' to sort row numbers.
02199     A.Assemble();
02200   }
02201 
02202 
02204   template<class T, class Prop, class Allocator1,
02205            class Allocator2, class Allocator3, class Allocator4>
02206   void
02207   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow,
02208                                  Vector<int, VectFull, Allocator2>& IndCol,
02209                                  Vector<complex<T>, VectFull, Allocator3>& Val,
02210                                  Matrix<T, Prop, ArrayRowComplexSparse,
02211                                  Allocator4>& A,
02212                                  int index)
02213   {
02214     if (IndRow.GetM() <= 0)
02215       {
02216         A.Clear();
02217         return;
02218       }
02219 
02220     T zero(0);
02221     int row_max = IndRow.GetNormInf();
02222     int col_max = IndCol.GetNormInf();
02223     int m = row_max - index + 1;
02224     int n = col_max - index + 1;
02225 
02226     // Sorts the array 'IndRow'.
02227     Sort(IndRow, IndCol, Val);
02228 
02229     // Number of elements per row.
02230     Vector<int> PtrReal(m), PtrImag(m), Ptr(m);
02231     PtrReal.Zero(); PtrImag.Zero(); Ptr.Zero();
02232     for (int i = 0; i < IndRow.GetM(); i++)
02233       {
02234         IndRow(i) -= index;
02235         IndCol(i) -= index;
02236         Ptr(IndRow(i))++;
02237         if (real(Val(i)) != zero)
02238           PtrReal(IndRow(i))++;
02239 
02240         if (imag(Val(i)) != zero)
02241           PtrImag(IndRow(i))++;
02242       }
02243 
02244     // Fills matrix 'A'.
02245     A.Reallocate(m, n);
02246     int offset = 0;
02247     for (int i = 0; i < m; i++)
02248       {
02249         if (PtrReal(i) > 0)
02250           {
02251             A.ReallocateRealRow(i, PtrReal(i));
02252             int nb = 0;
02253             for (int j = 0; j < Ptr(i); j++)
02254               if (real(Val(offset + j)) != zero)
02255                 {
02256                   A.IndexReal(i, nb) = IndCol(offset + j);
02257                   A.ValueReal(i, nb) = real(Val(offset + j));
02258                   nb++;
02259                 }
02260           }
02261 
02262         if (PtrImag(i) > 0)
02263           {
02264             A.ReallocateImagRow(i, PtrImag(i));
02265             int nb = 0;
02266             for (int j = 0; j < Ptr(i); j++)
02267               if (imag(Val(offset + j)) != zero)
02268                 {
02269                   A.IndexImag(i, nb) = IndCol(offset + j);
02270                   A.ValueImag(i, nb) = imag(Val(offset + j));
02271                   nb++;
02272                 }
02273           }
02274 
02275         offset += Ptr(i);
02276       }
02277 
02278     // Assembles 'A' to sort column numbers.
02279     A.Assemble();
02280   }
02281 
02282 
02284   template<class T, class Prop, class Allocator1,
02285            class Allocator2, class Allocator3, class Allocator4>
02286   void
02287   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow,
02288                                  Vector<int, VectFull, Allocator2>& IndCol,
02289                                  Vector<complex<T>, VectFull, Allocator3>& Val,
02290                                  Matrix<T, Prop, ArrayColComplexSparse,
02291                                  Allocator4>& A,
02292                                  int index)
02293   {
02294     if (IndRow.GetM() <= 0)
02295       {
02296         A.Clear();
02297         return;
02298       }
02299 
02300     T zero(0);
02301     int row_max = IndRow.GetNormInf();
02302     int col_max = IndCol.GetNormInf();
02303     int m = row_max - index + 1;
02304     int n = col_max - index + 1;
02305 
02306     // Sorts the array 'IndRow'.
02307     Sort(IndCol, IndRow, Val);
02308 
02309     // Number of elements per row.
02310     Vector<int> PtrReal(n), PtrImag(n), Ptr(n);
02311     PtrReal.Zero(); PtrImag.Zero(); Ptr.Zero();
02312     for (int i = 0; i < IndRow.GetM(); i++)
02313       {
02314         IndRow(i) -= index;
02315         IndCol(i) -= index;
02316         Ptr(IndCol(i))++;
02317         if (real(Val(i)) != zero)
02318           PtrReal(IndCol(i))++;
02319 
02320         if (imag(Val(i)) != zero)
02321           PtrImag(IndCol(i))++;
02322       }
02323 
02324     // Fills matrix 'A'.
02325     A.Reallocate(m, n);
02326     int offset = 0;
02327     for (int i = 0; i < n; i++)
02328       {
02329         if (PtrReal(i) > 0)
02330           {
02331             A.ReallocateRealColumn(i, PtrReal(i));
02332             int nb = 0;
02333             for (int j = 0; j < Ptr(i); j++)
02334               if (real(Val(offset + j)) != zero)
02335                 {
02336                   A.IndexReal(i, nb) = IndRow(offset + j);
02337                   A.ValueReal(i, nb) = real(Val(offset + j));
02338                   nb++;
02339                 }
02340           }
02341 
02342         if (PtrImag(i) > 0)
02343           {
02344             A.ReallocateImagColumn(i, PtrImag(i));
02345             int nb = 0;
02346             for (int j = 0; j < Ptr(i); j++)
02347               if (imag(Val(offset + j)) != zero)
02348                 {
02349                   A.IndexImag(i, nb) = IndRow(offset + j);
02350                   A.ValueImag(i, nb) = imag(Val(offset + j));
02351                   nb++;
02352                 }
02353           }
02354 
02355         offset += Ptr(i);
02356       }
02357 
02358     // Assembles 'A' to sort row numbers.
02359     A.Assemble();
02360   }
02361 
02362 
02364   template<class T, class Prop, class Allocator1,
02365            class Allocator2, class Allocator3, class Allocator4>
02366   void
02367   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow,
02368                                  Vector<int, VectFull, Allocator2>& IndCol,
02369                                  Vector<complex<T>, VectFull, Allocator3>& Val,
02370                                  Matrix<T, Prop, ArrayRowSymComplexSparse,
02371                                  Allocator4>& A, int index)
02372   {
02373     if (IndRow.GetM() <= 0)
02374       {
02375         A.Clear();
02376         return;
02377       }
02378 
02379     T zero(0);
02380     int row_max = IndRow.GetNormInf();
02381     int col_max = IndCol.GetNormInf();
02382     int m = row_max - index + 1;
02383     int n = col_max - index + 1;
02384 
02385     // Sorts the array 'IndRow'.
02386     Sort(IndRow, IndCol, Val);
02387 
02388     // Number of elements per row.
02389     Vector<int> PtrReal(m), PtrImag(m), Ptr(m);
02390     PtrReal.Zero(); PtrImag.Zero(); Ptr.Zero();
02391     for (int i = 0; i < IndRow.GetM(); i++)
02392       {
02393         IndRow(i) -= index;
02394         IndCol(i) -= index;
02395         Ptr(IndRow(i))++;
02396         if (IndRow(i) <= IndCol(i))
02397           {
02398             if (real(Val(i)) != zero)
02399               PtrReal(IndRow(i))++;
02400 
02401             if (imag(Val(i)) != zero)
02402               PtrImag(IndRow(i))++;
02403           }
02404       }
02405 
02406     // Fills matrix 'A'.
02407     A.Reallocate(m, n);
02408     int offset = 0;
02409     for (int i = 0; i < m; i++)
02410       {
02411         if (PtrReal(i) > 0)
02412           {
02413             A.ReallocateRealRow(i, PtrReal(i));
02414             int nb = 0;
02415             for (int j = 0; j < Ptr(i); j++)
02416               if (real(Val(offset + j)) != zero)
02417                 {
02418                   if (i <= IndCol(offset+j))
02419                     {
02420                       A.IndexReal(i, nb) = IndCol(offset + j);
02421                       A.ValueReal(i, nb) = real(Val(offset + j));
02422                       nb++;
02423                     }
02424                 }
02425           }
02426 
02427         if (PtrImag(i) > 0)
02428           {
02429             A.ReallocateImagRow(i, PtrImag(i));
02430             int nb = 0;
02431             for (int j = 0; j < Ptr(i); j++)
02432               if (imag(Val(offset + j)) != zero)
02433                 {
02434                   if (i <= IndCol(offset+j))
02435                     {
02436                       A.IndexImag(i, nb) = IndCol(offset + j);
02437                       A.ValueImag(i, nb) = imag(Val(offset + j));
02438                       nb++;
02439                     }
02440                 }
02441           }
02442 
02443         offset += Ptr(i);
02444       }
02445 
02446     // Assembles 'A' to sort column numbers.
02447     A.Assemble();
02448   }
02449 
02450 
02452   template<class T, class Prop, class Allocator1,
02453            class Allocator2, class Allocator3, class Allocator4>
02454   void
02455   ConvertMatrix_from_Coordinates(Vector<int, VectFull, Allocator1>& IndRow,
02456                                  Vector<int, VectFull, Allocator2>& IndCol,
02457                                  Vector<complex<T>, VectFull, Allocator3>& Val,
02458                                  Matrix<T, Prop, ArrayColSymComplexSparse,
02459                                  Allocator4>& A, int index)
02460   {
02461     if (IndRow.GetM() <= 0)
02462       {
02463         A.Clear();
02464         return;
02465       }
02466 
02467     T zero(0);
02468     int row_max = IndRow.GetNormInf();
02469     int col_max = IndCol.GetNormInf();
02470     int m = row_max - index + 1;
02471     int n = col_max - index + 1;
02472 
02473     // Sorts the array 'IndRow'.
02474     Sort(IndCol, IndRow, Val);
02475 
02476     // Number of elements per row.
02477     Vector<int> PtrReal(m), PtrImag(m), Ptr(m);
02478     PtrReal.Zero(); PtrImag.Zero(); Ptr.Zero();
02479     for (int i = 0; i < IndRow.GetM(); i++)
02480       {
02481         IndRow(i) -= index;
02482         IndCol(i) -= index;
02483         Ptr(IndCol(i))++;
02484         if (IndRow(i) <= IndCol(i))
02485           {
02486             if (real(Val(i)) != zero)
02487               PtrReal(IndCol(i))++;
02488 
02489             if (imag(Val(i)) != zero)
02490               PtrImag(IndCol(i))++;
02491           }
02492       }
02493 
02494     // Fills matrix 'A'.
02495     A.Reallocate(m, n);
02496     int offset = 0;
02497     for (int i = 0; i < m; i++)
02498       {
02499         if (PtrReal(i) > 0)
02500           {
02501             A.ReallocateRealColumn(i, PtrReal(i));
02502             int nb = 0;
02503             for (int j = 0; j < Ptr(i); j++)
02504               if (real(Val(offset + j)) != zero)
02505                 {
02506                   if (IndRow(offset+j) <= i)
02507                     {
02508                       A.IndexReal(i, nb) = IndRow(offset + j);
02509                       A.ValueReal(i, nb) = real(Val(offset + j));
02510                       nb++;
02511                     }
02512                 }
02513           }
02514 
02515         if (PtrImag(i) > 0)
02516           {
02517             A.ReallocateImagColumn(i, PtrImag(i));
02518             int nb = 0;
02519             for (int j = 0; j < Ptr(i); j++)
02520               if (imag(Val(offset + j)) != zero)
02521                 {
02522                   if (IndRow(offset+j) <= i)
02523                     {
02524                       A.IndexImag(i, nb) = IndRow(offset + j);
02525                       A.ValueImag(i, nb) = imag(Val(offset + j));
02526                       nb++;
02527                     }
02528                 }
02529           }
02530 
02531         offset += Ptr(i);
02532       }
02533 
02534     // Assembles 'A' to sort row numbers.
02535     A.Assemble();
02536   }
02537 
02538 
02539   /*
02540     From Sparse formats to CSC format
02541   */
02542 
02543 
02545 
02549   template<class T, class Prop, class Alloc1,
02550            class Tint, class Alloc2, class Alloc3, class Alloc4>
02551   void ConvertToCSC(const Matrix<T, Prop, RowSparse, Alloc1>& A,
02552                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
02553                     Vector<Tint, VectFull, Alloc3>& IndRow,
02554                     Vector<T, VectFull, Alloc4>& Val, bool sym_pat)
02555   {
02556     // Matrix (m,n) with nnz entries.
02557     int nnz = A.GetDataSize();
02558     int n = A.GetN();
02559     int* ptr_ = A.GetPtr();
02560     int* ind_ = A.GetInd();
02561 
02562     // Conversion in coordinate format.
02563     Vector<Tint, VectFull, CallocAlloc<Tint> > IndCol;
02564     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Val);
02565 
02566     // Sorting with respect to column numbers.
02567     Sort(IndCol, IndRow, Val);
02568 
02569     // Constructing pointer array 'Ptr'.
02570     Ptr.Reallocate(n + 1);
02571     Ptr.Fill(0);
02572 
02573     // Counting non-zero entries per column.
02574     for (int i = 0; i < nnz; i++)
02575       Ptr(IndCol(i) + 1)++;
02576 
02577     int nb_new_val = 0;
02578 
02579     if (sym_pat)
02580       {
02581         // Counting entries that are on the symmetrized pattern without being
02582         // in the original pattern.
02583         int k = 0;
02584         for (int i = 0; i < n; i++)
02585           {
02586             while (k < IndCol.GetM() && IndCol(k) < i)
02587               k++;
02588 
02589             for (int j = ptr_[i]; j < ptr_[i+1]; j++)
02590               {
02591                 int irow = ind_[j];
02592                 while (k < IndCol.GetM() && IndCol(k) == i
02593                        && IndRow(k) < irow)
02594                   k++;
02595 
02596                 if (k < IndCol.GetM() && IndCol(k) == i && IndRow(k) == irow)
02597                   // Already existing entry.
02598                   k++;
02599                 else
02600                   {
02601                     // New entry.
02602                     Ptr(i + 1)++;
02603                     nb_new_val++;
02604                   }
02605               }
02606           }
02607       }
02608 
02609     // Accumulation to get pointer array.
02610     Ptr(0) = 0;
02611     for (int i = 0; i < n; i++)
02612       Ptr(i + 1) += Ptr(i);
02613 
02614     if (sym_pat && (nb_new_val > 0))
02615       {
02616         // Changing 'IndRow' and 'Val', and assembling the pattern.
02617         Vector<Tint, VectFull, Alloc3> OldInd(IndRow);
02618         Vector<T, VectFull, Alloc4> OldVal(Val);
02619         IndRow.Reallocate(nnz + nb_new_val);
02620         Val.Reallocate(nnz + nb_new_val);
02621         int k = 0, nb = 0;
02622         for (int i = 0; i < n; i++)
02623           {
02624             while (k < IndCol.GetM() && IndCol(k) < i)
02625               {
02626                 IndRow(nb) = OldInd(k);
02627                 Val(nb) = OldVal(k);
02628                 nb++;
02629                 k++;
02630               }
02631 
02632             for (int j = ptr_[i]; j < ptr_[i+1]; j++)
02633               {
02634                 int irow = ind_[j];
02635                 while (k < IndCol.GetM() && IndCol(k) == i
02636                        && OldInd(k) < irow)
02637                   {
02638                     IndRow(nb) = OldInd(k);
02639                     Val(nb) = OldVal(k);
02640                     nb++;
02641                     k++;
02642                   }
02643 
02644                 if (k < IndCol.GetM() && IndCol(k) == i && OldInd(k) == irow)
02645                   {
02646                     // Already existing entry.
02647                     IndRow(nb) = OldInd(k);
02648                     Val(nb) = OldVal(k);
02649                     nb++;
02650                     k++;
02651                   }
02652                 else
02653                   {
02654                     // New entry (null).
02655                     IndRow(nb) = irow;
02656                     Val(nb) = 0;
02657                     nb++;
02658                   }
02659               }
02660           }
02661       }
02662   }
02663 
02664 
02666   template<class T, class Prop, class Alloc1,
02667            class Tint, class Alloc2, class Alloc3, class Alloc4>
02668   void ConvertToCSC(const Matrix<T, Prop, ArrayRowSparse, Alloc1>& A,
02669                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
02670                     Vector<Tint, VectFull, Alloc3>& IndRow,
02671                     Vector<T, VectFull, Alloc4>& Val, bool sym_pat)
02672   {
02673     // Matrix (m,n) with nnz entries.
02674     int nnz = A.GetDataSize();
02675     int n = A.GetN();
02676 
02677     // Conversion in coordinate format.
02678     Vector<Tint, VectFull, CallocAlloc<Tint> > IndCol;
02679     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Val);
02680 
02681     // Sorting with respect to column numbers.
02682     Sort(IndCol, IndRow, Val);
02683 
02684     // Constructing pointer array 'Ptr'.
02685     Ptr.Reallocate(n + 1);
02686     Ptr.Fill(0);
02687 
02688     // Counting non-zero entries per column.
02689     for (int i = 0; i < nnz; i++)
02690       Ptr(IndCol(i) + 1)++;
02691 
02692     int nb_new_val = 0;
02693 
02694     if (sym_pat)
02695       {
02696         // Counting entries that are on the symmetrized pattern without being
02697         // in the original pattern.
02698         int k = 0;
02699         for (int i = 0; i < n; i++)
02700           {
02701             while (k < IndCol.GetM() && IndCol(k) < i)
02702               k++;
02703 
02704             for (int j = 0; j < A.GetRowSize(i); j++)
02705               {
02706                 int irow = A.Index(i, j);
02707                 while (k < IndCol.GetM() && IndCol(k) == i
02708                        && IndRow(k) < irow)
02709                   k++;
02710 
02711                 if (k < IndCol.GetM() && IndCol(k) == i && IndRow(k) == irow)
02712                   // Already existing entry.
02713                   k++;
02714                 else
02715                   {
02716                     // New entry.
02717                     Ptr(i + 1)++;
02718                     nb_new_val++;
02719                   }
02720               }
02721           }
02722       }
02723 
02724     // Accumulation to get pointer array.
02725     Ptr(0) = 0;
02726     for (int i = 0; i < n; i++)
02727       Ptr(i + 1) += Ptr(i);
02728 
02729     if (sym_pat && (nb_new_val > 0))
02730       {
02731         // Changing 'IndRow' and 'Val', and assembling the pattern.
02732         Vector<Tint, VectFull, Alloc3> OldInd(IndRow);
02733         Vector<T, VectFull, Alloc4> OldVal(Val);
02734         IndRow.Reallocate(nnz + nb_new_val);
02735         Val.Reallocate(nnz + nb_new_val);
02736         int k = 0, nb = 0;
02737         for (int i = 0; i < n; i++)
02738           {
02739             while (k < IndCol.GetM() && IndCol(k) < i)
02740               {
02741                 IndRow(nb) = OldInd(k);
02742                 Val(nb) = OldVal(k);
02743                 nb++;
02744                 k++;
02745               }
02746 
02747             for (int j = 0; j < A.GetRowSize(i); j++)
02748               {
02749                 int irow = A.Index(i, j);
02750                 while (k < IndCol.GetM() && IndCol(k) == i
02751                        && OldInd(k) < irow)
02752                   {
02753                     IndRow(nb) = OldInd(k);
02754                     Val(nb) = OldVal(k);
02755                     nb++;
02756                     k++;
02757                   }
02758 
02759                 if (k < IndCol.GetM() && IndCol(k) == i && OldInd(k) == irow)
02760                   {
02761                     // Already existing entry.
02762                     IndRow(nb) = OldInd(k);
02763                     Val(nb) = OldVal(k);
02764                     nb++;
02765                     k++;
02766                   }
02767                 else
02768                   {
02769                     // New entry (null).
02770                     IndRow(nb) = irow;
02771                     Val(nb) = 0;
02772                     nb++;
02773                   }
02774               }
02775           }
02776       }
02777   }
02778 
02779 
02781   template<class T, class Prop, class Alloc1,
02782            class Tint, class Alloc2, class Alloc3, class Alloc4>
02783   void ConvertToCSC(const Matrix<T, Prop, ColSparse, Alloc1>& A,
02784                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
02785                     Vector<Tint, VectFull, Alloc3>& IndRow,
02786                     Vector<T, VectFull, Alloc4>& Val, bool sym_pat)
02787   {
02788     // Matrix (m,n) with 'nnz' entries.
02789     int nnz = A.GetDataSize();
02790     int n = A.GetN();
02791     int* ptr_ = A.GetPtr();
02792     int* ind_ = A.GetInd();
02793     T* data_ = A.GetData();
02794 
02795     // Conversion in coordinate format.
02796     Vector<Tint, VectFull, CallocAlloc<Tint> > IndCol;
02797     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Val);
02798 
02799     // Sorting with respect to row numbers.
02800     Sort(IndRow, IndCol, Val);
02801 
02802     // Constructing pointer array 'Ptr'.
02803     Ptr.Reallocate(n + 1);
02804     Ptr.Fill(0);
02805 
02806     // Counting non-zero entries per column.
02807     for (int i = 0; i < nnz; i++)
02808       Ptr(IndCol(i) + 1)++;
02809 
02810     int nb_new_val = 0;
02811 
02812     if (sym_pat)
02813       {
02814         // Counting entries that are on the symmetrized pattern without being
02815         // in the original pattern.
02816         int k = 0;
02817         for (int i = 0; i < n; i++)
02818           {
02819             while (k < IndRow.GetM() && IndRow(k) < i)
02820               k++;
02821 
02822             for (int j = ptr_[i]; j < ptr_[i+1]; j++)
02823               {
02824                 int icol = ind_[j];
02825                 while (k < IndRow.GetM() && IndRow(k) == i
02826                        && IndCol(k) < icol)
02827                   k++;
02828 
02829                 if (k < IndRow.GetM() && IndRow(k) == i && IndCol(k) == icol)
02830                   // Already existing entry.
02831                   k++;
02832                 else
02833                   {
02834                     // New entry.
02835                     Ptr(i + 1)++;
02836                     nb_new_val++;
02837                   }
02838               }
02839           }
02840       }
02841 
02842     // Accumulation to get pointer array.
02843     Ptr(0) = 0;
02844     for (int i = 0; i < n; i++)
02845       Ptr(i + 1) += Ptr(i);
02846 
02847     if (sym_pat && (nb_new_val > 0))
02848       {
02849         // Changing 'IndRow' and 'Val', and assembling the pattern.
02850         Vector<Tint, VectFull, Alloc3> OldInd(IndRow);
02851         Vector<T, VectFull, Alloc4> OldVal(Val);
02852         IndRow.Reallocate(nnz + nb_new_val);
02853         Val.Reallocate(nnz + nb_new_val);
02854         int k = 0, nb = 0;
02855         for (int i = 0; i < n; i++)
02856           {
02857             while (k < OldInd.GetM() && OldInd(k) < i)
02858               {
02859                 // null entries (due to symmetrisation)
02860                 IndRow(nb) = IndCol(k);
02861                 Val(nb) = 0;
02862                 nb++;
02863                 k++;
02864               }
02865 
02866             for (int j = ptr_[i]; j < ptr_[i+1]; j++)
02867               {
02868                 int irow = ind_[j];
02869                 while (k < OldInd.GetM() && OldInd(k) == i
02870                        && IndCol(k) < irow)
02871                   {
02872                     // null entries (due to symmetrisation)
02873                     IndRow(nb) = IndCol(k);
02874                     Val(nb) = 0;
02875                     nb++;
02876                     k++;
02877                   }
02878 
02879                 if (k < OldInd.GetM() && OldInd(k) == i && IndCol(k) == irow)
02880                   {
02881                     // Already existing entry.
02882                     IndRow(nb) = IndCol(k);
02883                     Val(nb) = data_[j];
02884                     nb++;
02885                     k++;
02886                   }
02887                 else
02888                   {
02889                     // New entry
02890                     IndRow(nb) = irow;
02891                     Val(nb) = data_[j];
02892                     nb++;
02893                   }
02894               }
02895           }
02896       }
02897     else
02898       {
02899         // sorting by columns
02900         Sort(IndCol, IndRow, Val);
02901       }
02902 
02903   }
02904 
02905 
02907   template<class T, class Prop, class Alloc1,
02908            class Tint, class Alloc2, class Alloc3, class Alloc4>
02909   void ConvertToCSC(const Matrix<T, Prop, ArrayColSparse, Alloc1>& A,
02910                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
02911                     Vector<Tint, VectFull, Alloc3>& IndRow,
02912                     Vector<T, VectFull, Alloc4>& Val, bool sym_pat)
02913   {
02914     // Matrix (m,n) with 'nnz' entries.
02915     int nnz = A.GetDataSize();
02916     int n = A.GetN();
02917 
02918     // Conversion in coordinate format.
02919     Vector<Tint, VectFull, CallocAlloc<Tint> > IndCol;
02920     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Val);
02921 
02922     // Sorting with respect to row numbers.
02923     Sort(IndRow, IndCol, Val);
02924 
02925     // Constructing pointer array 'Ptr'.
02926     Ptr.Reallocate(n + 1);
02927     Ptr.Fill(0);
02928 
02929     // Counting non-zero entries per column.
02930     for (int i = 0; i < nnz; i++)
02931       Ptr(IndCol(i) + 1)++;
02932 
02933     int nb_new_val = 0;
02934 
02935     if (sym_pat)
02936       {
02937         // Counting entries that are on the symmetrized pattern without being
02938         // in the original pattern.
02939         int k = 0;
02940         for (int i = 0; i < n; i++)
02941           {
02942             while (k < IndRow.GetM() && IndRow(k) < i)
02943               k++;
02944 
02945             for (int j = 0; j < A.GetColumnSize(i); j++)
02946               {
02947                 int icol = A.Index(i, j);
02948                 while (k < IndRow.GetM() && IndRow(k) == i
02949                        && IndCol(k) < icol)
02950                   k++;
02951 
02952                 if (k < IndRow.GetM() && IndRow(k) == i && IndCol(k) == icol)
02953                   // Already existing entry.
02954                   k++;
02955                 else
02956                   {
02957                     // New entry.
02958                     Ptr(i + 1)++;
02959                     nb_new_val++;
02960                   }
02961               }
02962           }
02963       }
02964 
02965     // Accumulation to get pointer array.
02966     Ptr(0) = 0;
02967     for (int i = 0; i < n; i++)
02968       Ptr(i + 1) += Ptr(i);
02969 
02970     if (sym_pat && (nb_new_val > 0))
02971       {
02972         // Changing 'IndRow' and 'Val', and assembling the pattern.
02973         Vector<Tint, VectFull, Alloc3> OldInd(IndRow);
02974         Vector<T, VectFull, Alloc4> OldVal(Val);
02975         IndRow.Reallocate(nnz + nb_new_val);
02976         Val.Reallocate(nnz + nb_new_val);
02977         int k = 0, nb = 0;
02978         for (int i = 0; i < n; i++)
02979           {
02980             while (k < OldInd.GetM() && OldInd(k) < i)
02981               {
02982                 // null entries (due to symmetrisation)
02983                 IndRow(nb) = IndCol(k);
02984                 Val(nb) = 0;
02985                 nb++;
02986                 k++;
02987               }
02988 
02989             for (int j = 0; j < A.GetColumnSize(i); j++)
02990               {
02991                 int irow = A.Index(i, j);
02992                 while (k < OldInd.GetM() && OldInd(k) == i
02993                        && IndCol(k) < irow)
02994                   {
02995                     // null entries (due to symmetrisation)
02996                     IndRow(nb) = IndCol(k);
02997                     Val(nb) = 0;
02998                     nb++;
02999                     k++;
03000                   }
03001 
03002                 if (k < OldInd.GetM() && OldInd(k) == i && IndCol(k) == irow)
03003                   {
03004                     // Already existing entry.
03005                     IndRow(nb) = IndCol(k);
03006                     Val(nb) = A.Value(i, j);
03007                     nb++;
03008                     k++;
03009                   }
03010                 else
03011                   {
03012                     // New entry
03013                     IndRow(nb) = irow;
03014                     Val(nb) = A.Value(i, j);
03015                     nb++;
03016                   }
03017               }
03018           }
03019       }
03020     else
03021       {
03022         // sorting by columns
03023         Sort(IndCol, IndRow, Val);
03024       }
03025 
03026   }
03027 
03028 
03030   template<class T, class Prop, class Alloc1,
03031            class Tint, class Alloc2, class Alloc3, class Alloc4>
03032   void ConvertToCSC(const Matrix<T, Prop, ColSymSparse, Alloc1>& A,
03033                     Symmetric& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03034                     Vector<Tint, VectFull, Alloc3>& Ind,
03035                     Vector<T, VectFull, Alloc4>& Value, bool sym_pat)
03036   {
03037     int n = A.GetN();
03038     int nnz = A.GetDataSize();
03039 
03040     Ptr.Reallocate(n+1);
03041     Ind.Reallocate(nnz);
03042     Value.Reallocate(nnz);
03043 
03044     int* ptr_ = A.GetPtr();
03045     int* ind_ = A.GetInd();
03046     T* data_ = A.GetData();
03047     for (int i = 0; i <= n; i++)
03048       Ptr(i) = ptr_[i];
03049 
03050     for (int i = 0; i < nnz; i++)
03051       {
03052         Ind(i) = ind_[i];
03053         Value(i) = data_[i];
03054       }
03055   }
03056 
03057 
03059   template<class T, class Prop, class Alloc1,
03060            class Tint, class Alloc2, class Alloc3, class Alloc4>
03061   void ConvertToCSC(const Matrix<T, Prop, ColSymSparse, Alloc1>& A,
03062                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03063                     Vector<Tint, VectFull, Alloc3>& IndRow,
03064                     Vector<T, VectFull, Alloc4>& Value, bool sym_pat)
03065   {
03066     int n = A.GetN();
03067 
03068     Vector<Tint, VectFull, Alloc3> IndCol;
03069 
03070     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Value, 0, true);
03071 
03072     // sorting by columns
03073     Sort(IndCol, IndRow, Value);
03074 
03075     Ptr.Reallocate(n+1);
03076     Ptr.Zero();
03077     // counting number of non-zero entries
03078     int nnz = 0;
03079     for (int i = 0; i < IndCol.GetM(); i++)
03080       {
03081         Ptr(IndCol(i) + 1)++;
03082         nnz++;
03083       }
03084 
03085     // incrementing Ptr
03086     for (int i = 2; i <= n; i++)
03087       Ptr(i) += Ptr(i-1);
03088 
03089   }
03090 
03091 
03093   template<class T, class Prop, class Alloc1,
03094            class Tint, class Alloc2, class Alloc3, class Alloc4>
03095   void ConvertToCSC(const Matrix<T, Prop, ArrayColSymSparse, Alloc1>& A,
03096                     Symmetric& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03097                     Vector<Tint, VectFull, Alloc3>& Ind,
03098                     Vector<T, VectFull, Alloc4>& Value, bool sym_pat)
03099   {
03100     int n = A.GetN();
03101     int nnz = A.GetDataSize();
03102 
03103     Ptr.Reallocate(n+1);
03104     Ind.Reallocate(nnz);
03105     Value.Reallocate(nnz);
03106 
03107     Ptr(0) = 0;
03108     for (int i = 1; i <= n; i++)
03109       Ptr(i) = Ptr(i-1) + A.GetColumnSize(i);
03110 
03111     int nb = 0;
03112     for (int i = 0; i < n; i++)
03113       for (int j = 0; j < A.GetColumnSize(i); j++)
03114         {
03115           Ind(nb) = A.Index(i, j);
03116           Value(nb) = A.Value(i, j);
03117           nb++;
03118         }
03119   }
03120 
03121 
03123   template<class T, class Prop, class Alloc1,
03124            class Tint, class Alloc2, class Alloc3, class Alloc4>
03125   void ConvertToCSC(const Matrix<T, Prop, ArrayColSymSparse, Alloc1>& A,
03126                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03127                     Vector<Tint, VectFull, Alloc3>& IndRow,
03128                     Vector<T, VectFull, Alloc4>& Value, bool sym_pat)
03129   {
03130     int n = A.GetN();
03131 
03132     Vector<Tint, VectFull, Alloc3> IndCol;
03133 
03134     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Value, 0, true);
03135 
03136     // sorting by columns
03137     Sort(IndCol, IndRow, Value);
03138 
03139     Ptr.Reallocate(n+1);
03140     Ptr.Zero();
03141     // counting number of non-zero entries
03142     int nnz = 0;
03143     for (int i = 0; i < IndCol.GetM(); i++)
03144       {
03145         Ptr(IndCol(i) + 1)++;
03146         nnz++;
03147       }
03148 
03149     // incrementing Ptr
03150     for (int i = 2; i <= n; i++)
03151       Ptr(i) += Ptr(i-1);
03152 
03153   }
03154 
03155 
03157   template<class T, class Prop, class Alloc1,
03158            class Tint, class Alloc2, class Alloc3, class Alloc4>
03159   void ConvertToCSC(const Matrix<T, Prop, RowSymSparse, Alloc1>& A,
03160                     Symmetric& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03161                     Vector<Tint, VectFull, Alloc3>& IndRow,
03162                     Vector<T, VectFull, Alloc4>& Value, bool sym_pat)
03163   {
03164     Vector<Tint, VectFull, Alloc3> IndCol;
03165 
03166     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Value, 0, false);
03167 
03168     // sorting by columns
03169     Sort(IndCol, IndRow, Value);
03170 
03171     int n = A.GetN();
03172     int nnz = A.GetDataSize();
03173 
03174     // creating pointer array
03175     Ptr.Reallocate(n+1);
03176     Ptr.Fill(0);
03177     for (int i = 0; i < nnz; i++)
03178       Ptr(IndCol(i) + 1)++;
03179 
03180     for (int i = 0; i < n; i++)
03181       Ptr(i+1) += Ptr(i);
03182   }
03183 
03184 
03186   template<class T, class Prop, class Alloc1,
03187            class Tint, class Alloc2, class Alloc3, class Alloc4>
03188   void ConvertToCSC(const Matrix<T, Prop, RowSymSparse, Alloc1>& A,
03189                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03190                     Vector<Tint, VectFull, Alloc3>& IndRow,
03191                     Vector<T, VectFull, Alloc4>& Value, bool sym_pat)
03192   {
03193     int n = A.GetN();
03194 
03195     Vector<Tint, VectFull, Alloc2> IndCol;
03196 
03197     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Value, 0, true);
03198 
03199     // sorting by columns
03200     Sort(IndCol, IndRow, Value);
03201 
03202     Ptr.Reallocate(n+1);
03203     Ptr.Zero();
03204     // counting number of non-zero entries
03205     int nnz = 0;
03206     for (int i = 0; i < IndCol.GetM(); i++)
03207       {
03208         Ptr(IndCol(i) + 1)++;
03209         nnz++;
03210       }
03211 
03212     // incrementing Ptr
03213     for (int i = 2; i <= n; i++)
03214       Ptr(i) += Ptr(i-1);
03215 
03216   }
03217 
03218 
03220   template<class T, class Prop, class Alloc1,
03221            class Tint, class Alloc2, class Alloc3, class Alloc4>
03222   void ConvertToCSC(const Matrix<T, Prop, ArrayRowSymSparse, Alloc1>& A,
03223                     Symmetric& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03224                     Vector<Tint, VectFull, Alloc3>& IndRow,
03225                     Vector<T, VectFull, Alloc4>& Value, bool sym_pat)
03226   {
03227     Vector<Tint, VectFull, Alloc3> IndCol;
03228 
03229     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Value, 0, false);
03230 
03231     // sorting by columns
03232     Sort(IndCol, IndRow, Value);
03233 
03234     int n = A.GetN();
03235     int nnz = A.GetDataSize();
03236 
03237     // creating pointer array
03238     Ptr.Reallocate(n+1);
03239     Ptr.Fill(0);
03240     for (int i = 0; i < nnz; i++)
03241       Ptr(IndCol(i) + 1)++;
03242 
03243     for (int i = 0; i < n; i++)
03244       Ptr(i+1) += Ptr(i);
03245   }
03246 
03247 
03249   template<class T, class Prop, class Alloc1,
03250            class Tint, class Alloc2, class Alloc3, class Alloc4>
03251   void ConvertToCSC(const Matrix<T, Prop, ArrayRowSymSparse, Alloc1>& A,
03252                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03253                     Vector<Tint, VectFull, Alloc3>& Ind,
03254                     Vector<T, VectFull, Alloc4>& AllVal, bool sym_pat)
03255   {
03256     int i, j;
03257 
03258     int nnz = A.GetDataSize();
03259     int n = A.GetM();
03260     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
03261     Vector<T> Val(nnz);
03262     int ind = 0;
03263     for (i = 0; i < n; i++)
03264       for (j = 0; j < A.GetRowSize(i); j++)
03265         if (A.Index(i, j) != i)
03266           {
03267             IndRow(ind) = i;
03268             IndCol(ind) = A.Index(i, j);
03269             Val(ind) = A.Value(i, j);
03270             ind++;
03271           }
03272 
03273     Sort(ind, IndCol, IndRow, Val);
03274 
03275     Ptr.Reallocate(n+1);
03276     Ind.Reallocate(nnz + ind);
03277     AllVal.Reallocate(nnz+ind);
03278     nnz = ind;
03279     ind = 0;
03280 
03281     int offset = 0; Ptr(0) = 0;
03282     for (i = 0; i < n; i++)
03283       {
03284         int first_index = ind;
03285         while (ind < nnz && IndCol(ind) <= i)
03286           ind++;
03287 
03288         int size_lower = ind - first_index;
03289         int size_upper = A.GetRowSize(i);
03290         int size_row = size_lower + size_upper;
03291 
03292         ind = first_index;
03293         for (j = 0; j < size_lower; j++)
03294           {
03295             Ind(offset+j) = IndRow(ind);
03296             AllVal(offset+j) = Val(ind);
03297             ind++;
03298           }
03299 
03300         for (j = 0; j < size_upper; j++)
03301           {
03302             Ind(offset + size_lower + j) = A.Index(i, j);
03303             AllVal(offset + size_lower + j) = A.Value(i, j);
03304           }
03305 
03306         offset += size_row; Ptr(i+1) = offset;
03307       }
03308   }
03309 
03310 
03312   template<class T, class Prop, class Storage, class Allocator>
03313   void Copy(const Matrix<T, Prop, Storage, Allocator>& A,
03314             Matrix<T, Prop, Storage, Allocator>& B)
03315   {
03316     B = A;
03317   }
03318 
03319 
03321   template<class T0, class Prop0, class Allocator0,
03322            class T1, class Prop1, class Allocator1>
03323   void Copy(const Matrix<T0, Prop0, ArrayColSparse, Allocator0>& mat_array,
03324             Matrix<T1, Prop1, ColSparse, Allocator1>& mat_csc)
03325   {
03326     Vector<T1, VectFull, Allocator1> Val;
03327     Vector<int, VectFull, CallocAlloc<int> > IndRow;
03328     Vector<int, VectFull, CallocAlloc<int> > IndCol;
03329 
03330     General sym;
03331     ConvertToCSC(mat_array, sym, IndCol, IndRow, Val);
03332 
03333     int m = mat_array.GetM();
03334     int n = mat_array.GetN();
03335 
03336     mat_csc.SetData(m, n, Val, IndCol, IndRow);
03337   }
03338 
03339 
03341   template<class T, class Prop, class Alloc1, class Alloc2>
03342   void Copy(const Matrix<T, Prop, RowSparse, Alloc1>& A,
03343             Matrix<T, Prop, ColSparse, Alloc2>& B)
03344   {
03345     Vector<int, VectFull, CallocAlloc<int> > Ptr;
03346     Vector<int, VectFull, CallocAlloc<int> > Ind;
03347     Vector<T, VectFull, Alloc2> Val;
03348 
03349     int m = A.GetM(), n = A.GetN();
03350     General sym;
03351     ConvertToCSC(A, sym, Ptr, Ind, Val);
03352 
03353     B.SetData(m, n, Val, Ptr, Ind);
03354   }
03355 
03356 
03358   template<class T0, class Prop0, class Allocator0,
03359            class T1, class Prop1, class Allocator1>
03360   void Copy(const Matrix<T0, Prop0, ArrayRowSparse,Allocator0>& mat_array,
03361             Matrix<T1, Prop1, ColSparse, Allocator1>& mat_csr)
03362   {
03363     Vector<int, VectFull, CallocAlloc<int> > Ptr, IndRow;
03364     Vector<T1, VectFull, Allocator1> Val;
03365 
03366     int m = mat_array.GetM();
03367     int n = mat_array.GetN();
03368     General sym;
03369     ConvertToCSC(mat_array, sym, Ptr, IndRow, Val);
03370 
03371     mat_csr.SetData(m, n, Val, Ptr, IndRow);
03372   }
03373 
03374 
03376   template<class T, class Prop1, class Prop2, class Alloc1, class Alloc2>
03377   void Copy(const Matrix<T, Prop1, RowSymSparse, Alloc1>& A,
03378             Matrix<T, Prop2, ColSparse, Alloc2>& B)
03379   {
03380     Vector<int, VectFull, CallocAlloc<int> > Ptr;
03381     Vector<int, VectFull, CallocAlloc<int> > Ind;
03382     Vector<T, VectFull, Alloc2> Val;
03383 
03384     int m = A.GetM(), n = A.GetN();
03385     General sym;
03386     ConvertToCSC(A, sym, Ptr, Ind, Val);
03387 
03388     B.SetData(m, n, Val, Ptr, Ind);
03389   }
03390 
03391 
03392   template<class T0, class Prop0, class Allocator0,
03393            class T1, class Prop1, class Allocator1>
03394   void Copy(const Matrix<T0, Prop0, ArrayRowSymSparse, Allocator0>& A,
03395             Matrix<T1, Prop1, ColSparse, Allocator1>& B)
03396   {
03397     Vector<int, VectFull, CallocAlloc<int> > Ptr, Ind;
03398     Vector<T1> AllVal;
03399 
03400     int n = A.GetM();
03401     General sym;
03402     ConvertToCSC(A, sym, Ptr, Ind, AllVal);
03403 
03404     B.SetData(n, n, AllVal, Ptr, Ind);
03405   }
03406 
03407 
03409   template<class T, class Prop1, class Prop2, class Alloc1, class Alloc2>
03410   void Copy(const Matrix<T, Prop1, ColSymSparse, Alloc1>& A,
03411             Matrix<T, Prop2, ColSparse, Alloc2>& B)
03412   {
03413     Vector<int, VectFull, CallocAlloc<int> > Ptr;
03414     Vector<int, VectFull, CallocAlloc<int> > Ind;
03415     Vector<T, VectFull, Alloc2> Val;
03416 
03417     int m = A.GetM(), n = A.GetN();
03418     General sym;
03419     ConvertToCSC(A, sym, Ptr, Ind, Val);
03420 
03421     B.SetData(m, n, Val, Ptr, Ind);
03422   }
03423 
03424 
03426   template<class T, class Prop1, class Prop2, class Alloc1, class Alloc2>
03427   void Copy(const Matrix<T, Prop1, ArrayColSymSparse, Alloc1>& A,
03428             Matrix<T, Prop2, ColSparse, Alloc2>& B)
03429   {
03430     Vector<int, VectFull, CallocAlloc<int> > Ptr;
03431     Vector<int, VectFull, CallocAlloc<int> > Ind;
03432     Vector<T, VectFull, Alloc2> Val;
03433 
03434     int m = A.GetM(), n = A.GetN();
03435     General sym;
03436     ConvertToCSC(A, sym, Ptr, Ind, Val);
03437 
03438     B.SetData(m, n, Val, Ptr, Ind);
03439   }
03440 
03441 
03442   /*
03443     From Sparse formats to CSR format
03444   */
03445 
03446 
03448   template<class T, class Prop, class Alloc1,
03449            class Tint, class Alloc2, class Alloc3, class Alloc4>
03450   void ConvertToCSR(const Matrix<T, Prop, ColSparse, Alloc1>& A,
03451                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03452                     Vector<Tint, VectFull, Alloc3>& IndCol,
03453                     Vector<T, VectFull, Alloc4>& Value)
03454   {
03455     int m = A.GetM();
03456     int n = A.GetN();
03457     int  nnz = A.GetDataSize();
03458     if (m <= 0)
03459       {
03460         Ptr.Clear();
03461         IndCol.Clear();
03462         Value.Clear();
03463         return;
03464       }
03465 
03466     int* ptr_ = A.GetPtr();
03467     int* ind_ = A.GetInd();
03468     T* data_ = A.GetData();
03469 
03470     // Computation of the indexes of the beginning of rows.
03471     Ptr.Reallocate(m + 1);
03472     Ptr.Fill(0);
03473     // Counting the number of entries per row.
03474     for (int i = 0; i < nnz; i++)
03475       Ptr(ind_[i])++;
03476 
03477     // Incrementing in order to get the row indexes.
03478     int increment = 0, size, num_row;
03479     for (int i = 0; i < m; i++)
03480       {
03481         size = Ptr(i);
03482         Ptr(i) = increment;
03483         increment += size;
03484       }
03485 
03486     // Last index.
03487     Ptr(m) = increment;
03488 
03489     // 'Offset' will be used to get current positions of new entries.
03490     Vector<int, VectFull, CallocAlloc<int> > Offset(Ptr);
03491     IndCol.Reallocate(nnz);
03492     Value.Reallocate(nnz);
03493 
03494     // Loop over the columns.
03495     for (int j = 0; j < n; j++)
03496       for (int i = ptr_[j]; i < ptr_[j + 1]; i++)
03497         {
03498           num_row = ind_[i];
03499           IndCol(Offset(num_row)) = j;
03500           Value(Offset(num_row)) = data_[i];
03501           Offset(num_row)++;
03502         }
03503   }
03504 
03505 
03507   template<class T, class Prop, class Alloc1,
03508            class Tint, class Alloc2, class Alloc3, class Alloc4>
03509   void ConvertToCSR(const Matrix<T, Prop, ArrayColSparse, Alloc1>& A,
03510                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03511                     Vector<Tint, VectFull, Alloc3>& IndCol,
03512                     Vector<T, VectFull, Alloc4>& Value)
03513   {
03514     int m = A.GetM();
03515     int n = A.GetN();
03516     int  nnz = A.GetDataSize();
03517     if (m <= 0)
03518       {
03519         Ptr.Clear();
03520         IndCol.Clear();
03521         Value.Clear();
03522         return;
03523       }
03524 
03525     // Computation of the indexes of the beginning of rows.
03526     Ptr.Reallocate(m + 1);
03527     Ptr.Fill(0);
03528     // Counting the number of entries per row.
03529     for (int i = 0; i < n; i++)
03530       for (int j = 0; j < A.GetColumnSize(i); j++)
03531         Ptr(A.Index(i, j))++;
03532 
03533     // Incrementing in order to get the row indexes.
03534     int increment = 0, size, num_row;
03535     for (int i = 0; i < m; i++)
03536       {
03537         size = Ptr(i);
03538         Ptr(i) = increment;
03539         increment += size;
03540       }
03541 
03542     // Last index.
03543     Ptr(m) = increment;
03544 
03545     // 'Offset' will be used to get current positions of new entries.
03546     Vector<int, VectFull, CallocAlloc<int> > Offset(Ptr);
03547     IndCol.Reallocate(nnz);
03548     Value.Reallocate(nnz);
03549 
03550     // Loop over the columns.
03551     for (int j = 0; j < n; j++)
03552       for (int i = 0; i < A.GetColumnSize(j); i++)
03553         {
03554           num_row = A.Index(j, i);
03555           IndCol(Offset(num_row)) = j;
03556           Value(Offset(num_row)) = A.Value(j, i);
03557           Offset(num_row)++;
03558         }
03559   }
03560 
03561 
03563   template<class T, class Prop, class Alloc1,
03564            class Tint, class Alloc2, class Alloc3, class Alloc4>
03565   void ConvertToCSR(const Matrix<T, Prop, ColSymSparse, Alloc1>& A,
03566                     Symmetric& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03567                     Vector<Tint, VectFull, Alloc3>& IndCol,
03568                     Vector<T, VectFull, Alloc4>& Value)
03569   {
03570     Vector<Tint, VectFull, Alloc3> IndRow;
03571 
03572     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Value, 0, false);
03573 
03574     // sorting by rows
03575     Sort(IndRow, IndCol, Value);
03576 
03577     int m = A.GetM();
03578     Ptr.Reallocate(m+1);
03579     Ptr.Zero();
03580 
03581     for (int i = 0; i < IndCol.GetM(); i++)
03582       Ptr(IndRow(i) + 1)++;
03583 
03584     // incrementing Ptr
03585     for (int i = 2; i <= m; i++)
03586       Ptr(i) += Ptr(i-1);
03587   }
03588 
03589 
03591   template<class T, class Prop, class Alloc1,
03592            class Tint, class Alloc2, class Alloc3, class Alloc4>
03593   void ConvertToCSR(const Matrix<T, Prop, ColSymSparse, Alloc1>& A,
03594                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03595                     Vector<Tint, VectFull, Alloc3>& IndCol,
03596                     Vector<T, VectFull, Alloc4>& Value)
03597   {
03598     Vector<Tint, VectFull, Alloc3> IndRow;
03599 
03600     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Value, 0, true);
03601 
03602     // sorting by rows
03603     Sort(IndRow, IndCol, Value);
03604 
03605     int m = A.GetM();
03606     Ptr.Reallocate(m+1);
03607     Ptr.Zero();
03608 
03609     for (int i = 0; i < IndCol.GetM(); i++)
03610       Ptr(IndRow(i) + 1)++;
03611 
03612     // incrementing Ptr
03613     for (int i = 2; i <= m; i++)
03614       Ptr(i) += Ptr(i-1);
03615 
03616   }
03617 
03618 
03620   template<class T, class Prop, class Alloc1,
03621            class Tint, class Alloc2, class Alloc3, class Alloc4>
03622   void ConvertToCSR(const Matrix<T, Prop, ArrayColSymSparse, Alloc1>& A,
03623                     Symmetric& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03624                     Vector<Tint, VectFull, Alloc3>& IndCol,
03625                     Vector<T, VectFull, Alloc4>& Value)
03626   {
03627     Vector<Tint, VectFull, Alloc3> IndRow;
03628 
03629     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Value, 0, false);
03630 
03631     // sorting by rows
03632     Sort(IndRow, IndCol, Value);
03633 
03634     int m = A.GetM();
03635     Ptr.Reallocate(m+1);
03636     Ptr.Zero();
03637 
03638     for (int i = 0; i < IndCol.GetM(); i++)
03639       Ptr(IndRow(i) + 1)++;
03640 
03641     // incrementing Ptr
03642     for (int i = 2; i <= m; i++)
03643       Ptr(i) += Ptr(i-1);
03644   }
03645 
03646 
03648   template<class T, class Prop, class Alloc1,
03649            class Tint, class Alloc2, class Alloc3, class Alloc4>
03650   void ConvertToCSR(const Matrix<T, Prop, ArrayColSymSparse, Alloc1>& A,
03651                     General& sym, Vector<Tint, VectFull, Alloc2>& Ptr,
03652                     Vector<Tint, VectFull, Alloc3>& IndCol,
03653                     Vector<T, VectFull, Alloc4>& Value)
03654   {
03655     Vector<Tint, VectFull, Alloc3> IndRow;
03656 
03657     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Value, 0, true);
03658 
03659     // sorting by rows
03660     Sort(IndRow, IndCol, Value);
03661 
03662     int m = A.GetM();
03663     Ptr.Reallocate(m+1);
03664     Ptr.Zero();
03665 
03666     for (int i = 0; i < IndCol.GetM(); i++)
03667       Ptr(IndRow(i) + 1)++;
03668 
03669     // incrementing Ptr
03670     for (int i = 2; i <= m; i++)
03671       Ptr(i) += Ptr(i-1);
03672   }
03673 
03674 
03676   template<class T, class Prop, class Alloc1,
03677            class Tint, class Alloc2, class Alloc3, class Alloc4>
03678   void ConvertToCSR(const Matrix<T, Prop, ArrayRowSparse, Alloc1>& A,
03679                     General& sym, Vector<Tint, VectFull, Alloc2>& IndRow,
03680                     Vector<Tint, VectFull, Alloc3>& IndCol,
03681                     Vector<T, VectFull, Alloc4>& Val)
03682   {
03683     // Matrix (m,n) with 'nnz' entries.
03684     int nnz = A.GetDataSize();
03685     int m = A.GetM();
03686 
03687     // Allocating arrays needed for CSR format.
03688     Val.Reallocate(nnz);
03689     IndRow.Reallocate(m + 1);
03690     IndCol.Reallocate(nnz);
03691 
03692     // Filling the arrays.
03693     int ind = 0;
03694     IndRow(0) = 0;
03695     for (int i = 0; i < m; i++)
03696       {
03697         for (int k = 0; k < A.GetRowSize(i); k++)
03698           {
03699             IndCol(ind) = A.Index(i, k);
03700             Val(ind) = A.Value(i, k);
03701             ind++;
03702           }
03703         IndRow(i + 1) = ind;
03704       }
03705   }
03706 
03707 
03709   template<class T, class Prop, class Alloc1,
03710            class Tint, class Alloc2, class Alloc3, class Alloc4>
03711   void ConvertToCSR(const Matrix<T, Prop, RowSymSparse, Alloc1>& A,
03712                     Symmetric& sym, Vector<Tint, VectFull, Alloc2>& IndRow,
03713                     Vector<Tint, VectFull, Alloc3>& IndCol,
03714                     Vector<T, VectFull, Alloc4>& Val)
03715   {
03716     // Number of rows and non-zero entries.
03717     int nnz = A.GetDataSize();
03718     int m = A.GetM();
03719     int* ptr_ = A.GetPtr();
03720     int* ind_ = A.GetInd();
03721     T* data_ = A.GetData();
03722 
03723     // Allocation of arrays for CSR format.
03724     Val.Reallocate(nnz);
03725     IndRow.Reallocate(m + 1);
03726     IndCol.Reallocate(nnz);
03727 
03728     int ind = 0;
03729     IndRow(0) = 0;
03730     for (int i = 0; i < m; i++)
03731       {
03732         for (int k = ptr_[i]; k < ptr_[i+1]; k++)
03733           {
03734             IndCol(ind) = ind_[k];
03735             Val(ind) = data_[k];
03736             ind++;
03737           }
03738 
03739         IndRow(i + 1) = ind;
03740       }
03741   }
03742 
03743 
03745   template<class T, class Prop, class Alloc1,
03746            class Tint, class Alloc2, class Alloc3, class Alloc4>
03747   void ConvertToCSR(const Matrix<T, Prop, ArrayRowSymSparse, Alloc1>& A,
03748                     Symmetric& sym, Vector<Tint, VectFull, Alloc2>& IndRow,
03749                     Vector<Tint, VectFull, Alloc3>& IndCol,
03750                     Vector<T, VectFull, Alloc4>& Val)
03751   {
03752     // Number of rows and non-zero entries.
03753     int nnz = A.GetDataSize();
03754     int m = A.GetM();
03755 
03756     // Allocation of arrays for CSR format.
03757     Val.Reallocate(nnz);
03758     IndRow.Reallocate(m + 1);
03759     IndCol.Reallocate(nnz);
03760 
03761     int ind = 0;
03762     IndRow(0) = 0;
03763     for (int i = 0; i < m; i++)
03764       {
03765         for (int k = 0; k < A.GetRowSize(i); k++)
03766           {
03767             IndCol(ind) = A.Index(i, k);
03768             Val(ind) = A.Value(i, k);
03769             ind++;
03770           }
03771         IndRow(i + 1) = ind;
03772       }
03773   }
03774 
03775 
03777   template<class T, class Prop, class Alloc1, class Alloc2>
03778   void Copy(const Matrix<T, Prop, ColSymSparse, Alloc1>& A,
03779             Matrix<T, Prop, RowSymSparse, Alloc2>& B)
03780   {
03781     Vector<int, VectFull, CallocAlloc<int> > Ptr, Ind;
03782     Vector<T, VectFull, Alloc2> Value;
03783 
03784     Symmetric sym;
03785     ConvertToCSR(A, sym, Ptr, Ind, Value);
03786 
03787     // creating the matrix
03788     int m = A.GetM();
03789     int n = A.GetN();
03790     B.SetData(m, n, Value, Ptr, Ind);
03791   }
03792 
03793 
03795 
03799   template<class T1, class T2, class Prop1, class Prop2,
03800            class Alloc1, class Alloc2>
03801   void Copy(const Matrix<T1, Prop1, ColSparse, Alloc1>& A,
03802             Matrix<T2, Prop2, RowSparse, Alloc2>& B)
03803   {
03804     Vector<int, VectFull, CallocAlloc<int> > Ptr, Ind;
03805     Vector<T1, VectFull, Alloc2> Value;
03806 
03807     General sym;
03808     ConvertToCSR(A, sym, Ptr, Ind, Value);
03809 
03810     // creating the matrix
03811     int m = A.GetM();
03812     int n = A.GetN();
03813     B.SetData(m, n, Value, Ptr, Ind);
03814   }
03815 
03816 
03818 
03822   template<class T1, class T2, class Prop1, class Prop2,
03823            class Alloc1, class Alloc2>
03824   void Copy(const Matrix<T1, Prop1, ArrayColSparse, Alloc1>& A,
03825             Matrix<T2, Prop2, RowSparse, Alloc2>& B)
03826   {
03827     Vector<int, VectFull, CallocAlloc<int> > Ptr, Ind;
03828     Vector<T1, VectFull, Alloc2> Value;
03829 
03830     General sym;
03831     ConvertToCSR(A, sym, Ptr, Ind, Value);
03832 
03833     // creating the matrix
03834     int m = A.GetM();
03835     int n = A.GetN();
03836     B.SetData(m, n, Value, Ptr, Ind);
03837   }
03838 
03839 
03841   template<class T0, class Prop0, class Allocator0,
03842            class T1, class Prop1, class Allocator1>
03843   void Copy(const Matrix<T0, Prop0, ArrayRowSparse,Allocator0>& mat_array,
03844             Matrix<T1, Prop1, RowSparse, Allocator1>& mat_csr)
03845   {
03846     Vector<T1, VectFull, Allocator1> Val;
03847     Vector<int, VectFull, CallocAlloc<int> > IndRow;
03848     Vector<int, VectFull, CallocAlloc<int> > IndCol;
03849 
03850     General sym;
03851     ConvertToCSR(mat_array, sym, IndRow, IndCol, Val);
03852 
03853     int m = mat_array.GetM();
03854     int n = mat_array.GetN();
03855     mat_csr.SetData(m, n, Val, IndRow, IndCol);
03856   }
03857 
03858 
03860   template<class T0, class Prop0, class Allocator0,
03861            class T1, class Prop1, class Allocator1>
03862   void Copy(const Matrix<T0, Prop0, ArrayRowSymSparse,Allocator0>& mat_array,
03863             Matrix<T1, Prop1, RowSymSparse, Allocator1>& mat_csr)
03864   {
03865     Vector<T1, VectFull, Allocator1> Val;
03866     Vector<int, VectFull, CallocAlloc<int> > IndRow;
03867     Vector<int, VectFull, CallocAlloc<int> > IndCol;
03868 
03869     Symmetric sym;
03870     ConvertToCSR(mat_array, sym, IndRow, IndCol, Val);
03871 
03872     int m = mat_array.GetM();
03873     mat_csr.SetData(m, m, Val, IndRow, IndCol);
03874   }
03875 
03876 
03877   /******************************
03878    * From Sparse to ArraySparse *
03879    ******************************/
03880 
03881 
03882   template<class T0, class Prop0, class Allocator0,
03883            class T1, class Prop1, class Allocator1>
03884   void Copy(const Matrix<T0, Prop0, RowSymSparse, Allocator0>& A,
03885             Matrix<T1, Prop1, ArrayRowSymSparse, Allocator1>& B)
03886   {
03887     int n = A.GetM();
03888     if (n <= 0)
03889       {
03890         B.Clear();
03891         return;
03892       }
03893 
03894     int* ptr_ = A.GetPtr();
03895     int* ind_ = A.GetInd();
03896     T0* data_ = A.GetData();
03897 
03898     B.Reallocate(n, n);
03899     for (int i = 0; i < n; i++)
03900       {
03901         int size_row = ptr_[i+1] - ptr_[i];
03902         B.ReallocateRow(i, size_row);
03903         for (int j = 0; j < size_row; j++)
03904           {
03905             B.Index(i, j) = ind_[ptr_[i] + j];
03906             B.Value(i, j) = data_[ptr_[i] + j];
03907           }
03908       }
03909 
03910   }
03911 
03912 
03913   template<class T0, class Prop0, class Allocator0,
03914            class T1, class Prop1, class Allocator1>
03915   void Copy(const Matrix<T0, Prop0, ColSymSparse, Allocator0>& A,
03916             Matrix<T1, Prop1, ArrayRowSymSparse, Allocator1>& B)
03917   {
03918     int n = A.GetM();
03919     if (n <= 0)
03920       {
03921         B.Clear();
03922         return;
03923       }
03924 
03925     Vector<int, VectFull, CallocAlloc<int> > Ptr, Ind;
03926     Vector<T0, VectFull, Allocator0> Value;
03927 
03928     Symmetric sym;
03929     ConvertToCSR(A, sym, Ptr, Ind, Value);
03930 
03931     B.Reallocate(n, n);
03932     for (int i = 0; i < n; i++)
03933       {
03934         int size_row = Ptr(i+1) - Ptr(i);
03935         B.ReallocateRow(i, size_row);
03936         for (int j = 0; j < size_row; j++)
03937           {
03938             B.Index(i, j) = Ind(Ptr(i) + j);
03939             B.Value(i, j) = Value(Ptr(i) + j);
03940           }
03941       }
03942   }
03943 
03944 
03945   template<class T0, class Prop0, class Allocator0,
03946            class T1, class Prop1, class Allocator1>
03947   void Copy(const Matrix<T0, Prop0, RowSparse, Allocator0>& A,
03948             Matrix<T1, Prop1, ArrayRowSparse, Allocator1>& B)
03949   {
03950     int m = A.GetM();
03951     int n = A.GetN();
03952     if (n <= 0)
03953       {
03954         B.Clear();
03955         return;
03956       }
03957 
03958     int* ptr_ = A.GetPtr();
03959     int* ind_ = A.GetInd();
03960     T0* data_ = A.GetData();
03961 
03962     B.Reallocate(m, n);
03963     for (int i = 0; i < m; i++)
03964       {
03965         int size_row = ptr_[i+1] - ptr_[i];
03966         B.ReallocateRow(i, size_row);
03967         for (int j = 0; j < size_row; j++)
03968           {
03969             B.Index(i, j) = ind_[ptr_[i] + j];
03970             B.Value(i, j) = data_[ptr_[i] + j];
03971           }
03972       }
03973 
03974   }
03975 
03976 
03977   template<class T0, class Prop0, class Allocator0,
03978            class T1, class Prop1, class Allocator1>
03979   void Copy(const Matrix<T0, Prop0, ColSparse, Allocator0>& Acsc,
03980             Matrix<T1, Prop1, ArrayRowSparse, Allocator1>& B)
03981   {
03982     int m = Acsc.GetM();
03983     int n = Acsc.GetN();
03984     if (n <= 0)
03985       {
03986         B.Clear();
03987         return;
03988       }
03989 
03990     // conversion to RowSparse
03991     Matrix<T0, Prop0, RowSparse, Allocator0> A;
03992     Copy(Acsc, A);
03993 
03994     int* ptr_ = A.GetPtr();
03995     int* ind_ = A.GetInd();
03996     T0* data_ = A.GetData();
03997 
03998     B.Reallocate(m, n);
03999     for (int i = 0; i < m; i++)
04000       {
04001         int size_row = ptr_[i+1] - ptr_[i];
04002         B.ReallocateRow(i, size_row);
04003         for (int j = 0; j < size_row; j++)
04004           {
04005             B.Index(i, j) = ind_[ptr_[i] + j];
04006             B.Value(i, j) = data_[ptr_[i] + j];
04007           }
04008       }
04009   }
04010 
04011 
04012   /***********************************
04013    * From ArraySparse to ArraySparse *
04014    ***********************************/
04015 
04016 
04018   template<class T0, class Prop0, class Allocator0,
04019            class T1, class Prop1, class Allocator1>
04020   void Copy(const Matrix<T0, Prop0, ArrayRowSymSparse, Allocator0>& A,
04021             Matrix<T1, Prop1, ArrayRowSymSparse, Allocator1>& B)
04022   {
04023     int m = A.GetM();
04024     int n = A.GetN();
04025     B.Reallocate(m, n);
04026     for (int i = 0; i < m; i++)
04027       {
04028         int size_row = A.GetRowSize(i);
04029         B.ReallocateRow(i, size_row);
04030         for (int j = 0; j < size_row; j++)
04031           {
04032             B.Index(i, j) = A.Index(i, j);
04033             B.Value(i, j) = A.Value(i, j);
04034           }
04035       }
04036   }
04037 
04038 
04039   template<class T, class Prop, class Allocator>
04040   void Copy(const Matrix<T, Prop, ArrayRowSparse, Allocator>& A,
04041             Matrix<T, Prop, ArrayRowSparse, Allocator>& B)
04042   {
04043     B = A;
04044   }
04045 
04046 
04047   template<class T, class Prop, class Allocator>
04048   void Copy(const Matrix<T, Prop, ArrayRowSymSparse, Allocator>& A,
04049             Matrix<T, Prop, ArrayRowSymSparse, Allocator>& B)
04050   {
04051     B = A;
04052   }
04053 
04054 
04056   template<class T0, class Prop0, class Allocator0,
04057            class T1, class Prop1, class Allocator1>
04058   void Copy(const Matrix<T0, Prop0, ArrayRowSparse, Allocator0>& A,
04059             Matrix<T1, Prop1, ArrayRowSparse, Allocator1>& B)
04060   {
04061     int m = A.GetM();
04062     int n = A.GetN();
04063     B.Reallocate(m, n);
04064     for (int i = 0; i < m; i++)
04065       {
04066         int size_row = A.GetRowSize(i);
04067         B.ReallocateRow(i, size_row);
04068         for (int j = 0; j < size_row; j++)
04069           {
04070             B.Index(i, j) = A.Index(i, j);
04071             B.Value(i, j) = A.Value(i, j);
04072           }
04073       }
04074   }
04075 
04076 
04078   template<class T0, class Prop0, class Allocator0,
04079            class T1, class Prop1, class Allocator1>
04080   void Copy(const Matrix<T0, Prop0, ArrayRowSparse, Allocator0>& A,
04081             Matrix<T1, Prop1, ArrayRowSymSparse, Allocator1>& B)
04082   {
04083     abort();
04084   }
04085 
04086 
04088   template<class T0, class Prop0, class Allocator0,
04089            class T1, class Prop1, class Allocator1>
04090   void Copy(const Matrix<T0, Prop0, ArrayColSymSparse, Allocator0>& A,
04091             Matrix<T1, Prop1, ArrayRowSymSparse, Allocator1>& B)
04092   {
04093     int n = A.GetM();
04094     if (n <= 0)
04095       {
04096         B.Clear();
04097         return;
04098       }
04099 
04100     Vector<int, VectFull, CallocAlloc<int> > Ptr, Ind;
04101     Vector<T0, VectFull, Allocator0> Value;
04102 
04103     Symmetric sym;
04104     ConvertToCSR(A, sym, Ptr, Ind, Value);
04105 
04106     B.Reallocate(n, n);
04107     for (int i = 0; i < n; i++)
04108       {
04109         int size_row = Ptr(i+1) - Ptr(i);
04110         B.ReallocateRow(i, size_row);
04111         for (int j = 0; j < size_row; j++)
04112           {
04113             B.Index(i, j) = Ind(Ptr(i) + j);
04114             B.Value(i, j) = Value(Ptr(i) + j);
04115           }
04116       }
04117   }
04118 
04119 
04120   template<class T0, class Prop0, class Allocator0,
04121            class T1, class Prop1, class Allocator1>
04122   void Copy(const Matrix<T0, Prop0, ArrayColSparse, Allocator0>& Acsc,
04123             Matrix<T1, Prop1, ArrayRowSparse, Allocator1>& B)
04124   {
04125     int m = Acsc.GetM();
04126     int n = Acsc.GetN();
04127     if (n <= 0)
04128       {
04129         B.Clear();
04130         return;
04131       }
04132 
04133     // conversion to RowSparse
04134     Matrix<T0, Prop0, RowSparse, Allocator0> A;
04135     Copy(Acsc, A);
04136 
04137     int* ptr_ = A.GetPtr();
04138     int* ind_ = A.GetInd();
04139     T0* data_ = A.GetData();
04140 
04141     B.Reallocate(m, n);
04142     for (int i = 0; i < m; i++)
04143       {
04144         int size_row = ptr_[i+1] - ptr_[i];
04145         B.ReallocateRow(i, size_row);
04146         for (int j = 0; j < size_row; j++)
04147           {
04148             B.Index(i, j) = ind_[ptr_[i] + j];
04149             B.Value(i, j) = data_[ptr_[i] + j];
04150           }
04151       }
04152   }
04153 
04154 
04155   template<class T0, class Prop0, class Allocator0,
04156            class T1, class Prop1, class Allocator1>
04157   void Copy(const Matrix<T0, Prop0, ArrayRowSymSparse, Allocator0>& A,
04158             Matrix<T1, Prop1, ArrayRowSparse, Allocator1>& B)
04159   {
04160     int i, j;
04161 
04162     int nnz = A.GetDataSize();
04163     int n = A.GetM();
04164     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz),IndCol(nnz);
04165     Vector<T1, VectFull, Allocator1> Val(nnz);
04166     int ind = 0;
04167     for (i = 0; i < n; i++)
04168       for (j = 0; j < A.GetRowSize(i); j++)
04169         if (A.Index(i, j) != i)
04170           {
04171             IndRow(ind) = i;
04172             IndCol(ind) = A.Index(i, j);
04173             Val(ind) = A.Value(i, j);
04174             ind++;
04175           }
04176     Sort(ind, IndCol, IndRow, Val);
04177     nnz = ind;
04178     ind = 0;
04179 
04180     B.Reallocate(n, n);
04181     for (i = 0; i < n; i++)
04182       {
04183         int first_index = ind;
04184         while (ind < nnz && IndCol(ind) <= i)
04185           ind++;
04186         int size_lower = ind - first_index;
04187         int size_upper = A.GetRowSize(i);
04188         int size_row = size_lower + size_upper;
04189         B.ResizeRow(i, size_row);
04190         ind = first_index;
04191         for (j = 0; j < size_lower; j++)
04192           {
04193             B.Index(i, j) = IndRow(ind);
04194             B.Value(i, j) = Val(ind);
04195             ind++;
04196           }
04197         for (j = 0; j < size_upper; j++)
04198           {
04199             B.Index(i, size_lower + j) = A.Index(i, j);
04200             B.Value(i, size_lower + j) = A.Value(i, j);
04201           }
04202         B.AssembleRow(i);
04203       }
04204   }
04205 
04206 
04207   template<class T0, class Prop0, class Allocator0,
04208            class T1, class Prop1, class Allocator1>
04209   void Copy(const Matrix<T0, Prop0, ArrayRowSymSparse, Allocator0>& A,
04210             Matrix<T1, Prop1, ArrayColSparse, Allocator1>& B)
04211   {
04212     int i, j;
04213 
04214     int nnz = A.GetDataSize();
04215     int n = A.GetM();
04216     Vector<int, VectFull, CallocAlloc<int> > IndRow(nnz), IndCol(nnz);
04217     Vector<T1> Val(nnz);
04218     int ind = 0;
04219     for (i = 0; i < n; i++)
04220       for (j = 0; j < A.GetRowSize(i); j++)
04221         if (A.Index(i, j) != i)
04222           {
04223             IndRow(ind) = i;
04224             IndCol(ind) = A.Index(i, j);
04225             Val(ind) = A.Value(i, j);
04226             ind++;
04227           }
04228     Sort(ind, IndCol, IndRow, Val);
04229     nnz = ind;
04230     ind = 0;
04231 
04232     B.Reallocate(n, n);
04233     for (i = 0; i < n; i++)
04234       {
04235         int first_index = ind;
04236         while (ind < nnz && IndCol(ind) <= i)
04237           ind++;
04238         int size_lower = ind - first_index;
04239         int size_upper = A.GetRowSize(i);
04240         int size_row = size_lower + size_upper;
04241         B.ResizeColumn(i, size_row);
04242         ind = first_index;
04243         for (j = 0; j < size_lower; j++)
04244           {
04245             B.Index(i, j) = IndRow(ind);
04246             B.Value(i, j) = Val(ind);
04247             ind++;
04248           }
04249         for (j = 0; j < size_upper; j++)
04250           {
04251             B.Index(i, size_lower + j) = A.Index(i, j);
04252             B.Value(i, size_lower + j) = A.Value(i, j);
04253           }
04254         B.AssembleColumn(i);
04255       }
04256   }
04257 
04258 
04260   template<class T0, class Prop0, class Allocator0,
04261            class T1, class Prop1, class Allocator1>
04262   void Copy(const Matrix<T0, Prop0, ArrayRowSparse,Allocator0>& A,
04263             Matrix<T1, Prop1, ArrayColSparse, Allocator1>& B)
04264   {
04265     int i;
04266 
04267     // Matrix (m,n) with nnz entries.
04268     int nnz = A.GetDataSize();
04269     int n = A.GetN();
04270 
04271     // Conversion in coordinate format.
04272     Vector<T1> Val;
04273     Vector<int, VectFull, CallocAlloc<int> > IndRow, IndCol;
04274     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Val);
04275 
04276     // Sorting with respect to column numbers.
04277     Sort(IndCol, IndRow, Val);
04278 
04279     // Constructing pointer array 'Ptr'.
04280     Vector<int, VectFull, CallocAlloc<int> > Ptr(n + 1);
04281 
04282     // Counting non-zero entries per column.
04283     for (i = 0; i < nnz; i++)
04284       Ptr(IndCol(i) + 1)++;
04285 
04286     // Accumulation to get pointer array.
04287     Ptr(0) = 0;
04288     for (i = 0; i < n; i++)
04289       Ptr(i + 1) += Ptr(i);
04290 
04291     // we fill matrix B
04292     for (int i = 0; i < n; i++)
04293       {
04294         int size_col = Ptr(i+1) - Ptr(i);
04295         if (size_col > 0)
04296           {
04297             B.ReallocateColumn(i, size_col);
04298             for (int j = Ptr(i); j < Ptr(i+1); j++)
04299               {
04300                 B.Index(i, j-Ptr(i)) = IndRow(j);
04301                 B.Value(i, j-Ptr(i)) = Val(j);
04302               }
04303           }
04304       }
04305   }
04306 
04307 
04308   /**************************
04309    * ComplexSparse matrices *
04310    **************************/
04311 
04312 
04314   template<class T0, class Prop0, class Allocator0,
04315            class T1, class Prop1, class Allocator1>
04316   void
04317   Copy(const Matrix<T0, Prop0, ArrayRowComplexSparse, Allocator0>& mat_array,
04318        Matrix<T1, Prop1, RowComplexSparse, Allocator1>& mat_csr)
04319   {
04320     int i, k;
04321 
04322     // Non-zero entries (real and imaginary part).
04323     int nnz_real = mat_array.GetRealDataSize();
04324     int nnz_imag = mat_array.GetImagDataSize();
04325     int m = mat_array.GetM();
04326 
04327     // Allocation of arrays for CSR.
04328     Vector<T0, VectFull, Allocator1> Val_real(nnz_real), Val_imag(nnz_imag);
04329     Vector<int, VectFull, CallocAlloc<int> > IndRow_real(m + 1);
04330     Vector<int, VectFull, CallocAlloc<int> > IndRow_imag(m + 1);
04331     Vector<int, VectFull, CallocAlloc<int> > IndCol_real(nnz_real);
04332     Vector<int, VectFull, CallocAlloc<int> > IndCol_imag(nnz_imag);
04333 
04334     int ind_real = 0, ind_imag = 0;
04335     IndRow_real(0) = 0;
04336     IndRow_imag(0) = 0;
04337     // Loop over rows.
04338     for (i = 0; i < m; i++)
04339       {
04340         for (k = 0; k < mat_array.GetRealRowSize(i); k++)
04341           {
04342             IndCol_real(ind_real) = mat_array.IndexReal(i, k);
04343             Val_real(ind_real) = mat_array.ValueReal(i, k);
04344             ind_real++;
04345           }
04346 
04347         IndRow_real(i + 1) = ind_real;
04348         for (k = 0; k < mat_array.GetImagRowSize(i); k++)
04349           {
04350             IndCol_imag(ind_imag) = mat_array.IndexImag(i, k);
04351             Val_imag(ind_imag) = mat_array.ValueImag(i, k);
04352             ind_imag++;
04353           }
04354 
04355         IndRow_imag(i + 1) = ind_imag;
04356       }
04357 
04358     mat_csr.SetData(m, m, Val_real, IndRow_real, IndCol_real,
04359                     Val_imag, IndRow_imag, IndCol_imag);
04360   }
04361 
04362 
04364   template<class T0, class Prop0, class Allocator0,
04365            class T1, class Prop1, class Allocator1>
04366   void
04367   Copy(const Matrix<T0, Prop0,
04368        ArrayRowSymComplexSparse, Allocator0>& mat_array,
04369        Matrix<T1, Prop1, RowSymComplexSparse, Allocator1>& mat_csr)
04370   {
04371     int i, k;
04372 
04373     // Non-zero entries (real and imaginary part).
04374     int nnz_real = mat_array.GetRealDataSize();
04375     int nnz_imag = mat_array.GetImagDataSize();
04376     int m = mat_array.GetM();
04377 
04378     // Allocation of arrays for CSR.
04379     Vector<T0, VectFull, Allocator1> Val_real(nnz_real), Val_imag(nnz_imag);
04380     Vector<int, VectFull, CallocAlloc<int> > IndRow_real(m + 1);
04381     Vector<int, VectFull, CallocAlloc<int> > IndRow_imag(m + 1);
04382     Vector<int, VectFull, CallocAlloc<int> > IndCol_real(nnz_real);
04383     Vector<int, VectFull, CallocAlloc<int> > IndCol_imag(nnz_imag);
04384 
04385     int ind_real = 0, ind_imag = 0;
04386     IndRow_real(0) = 0;
04387     IndRow_imag(0) = 0;
04388     // Loop over rows.
04389     for (i = 0; i < m; i++)
04390       {
04391         for (k = 0; k < mat_array.GetRealRowSize(i); k++)
04392           {
04393             IndCol_real(ind_real) = mat_array.IndexReal(i, k);
04394             Val_real(ind_real) = mat_array.ValueReal(i, k);
04395             ind_real++;
04396           }
04397 
04398         IndRow_real(i + 1) = ind_real;
04399         for (int k = 0; k < mat_array.GetImagRowSize(i); k++)
04400           {
04401             IndCol_imag(ind_imag) = mat_array.IndexImag(i, k);
04402             Val_imag(ind_imag) = mat_array.ValueImag(i, k);
04403             ind_imag++;
04404           }
04405 
04406         IndRow_imag(i + 1) = ind_imag;
04407       }
04408 
04409     mat_csr.SetData(m, m, Val_real, IndRow_real, IndCol_real,
04410                     Val_imag, IndRow_imag, IndCol_imag);
04411   }
04412 
04413 
04414   /***********************
04415    * GetSymmetricPattern *
04416    ***********************/
04417 
04418 
04419   template<class T, class Prop, class Storage, class Allocator,
04420            class Tint, class Allocator2, class Allocator3>
04421   void GetSymmetricPattern(const Matrix<T, Prop, Storage, Allocator>& A,
04422                            Vector<Tint, VectFull, Allocator2>& Ptr,
04423                            Vector<Tint, VectFull, Allocator3>& Ind)
04424   {
04425     int n = A.GetM();
04426 
04427     // Converting to coordinates.
04428     Vector<int, VectFull, CallocAlloc<int> > IndRow, IndCol;
04429     Vector<T> Value;
04430     ConvertMatrix_to_Coordinates(A, IndRow, IndCol, Value);
04431 
04432     // clearing values
04433     Value.Clear();
04434 
04435     // Sorting columns too.
04436     Vector<int, VectFull, CallocAlloc<int> > IndRow2, IndCol2, Index(2*n);
04437     IndRow2 = IndRow;
04438     IndCol2 = IndCol;
04439     Sort(IndCol2.GetM(), IndCol2, IndRow2);
04440 
04441     Tint max_nnz = 0;
04442     for (int i = 0; i < IndRow.GetM(); i++)
04443       if (IndRow(i) <= IndCol(i))
04444         max_nnz++;
04445 
04446     for (int i = 0; i < IndRow.GetM(); i++)
04447       if (IndCol2(i) <= IndRow2(i))
04448         max_nnz++;
04449 
04450     // then symmetrization of pattern and conversion to csr.
04451     Ptr.Reallocate(n+1);
04452     Ind.Reallocate(max_nnz);
04453     Tint j_begin = 0, j_end = 0;
04454     int size_row = 0;
04455     Tint j2_begin = 0, j2_end = 0;
04456     Ptr(0) = 0;
04457     for (int i = 0; i < A.GetM(); i++)
04458       {
04459         j_begin = j_end;
04460         size_row = 0;
04461         // We retrieve column numbers.
04462         while ( (j_end < IndRow.GetM()) && (IndRow(j_end) == i))
04463           {
04464             if (IndRow(j_end) <= IndCol(j_end))
04465               {
04466                 Index(size_row) = IndCol(j_end);
04467                 size_row++;
04468               }
04469 
04470             j_end++;
04471           }
04472 
04473         j2_begin = j2_end;
04474         while ( (j2_end < IndCol2.GetM()) && (IndCol2(j2_end) == i))
04475           {
04476             if (IndCol2(j2_end) <= IndRow2(j2_end))
04477               {
04478                 Index(size_row) = IndRow2(j2_end);
04479                 size_row++;
04480               }
04481 
04482             j2_end++;
04483           }
04484 
04485         // Sorting indexes.
04486         Assemble(size_row, Index);
04487 
04488         // Updating Ptr, Ind.
04489         for (int j = 0; j < size_row; j++)
04490           Ind(Ptr(i) + j) = Index(j);
04491 
04492         Ptr(i+1) = Ptr(i) + size_row;
04493       }
04494 
04495     IndRow2.Clear(); IndCol2.Clear();
04496     IndRow.Clear(); IndCol.Clear();
04497     Ind.Resize(Ptr(n));
04498   }
04499 
04500 
04501   template<class T, class Prop, class Storage, class Allocator, class AllocI>
04502   void GetSymmetricPattern(const Matrix<T, Prop, Storage, Allocator>& A,
04503                            Matrix<int, Symmetric, RowSymSparse, AllocI>& B)
04504   {
04505     Vector<int, VectFull, CallocAlloc<int> > Ptr, Ind;
04506 
04507     GetSymmetricPattern(A, Ptr, Ind);
04508 
04509     int n = A.GetM();
04510     Vector<int, VectFull, CallocAlloc<int> > Val(Ptr(n));
04511     // We put Ptr and Ind into the matrix B.
04512     B.SetData(n, n, Val, Ptr, Ind);
04513   }
04514 
04515 
04516   /*****************************************************
04517    * Conversion from sparse matrices to dense matrices *
04518    *****************************************************/
04519 
04520 
04522   template<class T, class Prop, class Allocator1, class Allocator2>
04523   void Copy(Matrix<T, Prop, RowSparse, Allocator1>& A,
04524             Matrix<T, Prop, RowMajor, Allocator2>& B)
04525   {
04526     int m = A.GetM();
04527     int n = A.GetN();
04528     int* ptr = A.GetPtr();
04529     int* ind = A.GetInd();
04530     T* data = A.GetData();
04531 
04532     B.Reallocate(m, n);
04533     T zero;
04534     SetComplexZero(zero);
04535     B.Fill(zero);
04536     for (int i = 0; i < m; i++)
04537       for (int j = ptr[i]; j < ptr[i+1]; j++)
04538         B(i, ind[j]) = data[j];
04539 
04540   }
04541 
04542 
04544   template<class T, class Prop, class Allocator1, class Allocator2>
04545   void Copy(Matrix<T, Prop, ArrayRowSparse, Allocator1>& A,
04546             Matrix<T, Prop, RowMajor, Allocator2>& B)
04547   {
04548     int m = A.GetM();
04549     int n = A.GetN();
04550 
04551     B.Reallocate(m, n);
04552     T zero;
04553     SetComplexZero(zero);
04554     B.Fill(zero);
04555     for (int i = 0; i < m; i++)
04556       for (int j = 0; j < A.GetRowSize(i); j++)
04557         B(i, A.Index(i, j)) = A.Value(i, j);
04558 
04559   }
04560 
04561 
04563   template<class T, class Prop, class Allocator1, class Allocator2>
04564   void Copy(Matrix<T, Prop, ArrayRowSymSparse, Allocator1>& A,
04565             Matrix<T, Prop, RowSymPacked, Allocator2>& B)
04566   {
04567     int m = A.GetM();
04568     int n = A.GetN();
04569     B.Reallocate(m, n);
04570     T zero;
04571     SetComplexZero(zero);
04572     B.Fill(zero);
04573     for (int i = 0; i < m; i++)
04574       for (int j = 0; j < A.GetRowSize(i); j++)
04575         B(i, A.Index(i, j)) = A.Value(i, j);
04576 
04577   }
04578 
04579 
04580   template<class T, class Prop1, class Prop2, class Alloc1, class Alloc2>
04581   void Copy(const Matrix<T, Prop1, PETScMPIDense, Alloc1>& A,
04582             Matrix<T, Prop2, RowMajor, Alloc2>& B)
04583   {
04584     int m, n;
04585     MatGetLocalSize(A.GetPetscMatrix(), &m, &n);
04586     n = A.GetN();
04587     B.Reallocate(m, n);
04588     T *local_a;
04589     MatGetArray(A.GetPetscMatrix(), &local_a);
04590     for (int i = 0; i < m; i++)
04591       for(int j = 0; j < n; j++)
04592         B(i, j) = local_a[i + j * m];
04593     MatRestoreArray(A.GetPetscMatrix(), &local_a);
04594   }
04595 
04596 
04597   template<class T, class Prop1, class Prop2, class Alloc1, class Alloc2>
04598   void Copy(const Matrix<T, Prop1, RowMajor, Alloc1>& A,
04599             Matrix<T, Prop2, PETScMPIDense, Alloc2>& B)
04600   {
04601     T *local_data;
04602     MatGetArray(B.GetPetscMatrix(), &local_data);
04603     int mlocal, nlocal;
04604     MatGetLocalSize(B.GetPetscMatrix(), &mlocal, &nlocal);
04605     Matrix<T, Prop1, ColMajor, Alloc1> local_D;
04606     local_D.SetData(mlocal, B.GetN(), local_data);
04607     for (int i = 0; i < A.GetM(); i++)
04608       for (int j = 0; j < A.GetN(); j++)
04609         local_D(i, j) = A(i, j);
04610     local_D.Nullify();
04611     MatRestoreArray(B.GetPetscMatrix(), &local_data);
04612   }
04613 
04614 
04615   /*****************************************************
04616    * Conversion from dense matrices to sparse matrices *
04617    *****************************************************/
04618 
04619 
04621   template<class T>
04622   void ConvertToSparse(const Matrix<T, Symmetric, RowSymPacked>& A,
04623                        Matrix<T, Symmetric, RowSymSparse>& B,
04624                        const T& threshold)
04625   {
04626     int nnz = 0;
04627     int n = A.GetM();
04628     for (int i = 0; i < n; i++)
04629       for (int j = i; j < n; j++)
04630         if (abs(A(i, j)) > threshold)
04631           nnz++;
04632 
04633     IVect IndCol(nnz), IndRow(n+1);
04634     Vector<T> Value(nnz);
04635     nnz = 0; IndRow(0) = 0;
04636     for (int i = 0; i < n; i++)
04637       {
04638         for (int j = i; j < n; j++)
04639           if (abs(A(i, j)) > threshold)
04640             {
04641               IndCol(nnz) = j;
04642               Value(nnz) = A(i, j);
04643               nnz++;
04644             }
04645 
04646         IndRow(i+1) = nnz;
04647       }
04648 
04649     B.SetData(n, n, Value, IndRow, IndCol);
04650 
04651   }
04652 
04653 
04655   template<class T>
04656   void ConvertToSparse(const Matrix<T, General, RowMajor>& A,
04657                        Matrix<T, General, ArrayRowSparse>& B,
04658                        const T& threshold)
04659   {
04660     int m = A.GetM();
04661     int n = A.GetN();
04662     B.Reallocate(m, n);
04663     for (int i = 0; i < m; i++)
04664       {
04665         int size_row = 0;
04666         for (int j = 0; j < n; j++)
04667           if (abs(A(i, j)) > threshold)
04668             size_row++;
04669 
04670         B.ReallocateRow(i, size_row);
04671 
04672         size_row = 0;
04673         for (int j = 0; j < n; j++)
04674           if (abs(A(i, j)) > threshold)
04675             {
04676               B.Index(i, size_row) = j;
04677               B.Value(i, size_row) = A(i, j);
04678               size_row++;
04679             }
04680       }
04681   }
04682 
04683 
04685   template<class T>
04686   void ConvertToSparse(const Matrix<T, General, RowMajor>& A,
04687                        Matrix<T, General, RowSparse>& B,
04688                        const T& threshold)
04689   {
04690     int nnz = 0;
04691     int m = A.GetM();
04692     int n = A.GetN();
04693     for (int i = 0; i < m; i++)
04694       for (int j = 0; j < n; j++)
04695         if (abs(A(i, j)) > threshold)
04696           nnz++;
04697 
04698     Vector<int, VectFull, CallocAlloc<int> > IndCol(nnz), IndRow(m+1);
04699     Vector<T> Value(nnz);
04700     nnz = 0; IndRow(0) = 0;
04701     for (int i = 0; i < m; i++)
04702       {
04703         for (int j = 0; j < n; j++)
04704           if (abs(A(i, j)) > threshold)
04705             {
04706               IndCol(nnz) = j;
04707               Value(nnz) = A(i, j);
04708               nnz++;
04709             }
04710 
04711         IndRow(i+1) = nnz;
04712       }
04713 
04714     B.SetData(m, n, Value, IndRow, IndCol);
04715 
04716   }
04717 
04718 } // namespace Seldon.
04719 
04720 #define SELDON_FILE_MATRIX_CONVERSIONS_CXX
04721 #endif