matrix_sparse/Functions_MatrixArray.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_FUNCTIONS_MATRIX_ARRAY_CXX
00022 
00023 /*
00024   Functions defined in this file:
00025   (storage ArrayRowSparse, ArrayColSparse, etc)
00026 
00027   alpha.M*X + beta.Y -> Y
00028   MltAdd(alpha, M, X, beta, Y)
00029 
00030   alpha.A + B -> B
00031   Add(alpha, A, B)
00032 
00033   alpha.M -> M
00034   Mlt(alpha, M)
00035 
00036 */
00037 
00038 namespace Seldon
00039 {
00040 
00041 
00043   // MltAdd //
00044 
00045 
00046   /*** ArrayRowSymComplexSparse ***/
00047 
00048 
00049   template<class T0, class T1, class T2, class T3, class T4,
00050            class Allocator1, class Allocator2, class Allocator3>
00051   void MltAdd(const T0& alpha, const Matrix<T1, Symmetric,
00052               ArrayRowSymComplexSparse, Allocator1>& A,
00053               const Vector<T2, VectFull, Allocator2>& B,
00054               const T4& beta,
00055               Vector<T3, VectFull, Allocator3>& C)
00056   {
00057     if (beta == T4(0))
00058       C.Fill(T3(0));
00059     else
00060       Mlt(beta, C);
00061 
00062     int m = A.GetM(), n, p;
00063     T1 val;
00064     T3 val_cplx;
00065     if (alpha == T0(1))
00066       {
00067         for (int i = 0 ; i < m ; i++)
00068           {
00069             n = A.GetRealRowSize(i);
00070             for (int k = 0; k < n ; k++)
00071               {
00072                 p = A.IndexReal(i, k);
00073                 val = A.ValueReal(i, k);
00074                 if (p == i)
00075                   C(i) += val * B(i);
00076                 else
00077                   {
00078                     C(i) += val * B(p);
00079                     C(p) += val * B(i);
00080                   }
00081               }
00082             n = A.GetImagRowSize(i);
00083             for (int k = 0; k < n ; k++)
00084               {
00085                 p = A.IndexImag(i, k);
00086                 val = A.ValueImag(i, k);
00087                 if (p == i)
00088                   C(i) += complex<T1>(0, val) * B(i);
00089                 else
00090                   {
00091                     C(i) += complex<T1>(0, val) * B(p);
00092                     C(p) += complex<T1>(0, val) * B(i);
00093                   }
00094               }
00095           }
00096       }
00097     else // alpha != 1.
00098       {
00099         for (int i = 0 ; i < m ; i++)
00100           {
00101             n = A.GetRealRowSize(i);
00102             for (int k = 0; k < n ; k++)
00103               {
00104                 p = A.IndexReal(i, k);
00105                 val_cplx = alpha * A.ValueReal(i, k);
00106                 if (p == i)
00107                   C(i) += val_cplx * B(i);
00108                 else
00109                   {
00110                     C(i) += val_cplx * B(p);
00111                     C(p) += val_cplx * B(i);
00112                   }
00113               }
00114             n = A.GetImagRowSize(i);
00115             for (int k = 0; k < n ; k++)
00116               {
00117                 p = A.IndexImag(i, k);
00118                 val_cplx = alpha * complex<T1>(0, A.ValueImag(i, k));
00119                 if (p == i)
00120                   C(i) += val_cplx * B(i);
00121                 else
00122                   {
00123                     C(i) += val_cplx * B(p);
00124                     C(p) += val_cplx * B(i);
00125                   }
00126               }
00127           }
00128       }
00129   }
00130 
00131 
00132   template<class T0, class T1, class T2, class T3, class T4,
00133            class Allocator1, class Allocator2, class Allocator3>
00134   void MltAdd(const T0& alpha,
00135               const class_SeldonNoTrans& Trans, const Matrix<T1, Symmetric,
00136               ArrayRowSymComplexSparse, Allocator1>& A,
00137               const Vector<T2, VectFull, Allocator2>& B,
00138               const T4& beta,
00139               Vector<T3, VectFull, Allocator3>& C)
00140   {
00141     MltAdd(alpha, A, B, beta, C);
00142   }
00143 
00144 
00145   template<class T0, class T1, class T2, class T3, class T4,
00146            class Allocator1, class Allocator2, class Allocator3>
00147   void MltAdd(const T0& alpha,
00148               const class_SeldonTrans& Trans, const Matrix<T1, Symmetric,
00149               ArrayRowSymComplexSparse, Allocator1>& A,
00150               const Vector<T2, VectFull, Allocator2>& B,
00151               const T4& beta,
00152               Vector<T3, VectFull, Allocator3>& C)
00153   {
00154     MltAdd(alpha, A, B, beta, C);
00155   }
00156 
00157 
00158   template<class T0, class T1, class T2, class T3, class T4,
00159            class Allocator1, class Allocator2, class Allocator3>
00160   void MltAdd(const T0& alpha,
00161               const class_SeldonConjTrans& Trans, const Matrix<T1, Symmetric,
00162               ArrayRowSymComplexSparse, Allocator1>& A,
00163               const Vector<T2, VectFull, Allocator2>& B,
00164               const T4& beta,
00165               Vector<T3, VectFull, Allocator3>& C)
00166   {
00167     if (beta == T4(0))
00168       C.Fill(T3(0));
00169     else
00170       Mlt(beta, C);
00171     int m = A.GetM(),n,p;
00172     T1 val;
00173     T3 val_cplx;
00174     if (alpha == T0(1))
00175       {
00176         for (int i = 0 ; i < m ; i++)
00177           {
00178             n = A.GetRealRowSize(i);
00179             for (int k = 0; k < n ; k++)
00180               {
00181                 p = A.IndexReal(i, k);
00182                 val = A.ValueReal(i, k);
00183                 if (p == i)
00184                   C(i) += val * B(i);
00185                 else
00186                   {
00187                     C(i) += val * B(p);
00188                     C(p) += val * B(i);
00189                   }
00190               }
00191             n = A.GetImagRowSize(i);
00192             for (int k = 0; k < n ; k++)
00193               {
00194                 p = A.IndexImag(i, k);
00195                 val = A.ValueImag(i, k);
00196                 if (p == i)
00197                   C(i) -= complex<T1>(0, val) * B(i);
00198                 else
00199                   {
00200                     C(i) -= complex<T1>(0, val) * B(p);
00201                     C(p) -= complex<T1>(0, val) * B(i);
00202                   }
00203               }
00204           }
00205       }
00206     else
00207       {
00208         // alpha different from 1
00209         for (int i = 0 ; i < m ; i++)
00210           {
00211             n = A.GetRealRowSize(i);
00212             for (int k = 0; k < n ; k++)
00213               {
00214                 p = A.IndexReal(i, k);
00215                 val_cplx = alpha * A.ValueReal(i, k);
00216                 if (p == i)
00217                   C(i) += val_cplx * B(i);
00218                 else
00219                   {
00220                     C(i) += val_cplx * B(p);
00221                     C(p) += val_cplx * B(i);
00222                   }
00223               }
00224             n = A.GetImagRowSize(i);
00225             for (int k = 0; k < n ; k++)
00226               {
00227                 p = A.IndexImag(i, k);
00228                 val_cplx = alpha * complex<T1>(0, A.ValueImag(i, k));
00229                 if (p == i)
00230                   C(i) -= val_cplx * B(i);
00231                 else
00232                   {
00233                     C(i) -= val_cplx * B(p);
00234                     C(p) -= val_cplx * B(i);
00235                   }
00236               }
00237           }
00238       }
00239   }
00240 
00241 
00242   /*** ArrayRowComplexSparse ***/
00243 
00244 
00245   template<class T0, class T1, class T2, class T3, class T4,
00246            class Allocator1, class Allocator2, class Allocator3>
00247   void MltAdd(const T0& alpha, const Matrix<T1, General,
00248               ArrayRowComplexSparse, Allocator1>& A,
00249               const Vector<T2, VectFull, Allocator2>& B,
00250               const T4& beta,
00251               Vector<T3, VectFull, Allocator3>& C)
00252   {
00253     if (beta == T4(0))
00254       C.Fill(T3(0));
00255     else
00256       Mlt(beta, C);
00257     int m = A.GetM(), n, p;
00258     T1 val;
00259     T3 val_cplx;
00260     if (alpha == T0(1, 0))
00261       {
00262         for (int i = 0 ; i < m ; i++)
00263           {
00264             n = A.GetRealRowSize(i);
00265             for (int k = 0; k < n ; k++)
00266               {
00267                 p = A.IndexReal(i, k);
00268                 val = A.ValueReal(i, k);
00269                 C(i) += val * B(p);
00270               }
00271             n = A.GetImagRowSize(i);
00272             for (int k = 0; k < n ; k++)
00273               {
00274                 p = A.IndexImag(i, k);
00275                 val = A.ValueImag(i, k);
00276                 C(i) += complex<T1>(0, val) * B(p);
00277               }
00278           }
00279       }
00280     else
00281       {
00282         // alpha different from 1
00283         for (int i = 0 ; i < m ; i++)
00284           {
00285             n = A.GetRealRowSize(i);
00286             for (int k = 0; k < n ; k++)
00287               {
00288                 p = A.IndexReal(i, k);
00289                 val_cplx = alpha * A.ValueReal(i, k);
00290                 C(i) += val_cplx * B(p);
00291               }
00292             n = A.GetImagRowSize(i);
00293             for (int k = 0; k < n ; k++)
00294               {
00295                 p = A.IndexImag(i, k);
00296                 val_cplx = alpha * complex<T1>(0, A.ValueImag(i, k));
00297                 C(i) += val_cplx * B(p);
00298               }
00299           }
00300       }
00301   }
00302 
00303 
00304   template<class T0, class T1, class T2, class T3, class T4,
00305            class Allocator1, class Allocator2, class Allocator3>
00306   void MltAdd(const T0& alpha,
00307               const class_SeldonNoTrans& Trans, const Matrix<T1, General,
00308               ArrayRowComplexSparse, Allocator1>& A,
00309               const Vector<T2, VectFull, Allocator2>& B,
00310               const T4& beta,
00311               Vector<T3, VectFull, Allocator3>& C)
00312   {
00313     MltAdd(alpha, A, B, beta, C);
00314   }
00315 
00316 
00317   template<class T0, class T1, class T2, class T3, class T4,
00318            class Allocator1, class Allocator2, class Allocator3>
00319   void MltAdd(const T0& alpha,
00320               const class_SeldonTrans& Trans, const Matrix<T1, General,
00321               ArrayRowComplexSparse, Allocator1>& A,
00322               const Vector<T2, VectFull, Allocator2>& B,
00323               const T4& beta,
00324               Vector<T3, VectFull, Allocator3>& C)
00325   {
00326     if (beta == T4(0))
00327       C.Fill(T3(0));
00328     else
00329       Mlt(beta, C);
00330     int m = A.GetM(),n,p;
00331     T1 val;
00332     T3 val_cplx;
00333     if (alpha == T0(1))
00334       {
00335         for (int i = 0 ; i < m ; i++)
00336           {
00337             n = A.GetRealRowSize(i);
00338             for (int k = 0; k < n ; k++)
00339               {
00340                 p = A.IndexReal(i, k);
00341                 val = A.ValueReal(i, k);
00342                 C(p) += val * B(i);
00343               }
00344             n = A.GetImagRowSize(i);
00345             for (int k = 0; k < n ; k++)
00346               {
00347                 p = A.IndexImag(i, k);
00348                 val = A.ValueImag(i, k);
00349                 C(p) += complex<T1>(0, val) * B(i);
00350               }
00351           }
00352       }
00353     else
00354       {
00355         // alpha different from 1
00356         for (int i = 0 ; i < m ; i++)
00357           {
00358             n = A.GetRealRowSize(i);
00359             for (int k = 0; k < n ; k++)
00360               {
00361                 p = A.IndexReal(i, k);
00362                 val_cplx = alpha * A.ValueReal(i, k);
00363                 C(p) += val_cplx * B(i);
00364               }
00365             n = A.GetImagRowSize(i);
00366             for (int k = 0; k < n ; k++)
00367               {
00368                 p = A.IndexImag(i, k);
00369                 val_cplx = alpha * complex<T1>(0, A.ValueImag(i, k));
00370                 C(p) += val_cplx * B(i);
00371               }
00372           }
00373       }
00374   }
00375 
00376 
00377   template<class T0, class T1, class T2, class T3, class T4,
00378            class Allocator1, class Allocator2, class Allocator3>
00379   void MltAdd(const T0& alpha,
00380               const class_SeldonConjTrans& Trans, const Matrix<T1, General,
00381               ArrayRowComplexSparse, Allocator1>& A,
00382               const Vector<T2, VectFull, Allocator2>& B,
00383               const T4& beta,
00384               Vector<T3, VectFull, Allocator3>& C)
00385   {
00386     if (beta == T4(0))
00387       C.Fill(T3(0));
00388     else
00389       Mlt(beta, C);
00390     int m = A.GetM(),n,p;
00391     T1 val;
00392     T3 val_cplx;
00393     if (alpha == T0(1))
00394       {
00395         for (int i = 0 ; i < m ; i++)
00396           {
00397             n = A.GetRealRowSize(i);
00398             for (int k = 0; k < n ; k++)
00399               {
00400                 p = A.IndexReal(i, k);
00401                 val = A.ValueReal(i, k);
00402                 C(p) += val * B(i);
00403               }
00404             n = A.GetImagRowSize(i);
00405             for (int k = 0; k < n ; k++)
00406               {
00407                 p = A.IndexImag(i, k);
00408                 val = A.ValueImag(i, k);
00409                 C(p) -= complex<T1>(0, val) * B(i);
00410               }
00411           }
00412       }
00413     else
00414       {
00415         // alpha different from 1
00416         for (int i = 0 ; i < m ; i++)
00417           {
00418             n = A.GetRealRowSize(i);
00419             for (int k = 0; k < n ; k++)
00420               {
00421                 p = A.IndexReal(i, k);
00422                 val_cplx = alpha * A.ValueReal(i, k);
00423                 C(p) += val_cplx * B(i);
00424               }
00425             n = A.GetImagRowSize(i);
00426             for (int k = 0; k < n ; k++)
00427               {
00428                 p = A.IndexImag(i, k);
00429                 val_cplx -= alpha * complex<T1>(0, A.ValueImag(i, k));
00430                 C(p) += val_cplx * B(i);
00431               }
00432           }
00433       }
00434   }
00435 
00436 
00437   /*** ArrayRowSymSparse ***/
00438 
00439 
00440   template<class T0, class T1, class T2, class T3, class T4,
00441            class Allocator1, class Allocator2, class Allocator3>
00442   void MltAdd(const T0& alpha, const Matrix<T1, Symmetric,
00443               ArrayRowSymSparse, Allocator1>& A,
00444               const Vector<T2, VectFull, Allocator2>& B,
00445               const T4& beta,
00446               Vector<T3, VectFull, Allocator3>& C)
00447   {
00448     if (B.GetM() <= 0)
00449       return;
00450 
00451     T3 zero(B(0));
00452     zero *= 0;
00453 
00454     if (beta == zero)
00455       C.Fill(zero);
00456     else
00457       Mlt(beta, C);
00458 
00459     int m = A.GetM(), n, p;
00460     T3 val;
00461     if (alpha == T0(1))
00462       {
00463         for (int i = 0 ; i < m ; i++)
00464           {
00465             n = A.GetRowSize(i);
00466             for (int k = 0; k < n ; k++)
00467               {
00468                 p = A.Index(i, k);
00469                 val = A.Value(i, k);
00470 
00471                 if (p == i)
00472                   C(i) += val * B(i);
00473                 else
00474                   {
00475                     C(i) += val * B(p);
00476                     C(p) += val * B(i);
00477                   }
00478               }
00479           }
00480       }
00481     else
00482       {
00483         // alpha different from 1
00484         for (int i = 0 ; i < m ; i++)
00485           {
00486             n = A.GetRowSize(i);
00487             for (int k = 0; k < n ; k++)
00488               {
00489                 p = A.Index(i, k);
00490                 val = alpha * A.Value(i, k);
00491 
00492                 if (p==i)
00493                   C(i) += val * B(i);
00494                 else
00495                   {
00496                     C(i) += val * B(p);
00497                     C(p) += val * B(i);
00498                   }
00499               }
00500           }
00501       }
00502   }
00503 
00504 
00505   template<class T0, class T1, class T2, class T3, class T4,
00506            class Allocator1, class Allocator2, class Allocator3>
00507   void MltAdd(const T0& alpha,
00508               const class_SeldonNoTrans& Trans, const Matrix<T1, Symmetric,
00509               ArrayRowSymSparse, Allocator1>& A,
00510               const Vector<T2, VectFull, Allocator2>& B,
00511               const T4& beta,
00512               Vector<T3, VectFull, Allocator3>& C)
00513   {
00514     MltAdd(alpha, A, B, beta, C);
00515   }
00516 
00517 
00518   template<class T0, class T1, class T2, class T3, class T4,
00519            class Allocator1, class Allocator2, class Allocator3>
00520   void MltAdd(const T0& alpha,
00521               const class_SeldonTrans& Trans, const Matrix<T1, Symmetric,
00522               ArrayRowSymSparse, Allocator1>& A,
00523               const Vector<T2, VectFull, Allocator2>& B,
00524               const T4& beta,
00525               Vector<T3, VectFull, Allocator3>& C)
00526   {
00527     MltAdd(alpha, A, B, beta, C);
00528   }
00529 
00530 
00531   /*** ArrayRowSparse ***/
00532 
00533 
00534   template<class T0, class T1, class T2, class T3, class T4,
00535            class Allocator1, class Allocator2, class Allocator3>
00536   void MltAdd(const T0& alpha,
00537               const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
00538               const Vector<T2, VectFull, Allocator2>& B,
00539               const T4& beta,
00540               Vector<T3, VectFull, Allocator3>& C)
00541   {
00542     if (beta == T4(0))
00543       C.Fill(T3(0));
00544     else
00545       Mlt(beta, C);
00546 
00547     int m = A.GetM(), n, p;
00548     T1 val;
00549     if (alpha == T0(1))
00550       {
00551         for (int i = 0 ; i < m ; i++)
00552           {
00553             n = A.GetRowSize(i);
00554             for (int k = 0; k < n ; k++)
00555               {
00556                 p = A.Index(i, k);
00557                 val = A.Value(i, k);
00558                 C(i) += val * B(p);
00559               }
00560           }
00561       }
00562     else // alpha != 1.
00563       {
00564         for (int i = 0 ; i < m ; i++)
00565           {
00566             n = A.GetRowSize(i);
00567             for (int k = 0; k < n ; k++)
00568               {
00569                 p = A.Index(i, k);
00570                 val = A.Value(i, k);
00571                 C(i) += alpha * val * B(p);
00572               }
00573           }
00574       }
00575   }
00576 
00577 
00578   template<class T0, class T1, class T2, class T3, class T4,
00579            class Allocator1, class Allocator2, class Allocator3>
00580   void MltAdd(const T0& alpha,
00581               const class_SeldonNoTrans& Trans,
00582               const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
00583               const Vector<T2, VectFull, Allocator2>& B,
00584               const T4& beta,
00585               Vector<T4, VectFull, Allocator3>& C)
00586   {
00587     MltAdd(alpha, A, B, beta, C);
00588   }
00589 
00590 
00591   template<class T0, class T1, class T2, class T3, class T4,
00592            class Allocator1, class Allocator2, class Allocator3>
00593   void MltAdd(const T0& alpha,
00594               const class_SeldonTrans& Trans,
00595               const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
00596               const Vector<T2, VectFull, Allocator2>& B,
00597               const T4& beta,
00598               Vector<T3, VectFull, Allocator3>& C)
00599   {
00600     if (beta == T4(0))
00601       C.Fill(T3(0));
00602     else
00603       Mlt(beta, C);
00604     int m = A.GetM(), n, p;
00605     T1 val;
00606     if (alpha == T0(1))
00607       {
00608         for (int i = 0 ; i < m ; i++)
00609           {
00610             n = A.GetRowSize(i);
00611             for (int k = 0; k < n ; k++)
00612               {
00613                 p = A.Index(i, k);
00614                 val = A.Value(i, k);
00615                 C(p) += val * B(i);
00616               }
00617           }
00618       }
00619     else // alpha != 1.
00620       {
00621         for (int i = 0 ; i < m ; i++)
00622           {
00623             n = A.GetRowSize(i);
00624             for (int k = 0; k < n ; k++)
00625               {
00626                 p = A.Index(i, k);
00627                 val = A.Value(i, k);
00628                 C(p) += alpha * val * B(i);
00629               }
00630           }
00631       }
00632   }
00633 
00634 
00635   // MltAdd //
00637 
00638 
00639 
00641   // Add //
00642 
00643 
00644   template<class T0, class T1, class T2, class Allocator1, class Allocator2>
00645   void Add(const T0& alpha,
00646            const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
00647            Matrix<T2, General, ArrayRowSparse, Allocator2>& B)
00648   {
00649     int m = B.GetM(),n;
00650     Vector<T2, VectFull, Allocator2> value;
00651     for (int i = 0 ; i < m ; i++)
00652       {
00653         n = A.GetRowSize(i);
00654         value.Reallocate(n);
00655         for (int j = 0; j < n; j++)
00656           value(j) = T2(A.Value(i, j));
00657 
00658         Mlt(alpha, value);
00659         B.AddInteractionRow(i, n, A.GetIndex(i), value.GetData());
00660       }
00661   }
00662 
00663 
00664   template<class T0, class T1, class T2, class Allocator1, class Allocator2>
00665   void Add(const T0& alpha,
00666            const Matrix<T1, Symmetric, ArrayRowSymSparse, Allocator1>& A,
00667            Matrix<T2, Symmetric, ArrayRowSymSparse, Allocator2>& B)
00668   {
00669     int m = B.GetM(),n;
00670     Vector<T2, VectFull, Allocator2> value;
00671     for (int i = 0 ; i < m ; i++)
00672       {
00673         n = A.GetRowSize(i);
00674         value.Reallocate(n);
00675         for (int j = 0; j < n; j++)
00676           value(j) = A.Value(i, j);
00677 
00678         Mlt(alpha, value);
00679         B.AddInteractionRow(i, n, A.GetIndex(i), value.GetData());
00680       }
00681   }
00682 
00683 
00684   template<class T0, class T1, class T2, class Allocator1, class Allocator2>
00685   void Add(const T0& alpha,
00686            const Matrix<T1, Symmetric,
00687            ArrayRowSymComplexSparse, Allocator1>& A,
00688            Matrix<T2, Symmetric, ArrayRowSymComplexSparse, Allocator2>& B)
00689   {
00690     int m = B.GetM(), n, ni;
00691     Vector<complex<T2> > value;
00692     IVect index;
00693     for (int i = 0 ; i < m ; i++)
00694       {
00695         n = A.GetRealRowSize(i);
00696         ni = A.GetImagRowSize(i);
00697         value.Reallocate(n + ni);
00698         index.Reallocate(n + ni);
00699         for (int j = 0; j < n; j++)
00700           {
00701             value(j) = A.ValueReal(i, j);
00702             index(j) = A.IndexReal(i, j);
00703           }
00704 
00705         for (int j = 0; j < ni; j++)
00706           {
00707             value(j+n) = complex<T2>(0, 1) * A.ValueImag(i, j);
00708             index(j+n) = A.IndexImag(i, j);
00709           }
00710 
00711         Mlt(alpha, value);
00712         B.AddInteractionRow(i, n+ni, index, value);
00713       }
00714   }
00715 
00716 
00717   template<class T0, class T1, class T2, class Allocator1, class Allocator2>
00718   void Add(const T0& alpha, const Matrix<T1, Symmetric,
00719            ArrayRowSymComplexSparse, Allocator1>& A,
00720            Matrix<T2, Symmetric, ArrayRowSymSparse, Allocator2>& B)
00721   {
00722     int m = B.GetM(), n;
00723     Vector<T2, VectFull, Allocator2> value;
00724     for (int i = 0 ; i < m ; i++)
00725       {
00726         n = A.GetRealRowSize(i);
00727         value.Reallocate(n);
00728         for (int j = 0; j < n; j++)
00729           value(j) = A.ValueReal(i, j);
00730 
00731         Mlt(alpha, value);
00732         B.AddInteractionRow(i, n, A.GetRealInd(i), value.GetData());
00733         n = A.GetImagRowSize(i);
00734         value.Reallocate(n);
00735         for (int j = 0; j < n; j++)
00736           value(j) = complex<T1>(0, 1) * A.ValueImag(i, j);
00737 
00738         Mlt(alpha, value);
00739         B.AddInteractionRow(i, n, A.GetImagInd(i), value.GetData());
00740       }
00741   }
00742 
00743 
00744   template<class T0, class T1, class T2, class Allocator1, class Allocator2>
00745   void Add(const T0& alpha, const Matrix<T1, General,
00746            ArrayRowComplexSparse, Allocator1>& A,
00747            Matrix<T2, Symmetric, ArrayRowSparse, Allocator2>& B)
00748   {
00749     int m = B.GetM(),n;
00750     Vector<T2, VectFull, Allocator2> value;
00751     for (int i = 0; i < m; i++)
00752       {
00753         n = A.GetRealRowSize(i);
00754         value.Reallocate(n);
00755         for (int j = 0; j < n; j++)
00756           value(j) = A.ValueReal(i, j);
00757 
00758         Mlt(alpha, value);
00759         B.AddInteractionRow(i, n, A.GetRealInd(i), value.GetData());
00760         n = A.GetImagRowSize(i);
00761         value.Reallocate(n);
00762         for (int j = 0; j < n; j++)
00763           value(j) = complex<T1>(0, 1) * A.ValueImag(i, j);
00764 
00765         Mlt(alpha, value);
00766         B.AddInteractionRow(i, n, A.GetImagInd(i), value.GetData());
00767       }
00768   }
00769 
00770 
00771   template<class T0, class T1, class T2, class Allocator1,class Allocator2>
00772   void Add(const T0& alpha, const Matrix<T1, General,
00773            ArrayRowComplexSparse, Allocator1>& A,
00774            Matrix<T2, General, ArrayRowComplexSparse, Allocator2>& B)
00775   {
00776     int m = B.GetM(), n, ni;
00777     Vector<complex<T2> > value; IVect index;
00778     for (int i = 0 ; i < m ; i++)
00779       {
00780         n = A.GetRealRowSize(i);
00781         ni = A.GetImagRowSize(i);
00782         value.Reallocate(n + ni);
00783         index.Reallocate(n + ni);
00784         for (int j = 0; j < n; j++)
00785           {
00786             value(j) = A.ValueReal(i, j);
00787             index(j) = A.IndexReal(i, j);
00788           }
00789 
00790         for (int j = 0; j < ni; j++)
00791           {
00792             value(n+j) = complex<T2>(0, 1) * A.ValueImag(i, j);
00793             index(n+j) = A.IndexImag(i, j);
00794           }
00795 
00796         Mlt(alpha, value);
00797         B.AddInteractionRow(i, n+ni, index, value);
00798       }
00799   }
00800 
00801 
00802   // C = C + complex(A,B)
00803   template<class T0, class T1, class T2, class T3, class Allocator1,
00804            class Allocator2, class Allocator3>
00805   void Add(const T0& alpha,
00806            const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
00807            const Matrix<T2, General, ArrayRowSparse, Allocator2>& B,
00808            Matrix<complex<T3>, General, ArrayRowSparse, Allocator3>& C)
00809   {
00810     int m = B.GetM(),n1,n2,size_row;;
00811     Vector<complex<T3>, VectFull, Allocator3> val_row;
00812     IVect ind_row;
00813     for (int i = 0 ; i < m ; i++)
00814       {
00815         n1 = A.GetRowSize(i);
00816         n2 = B.GetRowSize(i);
00817         size_row = n1 + n2;
00818         val_row.Reallocate(size_row);
00819         ind_row.Reallocate(size_row);
00820         for (int j = 0 ; j < n1 ; j++)
00821           {
00822             ind_row(j) = A.Index(i, j);
00823             val_row(j) = alpha*complex<T3>(A.Value(i, j), 0);
00824           }
00825 
00826         for (int j = 0 ; j < n2 ; j++)
00827           {
00828             ind_row(j+n1) = B.Index(i, j);
00829             val_row(j+n1) = alpha * complex<T3>(B.Value(i, j));
00830           }
00831         
00832         C.AddInteractionRow(i, size_row, ind_row, val_row);
00833       }
00834   }
00835 
00836 
00837   // C = C + complex(A,B)
00838   template<class T0, class T1, class T2, class T3,
00839            class Allocator1, class Allocator2, class Allocator3>
00840   void Add(const T0& alpha,
00841            const Matrix<T1, Symmetric, ArrayRowSymSparse, Allocator1>& A,
00842            const Matrix<T2, Symmetric, ArrayRowSymSparse, Allocator2>& B,
00843            Matrix<complex<T3>, Symmetric, ArrayRowSymSparse, Allocator3>& C)
00844   {
00845     int m = B.GetM(), n1, n2, size_row;
00846     Vector<complex<T3>, VectFull, Allocator3> val_row;
00847     IVect ind_row;
00848     for (int i = 0 ; i < m ; i++)
00849       {
00850         n1 = A.GetRowSize(i);
00851         n2 = B.GetRowSize(i);
00852         size_row = n1 + n2;
00853         val_row.Reallocate(size_row);
00854         ind_row.Reallocate(size_row);
00855         for (int j = 0 ; j < n1 ; j++)
00856           {
00857             ind_row(j) = A.Index(i, j);
00858             val_row(j) = alpha * complex<T3>(A.Value(i, j), 0);
00859           }
00860 
00861         for (int j = 0 ; j < n2 ; j++)
00862           {
00863             ind_row(j+n1) = B.Index(i, j);
00864             val_row(j+n1) = alpha * complex<T3>(B.Value(i, j));
00865           }
00866 
00867         C.AddInteractionRow(i, size_row, ind_row, val_row);
00868       }
00869   }
00870 
00871 
00872   // C = C + complex(A,B)
00873   template<class T0, class T1, class T2, class T3,
00874            class Allocator1, class Allocator2, class Allocator3>
00875   void Add(const T0& alpha,
00876            const Matrix<T1, Symmetric, ArrayRowSymSparse, Allocator1>& A,
00877            const Matrix<T2, Symmetric, ArrayRowSymSparse, Allocator2>& B,
00878            Matrix<T3, Symmetric, ArrayRowSymComplexSparse, Allocator3>& C)
00879   {
00880     int m = B.GetM(), n, ni;
00881     Vector<complex<T3> > value; IVect index;
00882     for (int i = 0 ; i < m ; i++)
00883       {
00884         n = A.GetRowSize(i);
00885         ni = B.GetRowSize(i);
00886         value.Reallocate(n+ni);
00887         index.Reallocate(n+ni);
00888         for (int j = 0; j < n; j++)
00889           {
00890             value(j) = A.Value(i, j);
00891             index(j) = A.Index(i, j);
00892           }
00893 
00894         for (int j = 0; j < ni; j++)
00895           {
00896             value(n+j) = complex<T3>(0, 1) * B.Value(i, j);
00897             index(n+j) = B.Index(i, j);
00898           }
00899 
00900         Mlt(alpha, value);
00901         C.AddInteractionRow(i, n+ni, index, value);
00902       }
00903   }
00904 
00905 
00906   // C = C + complex(A,B)
00907   template<class T0, class T1, class T2, class T3,
00908            class Allocator1, class Allocator2, class Allocator3>
00909   void Add(const T0& alpha,
00910            const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
00911            const Matrix<T2, General, ArrayRowSparse, Allocator2>& B,
00912            Matrix<T3, General, ArrayRowComplexSparse, Allocator3>& C)
00913   {
00914     int m = B.GetM(), n, ni;
00915     Vector<complex<T3> > value;
00916     IVect index;
00917     for (int i = 0 ; i < m ; i++)
00918       {
00919         n = A.GetRowSize(i);
00920         ni = B.GetRowSize(i);
00921         value.Reallocate(n + ni);
00922         index.Reallocate(n + ni);
00923         for (int j = 0; j < n; j++)
00924           {
00925             value(j) = A.Value(i, j);
00926             index(j) = A.Index(i, j);
00927           }
00928 
00929         for (int j = 0; j < ni; j++)
00930           {
00931             value(n+j) = complex<T3>(0, 1) * B.Value(i, j);
00932             index(n+j) = B.Index(i, j);
00933           }
00934 
00935         Mlt(alpha, value);
00936         C.AddInteractionRow(i, n+ni, index, value);
00937       }
00938   }
00939 
00940 
00941   // Add //
00943 
00944 
00945 
00947   // Mlt //
00948 
00949 
00950   template<class T0, class T, class Allocator>
00951   void Mlt(const T0& alpha, Matrix<T, General, ArrayRowSparse, Allocator>& A)
00952   {
00953     for (int i = 0; i < A.GetM(); i++)
00954       for (int j = 0; j < A.GetRowSize(i); j++)
00955         A.Value(i,j) *= alpha;
00956   }
00957 
00958 
00959   template<class T0, class T, class Allocator>
00960   void Mlt(const T0& alpha, Matrix<T, General, ArrayColSparse, Allocator>& A)
00961   {
00962     for (int i = 0; i < A.GetN(); i++)
00963       for (int j = 0; j < A.GetColSize(i); j++)
00964         A.Value(i,j) *= alpha;
00965   }
00966 
00967 
00968   template<class T0, class T, class Allocator>
00969   void Mlt(const T0& alpha,
00970            Matrix<T, Symmetric, ArrayRowSymSparse, Allocator>& A)
00971   {
00972     for (int i = 0; i < A.GetM(); i++)
00973       for (int j = 0; j < A.GetRowSize(i); j++)
00974         A.Value(i,j) *= alpha;
00975   }
00976 
00977 
00978   template<class T0, class T, class Allocator>
00979   void Mlt(const T0& alpha,
00980            Matrix<T, Symmetric, ArrayColSymSparse, Allocator>& A)
00981   {
00982     for (int i = 0; i < A.GetN(); i++)
00983       for (int j = 0; j < A.GetColSize(i); j++)
00984         A.Value(i,j) *= alpha;
00985   }
00986 
00987 
00988   template<class T0, class T, class Allocator>
00989   void Mlt(const T0& alpha,
00990            Matrix<T, General, ArrayRowComplexSparse, Allocator>& A)
00991   {
00992     for (int i = 0; i < A.GetM(); i++)
00993       {
00994         for (int j = 0; j < A.GetRealRowSize(i); j++)
00995           A.ValueReal(i,j) *= alpha;
00996         for (int j = 0; j < A.GetImagRowSize(i); j++)
00997           A.ValueImag(i,j) *= alpha;
00998       }
00999   }
01000 
01001 
01002   template<class T0, class T, class Allocator>
01003   void Mlt(const T0& alpha, Matrix<T, Symmetric,
01004            ArrayRowSymComplexSparse, Allocator>& A)
01005   {
01006     for (int i = 0; i < A.GetM(); i++)
01007       {
01008         for (int j = 0; j < A.GetRealRowSize(i); j++)
01009           A.ValueReal(i,j) *= alpha;
01010 
01011         for (int j = 0; j < A.GetImagRowSize(i); j++)
01012           A.ValueImag(i,j) *= alpha;
01013       }
01014   }
01015 
01016 
01017   // Matrix-matrix product (sparse matrix against full matrix)
01018   template<class T1, class Allocator1, class T2, class Prop2,
01019            class Storage2, class Allocator2, class T3, class Prop3,
01020            class Storage3, class Allocator3>
01021   void Mlt(const Matrix<T1, General, ArrayRowSparse, Allocator1>& A,
01022            const Matrix<T2, Prop2, Storage2, Allocator2>& B,
01023            Matrix<T3, Prop3, Storage3, Allocator3>& C)
01024   {
01025     int m = A.GetM();
01026     int n = B.GetN();
01027     C.Reallocate(m,n);
01028     T3 val;
01029     for (int i = 0; i < m; i++)
01030       for (int j = 0; j < n; j++)
01031         {
01032           val = T3(0);
01033           for (int ind = 0; ind < A.GetRowSize(i); ind++)
01034             {
01035               int k = A.Index(i, ind);
01036               val += A.Value(i, ind) * B(k, j);
01037             }
01038           C(i, j) = val;
01039         }
01040   }
01041 
01042 
01043   // Mlt //
01045 
01046 
01047 } // namespace Seldon
01048 
01049 #define SELDON_FILE_FUNCTIONS_MATRIX_ARRAY_CXX
01050 #endif