srmatrix.hpp

00001 /*
00002 **  CXSC is a C++ library for eXtended Scientific Computing (V 2.5.1)
00003 **
00004 **  Copyright (C) 1990-2000 Institut fuer Angewandte Mathematik,
00005 **                          Universitaet Karlsruhe, Germany
00006 **            (C) 2000-2011 Wiss. Rechnen/Softwaretechnologie
00007 **                          Universitaet Wuppertal, Germany   
00008 **
00009 **  This library is free software; you can redistribute it and/or
00010 **  modify it under the terms of the GNU Library General Public
00011 **  License as published by the Free Software Foundation; either
00012 **  version 2 of the License, or (at your option) any later version.
00013 **
00014 **  This library is distributed in the hope that it will be useful,
00015 **  but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017 **  Library General Public License for more details.
00018 **
00019 **  You should have received a copy of the GNU Library General Public
00020 **  License along with this library; if not, write to the Free
00021 **  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 */
00023 
00024 /* CVS $Id: srmatrix.hpp,v 1.15 2011/06/07 15:17:42 cxsc Exp $ */
00025 
00026 #ifndef _CXSC_SRMATRIX_HPP_INCLUDED
00027 #define _CXSC_SRMATRIX_HPP_INCLUDED
00028 
00029 #include <real.hpp>
00030 #include <rmatrix.hpp>
00031 #include <srvector.hpp>
00032 #include <cidot.hpp>
00033 #include <vector>
00034 #include <algorithm>
00035 #include <iostream>
00036 #include <sparsedot.hpp>
00037 #include <sparsematrix.hpp>
00038 
00039 namespace cxsc {
00040 
00041 enum STORAGE_TYPE{triplet,compressed_row,compressed_column};
00042 
00043 class srmatrix_slice;
00044 class srmatrix_subv;
00045 class scmatrix;
00046 class scmatrix_slice;
00047 class scmatrix_subv;
00048 class simatrix;
00049 class simatrix_slice;
00050 class simatrix_subv;
00051 class sivector_slice;
00052 class scimatrix;
00053 class scimatrix_slice;
00054 class scimatrix_subv;
00055 class scivector_slice;
00056 
00057 
00058 inline bool comp_pair(std::pair<int,real> p1, std::pair<int,real> p2) {
00059   return p1.first < p2.first;
00060 }
00061 
00062 
00063 class srmatrix {
00064 
00065   private:
00066     std::vector<int> p;
00067     std::vector<int> ind;
00068     std::vector<real> x;
00069     int m;
00070     int n;
00071     int lb1,ub1,lb2,ub2;
00072 
00073   public:
00074 
00075     std::vector<int>& column_pointers() {
00076       return p;
00077     }
00078 
00079     std::vector<int>& row_indices() {
00080       return ind;
00081     }
00082 
00083     std::vector<real>& values() {
00084       return x;
00085     }
00086 
00087     const std::vector<int>& column_pointers() const {
00088       return p;
00089     }
00090 
00091     const std::vector<int>& row_indices() const {
00092       return ind;
00093     }
00094 
00095     const std::vector<real>& values() const {
00096       return x;
00097     }
00098 
00099     srmatrix() {
00100       p.push_back(0);
00101       m = n = 0;
00102       lb1 = lb2 = ub1 = ub2 = 0;
00103     }
00104 
00105     srmatrix(const int r, const int c) : m(r),n(c),lb1(1),ub1(r),lb2(1),ub2(c) {
00106       p = std::vector<int>((n>0) ? n+1 : 1, 0);
00107       ind.reserve(2*(m+n));
00108       x.reserve(2*(m+n));
00109 
00110       p[0] = 0;
00111     }
00112 
00113     srmatrix(const int r, const int c, const int e) : m(r),n(c),lb1(1),ub1(r),lb2(1),ub2(c) {
00114       p = std::vector<int>((n>0) ? n+1 : 1, 0);
00115       ind.reserve(e);
00116       x.reserve(e);
00117 
00118       p[0] = 0;
00119     }
00120 
00121     srmatrix(const int m, const int n, const int nnz, const intvector& rows, const intvector& cols, const rvector& values, const enum STORAGE_TYPE t = triplet) {
00122       if(t == triplet) {
00123          this->m = m;
00124          this->n = n;
00125          p = std::vector<int>(n+1,0);
00126          ind.reserve(nnz);
00127          x.reserve(nnz);
00128          lb1 = lb2 = 1;
00129          ub1 = m; ub2 = n;
00130 
00131          std::vector<triplet_store<real> > work;
00132          work.reserve(nnz);
00133 
00134          for(int k=0 ; k<nnz ; k++) {
00135            work.push_back(triplet_store<real>(rows[Lb(rows)+k],cols[Lb(cols)+k],values[Lb(values)+k]));
00136          }
00137 
00138          sort(work.begin(), work.end());
00139 
00140          int i=0;
00141 
00142          for(int j=0 ; j<n ; j++) {        
00143 
00144            while((unsigned int)i < work.size() && work[i].col == j ) {
00145                ind.push_back(work[i].row);
00146                x.push_back(work[i].val);
00147                i++;
00148            }
00149 
00150            p[j+1] = i;
00151          }
00152          
00153       } else if(t == compressed_row) {
00154 
00155          this->m = m;
00156          this->n = n;
00157          p = std::vector<int>(n+1,0);
00158          ind.reserve(nnz);
00159          x.reserve(nnz);
00160          lb1 = lb2 = 1;
00161          ub1 = m; ub2 = n;
00162 
00163          for(int i=0 ; i<n+1 ; i++)
00164            p[i] = rows[Lb(rows)+i];
00165 
00166          std::vector<triplet_store<real> > work;
00167          work.reserve(nnz);
00168 
00169          for(int j=0 ; j<n ; j++) {
00170            for(int k=p[j] ; k<p[j+1] ; k++) {
00171              work.push_back(triplet_store<real>(j,cols[Lb(cols)+k],values[Lb(values)+k]));
00172            }
00173          }
00174 
00175          sort(work.begin(), work.end());
00176 
00177          int i=0;
00178 
00179          for(int j=0 ; j<n ; j++) {        
00180 
00181            while((unsigned int)i < work.size() && work[i].col == j ) {
00182                ind.push_back(work[i].row);
00183                x.push_back(work[i].val);
00184                i++;
00185            }
00186 
00187            p[j+1] = i;
00188          }
00189     
00190       } else if(t == compressed_column) {
00191          this->m = m;
00192          this->n = n;
00193          p = std::vector<int>(n+1,0);
00194          ind.reserve(nnz);
00195          x.reserve(nnz);
00196          lb1 = lb2 = 1;
00197          ub1 = m; ub2 = n;
00198 
00199          for(int i=0 ; i<n+1 ; i++)
00200            p[i] = rows[Lb(rows)+i];
00201 
00202          std::vector<std::pair<int,real> > work;
00203          work.reserve(n);
00204 
00205          for(int j=0 ; j<n ; j++) {
00206            work.clear();
00207 
00208            for(int k=p[j] ; k<p[j+1] ; k++) {
00209              work.push_back(std::make_pair(cols[Lb(cols)+k],values[Lb(values)+k]));
00210            }
00211 
00212            std::sort(work.begin(),work.end(),comp_pair);
00213 
00214            for(unsigned int i=0 ; i<work.size() ; i++) {
00215              ind.push_back(work[i].first);
00216              x.push_back(work[i].second);
00217            }
00218          }
00219 
00220       }
00221 
00222     }
00223 
00224     srmatrix(const int m, const int n, const int nnz, const int* rows, const int* cols, const real* values, const enum STORAGE_TYPE t = triplet) {
00225       if(t == triplet) {
00226          this->m = m;
00227          this->n = n;
00228          p = std::vector<int>(n+1,0);
00229          ind.reserve(nnz);
00230          x.reserve(nnz);
00231          lb1 = lb2 = 1;
00232          ub1 = m; ub2 = n;
00233 
00234          std::vector<triplet_store<real> > work;
00235          work.reserve(nnz);
00236 
00237          for(int k=0 ; k<nnz ; k++) {
00238            work.push_back(triplet_store<real>(rows[k],cols[k],values[k]));
00239          }
00240 
00241          sort(work.begin(), work.end());
00242 
00243          int i=0;
00244 
00245          for(int j=0 ; j<n ; j++) {        
00246 
00247            while((unsigned int)i < work.size() && work[i].col == j ) {
00248                ind.push_back(work[i].row);
00249                x.push_back(work[i].val);
00250                i++;
00251            }
00252 
00253            p[j+1] = i;
00254          }
00255          
00256       } else if(t == compressed_row) {
00257 
00258          this->m = m;
00259          this->n = n;
00260          p = std::vector<int>(n+1,0);
00261          ind.reserve(nnz);
00262          x.reserve(nnz);
00263          lb1 = lb2 = 1;
00264          ub1 = m; ub2 = n;
00265 
00266          for(int i=0 ; i<n+1 ; i++)
00267            p[i] = rows[i];
00268 
00269          std::vector<triplet_store<real> > work;
00270          work.reserve(nnz);
00271 
00272          for(int j=0 ; j<n ; j++) {
00273            for(int k=p[j] ; k<p[j+1] ; k++) {
00274              work.push_back(triplet_store<real>(j,cols[k],values[k]));
00275            }
00276          }
00277 
00278          sort(work.begin(), work.end());
00279 
00280          int i=0;
00281 
00282          for(int j=0 ; j<n ; j++) {        
00283 
00284            while((unsigned int)i < work.size() && work[i].col == j ) {
00285                ind.push_back(work[i].row);
00286                x.push_back(work[i].val);
00287                i++;
00288            }
00289 
00290            p[j+1] = i;
00291          }
00292     
00293       } else if(t == compressed_column) {
00294          this->m = m;
00295          this->n = n;
00296          p = std::vector<int>(n+1,0);
00297          ind.reserve(nnz);
00298          x.reserve(nnz);
00299          lb1 = lb2 = 1;
00300          ub1 = m; ub2 = n;
00301 
00302          for(int i=0 ; i<n+1 ; i++)
00303            p[i] = rows[i];
00304 
00305          std::vector<std::pair<int,real> > work;
00306          work.reserve(n);
00307 
00308          for(int j=0 ; j<n ; j++) {
00309            work.clear();
00310 
00311            for(int k=p[j] ; k<p[j+1] ; k++) {
00312              work.push_back(std::make_pair(cols[k],values[k]));
00313            }
00314 
00315            std::sort(work.begin(),work.end(),comp_pair);
00316 
00317            for(unsigned int i=0 ; i<work.size() ; i++) {
00318              ind.push_back(work[i].first);
00319              x.push_back(work[i].second);
00320            }
00321          }
00322 
00323       }
00324 
00325     }
00326 
00327     srmatrix(const rmatrix& A) : m(ColLen(A)),n(RowLen(A)),lb1(Lb(A,1)),ub1(Ub(A,1)),lb2(Lb(A,2)),ub2(Ub(A,2)) {
00328       p = std::vector<int>((n>0) ? n+1 : 1, 0);
00329       ind.reserve((m*n*0.1 < 2*m) ? (int)(m*n*0.1) : 2*m);
00330       x.reserve((m*n*0.1 < 2*m) ? (int)(m*n*0.1) : 2*m);
00331 
00332       p[0] = 0;
00333       int nnz = 0;
00334 
00335       for(int j=0 ; j<n ; j++) {
00336         for(int i=0 ; i<m ; i++) {
00337           if(A[i+lb1][j+lb2] != 0.0) {
00338              ind.push_back(i);
00339              x.push_back(A[i+lb1][j+lb2]);
00340              nnz++;
00341           }
00342         }
00343           
00344         p[j+1] = nnz;
00345       }
00346 
00347     }
00348 
00349 
00350     srmatrix(const int ms, const int ns, const rmatrix& A) : m(ms), n(ns), lb1(1), ub1(ms), lb2(1), ub2(ns)  {
00351       //Banded matrix constructor
00352       int nnz = RowLen(A)*ColLen(A);
00353       p = std::vector<int>((n>0) ? n+1 : 1, 0);
00354       ind.reserve(nnz);
00355       x.reserve(nnz);
00356 
00357       std::vector<triplet_store<real> > work;
00358       work.reserve(nnz);
00359 
00360       
00361       for(int i=0 ; i<ColLen(A) ; i++) {
00362         for(int j=Lb(A,2) ; j<=Ub(A,2) ; j++) {
00363           if(i+j >=0  &&  i+j < n) {
00364             work.push_back(triplet_store<real>(i,i+j,A[i+Lb(A,1)][j]));
00365           }
00366         }
00367       }
00368 
00369       sort(work.begin(), work.end());
00370 
00371       int i=0;
00372 
00373       for(int j=0 ; j<n ; j++) {        
00374 
00375         while((unsigned int)i < work.size() && work[i].col == j ) {
00376           ind.push_back(work[i].row);
00377           x.push_back(work[i].val);
00378           i++;
00379         }
00380 
00381         p[j+1] = i;
00382       }
00383 
00384     }
00385 
00386 
00387 
00388     srmatrix(const srmatrix_slice&);
00389 
00390     void full(rmatrix& A) const {
00391        A = rmatrix(lb1,ub1,lb2,ub2);
00392        A = 0.0;
00393        for(int j=0 ; j<n ; j++) {
00394           for(int k=p[j] ; k<p[j+1] ; k++) {
00395              A[ind[k]+lb1][j+lb2] = x[k];
00396           }
00397        }
00398     }
00399 
00400     void dropzeros() {
00401       std::vector<int> pnew(n+1,0);
00402       std::vector<int> indnew;
00403       std::vector<real> xnew;
00404       int nnznew = 0;
00405 
00406       for(int j=0 ; j<n ; j++) {
00407         for(int k=p[j] ; k<p[j+1] ; k++) {
00408           if(x[k] != 0.0) {
00409             xnew.push_back(x[k]);
00410             indnew.push_back(ind[k]);
00411             nnznew++;
00412           }
00413         }
00414         pnew[j+1] = nnznew;
00415       }
00416 
00417       p = pnew;
00418       ind = indnew;
00419       x = xnew;
00420     }
00421 
00422 
00423     srmatrix& operator=(const real& A) {
00424       return sp_ms_assign<srmatrix,real,real>(*this,A);
00425     }
00426 
00427     srmatrix& operator=(const rmatrix& A) {
00428       return spf_mm_assign<srmatrix,rmatrix,real>(*this,A);
00429     }
00430 
00431     srmatrix& operator=(const rmatrix_slice& A) {
00432       return spf_mm_assign<srmatrix,rmatrix,real>(*this,A);
00433     }
00434 
00435 /*    srmatrix& operator=(const srmatrix& A) {
00436       p = A.p;
00437       ind = A.ind;
00438       x = A.x;
00439       return *this;
00440     }*/
00441 
00442     srmatrix& operator=(const srmatrix_slice&);
00443 
00444     const real operator()(int i, int j) const {
00445 #if(CXSC_INDEX_CHECK)
00446       if(i<lb1 || i>ub1 || j<lb2 || j>ub2)
00447         cxscthrow(ROW_OR_COL_NOT_IN_MAT("srmatrix::operator()(int, int)"));
00448 #endif
00449       real r = 0.0;
00450       for(int k=p[j-lb2] ; k<p[j-lb2+1] && ind[k]<=i-lb1 ; k++) {
00451         if(ind[k] == i-lb1)  r = x[k];
00452       }
00453       return r;
00454     }
00455 
00456     real& element(int i, int j) {
00457 #if(CXSC_INDEX_CHECK)
00458       if(i<lb1 || i>ub1 || j<lb2 || j>ub2)
00459         cxscthrow(ROW_OR_COL_NOT_IN_MAT("srmatrix::element(int, int)"));
00460 #endif
00461       int k;
00462       for(k=p[j-lb2] ; k<p[j-lb2+1] && ind[k]<=i-lb1 ; k++) {
00463         if(ind[k] == i-lb1)  return x[k];
00464       }
00465 
00466       //Nicht gefunden, Element muss angelegt werden, da Schreibzugriff moeglich
00467       std::vector<int>::iterator ind_it = ind.begin() + k;
00468       std::vector<real>::iterator x_it  = x.begin() + k;
00469       ind.insert(ind_it, i-lb1);
00470       x_it = x.insert(x_it, 0.0);
00471       for(k=j-lb2+1 ; k<(int)p.size() ; k++)
00472         p[k]++;
00473 
00474       return *x_it;
00475     }
00476 
00477     srmatrix_subv operator[](const cxscmatrix_column&);
00478     srmatrix_subv operator[](const int);
00479     const srmatrix_subv operator[](const cxscmatrix_column&) const;
00480     const srmatrix_subv operator[](const int) const;
00481 
00482     srmatrix_slice operator()(const int, const int , const int, const int);
00483 
00484     srmatrix operator()(const intvector& pervec, const intvector& q) {
00485       srmatrix A(m,n,get_nnz());
00486       intvector per = perminv(pervec);
00487 
00488       int nnz=0;
00489       for(int k=0 ; k<n ; k++) {
00490         A.p[k] = nnz;
00491 
00492         std::map<int,real> work;
00493         for(int j=p[q[Lb(q)+k]] ; j<p[q[Lb(q)+k]+1] ; j++) 
00494            work.insert(std::make_pair(per[Lb(per)+ind[j]], x[j]));
00495         
00496         for(std::map<int,real>::iterator it = work.begin() ; it != work.end() ; it++) {
00497            A.ind.push_back(it->first);
00498            A.x.push_back(it->second);
00499         }
00500 
00501         nnz += work.size();
00502  
00503       }
00504 
00505       A.p[n] = nnz;
00506 
00507       return A;
00508     }
00509 
00510     srmatrix operator()(const intvector& pervec) {
00511       srmatrix A(m,n,get_nnz());
00512       intvector per = perminv(pervec);
00513 
00514       for(int k=0 ; k<n ; k++) {
00515         A.p[k] = p[k];
00516 
00517         std::map<int,real> work;
00518         for(int j=p[k] ; j<p[k+1] ; j++) 
00519            work.insert(std::make_pair(per[Lb(per)+ind[j]], x[j]));
00520         
00521         for(std::map<int,real>::iterator it = work.begin() ; it != work.end() ; it++) {
00522            A.ind.push_back(it->first);
00523            A.x.push_back(it->second);
00524         }
00525  
00526       }
00527 
00528       A.p[n] = p[n];
00529 
00530       return A;
00531     }
00532 
00533     srmatrix operator()(const intmatrix& P, const intmatrix& Q) {
00534       intvector p = permvec(P);
00535       intvector q = perminv(permvec(Q));
00536       return (*this)(p,q);
00537     }
00538 
00539     srmatrix operator()(const intmatrix& P) {
00540       intvector p = permvec(P);
00541       return (*this)(p);
00542     }
00543 
00544     real density() const {
00545       return p[n]/((double)m*n);
00546     }
00547 
00548     int get_nnz() const {
00549       return p[n];
00550     }
00551 
00552     srmatrix& operator+=(const rmatrix& B) {
00553       return spf_mm_addassign<srmatrix,rmatrix,rmatrix>(*this,B);
00554     }
00555 
00556     srmatrix& operator+=(const rmatrix_slice& B) {
00557       return spf_mm_addassign<srmatrix,rmatrix_slice,rmatrix>(*this,B);
00558     }
00559 
00560     srmatrix& operator+=(const srmatrix& B) {
00561       return spsp_mm_addassign<srmatrix,srmatrix,real>(*this,B);
00562     }
00563 
00564     srmatrix& operator-=(const rmatrix& B) {
00565       return spf_mm_subassign<srmatrix,rmatrix,rmatrix>(*this,B);
00566     }
00567 
00568     srmatrix& operator-=(const rmatrix_slice& B) {
00569       return spf_mm_subassign<srmatrix,rmatrix_slice,rmatrix>(*this,B);
00570     }
00571 
00572     srmatrix& operator-=(const srmatrix& B) {
00573       return spsp_mm_subassign<srmatrix,srmatrix,real>(*this,B);
00574     }
00575 
00576     srmatrix& operator*=(const rmatrix& B) {
00577       return spf_mm_multassign<srmatrix,rmatrix,sparse_dot,rmatrix>(*this,B);
00578     }
00579 
00580     srmatrix& operator*=(const rmatrix_slice& B) {
00581       return spf_mm_multassign<srmatrix,rmatrix,sparse_dot,rmatrix>(*this,B);
00582     }
00583 
00584     srmatrix& operator*=(const srmatrix& B) {
00585       return spsp_mm_multassign<srmatrix,srmatrix,sparse_dot,real>(*this,B);
00586     }
00587 
00588     srmatrix& operator*=(const real& r) {
00589       return sp_ms_multassign(*this,r);
00590     }
00591 
00592     srmatrix& operator/=(const real& r) {
00593       return sp_ms_divassign(*this,r);
00594     }
00595 
00596     friend int Lb(const srmatrix&, int);
00597     friend int Ub(const srmatrix&, int);
00598     friend void SetLb(srmatrix&, const int, const int);
00599     friend void SetUb(srmatrix&, const int, const int);
00600     friend int RowLen(const srmatrix&);
00601     friend int ColLen(const srmatrix&);
00602     friend srmatrix Re(const scmatrix&);
00603     friend srmatrix Im(const scmatrix&);
00604     friend srmatrix Inf(const simatrix&);
00605     friend srmatrix Sup(const simatrix&);
00606     friend srmatrix InfRe(const scimatrix&);
00607     friend srmatrix SupRe(const scimatrix&);
00608     friend srmatrix InfIm(const scimatrix&);
00609     friend srmatrix SupIm(const scimatrix&);
00610     friend srmatrix mid(const simatrix&);
00611     friend srmatrix diam(const simatrix&);
00612     friend srmatrix absmin(const simatrix&);
00613     friend srmatrix absmax(const simatrix&);
00614     friend srmatrix abs(const srmatrix&);
00615 
00616     friend srmatrix CompMat(const simatrix&);
00617     friend srmatrix transp(const srmatrix&);
00618     friend srmatrix Id(const srmatrix&);
00619 
00620     friend std::istream& operator>>(std::istream&, srmatrix_slice&);
00621     friend std::istream& operator>>(std::istream&, srmatrix_subv&);
00622 
00623     friend class srmatrix_slice;
00624     friend class srmatrix_subv;
00625     friend class srvector;
00626     friend class scmatrix;
00627     friend class scmatrix_slice;
00628     friend class scmatrix_subv;
00629     friend class simatrix;
00630     friend class simatrix_slice;
00631     friend class simatrix_subv;
00632     friend class scivector;
00633     friend class scimatrix;
00634     friend class scimatrix_slice;
00635     friend class scimatrix_subv;
00636     friend class rmatrix;
00637     friend class imatrix;
00638     friend class cmatrix;
00639     friend class cimatrix;
00640 
00641 #include "matrix_friend_declarations.inl"
00642 };
00643 
00644 inline rmatrix::rmatrix(const srmatrix& A) {
00645   dat = new real[A.m*A.n];
00646   lb1 = A.lb1; lb2 = A.lb2; ub1 = A.ub1; ub2 = A.ub2;
00647   xsize = A.n;
00648   ysize = A.m;
00649   *this = 0.0;
00650 
00651   for(int j=0 ; j<A.n ; j++) {
00652      for(int k=A.p[j] ; k<A.p[j+1] ; k++) {
00653         dat[A.ind[k]*A.n+j] = A.x[k];
00654      }
00655   }
00656 }
00657 
00658 inline srmatrix Id(const srmatrix& A) {
00659   srmatrix I(A.m, A.n, (A.m>A.n) ? A.m : A.n);
00660   I.lb1 = A.lb1; I.lb2 = A.lb2;
00661   I.ub1 = A.ub1; I.ub2 = A.ub2;
00662 
00663   if(A.m < A.n) {
00664     for(int i=0 ; i<A.m ; i++) {
00665       I.p[i+1] = I.p[i] + 1;
00666       I.ind.push_back(i);
00667       I.x.push_back(1.0);
00668     }
00669   } else {
00670     for(int i=0 ; i<A.n ; i++) {
00671       I.p[i+1] = I.p[i] + 1;
00672       I.ind.push_back(i);
00673       I.x.push_back(1.0);
00674     }
00675   }
00676 
00677   return I;
00678 }
00679 
00680 inline srmatrix transp(const srmatrix& A) {
00681   srmatrix B(A.n, A.m, A.get_nnz());
00682 
00683   //NIchtnullen pro Zeile bestimmen
00684   std::vector<int> w(A.m,0);
00685   for(unsigned int i=0 ; i<A.ind.size() ; i++) 
00686     w[A.ind[i]]++;
00687 
00688   //Spalten"pointer" setzen
00689   B.p.resize(A.m+1);
00690   B.p[0] = 0;
00691   for(unsigned int i=1 ; i<B.p.size() ; i++)
00692     B.p[i] = w[i-1] + B.p[i-1];
00693 
00694   //w vorbereiten
00695   w.insert(w.begin(), 0); 
00696   for(unsigned int i=1 ; i<w.size() ; i++) {
00697     w[i] += w[i-1];
00698   }
00699 
00700   //neuer zeilenindex und wert wird gesetzt
00701   int q;
00702   B.ind.resize(A.get_nnz());
00703   B.x.resize(A.get_nnz());
00704   for(int j=0 ; j<A.n ; j++) {
00705     for(int k=A.p[j] ; k<A.p[j+1] ; k++) {
00706       q = w[A.ind[k]]++;
00707       B.ind[q] = j;
00708       B.x[q] = A.x[k];
00709     }
00710   }
00711 
00712   return B;
00713 }
00714 
00715 
00716 inline srmatrix abs(const srmatrix& A) {
00717   srmatrix ret(A);
00718   for(unsigned int i=0 ; i<ret.x.size() ; i++) 
00719     ret.x[i] = abs(ret.x[i]);
00720   return ret;
00721 }
00722 
00723 
00724 inline void SetLb(srmatrix& A, const int i, const int j) {
00725   if(i==1) {
00726     A.lb1 = j;
00727     A.ub1 = j + A.m - 1;
00728   } else if(i==2) {
00729     A.lb2 = j;
00730     A.ub2 = j + A.n - 1;
00731   }
00732 }
00733 
00734 inline void SetUb(srmatrix& A, const int i, const int j) {
00735   if(i==1) {
00736     A.ub1 = j;
00737     A.lb1 = j - A.m + 1;
00738   } else if(i==2) {
00739     A.ub2 = j;
00740     A.lb2 = j - A.n + 1;
00741   }
00742 }
00743 
00744 inline int Lb(const srmatrix& A, int i) {
00745   if(i==1) 
00746     return A.lb1;
00747   else if(i==2)
00748     return A.lb2;
00749   else
00750     return 1;
00751 }
00752 
00753 inline int Ub(const srmatrix& A, int i) {
00754   if(i==1) 
00755     return A.ub1;
00756   else if(i==2)
00757     return A.ub2;
00758   else
00759     return 1;
00760 }
00761 
00762 inline int RowLen(const srmatrix& A) {
00763   return A.n;
00764 }
00765 
00766 inline int ColLen(const srmatrix& A) {
00767   return A.m;
00768 }
00769 
00770 inline void Resize(srmatrix& A) {
00771   sp_m_resize(A);
00772 }
00773 
00774 inline void Resize(srmatrix& A, const int m, const int n) {
00775   sp_m_resize(A,m,n);
00776 }
00777 
00778 inline void Resize(srmatrix& A, const int l1, const int u1, const int l2, const int u2) {
00779   sp_m_resize(A,l1,u1,l2,u2);
00780 }
00781 
00782 inline rmatrix operator*(const rmatrix& A, const srmatrix& B) {
00783   return fsp_mm_mult<rmatrix,srmatrix,rmatrix,sparse_dot>(A,B);
00784 }
00785 
00786 inline rmatrix operator*(const srmatrix& A, const rmatrix& B) {
00787   return spf_mm_mult<srmatrix,rmatrix,rmatrix,sparse_dot>(A,B);
00788 }
00789 
00790 inline rmatrix operator*(const rmatrix_slice& A, const srmatrix& B) {
00791   return fsp_mm_mult<rmatrix_slice,srmatrix,rmatrix,sparse_dot>(A,B);
00792 }
00793 
00794 inline rmatrix operator*(const srmatrix& A, const rmatrix_slice& B) {
00795   return spf_mm_mult<srmatrix,rmatrix_slice,rmatrix,sparse_dot>(A,B);
00796 }
00797 
00798 inline srmatrix operator*(const srmatrix& A, const srmatrix& B) {
00799   return spsp_mm_mult<srmatrix,srmatrix,srmatrix,sparse_dot,real>(A,B);
00800 }
00801 
00802 inline srmatrix operator*(const srmatrix& A, const real& r) {
00803   return sp_ms_mult<srmatrix,real,srmatrix>(A,r);
00804 }
00805 
00806 inline srmatrix operator/(const srmatrix& A, const real& r) {
00807   return sp_ms_div<srmatrix,real,srmatrix>(A,r);
00808 }
00809 
00810 inline srmatrix operator*(const real& r, const srmatrix& A) {
00811   return sp_sm_mult<real,srmatrix,srmatrix>(r,A);
00812 }
00813 
00814 inline rvector operator*(const srmatrix& A, const rvector& v) {
00815   return spf_mv_mult<srmatrix,rvector,rvector,sparse_dot>(A,v);
00816 }
00817 
00818 inline rvector operator*(const srmatrix& A, const rvector_slice& v) {
00819   return spf_mv_mult<srmatrix,rvector_slice,rvector,sparse_dot>(A,v);
00820 }
00821 
00822 inline srvector operator*(const srmatrix& A, const srvector& v) {
00823   return spsp_mv_mult<srmatrix,srvector,srvector,sparse_dot,real>(A,v);
00824 }
00825 
00826 inline srvector operator*(const srmatrix& A, const srvector_slice& v) {
00827   return spsl_mv_mult<srmatrix,srvector_slice,srvector,sparse_dot,real>(A,v);
00828 }
00829 
00830 inline rvector operator*(const rmatrix& A, const srvector& v) {
00831   return fsp_mv_mult<rmatrix,srvector,rvector,sparse_dot>(A,v);
00832 }
00833 
00834 inline rvector operator*(const rmatrix_slice& A, const srvector& v) {
00835   return fsp_mv_mult<rmatrix_slice,srvector,rvector,sparse_dot>(A,v);
00836 }
00837 
00838 inline rvector operator*(const rmatrix& A, const srvector_slice& v) {
00839   return fsl_mv_mult<rmatrix,srvector_slice,rvector,sparse_dot>(A,v);
00840 }
00841 
00842 inline rvector operator*(const rmatrix_slice& A, const srvector_slice& v) {
00843   return fsl_mv_mult<rmatrix_slice,srvector_slice,rvector,sparse_dot>(A,v);
00844 }
00845 
00846 inline rmatrix operator+(const rmatrix& A, const srmatrix& B) {
00847   return fsp_mm_add<rmatrix,srmatrix,rmatrix>(A,B);
00848 }
00849 
00850 inline rmatrix operator+(const srmatrix& A, const rmatrix& B) {
00851   return spf_mm_add<srmatrix,rmatrix,rmatrix>(A,B);
00852 }
00853 
00854 inline rmatrix operator+(const rmatrix_slice& A, const srmatrix& B) {
00855   return fsp_mm_add<rmatrix_slice,srmatrix,rmatrix>(A,B);
00856 }
00857 
00858 inline rmatrix operator+(const srmatrix& A, const rmatrix_slice& B) {
00859   return spf_mm_add<srmatrix,rmatrix_slice,rmatrix>(A,B);
00860 }
00861 
00862 inline srmatrix operator+(const srmatrix& A, const srmatrix& B) {
00863   return spsp_mm_add<srmatrix,srmatrix,srmatrix,real>(A,B);
00864 }
00865 
00866 inline rmatrix operator-(const rmatrix& A, const srmatrix& B) {
00867   return fsp_mm_sub<rmatrix,srmatrix,rmatrix>(A,B);
00868 }
00869 
00870 inline rmatrix operator-(const srmatrix& A, const rmatrix& B) {
00871   return spf_mm_sub<srmatrix,rmatrix,rmatrix>(A,B);
00872 }
00873 
00874 inline rmatrix operator-(const rmatrix_slice& A, const srmatrix& B) {
00875   return fsp_mm_sub<rmatrix_slice,srmatrix,rmatrix>(A,B);
00876 }
00877 
00878 inline rmatrix operator-(const srmatrix& A, const rmatrix_slice& B) {
00879   return spf_mm_sub<srmatrix,rmatrix_slice,rmatrix>(A,B);
00880 }
00881 
00882 inline srmatrix operator-(const srmatrix& A, const srmatrix& B) {
00883   return spsp_mm_sub<srmatrix,srmatrix,srmatrix,real>(A,B);
00884 }
00885 
00886 inline srmatrix operator-(const srmatrix& M) {
00887   return sp_m_negative<srmatrix,srmatrix>(M);
00888 }
00889 
00890 inline srmatrix& operator+(srmatrix& A) {
00891   return A;
00892 }
00893 
00894 inline rmatrix& rmatrix::operator=(const srmatrix& B) {
00895   *this = rmatrix(B);
00896   return *this;
00897 }
00898 
00899 inline rmatrix_slice& rmatrix_slice::operator=(const srmatrix& B) {
00900   *this = rmatrix(B);
00901   return *this;
00902 }
00903 
00904 inline rmatrix& rmatrix::operator+=(const srmatrix& B) {
00905   return fsp_mm_addassign(*this,B);
00906 }
00907 
00908 inline rmatrix_slice& rmatrix_slice::operator+=(const srmatrix& B) {
00909   return fsp_mm_addassign(*this,B);
00910 }
00911 
00912 inline rmatrix& rmatrix::operator-=(const srmatrix& B) {
00913   return fsp_mm_subassign(*this,B);
00914 }
00915 
00916 inline rmatrix_slice& rmatrix_slice::operator-=(const srmatrix& B) {
00917   return fsp_mm_subassign(*this,B);
00918 }
00919 
00920 inline rmatrix& rmatrix::operator*=(const srmatrix& B) {
00921   return fsp_mm_multassign<rmatrix,srmatrix,sparse_dot,rmatrix>(*this,B);
00922 }
00923 
00924 inline rmatrix_slice& rmatrix_slice::operator*=(const srmatrix& B) {
00925   return fsp_mm_multassign<rmatrix_slice,srmatrix,sparse_dot,rmatrix>(*this,B);
00926 }
00927 
00928 inline bool operator==(const srmatrix& A, const srmatrix& B) {
00929   return spsp_mm_comp(A,B);
00930 }
00931 
00932 inline bool operator==(const srmatrix& A, const rmatrix& B) {
00933   return spf_mm_comp(A,B);
00934 }
00935 
00936 inline bool operator==(const rmatrix& A, const srmatrix& B) {
00937   return fsp_mm_comp(A,B);
00938 }
00939 
00940 inline bool operator==(const rmatrix_slice& A, const srmatrix& B) {
00941   return fsp_mm_comp(A,B);
00942 }
00943 
00944 inline bool operator==(const srmatrix& A, const rmatrix_slice& B) {
00945   return spf_mm_comp(A,B);
00946 }
00947 
00948 inline bool operator!=(const srmatrix& A, const srmatrix& B) {
00949   return !spsp_mm_comp(A,B);
00950 }
00951 
00952 inline bool operator!=(const srmatrix& A, const rmatrix& B) {
00953   return !spf_mm_comp(A,B);
00954 }
00955 
00956 inline bool operator!=(const rmatrix& A, const srmatrix& B) {
00957   return !fsp_mm_comp(A,B);
00958 }
00959 
00960 inline bool operator!=(const rmatrix_slice& A, const srmatrix& B) {
00961   return !fsp_mm_comp(A,B);
00962 }
00963 
00964 inline bool operator!=(const srmatrix& A, const rmatrix_slice& B) {
00965   return !spf_mm_comp(A,B);
00966 }
00967 
00968 inline bool operator<(const srmatrix& A, const srmatrix& B) {
00969   return spsp_mm_less<srmatrix,srmatrix,real>(A,B);
00970 }
00971 
00972 inline bool operator<(const srmatrix& A, const rmatrix& B) {
00973   return spf_mm_less<srmatrix,rmatrix,real>(A,B);
00974 }
00975 
00976 inline bool operator<(const rmatrix& A, const srmatrix& B) {
00977   return fsp_mm_less<rmatrix,srmatrix,real>(A,B);
00978 }
00979 
00980 inline bool operator<(const rmatrix_slice& A, const srmatrix& B) {
00981   return fsp_mm_less<rmatrix_slice,srmatrix,real>(A,B);
00982 }
00983 
00984 inline bool operator<(const srmatrix& A, const rmatrix_slice& B) {
00985   return spf_mm_less<srmatrix,rmatrix_slice,real>(A,B);
00986 }
00987 
00988 inline bool operator<=(const srmatrix& A, const srmatrix& B) {
00989   return spsp_mm_leq<srmatrix,srmatrix,real>(A,B);
00990 }
00991 
00992 inline bool operator<=(const srmatrix& A, const rmatrix& B) {
00993   return spf_mm_leq<srmatrix,rmatrix,real>(A,B);
00994 }
00995 
00996 inline bool operator<=(const rmatrix& A, const srmatrix& B) {
00997   return fsp_mm_leq<rmatrix,srmatrix,real>(A,B);
00998 }
00999 
01000 inline bool operator<=(const rmatrix_slice& A, const srmatrix& B) {
01001   return fsp_mm_leq<rmatrix_slice,srmatrix,real>(A,B);
01002 }
01003 
01004 inline bool operator<=(const srmatrix& A, const rmatrix_slice& B) {
01005   return spf_mm_leq<srmatrix,rmatrix_slice,real>(A,B);
01006 }
01007 
01008 inline bool operator>(const srmatrix& A, const srmatrix& B) {
01009   return spsp_mm_greater<srmatrix,srmatrix,real>(A,B);
01010 }
01011 
01012 inline bool operator>(const srmatrix& A, const rmatrix& B) {
01013   return spf_mm_greater<srmatrix,rmatrix,real>(A,B);
01014 }
01015 
01016 inline bool operator>(const rmatrix& A, const srmatrix& B) {
01017   return fsp_mm_greater<rmatrix,srmatrix,real>(A,B);
01018 }
01019 
01020 inline bool operator>(const rmatrix_slice& A, const srmatrix& B) {
01021   return fsp_mm_greater<rmatrix_slice,srmatrix,real>(A,B);
01022 }
01023 
01024 inline bool operator>(const srmatrix& A, const rmatrix_slice& B) {
01025   return spf_mm_greater<srmatrix,rmatrix_slice,real>(A,B);
01026 }
01027 
01028 inline bool operator>=(const srmatrix& A, const srmatrix& B) {
01029   return spsp_mm_geq<srmatrix,srmatrix,real>(A,B);
01030 }
01031 
01032 inline bool operator>=(const srmatrix& A, const rmatrix& B) {
01033   return spf_mm_geq<srmatrix,rmatrix,real>(A,B);
01034 }
01035 
01036 inline bool operator>=(const rmatrix& A, const srmatrix& B) {
01037   return fsp_mm_geq<rmatrix,srmatrix,real>(A,B);
01038 }
01039 
01040 inline bool operator>=(const rmatrix_slice& A, const srmatrix& B) {
01041   return fsp_mm_geq<rmatrix_slice,srmatrix,real>(A,B);
01042 }
01043 
01044 inline bool operator>=(const srmatrix& A, const rmatrix_slice& B) {
01045   return spf_mm_geq<srmatrix,rmatrix_slice,real>(A,B);
01046 }
01047 
01048 inline bool operator!(const srmatrix& A) {
01049   return sp_m_not(A);
01050 }
01051 
01052 inline std::ostream& operator<<(std::ostream& os, const srmatrix& A) {
01053   return sp_m_output<srmatrix,real>(os,A);
01054 }
01055 
01056 inline std::istream& operator>>(std::istream& is, srmatrix& A) {
01057   return sp_m_input<srmatrix,real>(is,A);
01058 }
01059 
01060 class srmatrix_slice {
01061   public:
01062     srmatrix  A;
01063     srmatrix* M; //Originalmatrix
01064 
01065   private:
01066     srmatrix_slice(srmatrix& Mat, int sl1l, int sl1u, int sl2l, int sl2u) {    
01067         A.lb1 = sl1l;
01068         A.lb2 = sl2l;
01069         A.ub1 = sl1u;
01070         A.ub2 = sl2u;
01071         A.m   = sl1u-sl1l+1;
01072         A.n   = sl2u-sl2l+1;
01073 
01074         //Kopieren der Werte aus A
01075         A.p = std::vector<int>(A.n+1, 0);
01076         A.ind.reserve(A.m + A.n);
01077         A.x.reserve(A.m + A.n);
01078 
01079         for(int i=0 ; i<A.n ; i++) {
01080            A.p[i+1] = A.p[i];
01081            for(int j=Mat.p[sl2l-Mat.lb2+i] ; j<Mat.p[sl2l-Mat.lb2+i+1] ; j++) {
01082               if(Mat.ind[j] >= sl1l-Mat.lb1  &&  Mat.ind[j] <= sl1u-Mat.lb1) {
01083                 A.ind.push_back(Mat.ind[j]-(sl1l-Mat.lb1));
01084                 A.x.push_back(Mat.x[j]);
01085                 A.p[i+1]++;
01086               }
01087            }
01088         }
01089 
01090         //Zeiger auf A fuer Datenmanipulationen
01091         M = &Mat;
01092     }
01093 
01094     srmatrix_slice(const srmatrix& Mat, int sl1l, int sl1u, int sl2l, int sl2u) {    
01095         A.lb1 = sl1l;
01096         A.lb2 = sl2l;
01097         A.ub1 = sl1u;
01098         A.ub2 = sl2u;
01099         A.m   = sl1u-sl1l+1;
01100         A.n   = sl2u-sl2l+1;
01101 
01102         //Kopieren der Werte aus A
01103         A.p = std::vector<int>(A.n+1, 0);
01104         A.ind.reserve(A.m + A.n);
01105         A.x.reserve(A.m + A.n);
01106 
01107         for(int i=0 ; i<A.n ; i++) {
01108            A.p[i+1] = A.p[i];
01109            for(int j=Mat.p[sl2l-Mat.lb2+i] ; j<Mat.p[sl2l-Mat.lb2+i+1] ; j++) {
01110               if(Mat.ind[j] >= sl1l-Mat.lb1  &&  Mat.ind[j] <= sl1u-Mat.lb1) {
01111                 A.ind.push_back(Mat.ind[j]-(sl1l-Mat.lb1));
01112                 A.x.push_back(Mat.x[j]);
01113                 A.p[i+1]++;
01114               }
01115            }
01116         }
01117 
01118         //Zeiger auf A fuer Datenmanipulationen
01119         M = const_cast<srmatrix*>(&Mat);
01120     }
01121 
01122   public:
01123     srmatrix_slice& operator=(const real& C) {
01124       return sl_ms_assign<srmatrix_slice, real, std::vector<real>::iterator, real>(*this,C);
01125     }
01126 
01127     srmatrix_slice& operator=(const srmatrix& C) {
01128       return slsp_mm_assign<srmatrix_slice, srmatrix, std::vector<real>::iterator>(*this,C);
01129     }
01130 
01131     srmatrix_slice& operator=(const rmatrix& C) {
01132       return slf_mm_assign<srmatrix_slice, rmatrix, std::vector<real>::iterator, real>(*this,C);
01133     }
01134 
01135     srmatrix_slice& operator=(const rmatrix_slice& C) {
01136       return slf_mm_assign<srmatrix_slice, rmatrix_slice, std::vector<real>::iterator, real>(*this,C);
01137     }
01138 
01139     srmatrix_slice& operator=(const srmatrix_slice& C) {
01140       *this = C.A;
01141       return *this;
01142     }
01143 
01144     srmatrix_slice& operator*=(const srmatrix_slice& M) {
01145       *this = A*M.A;
01146       return *this;
01147     }
01148 
01149     srmatrix_slice& operator*=(const srmatrix& M) {
01150       *this = A*M;
01151       return *this;
01152     }
01153 
01154     srmatrix_slice& operator*=(const rmatrix& M) {
01155       *this = A*M;
01156       return *this;
01157     }
01158 
01159     srmatrix_slice& operator*=(const rmatrix_slice& M) {
01160       *this = A*M;
01161       return *this;
01162     }
01163 
01164     srmatrix_slice& operator*=(const real& r) {
01165       *this = A*r;
01166       return *this;
01167     }
01168 
01169     srmatrix_slice& operator/=(const real& r) {
01170       *this = A/r;
01171       return *this;
01172     }
01173 
01174     srmatrix_slice& operator+=(const srmatrix_slice& M) {
01175       *this = A+M.A;
01176       return *this;
01177     } 
01178 
01179     srmatrix_slice& operator+=(const srmatrix& M) {
01180       *this = A+M;
01181       return *this;
01182     } 
01183 
01184     srmatrix_slice& operator+=(const rmatrix& M) {
01185       *this = A+M;
01186       return *this;
01187     } 
01188 
01189     srmatrix_slice& operator+=(const rmatrix_slice& M) {
01190       *this = A+M;
01191       return *this;
01192     } 
01193 
01194     srmatrix_slice& operator-=(const srmatrix_slice& M) {
01195       *this = A-M.A;
01196       return *this;
01197     } 
01198 
01199     srmatrix_slice& operator-=(const srmatrix& M) {
01200       *this = A-M;
01201       return *this;
01202     } 
01203 
01204     srmatrix_slice& operator-=(const rmatrix& M) {
01205       *this = A-M;
01206       return *this;
01207     } 
01208 
01209     srmatrix_slice& operator-=(const rmatrix_slice& M) {
01210       *this = A-M;
01211       return *this;
01212     }
01213 
01214     const real operator()(const int i, const int j) const {
01215 #if(CXSC_INDEX_CHECK)
01216       if(i<A.lb1 || i>A.ub1 || j<A.lb2 || j>A.ub2)
01217         cxscthrow(ELEMENT_NOT_IN_VEC("srmatrix_slice::operator()(int, int)"));
01218 #endif
01219       real r = A(i,j);
01220       return r;
01221     }
01222 
01223     real& element(const int i, const int j) {
01224 #if(CXSC_INDEX_CHECK)
01225       if(i<A.lb1 || i>A.ub1 || j<A.lb2 || j>A.ub2)
01226         cxscthrow(ELEMENT_NOT_IN_VEC("srmatrix::element(int, int)"));
01227 #endif
01228       return M->element(i,j);
01229     }
01230 
01231     srmatrix_subv operator[](const int);
01232     srmatrix_subv operator[](const cxscmatrix_column&);
01233     const srmatrix_subv operator[](const int) const;
01234     const srmatrix_subv operator[](const cxscmatrix_column&) const;
01235 
01236     friend int Lb(const srmatrix_slice&, const int);
01237     friend int Ub(const srmatrix_slice&, const int);
01238     friend int RowLen(const srmatrix_slice&);
01239     friend int ColLen(const srmatrix_slice&);
01240 
01241     friend class srmatrix;
01242     friend class srmatrix_subv;
01243     friend class srvector;
01244     friend class scmatrix;
01245     friend class scmatrix_slice;
01246     friend class scmatrix_subv;
01247     friend class scvector;
01248     friend class simatrix;
01249     friend class simatrix_slice;
01250     friend class simatrix_subv;
01251     friend class sivector;
01252     friend class scimatrix;
01253     friend class scimatrix_slice;
01254     friend class scimatrix_subv;
01255     friend class scivector;
01256     friend class rmatrix;
01257     friend class imatrix;
01258     friend class cmatrix;
01259     friend class cimatrix;
01260 
01261 #include "matrix_friend_declarations.inl"    
01262 };
01263 
01264 inline rmatrix::rmatrix(const srmatrix_slice& A) {
01265   dat = new real[A.A.m*A.A.n];
01266   lb1 = A.A.lb1; lb2 = A.A.lb2; ub1 = A.A.ub1; ub2 = A.A.ub2;
01267   xsize = A.A.n;
01268   ysize = A.A.m;
01269   *this = 0.0;
01270   for(int j=0 ; j<A.A.n ; j++) {
01271      for(int k=A.A.p[j] ; k<A.A.p[j+1] ; k++) {
01272         dat[A.A.ind[k]*A.A.n+j] = A.A.x[k];
01273      }
01274   }
01275 }
01276 
01277 inline int Lb(const srmatrix_slice& S, const int i) {
01278   return Lb(S.A, i);
01279 }
01280 
01281 inline int Ub(const srmatrix_slice& S, const int i) {
01282   return Ub(S.A, i);
01283 }
01284 
01285 inline int RowLen(const srmatrix_slice& S) {
01286   return RowLen(S.A);
01287 }
01288 
01289 inline int ColLen(const srmatrix_slice& S) {
01290   return ColLen(S.A);
01291 }
01292 
01293 inline srmatrix_slice srmatrix::operator()(const int i, const int j, const int k, const int l) {
01294 #if(CXSC_INDEX_CHECK)
01295   if(i<lb1 || j>ub1 || k<lb2 || l>ub2)
01296     cxscthrow(ROW_OR_COL_NOT_IN_MAT("srmatrix::operator()(int, int)"));
01297 #endif
01298   return srmatrix_slice(*this, i, j, k, l);
01299 }
01300 
01301 inline srmatrix& srmatrix::operator=(const srmatrix_slice& S) {
01302   *this = S.A;
01303   return *this;
01304 }
01305 
01306 inline srmatrix::srmatrix(const srmatrix_slice& S) {
01307   m = S.A.m;
01308   n = S.A.n;
01309   lb1 = S.A.lb1;
01310   ub1 = S.A.ub1;
01311   lb2 = S.A.lb2;
01312   ub2 = S.A.ub2;
01313   *this = S.A;
01314 }
01315 
01316 inline srmatrix operator-(const srmatrix_slice& M) {
01317   return sp_m_negative<srmatrix,srmatrix>(M.A);
01318 }
01319 
01320 inline srmatrix operator+(const srmatrix_slice& M) {
01321   return M.A;
01322 }
01323 
01324 inline srmatrix operator*(const srmatrix_slice& M1, const srmatrix_slice& M2) {
01325   return spsp_mm_mult<srmatrix,srmatrix,srmatrix,sparse_dot,real>(M1.A,M2.A);
01326 }
01327 
01328 inline srmatrix operator*(const srmatrix_slice& M1, const srmatrix& M2) {
01329   return spsp_mm_mult<srmatrix,srmatrix,srmatrix,sparse_dot,real>(M1.A,M2);
01330 }
01331 
01332 inline srmatrix operator*(const srmatrix& M1, const srmatrix_slice& M2) {
01333   return spsp_mm_mult<srmatrix,srmatrix,srmatrix,sparse_dot,real>(M1,M2.A);
01334 }
01335 
01336 inline rmatrix operator*(const srmatrix_slice& M1, const rmatrix& M2) {
01337   return spf_mm_mult<srmatrix,rmatrix,rmatrix,sparse_dot>(M1.A,M2);
01338 }
01339 
01340 inline rmatrix operator*(const rmatrix& M1, const srmatrix_slice& M2) {
01341   return fsp_mm_mult<rmatrix,srmatrix,rmatrix,sparse_dot>(M1,M2.A);
01342 }
01343 
01344 inline rmatrix operator*(const srmatrix_slice& M1, const rmatrix_slice& M2) {
01345   return spf_mm_mult<srmatrix,rmatrix_slice,rmatrix,sparse_dot>(M1.A,M2);
01346 }
01347 
01348 inline rmatrix operator*(const rmatrix_slice& M1, const srmatrix_slice& M2) {
01349   return fsp_mm_mult<rmatrix,srmatrix,rmatrix,sparse_dot>(M1,M2.A);
01350 }
01351 
01352 inline srvector operator*(const srmatrix_slice& M, const srvector& v) {
01353   return spsp_mv_mult<srmatrix,srvector,srvector,sparse_dot,real>(M.A,v);
01354 }
01355 
01356 inline srvector operator*(const srmatrix_slice& M, const srvector_slice& v) {
01357   return spsl_mv_mult<srmatrix,srvector_slice,srvector,sparse_dot,real>(M.A,v);
01358 }
01359 
01360 inline rvector operator*(const srmatrix_slice& M, const rvector& v) {
01361   return spf_mv_mult<srmatrix,rvector,rvector,sparse_dot>(M.A,v);
01362 }
01363 
01364 inline rvector operator*(const srmatrix_slice& M, const rvector_slice& v) {
01365   return spf_mv_mult<srmatrix,rvector_slice,rvector,sparse_dot>(M.A,v);
01366 }
01367 
01368 inline srmatrix operator*(const srmatrix_slice& M, const real& r) {
01369   return sp_ms_mult<srmatrix,real,srmatrix>(M.A,r);
01370 }
01371 
01372 inline srmatrix operator/(const srmatrix_slice& M, const real& r) {
01373   return sp_ms_div<srmatrix,real,srmatrix>(M.A,r);
01374 }
01375 
01376 inline srmatrix operator*(const real& r, const srmatrix_slice& M) {
01377   return sp_sm_mult<real,srmatrix,srmatrix>(r,M.A);
01378 }
01379 
01380 inline srmatrix operator+(const srmatrix_slice& M1, const srmatrix_slice& M2) {
01381   return spsp_mm_add<srmatrix,srmatrix,srmatrix,real>(M1.A,M2.A);
01382 }
01383 
01384 inline srmatrix operator+(const srmatrix_slice& M1, const srmatrix& M2) {
01385   return spsp_mm_add<srmatrix,srmatrix,srmatrix,real>(M1.A,M2);
01386 }
01387 
01388 inline srmatrix operator+(const srmatrix& M1, const srmatrix_slice& M2) {
01389   return spsp_mm_add<srmatrix,srmatrix,srmatrix,real>(M1,M2.A);
01390 }
01391 
01392 inline rmatrix operator+(const srmatrix_slice& M1, const rmatrix& M2) {
01393   return spf_mm_add<srmatrix,rmatrix,rmatrix>(M1.A,M2);
01394 }
01395 
01396 inline rmatrix operator+(const rmatrix& M1, const srmatrix_slice& M2) {
01397   return fsp_mm_add<rmatrix,srmatrix,rmatrix>(M1,M2.A);
01398 }
01399 
01400 inline rmatrix operator+(const srmatrix_slice& M1, const rmatrix_slice& M2) {
01401   return spf_mm_add<srmatrix,rmatrix_slice,rmatrix>(M1.A,M2);
01402 }
01403 
01404 inline rmatrix operator+(const rmatrix_slice& M1, const srmatrix_slice& M2) {
01405   return fsp_mm_add<rmatrix_slice,srmatrix,rmatrix>(M1,M2.A);
01406 }
01407 
01408 inline srmatrix operator-(const srmatrix_slice& M1, const srmatrix_slice& M2) {
01409   return spsp_mm_sub<srmatrix,srmatrix,srmatrix,real>(M1.A,M2.A);
01410 }
01411 
01412 inline srmatrix operator-(const srmatrix_slice& M1, const srmatrix& M2) {
01413   return spsp_mm_sub<srmatrix,srmatrix,srmatrix,real>(M1.A,M2);
01414 }
01415 
01416 inline srmatrix operator-(const srmatrix& M1, const srmatrix_slice& M2) {
01417   return spsp_mm_sub<srmatrix,srmatrix,srmatrix,real>(M1,M2.A);
01418 }
01419 
01420 inline rmatrix operator-(const srmatrix_slice& M1, const rmatrix& M2) {
01421   return spf_mm_sub<srmatrix,rmatrix,rmatrix>(M1.A,M2);
01422 }
01423 
01424 inline rmatrix operator-(const rmatrix& M1, const srmatrix_slice& M2) {
01425   return fsp_mm_sub<rmatrix,srmatrix,rmatrix>(M1,M2.A);
01426 }
01427 
01428 inline rmatrix operator-(const srmatrix_slice& M1, const rmatrix_slice& M2) {
01429   return spf_mm_sub<srmatrix,rmatrix_slice,rmatrix>(M1.A,M2);
01430 }
01431 
01432 inline rmatrix operator-(const rmatrix_slice& M1, const srmatrix_slice& M2) {
01433   return fsp_mm_sub<rmatrix_slice,srmatrix,rmatrix>(M1,M2.A);
01434 }
01435 
01436 inline rmatrix& rmatrix::operator=(const srmatrix_slice& M) {
01437   *this = rmatrix(M);
01438   return *this;
01439 }
01440 
01441 inline rmatrix& rmatrix::operator+=(const srmatrix_slice& M) {
01442   *this += M.A;
01443   return *this;
01444 }
01445 
01446 inline rmatrix_slice& rmatrix_slice::operator+=(const srmatrix_slice& M) {
01447   *this += M.A;
01448   return *this;
01449 }
01450 
01451 inline rmatrix& rmatrix::operator-=(const srmatrix_slice& M) {
01452   *this -= M.A;
01453   return *this;
01454 }
01455 
01456 inline rmatrix_slice& rmatrix_slice::operator-=(const srmatrix_slice& M) {
01457   *this -= M.A;
01458   return *this;
01459 }
01460 
01461 inline rmatrix& rmatrix::operator*=(const srmatrix_slice& M) {
01462   *this *= M.A;
01463   return *this;
01464 }
01465 
01466 inline rmatrix_slice& rmatrix_slice::operator*=(const srmatrix_slice& M) {
01467   *this *= M.A;
01468   return *this;
01469 }
01470 
01471 inline bool operator==(const srmatrix_slice& M1, const srmatrix_slice& M2) {
01472   return spsp_mm_comp(M1.A,M2.A);
01473 }
01474 
01475 inline bool operator==(const srmatrix_slice& M1, const srmatrix& M2) {
01476   return spsp_mm_comp(M1.A,M2);
01477 }
01478 
01479 inline bool operator==(const srmatrix& M1, const srmatrix_slice& M2) {
01480   return spsp_mm_comp(M1,M2.A);
01481 }
01482 
01483 inline bool operator==(const srmatrix_slice& M1, const rmatrix& M2) {
01484   return spf_mm_comp(M1.A,M2);
01485 }
01486 
01487 inline bool operator==(const rmatrix& M1, const srmatrix_slice& M2) {
01488   return fsp_mm_comp(M1,M2.A);
01489 }
01490 
01491 inline bool operator==(const rmatrix_slice& M1, const srmatrix_slice& M2) {
01492   return fsp_mm_comp(M1,M2.A);
01493 }
01494 
01495 inline bool operator==(const srmatrix_slice& M1, const rmatrix_slice& M2) {
01496   return spf_mm_comp(M1.A,M2);
01497 }
01498 
01499 inline bool operator!=(const srmatrix_slice& M1, const srmatrix_slice& M2) {
01500   return !spsp_mm_comp(M1.A,M2.A);
01501 }
01502 
01503 inline bool operator!=(const srmatrix_slice& M1, const srmatrix& M2) {
01504   return !spsp_mm_comp(M1.A,M2);
01505 }
01506 
01507 inline bool operator!=(const srmatrix& M1, const srmatrix_slice& M2) {
01508   return !spsp_mm_comp(M1,M2.A);
01509 }
01510 
01511 inline bool operator!=(const srmatrix_slice& M1, const rmatrix& M2) {
01512   return !spf_mm_comp(M1.A,M2);
01513 }
01514 
01515 inline bool operator!=(const rmatrix& M1, const srmatrix_slice& M2) {
01516   return !fsp_mm_comp(M1,M2.A);
01517 }
01518 
01519 inline bool operator!=(const rmatrix_slice& M1, const srmatrix_slice& M2) {
01520   return !fsp_mm_comp(M1,M2.A);
01521 }
01522 
01523 inline bool operator!=(const srmatrix_slice& M1, const rmatrix_slice& M2) {
01524   return !spf_mm_comp(M1.A,M2);
01525 }
01526 
01527 inline bool operator<(const srmatrix_slice& M1, const srmatrix_slice& M2) {
01528   return spsp_mm_less<srmatrix,srmatrix,real>(M1.A,M2.A);
01529 }
01530 
01531 inline bool operator<(const srmatrix_slice& M1, const srmatrix& M2) {
01532   return spsp_mm_less<srmatrix,srmatrix,real>(M1.A,M2);
01533 }
01534 
01535 inline bool operator<(const srmatrix& M1, const srmatrix_slice& M2) {
01536   return spsp_mm_less<srmatrix,srmatrix,real>(M1,M2.A);
01537 }
01538 
01539 inline bool operator<(const srmatrix_slice& M1, const rmatrix& M2) {
01540   return spf_mm_less<srmatrix,rmatrix,real>(M1.A,M2);
01541 }
01542 
01543 inline bool operator<(const rmatrix& M1, const srmatrix_slice& M2) {
01544   return fsp_mm_less<rmatrix,srmatrix,real>(M1,M2.A);
01545 }
01546 
01547 inline bool operator<(const rmatrix_slice& M1, const srmatrix_slice& M2) {
01548   return fsp_mm_less<rmatrix_slice,srmatrix,real>(M1,M2.A);
01549 }
01550 
01551 inline bool operator<(const srmatrix_slice& M1, const rmatrix_slice& M2) {
01552   return spf_mm_less<srmatrix,rmatrix_slice,real>(M1.A,M2);
01553 }
01554 
01555 inline bool operator<=(const srmatrix_slice& M1, const srmatrix_slice& M2) {
01556   return spsp_mm_leq<srmatrix,srmatrix,real>(M1.A,M2.A);
01557 }
01558 
01559 inline bool operator<=(const srmatrix_slice& M1, const srmatrix& M2) {
01560   return spsp_mm_leq<srmatrix,srmatrix,real>(M1.A,M2);
01561 }
01562 
01563 inline bool operator<=(const srmatrix& M1, const srmatrix_slice& M2) {
01564   return spsp_mm_leq<srmatrix,srmatrix,real>(M1,M2.A);
01565 }
01566 
01567 inline bool operator<=(const srmatrix_slice& M1, const rmatrix& M2) {
01568   return spf_mm_leq<srmatrix,rmatrix,real>(M1.A,M2);
01569 }
01570 
01571 inline bool operator<=(const rmatrix& M1, const srmatrix_slice& M2) {
01572   return fsp_mm_leq<rmatrix,srmatrix,real>(M1,M2.A);
01573 }
01574 
01575 inline bool operator<=(const rmatrix_slice& M1, const srmatrix_slice& M2) {
01576   return fsp_mm_leq<rmatrix_slice,srmatrix,real>(M1,M2.A);
01577 }
01578 
01579 inline bool operator<=(const srmatrix_slice& M1, const rmatrix_slice& M2) {
01580   return spf_mm_leq<srmatrix,rmatrix_slice,real>(M1.A,M2);
01581 }
01582 
01583 inline bool operator>(const srmatrix_slice& M1, const srmatrix_slice& M2) {
01584   return spsp_mm_greater<srmatrix,srmatrix,real>(M1.A,M2.A);
01585 }
01586 
01587 inline bool operator>(const srmatrix_slice& M1, const srmatrix& M2) {
01588   return spsp_mm_greater<srmatrix,srmatrix,real>(M1.A,M2);
01589 }
01590 
01591 inline bool operator>(const srmatrix& M1, const srmatrix_slice& M2) {
01592   return spsp_mm_greater<srmatrix,srmatrix,real>(M1,M2.A);
01593 }
01594 
01595 inline bool operator>(const srmatrix_slice& M1, const rmatrix& M2) {
01596   return spf_mm_greater<srmatrix,rmatrix,real>(M1.A,M2);
01597 }
01598 
01599 inline bool operator>(const rmatrix& M1, const srmatrix_slice& M2) {
01600   return fsp_mm_greater<rmatrix,srmatrix,real>(M1,M2.A);
01601 }
01602 
01603 inline bool operator>(const rmatrix_slice& M1, const srmatrix_slice& M2) {
01604   return fsp_mm_greater<rmatrix_slice,srmatrix,real>(M1,M2.A);
01605 }
01606 
01607 inline bool operator>(const srmatrix_slice& M1, const rmatrix_slice& M2) {
01608   return spf_mm_greater<srmatrix,rmatrix_slice,real>(M1.A,M2);
01609 }
01610 
01611 inline bool operator>=(const srmatrix_slice& M1, const srmatrix_slice& M2) {
01612   return spsp_mm_geq<srmatrix,srmatrix,real>(M1.A,M2.A);
01613 }
01614 
01615 inline bool operator>=(const srmatrix_slice& M1, const srmatrix& M2) {
01616   return spsp_mm_geq<srmatrix,srmatrix,real>(M1.A,M2);
01617 }
01618 
01619 inline bool operator>=(const srmatrix& M1, const srmatrix_slice& M2) {
01620   return spsp_mm_geq<srmatrix,srmatrix,real>(M1,M2.A);
01621 }
01622 
01623 inline bool operator>=(const srmatrix_slice& M1, const rmatrix& M2) {
01624   return spf_mm_geq<srmatrix,rmatrix,real>(M1.A,M2);
01625 }
01626 
01627 inline bool operator>=(const rmatrix& M1, const srmatrix_slice& M2) {
01628   return fsp_mm_geq<rmatrix,srmatrix,real>(M1,M2.A);
01629 }
01630 
01631 inline bool operator>=(const rmatrix_slice& M1, const srmatrix_slice& M2) {
01632   return fsp_mm_geq<rmatrix_slice,srmatrix,real>(M1,M2.A);
01633 }
01634 
01635 inline bool operator>=(const srmatrix_slice& M1, const rmatrix_slice& M2) {
01636   return spf_mm_geq<srmatrix,rmatrix_slice,real>(M1.A,M2);
01637 }
01638 
01639 inline bool operator!(const srmatrix_slice& M) {
01640   return sp_m_not(M.A);
01641 }
01642 
01643 inline std::ostream& operator<<(std::ostream& os, const srmatrix_slice& M) {
01644   return sp_m_output<srmatrix,real>(os, M.A);
01645 }
01646 
01647 inline std::istream& operator>>(std::istream& is, srmatrix_slice& M) {
01648   srmatrix tmp(M.A.m,M.A.n);
01649   sp_m_input<srmatrix,real>(is, tmp);
01650   M = tmp;
01651   return is;
01652 }
01653 
01654 
01655 class srmatrix_subv {
01656   private:
01657     srmatrix_slice dat;
01658     bool row;
01659     int index;
01660 
01661     srmatrix_subv(srmatrix& A, bool r, int i, int j, int k, int l) : dat(A,i,j,k,l), row(r) {
01662        if(row) index=i; else index=k;
01663     }
01664 
01665     srmatrix_subv(const srmatrix& A, bool r, int i, int j, int k, int l) : dat(A,i,j,k,l), row(r){
01666        if(row) index=i; else index=k;
01667     }
01668 
01669   public:
01670     real& operator[](const int i) {
01671       if(row) {
01672 #if(CXSC_INDEX_CHECK)
01673         if(i<dat.A.lb2 || i>dat.A.ub2)
01674           cxscthrow(ELEMENT_NOT_IN_VEC("srmatrix_subv::operator[](int)"));
01675 #endif
01676         return dat.element(index,i);
01677       } else {
01678 #if(CXSC_INDEX_CHECK)
01679         if(i<dat.A.lb1 || i>dat.A.ub1)
01680           cxscthrow(ELEMENT_NOT_IN_VEC("srmatrix_subv::operator[](int)"));
01681 #endif
01682         return dat.element(i,index);
01683       }
01684     }
01685 
01686     const real operator[](const int i) const {
01687       if(row) {
01688 #if(CXSC_INDEX_CHECK)
01689         if(i<dat.A.lb2 || i>dat.A.ub2)
01690           cxscthrow(ELEMENT_NOT_IN_VEC("srmatrix_subv::operator[](int)"));
01691 #endif
01692         return dat(index,i);
01693       } else {
01694 #if(CXSC_INDEX_CHECK)
01695         if(i<dat.A.lb1 || i>dat.A.ub1)
01696           cxscthrow(ELEMENT_NOT_IN_VEC("srmatrix_subv::operator[](int)"));
01697 #endif
01698         return dat(i,index);
01699       }
01700     }
01701 
01702     srmatrix_subv& operator=(const srmatrix_subv& v) {
01703       return svsp_vv_assign(*this,srvector(v));
01704     }
01705 
01706     srmatrix_subv& operator=(const real& v) {
01707       return sv_vs_assign(*this,v);
01708     }
01709 
01710     srmatrix_subv& operator=(const srvector& v) {
01711       return svsp_vv_assign(*this,v);
01712     }
01713 
01714     srmatrix_subv& operator=(const srvector_slice& v) {
01715       return svsl_vv_assign(*this,v);
01716     }
01717 
01718     srmatrix_subv& operator=(const rvector& v) {
01719       return svf_vv_assign(*this,v);
01720     }
01721 
01722     srmatrix_subv& operator=(const rvector_slice& v) {
01723       return svf_vv_assign(*this,v);
01724     }
01725 
01726     srmatrix_subv& operator*=(const real&);
01727     srmatrix_subv& operator/=(const real&);
01728     srmatrix_subv& operator+=(const srvector&);
01729     srmatrix_subv& operator+=(const srvector_slice&);
01730     srmatrix_subv& operator+=(const rvector&);
01731     srmatrix_subv& operator+=(const rvector_slice&);
01732     srmatrix_subv& operator-=(const srvector&);
01733     srmatrix_subv& operator-=(const srvector_slice&);
01734     srmatrix_subv& operator-=(const rvector&);
01735     srmatrix_subv& operator-=(const rvector_slice&);
01736 
01737     friend srvector operator-(const srmatrix_subv&);
01738 
01739     friend std::istream& operator>>(std::istream&, srmatrix_subv&);
01740 
01741     friend int Lb(const srmatrix_subv&);
01742     friend int Ub(const srmatrix_subv&);
01743     friend int VecLen(const srmatrix_subv&);
01744 
01745     friend class srvector;
01746     friend class srmatrix;
01747     friend class srmatrix_slice;
01748     friend class scvector;
01749     friend class scmatrix;
01750     friend class scmatrix_slice;
01751     friend class sivector;
01752     friend class simatrix;
01753     friend class simatrix_slice;
01754     friend class scivector;
01755     friend class scimatrix;
01756     friend class scimatrix_slice;
01757 
01758 #include "vector_friend_declarations.inl"
01759 };
01760 
01761 inline int Lb(const srmatrix_subv& S) {
01762   if(S.row)
01763     return Lb(S.dat, 2);
01764   else
01765     return Lb(S.dat, 1);
01766 }
01767 
01768 inline int Ub(const srmatrix_subv& S) {
01769   if(S.row)
01770     return Ub(S.dat, 2);
01771   else
01772     return Ub(S.dat, 1);
01773 }
01774 
01775 inline int VecLen(const srmatrix_subv& S) {
01776   return Ub(S)-Lb(S)+1;
01777 }
01778 
01779 inline std::ostream& operator<<(std::ostream& os, const srmatrix_subv& v) {
01780   os << srvector(v);
01781   return os;
01782 }
01783 
01784 inline std::istream& operator>>(std::istream& is, srmatrix_subv& v) {
01785   int n = 0;
01786   if(v.row) n=v.dat.A.n; else n=v.dat.A.m;
01787   srvector tmp(n);
01788   is >> tmp;
01789   v = tmp;
01790   return is;
01791 }
01792 
01793 inline srmatrix_subv srmatrix::operator[](const cxscmatrix_column& c) {
01794 #if(CXSC_INDEX_CHECK)
01795   if(c.col()<lb2 || c.col()>ub2)
01796     cxscthrow(ROW_OR_COL_NOT_IN_MAT("srmatrix::operator[](const cxscmatrix_column&)"));
01797 #endif
01798   return srmatrix_subv(*this, false, lb1, ub1, c.col(), c.col());
01799 }
01800 
01801 inline srmatrix_subv srmatrix::operator[](const int i) {
01802 #if(CXSC_INDEX_CHECK)
01803   if(i<lb1 || i>ub1)
01804     cxscthrow(ROW_OR_COL_NOT_IN_MAT("srmatrix::operator[](const int)"));
01805 #endif
01806   return srmatrix_subv(*this, true, i, i, lb2, ub2);
01807 }
01808 
01809 inline const srmatrix_subv srmatrix::operator[](const cxscmatrix_column& c) const {
01810 #if(CXSC_INDEX_CHECK)
01811   if(c.col()<lb2 || c.col()>ub2)
01812     cxscthrow(ROW_OR_COL_NOT_IN_MAT("srmatrix::operator[](const cxscmatrix_column&)"));
01813 #endif
01814   return srmatrix_subv(*this, false, lb1, ub1, c.col(), c.col());
01815 }
01816 
01817 inline const srmatrix_subv srmatrix::operator[](const int i) const {
01818 #if(CXSC_INDEX_CHECK)
01819   if(i<lb1 || i>ub1)
01820     cxscthrow(ROW_OR_COL_NOT_IN_MAT("srmatrix::operator[](const int)"));
01821 #endif
01822   return srmatrix_subv(*this, true, i, i, lb2, ub2);
01823 }
01824 
01825 inline srmatrix_subv srmatrix_slice::operator[](const int i) {
01826 #if(CXSC_INDEX_CHECK)
01827   if(i<A.lb1 || i>A.ub1)
01828     cxscthrow(ROW_OR_COL_NOT_IN_MAT("srmatrix_slice::operator[](const int)"));
01829 #endif
01830   return srmatrix_subv(*M, true, i, i, A.lb2, A.ub2);
01831 }
01832 
01833 inline srmatrix_subv srmatrix_slice::operator[](const cxscmatrix_column& c) {
01834 #if(CXSC_INDEX_CHECK)
01835   if(c.col()<A.lb2 || c.col()>A.ub2)
01836     cxscthrow(ROW_OR_COL_NOT_IN_MAT("srmatrix_slice::operator[](const cxscmatrix_column&)"));
01837 #endif
01838   return srmatrix_subv(*M, false, A.lb1, A.ub1, c.col(), c.col());
01839 }
01840 
01841 inline const srmatrix_subv srmatrix_slice::operator[](const int i) const {
01842 #if(CXSC_INDEX_CHECK)
01843   if(i<A.lb1 || i>A.ub1)
01844     cxscthrow(ROW_OR_COL_NOT_IN_MAT("srmatrix_slice::operator[](const int)"));
01845 #endif
01846   return srmatrix_subv(*M, true, i, i, A.lb2, A.ub2);
01847 }
01848 
01849 inline const srmatrix_subv srmatrix_slice::operator[](const cxscmatrix_column& c) const {
01850 #if(CXSC_INDEX_CHECK)
01851   if(c.col()<A.lb2 || c.col()>A.ub2)
01852     cxscthrow(ROW_OR_COL_NOT_IN_MAT("srmatrix_slice::operator[](const cxscmatrix_column&)"));
01853 #endif
01854   return srmatrix_subv(*M, false, A.lb1, A.ub1, c.col(), c.col());
01855 }
01856 
01857 inline srvector::srvector(const srmatrix_subv& A) {
01858   p.reserve(A.dat.A.get_nnz());
01859   x.reserve(A.dat.A.get_nnz());
01860 
01861   if(A.row) {
01862     lb = A.dat.A.lb2;
01863     ub = A.dat.A.ub2;
01864     n = ub-lb+1; 
01865 
01866     for(int j=0 ; j<n ; j++) {
01867       for(int k=A.dat.A.p[j] ; k<A.dat.A.p[j+1] ; k++) {
01868         p.push_back(j);
01869         x.push_back(A.dat.A.x[k]);
01870       }
01871     }
01872 
01873   } else {
01874     lb = A.dat.A.lb1;
01875     ub = A.dat.A.ub1;
01876     n = ub-lb+1; 
01877 
01878     for(unsigned int k=0 ; k<A.dat.A.ind.size() ; k++) {
01879         p.push_back(A.dat.A.ind[k]);
01880         x.push_back(A.dat.A.x[k]);
01881     }
01882   }
01883 }
01884 
01885 inline srvector operator-(const srmatrix_subv& v) {
01886  srvector s(v);
01887  return -s;
01888 }
01889 
01890 inline srvector operator*(const srmatrix_subv& v1, const real& v2) {
01891   return srvector(v1) * v2;
01892 }
01893 
01894 inline srvector operator/(const srmatrix_subv& v1, const real& v2) {
01895   return srvector(v1) / v2;
01896 }
01897 
01898 inline srvector operator*(const real& v1, const srmatrix_subv& v2) {
01899   return v1 * srvector(v2);
01900 }
01901 
01902 inline real operator*(const srmatrix_subv& v1, const srvector& v2) {
01903   return srvector(v1) * v2;
01904 }
01905 
01906 inline real operator*(const srmatrix_subv& v1, const srvector_slice& v2) {
01907   return srvector(v1) * v2;
01908 }
01909 
01910 inline real operator*(const srmatrix_subv& v1, const rvector& v2) {
01911   return srvector(v1) * v2;
01912 }
01913 
01914 inline real operator*(const srmatrix_subv& v1, const rvector_slice& v2) {
01915   return srvector(v1) * v2;
01916 }
01917 
01918 inline real operator*(const srvector& v1, const srmatrix_subv& v2) {
01919   return v1 * srvector(v2);
01920 }
01921 
01922 inline real operator*(const srvector_slice& v1, const srmatrix_subv& v2) {
01923   return v1 * srvector(v2);
01924 }
01925 
01926 inline real operator*(const rvector& v1, const srmatrix_subv& v2) {
01927   return v1 * srvector(v2);
01928 }
01929 
01930 inline real operator*(const rvector_slice& v1, const srmatrix_subv& v2) {
01931   return v1 * srvector(v2);
01932 }
01933 
01934 inline srvector operator+(const srmatrix_subv& v1, const srvector& v2) {
01935   return srvector(v1) + v2;
01936 }
01937 
01938 inline srvector operator+(const srmatrix_subv& v1, const srvector_slice& v2) {
01939   return srvector(v1) + v2;
01940 }
01941 
01942 inline rvector operator+(const srmatrix_subv& v1, const rvector& v2) {
01943   return srvector(v1) + v2;
01944 }
01945 
01946 inline rvector operator+(const srmatrix_subv& v1, const rvector_slice& v2) {
01947   return srvector(v1) + v2;
01948 }
01949 
01950 inline srvector operator+(const srvector& v1, const srmatrix_subv& v2) {
01951   return v1 + srvector(v2);
01952 }
01953 
01954 inline srvector operator+(const srvector_slice& v1, const srmatrix_subv& v2) {
01955   return v1 + srvector(v2);
01956 }
01957 
01958 inline rvector operator+(const rvector& v1, const srmatrix_subv& v2) {
01959   return v1 + srvector(v2);
01960 }
01961 
01962 inline rvector operator+(const rvector_slice& v1, const srmatrix_subv& v2) {
01963   return v1 + srvector(v2);
01964 }
01965 
01966 inline srvector operator-(const srmatrix_subv& v1, const srvector& v2) {
01967   return srvector(v1) - v2;
01968 }
01969 
01970 inline srvector operator-(const srmatrix_subv& v1, const srvector_slice& v2) {
01971   return srvector(v1) - v2;
01972 }
01973 
01974 inline rvector operator-(const srmatrix_subv& v1, const rvector& v2) {
01975   return srvector(v1) - v2;
01976 }
01977 
01978 inline rvector operator-(const srmatrix_subv& v1, const rvector_slice& v2) {
01979   return srvector(v1) - v2;
01980 }
01981 
01982 inline srvector operator-(const srvector& v1, const srmatrix_subv& v2) {
01983   return v1 - srvector(v2);
01984 }
01985 
01986 inline srvector operator-(const srvector_slice& v1, const srmatrix_subv& v2) {
01987   return v1 - srvector(v2);
01988 }
01989 
01990 inline rvector operator-(const rvector& v1, const srmatrix_subv& v2) {
01991   return v1 - srvector(v2);
01992 }
01993 
01994 inline rvector operator-(const rvector_slice& v1, const srmatrix_subv& v2) {
01995   return v1 - srvector(v2);
01996 }
01997 
01998 inline srmatrix_subv& srmatrix_subv::operator*=(const real& v) {
01999   *this = *this * v;
02000   return *this;
02001 }
02002 
02003 inline srmatrix_subv& srmatrix_subv::operator/=(const real& v) {
02004   *this = *this * v;
02005   return *this;
02006 }
02007 
02008 inline srmatrix_subv& srmatrix_subv::operator+=(const srvector& v) {
02009   *this = *this + v;
02010   return *this;
02011 }
02012 
02013 inline srmatrix_subv& srmatrix_subv::operator+=(const srvector_slice& v) {
02014   *this = *this + v;
02015   return *this;
02016 }
02017 
02018 inline srmatrix_subv& srmatrix_subv::operator+=(const rvector& v) {
02019   *this = *this + v;
02020   return *this;
02021 }
02022 
02023 inline srmatrix_subv& srmatrix_subv::operator+=(const rvector_slice& v) {
02024   *this = *this + v;
02025   return *this;
02026 }
02027 
02028 inline srmatrix_subv& srmatrix_subv::operator-=(const srvector& v) {
02029   *this = *this - v;
02030   return *this;
02031 }
02032 
02033 inline srmatrix_subv& srmatrix_subv::operator-=(const srvector_slice& v) {
02034   *this = *this - v;
02035   return *this;
02036 }
02037 
02038 inline srmatrix_subv& srmatrix_subv::operator-=(const rvector& v) {
02039   *this = *this - v;
02040   return *this;
02041 }
02042 
02043 inline srmatrix_subv& srmatrix_subv::operator-=(const rvector_slice& v) {
02044   *this = *this - v;
02045   return *this;
02046 }
02047 
02048 inline rmatrix_subv& rmatrix_subv::operator+=(const srmatrix_subv& v) {
02049   *this += rvector(v);
02050   return *this;
02051 }
02052 
02053 inline rmatrix_subv& rmatrix_subv::operator+=(const srvector& v) {
02054   *this += rvector(v);
02055   return *this;
02056 }
02057 
02058 inline rmatrix_subv& rmatrix_subv::operator+=(const srvector_slice& v) {
02059   *this += rvector(v);
02060   return *this;
02061 }
02062 
02063 inline rmatrix_subv& rmatrix_subv::operator-=(const srmatrix_subv& v) {
02064   *this -= rvector(v);
02065   return *this;
02066 }
02067 
02068 inline rmatrix_subv& rmatrix_subv::operator=(const srvector& v) {
02069   *this = rvector(v);
02070   return *this;
02071 }
02072 
02073 inline rmatrix_subv& rmatrix_subv::operator=(const srvector_slice& v) {
02074   *this = rvector(v);
02075   return *this;
02076 }
02077 
02078 inline rmatrix_subv& rmatrix_subv::operator=(const srmatrix_subv& v) {
02079   *this = rvector(v);
02080   return *this;
02081 }
02082 
02083 inline bool operator==(const srmatrix_subv& v1, const srvector& v2) {
02084   return srvector(v1) == v2;
02085 }
02086 
02087 inline bool operator==(const srmatrix_subv& v1, const srvector_slice& v2) {
02088   return srvector(v1) == v2;
02089 }
02090 
02091 inline bool operator==(const srmatrix_subv& v1, const rvector& v2) {
02092   return srvector(v1) == v2;
02093 }
02094 
02095 inline bool operator==(const srmatrix_subv& v1, const rvector_slice& v2) {
02096   return srvector(v1) == v2;
02097 }
02098 
02099 inline bool operator==(const srvector& v1, const srmatrix_subv& v2) {
02100   return v1 == srvector(v2);
02101 }
02102 
02103 inline bool operator==(const srvector_slice& v1, const srmatrix_subv& v2) {
02104   return v1 == srvector(v2);
02105 }
02106 
02107 inline bool operator==(const rvector& v1, const srmatrix_subv& v2) {
02108   return v1 == srvector(v2);
02109 }
02110 
02111 inline bool operator==(const rvector_slice& v1, const srmatrix_subv& v2) {
02112   return v1 == srvector(v2);
02113 }
02114 
02115 inline bool operator!=(const srmatrix_subv& v1, const srvector& v2) {
02116   return srvector(v1) != v2;
02117 }
02118 
02119 inline bool operator!=(const srmatrix_subv& v1, const srvector_slice& v2) {
02120   return srvector(v1) != v2;
02121 }
02122 
02123 inline bool operator!=(const srmatrix_subv& v1, const rvector& v2) {
02124   return srvector(v1) != v2;
02125 }
02126 
02127 inline bool operator!=(const srmatrix_subv& v1, const rvector_slice& v2) {
02128   return srvector(v1) != v2;
02129 }
02130 
02131 inline bool operator!=(const srvector& v1, const srmatrix_subv& v2) {
02132   return v1 != srvector(v2);
02133 }
02134 
02135 inline bool operator!=(const srvector_slice& v1, const srmatrix_subv& v2) {
02136   return v1 != srvector(v2);
02137 }
02138 
02139 inline bool operator!=(const rvector& v1, const srmatrix_subv& v2) {
02140   return v1 != srvector(v2);
02141 }
02142 
02143 inline bool operator!=(const rvector_slice& v1, const srmatrix_subv& v2) {
02144   return v1 != srvector(v2);
02145 }
02146 
02147 inline bool operator<(const srmatrix_subv& v1, const srvector& v2) {
02148   return srvector(v1) < v2;
02149 }
02150 
02151 inline bool operator<(const srmatrix_subv& v1, const srvector_slice& v2) {
02152   return srvector(v1) < v2;
02153 }
02154 
02155 inline bool operator<(const srmatrix_subv& v1, const rvector& v2) {
02156   return srvector(v1) < v2;
02157 }
02158 
02159 inline bool operator<(const srmatrix_subv& v1, const rvector_slice& v2) {
02160   return srvector(v1) < v2;
02161 }
02162 
02163 inline bool operator<(const srvector& v1, const srmatrix_subv& v2) {
02164   return v1 < srvector(v2);
02165 }
02166 
02167 inline bool operator<(const srvector_slice& v1, const srmatrix_subv& v2) {
02168   return v1 < srvector(v2);
02169 }
02170 
02171 inline bool operator<(const rvector& v1, const srmatrix_subv& v2) {
02172   return v1 < srvector(v2);
02173 }
02174 
02175 inline bool operator<(const rvector_slice& v1, const srmatrix_subv& v2) {
02176   return v1 < srvector(v2);
02177 }
02178 
02179 inline bool operator<=(const srmatrix_subv& v1, const srvector& v2) {
02180   return srvector(v1) <= v2;
02181 }
02182 
02183 inline bool operator<=(const srmatrix_subv& v1, const srvector_slice& v2) {
02184   return srvector(v1) <= v2;
02185 }
02186 
02187 inline bool operator<=(const srmatrix_subv& v1, const rvector& v2) {
02188   return srvector(v1) <= v2;
02189 }
02190 
02191 inline bool operator<=(const srmatrix_subv& v1, const rvector_slice& v2) {
02192   return srvector(v1) <= v2;
02193 }
02194 
02195 inline bool operator<=(const srvector& v1, const srmatrix_subv& v2) {
02196   return v1 <= srvector(v2);
02197 }
02198 
02199 inline bool operator<=(const srvector_slice& v1, const srmatrix_subv& v2) {
02200   return v1 <= srvector(v2);
02201 }
02202 
02203 inline bool operator<=(const rvector& v1, const srmatrix_subv& v2) {
02204   return v1 <= srvector(v2);
02205 }
02206 
02207 inline bool operator<=(const rvector_slice& v1, const srmatrix_subv& v2) {
02208   return v1 <= srvector(v2);
02209 }
02210 
02211 inline bool operator>(const srmatrix_subv& v1, const srvector& v2) {
02212   return srvector(v1) > v2;
02213 }
02214 
02215 inline bool operator>(const srmatrix_subv& v1, const srvector_slice& v2) {
02216   return srvector(v1) > v2;
02217 }
02218 
02219 inline bool operator>(const srmatrix_subv& v1, const rvector& v2) {
02220   return srvector(v1) > v2;
02221 }
02222 
02223 inline bool operator>(const srmatrix_subv& v1, const rvector_slice& v2) {
02224   return srvector(v1) > v2;
02225 }
02226 
02227 inline bool operator>(const srvector& v1, const srmatrix_subv& v2) {
02228   return v1 > srvector(v2);
02229 }
02230 
02231 inline bool operator>(const srvector_slice& v1, const srmatrix_subv& v2) {
02232   return v1 > srvector(v2);
02233 }
02234 
02235 inline bool operator>(const rvector& v1, const srmatrix_subv& v2) {
02236   return v1 > srvector(v2);
02237 }
02238 
02239 inline bool operator>(const rvector_slice& v1, const srmatrix_subv& v2) {
02240   return v1 > srvector(v2);
02241 }
02242 
02243 inline bool operator>=(const srmatrix_subv& v1, const srvector& v2) {
02244   return srvector(v1) >= v2;
02245 }
02246 
02247 inline bool operator>=(const srmatrix_subv& v1, const srvector_slice& v2) {
02248   return srvector(v1) >= v2;
02249 }
02250 
02251 inline bool operator>=(const srmatrix_subv& v1, const rvector& v2) {
02252   return srvector(v1) >= v2;
02253 }
02254 
02255 inline bool operator>=(const srmatrix_subv& v1, const rvector_slice& v2) {
02256   return srvector(v1) >= v2;
02257 }
02258 
02259 inline bool operator>=(const srvector& v1, const srmatrix_subv& v2) {
02260   return v1 >= srvector(v2);
02261 }
02262 
02263 inline bool operator>=(const srvector_slice& v1, const srmatrix_subv& v2) {
02264   return v1 >= srvector(v2);
02265 }
02266 
02267 inline bool operator>=(const rvector& v1, const srmatrix_subv& v2) {
02268   return v1 >= srvector(v2);
02269 }
02270 
02271 inline bool operator>=(const rvector_slice& v1, const srmatrix_subv& v2) {
02272   return v1 >= srvector(v2);
02273 }
02274 
02275 inline bool operator!(const srmatrix_subv& v) {
02276   return sv_v_not(v);
02277 }
02278 
02279 inline void accumulate(dotprecision& dot, const srmatrix_subv& v1, const srmatrix_subv& v2) {
02280   spsp_vv_accu<dotprecision,srvector,srvector,sparse_dot>(dot, srvector(v1), srvector(v2));
02281 }
02282 
02283 inline void accumulate(dotprecision& dot, const srmatrix_subv& v1, const srvector& v2) {
02284   spsp_vv_accu<dotprecision,srvector,srvector,sparse_dot>(dot, srvector(v1), v2);
02285 }
02286 
02287 inline void accumulate(dotprecision& dot, const srmatrix_subv& v1, const srvector_slice& v2) {
02288   spsl_vv_accu<dotprecision,srvector,srvector_slice,sparse_dot>(dot, srvector(v1), v2);
02289 }
02290 
02291 inline void accumulate(dotprecision& dot, const srmatrix_subv& v1, const rvector& v2) {
02292   spf_vv_accu<dotprecision,srvector,rvector,sparse_dot>(dot, srvector(v1), v2);
02293 }
02294 
02295 inline void accumulate(dotprecision& dot, const srmatrix_subv& v1, const rvector_slice& v2) {
02296   spf_vv_accu<dotprecision,srvector,rvector_slice,sparse_dot>(dot, srvector(v1), v2);
02297 }
02298 
02299 inline void accumulate(dotprecision& dot, const srvector& v1, const srmatrix_subv& v2) {
02300   spsp_vv_accu<dotprecision,srvector,srvector,sparse_dot>(dot, v1, srvector(v2));
02301 }
02302 
02303 inline void accumulate(dotprecision& dot, const srvector_slice& v1, const srmatrix_subv& v2) {
02304   slsp_vv_accu<dotprecision,srvector_slice,srvector,sparse_dot>(dot, v1, srvector(v2));
02305 }
02306 
02307 inline void accumulate(dotprecision& dot, const rvector& v1, const srmatrix_subv& v2) {
02308   fsp_vv_accu<dotprecision,rvector,srvector,sparse_dot>(dot, v1, srvector(v2));
02309 }
02310 
02311 inline void accumulate(dotprecision& dot, const rvector_slice& v1, const srmatrix_subv& v2) {
02312   fsp_vv_accu<dotprecision,rvector_slice,srvector,sparse_dot>(dot, v1, srvector(v2));
02313 }
02314 
02315 inline void accumulate_approx(dotprecision& dot, const srmatrix_subv& v1, const srmatrix_subv& v2) {
02316   spsp_vv_accuapprox<dotprecision,srvector,srvector,sparse_dot>(dot, srvector(v1), srvector(v2));
02317 }
02318 
02319 inline void accumulate_approx(dotprecision& dot, const srmatrix_subv& v1, const srvector& v2) {
02320   spsp_vv_accuapprox<dotprecision,srvector,srvector,sparse_dot>(dot, srvector(v1), v2);
02321 }
02322 
02323 inline void accumulate_approx(dotprecision& dot, const srmatrix_subv& v1, const srvector_slice& v2) {
02324   spsl_vv_accuapprox<dotprecision,srvector,srvector_slice,sparse_dot>(dot, srvector(v1), v2);
02325 }
02326 
02327 inline void accumulate_approx(dotprecision& dot, const srmatrix_subv& v1, const rvector& v2) {
02328   spf_vv_accuapprox<dotprecision,srvector,rvector,sparse_dot>(dot, srvector(v1), v2);
02329 }
02330 
02331 inline void accumulate_approx(dotprecision& dot, const srmatrix_subv& v1, const rvector_slice& v2) {
02332   spf_vv_accuapprox<dotprecision,srvector,rvector_slice,sparse_dot>(dot, srvector(v1), v2);
02333 }
02334 
02335 inline void accumulate_approx(dotprecision& dot, const srvector& v1, const srmatrix_subv& v2) {
02336   spsp_vv_accuapprox<dotprecision,srvector,srvector,sparse_dot>(dot, v1, srvector(v2));
02337 }
02338 
02339 inline void accumulate_approx(dotprecision& dot, const srvector_slice& v1, const srmatrix_subv& v2) {
02340   slsp_vv_accuapprox<dotprecision,srvector_slice,srvector,sparse_dot>(dot, v1, srvector(v2));
02341 }
02342 
02343 inline void accumulate_approx(dotprecision& dot, const rvector& v1, const srmatrix_subv& v2) {
02344   fsp_vv_accuapprox<dotprecision,rvector,srvector,sparse_dot>(dot, v1, srvector(v2));
02345 }
02346 
02347 inline void accumulate_approx(dotprecision& dot, const rvector_slice& v1, const srmatrix_subv& v2) {
02348   fsp_vv_accuapprox<dotprecision,rvector_slice,srvector,sparse_dot>(dot, v1, srvector(v2));
02349 }
02350 
02351 inline void accumulate(idotprecision& dot, const srmatrix_subv& v1, const srmatrix_subv& v2) {
02352   dotprecision tmp(0.0);
02353   tmp.set_k(dot.get_k());
02354   accumulate(tmp,srvector(v1),srvector(v2));
02355   dot += tmp;
02356 }
02357 
02358 inline void accumulate(idotprecision& dot, const srmatrix_subv& v1, const srvector& v2) {
02359   dotprecision tmp(0.0);
02360   tmp.set_k(dot.get_k());
02361   accumulate(tmp,srvector(v1),v2);
02362   dot += tmp;
02363 }
02364 
02365 inline void accumulate(idotprecision& dot, const srmatrix_subv& v1, const srvector_slice& v2) {
02366   dotprecision tmp(0.0);
02367   tmp.set_k(dot.get_k());
02368   accumulate(tmp,srvector(v1),v2);
02369   dot += tmp;
02370 }
02371 
02372 inline void accumulate(idotprecision& dot, const srmatrix_subv& v1, const rvector& v2) {
02373   dotprecision tmp(0.0);
02374   tmp.set_k(dot.get_k());
02375   accumulate(tmp,srvector(v1),v2);
02376   dot += tmp;
02377 }
02378 
02379 inline void accumulate(idotprecision& dot, const srmatrix_subv& v1, const rvector_slice& v2) {
02380   dotprecision tmp(0.0);
02381   tmp.set_k(dot.get_k());
02382   accumulate(tmp,srvector(v1),v2);
02383   dot += tmp;
02384 }
02385 
02386 inline void accumulate(idotprecision& dot, const srvector& v1, const srmatrix_subv& v2) {
02387   dotprecision tmp(0.0);
02388   tmp.set_k(dot.get_k());
02389   accumulate(tmp,v1,srvector(v2));
02390   dot += tmp;
02391 }
02392 
02393 inline void accumulate(idotprecision& dot, const srvector_slice& v1, const srmatrix_subv& v2) {
02394   dotprecision tmp(0.0);
02395   tmp.set_k(dot.get_k());
02396   accumulate(tmp,v1,srvector(v2));
02397   dot += tmp;
02398 }
02399 
02400 inline void accumulate(idotprecision& dot, const rvector& v1, const srmatrix_subv& v2) {
02401   dotprecision tmp(0.0);
02402   tmp.set_k(dot.get_k());
02403   accumulate(tmp,v1,srvector(v2));
02404   dot += tmp;
02405 }
02406 
02407 inline void accumulate(idotprecision& dot, const rvector_slice& v1, const srmatrix_subv& v2) {
02408   dotprecision tmp(0.0);
02409   tmp.set_k(dot.get_k());
02410   accumulate(tmp,v1,srvector(v2));
02411   dot += tmp;
02412 }
02413 
02414 inline void accumulate(cdotprecision& dot, const srmatrix_subv& v1, const srmatrix_subv& v2) {
02415   dotprecision tmp(0.0);
02416   tmp.set_k(dot.get_k());
02417   accumulate(tmp,srvector(v1),srvector(v2));
02418   dot += tmp;
02419 }
02420 
02421 inline void accumulate(cdotprecision& dot, const srmatrix_subv& v1, const srvector& v2) {
02422   dotprecision tmp(0.0);
02423   tmp.set_k(dot.get_k());
02424   accumulate(tmp,srvector(v1),v2);
02425   dot += tmp;
02426 }
02427 
02428 inline void accumulate(cdotprecision& dot, const srmatrix_subv& v1, const srvector_slice& v2) {
02429   dotprecision tmp(0.0);
02430   tmp.set_k(dot.get_k());
02431   accumulate(tmp,srvector(v1),v2);
02432   dot += tmp;
02433 }
02434 
02435 inline void accumulate(cdotprecision& dot, const srmatrix_subv& v1, const rvector& v2) {
02436   dotprecision tmp(0.0);
02437   tmp.set_k(dot.get_k());
02438   accumulate(tmp,srvector(v1),v2);
02439   dot += tmp;
02440 }
02441 
02442 inline void accumulate(cdotprecision& dot, const srmatrix_subv& v1, const rvector_slice& v2) {
02443   dotprecision tmp(0.0);
02444   tmp.set_k(dot.get_k());
02445   accumulate(tmp,srvector(v1),v2);
02446   dot += tmp;
02447 }
02448 
02449 inline void accumulate(cdotprecision& dot, const srvector& v1, const srmatrix_subv& v2) {
02450   dotprecision tmp(0.0);
02451   tmp.set_k(dot.get_k());
02452   accumulate(tmp,v1,srvector(v2));
02453   dot += tmp;
02454 }
02455 
02456 inline void accumulate(cdotprecision& dot, const srvector_slice& v1, const srmatrix_subv& v2) {
02457   dotprecision tmp(0.0);
02458   tmp.set_k(dot.get_k());
02459   accumulate(tmp,v1,srvector(v2));
02460   dot += tmp;
02461 }
02462 
02463 inline void accumulate(cdotprecision& dot, const rvector& v1, const srmatrix_subv& v2) {
02464   dotprecision tmp(0.0);
02465   tmp.set_k(dot.get_k());
02466   accumulate(tmp,v1,srvector(v2));
02467   dot += tmp;
02468 }
02469 
02470 inline void accumulate_approx(cdotprecision& dot, const srmatrix_subv& v1, const srmatrix_subv& v2) {
02471   dotprecision tmp(0.0);
02472   tmp.set_k(dot.get_k());
02473   accumulate_approx(tmp,srvector(v1),srvector(v2));
02474   dot += tmp;
02475 }
02476 
02477 inline void accumulate_approx(cdotprecision& dot, const srmatrix_subv& v1, const srvector& v2) {
02478   dotprecision tmp(0.0);
02479   tmp.set_k(dot.get_k());
02480   accumulate_approx(tmp,srvector(v1),v2);
02481   dot += tmp;
02482 }
02483 
02484 inline void accumulate_approx(cdotprecision& dot, const srmatrix_subv& v1, const srvector_slice& v2) {
02485   dotprecision tmp(0.0);
02486   tmp.set_k(dot.get_k());
02487   accumulate_approx(tmp,srvector(v1),v2);
02488   dot += tmp;
02489 }
02490 
02491 inline void accumulate_approx(cdotprecision& dot, const srmatrix_subv& v1, const rvector& v2) {
02492   dotprecision tmp(0.0);
02493   tmp.set_k(dot.get_k());
02494   accumulate_approx(tmp,srvector(v1),v2);
02495   dot += tmp;
02496 }
02497 
02498 inline void accumulate_approx(cdotprecision& dot, const srmatrix_subv& v1, const rvector_slice& v2) {
02499   dotprecision tmp(0.0);
02500   tmp.set_k(dot.get_k());
02501   accumulate_approx(tmp,srvector(v1),v2);
02502   dot += tmp;
02503 }
02504 
02505 inline void accumulate_approx(cdotprecision& dot, const srvector& v1, const srmatrix_subv& v2) {
02506   dotprecision tmp(0.0);
02507   tmp.set_k(dot.get_k());
02508   accumulate_approx(tmp,v1,srvector(v2));
02509   dot += tmp;
02510 }
02511 
02512 inline void accumulate_approx(cdotprecision& dot, const srvector_slice& v1, const srmatrix_subv& v2) {
02513   dotprecision tmp(0.0);
02514   tmp.set_k(dot.get_k());
02515   accumulate_approx(tmp,v1,srvector(v2));
02516   dot += tmp;
02517 }
02518 
02519 inline void accumulate_approx(cdotprecision& dot, const rvector& v1, const srmatrix_subv& v2) {
02520   dotprecision tmp(0.0);
02521   tmp.set_k(dot.get_k());
02522   accumulate_approx(tmp,v1,srvector(v2));
02523   dot += tmp;
02524 }
02525 
02526 inline void accumulate(cdotprecision& dot, const rvector_slice& v1, const srmatrix_subv& v2) {
02527   dotprecision tmp(0.0);
02528   tmp.set_k(dot.get_k());
02529   accumulate(tmp,v1,srvector(v2));
02530   dot += tmp;
02531 }
02532 
02533 inline void accumulate(cidotprecision& dot, const srmatrix_subv& v1, const srmatrix_subv& v2) {
02534   dotprecision tmp(0.0);
02535   tmp.set_k(dot.get_k());
02536   accumulate(tmp,srvector(v1),srvector(v2));
02537   dot += tmp;
02538 }
02539 
02540 inline void accumulate(cidotprecision& dot, const srmatrix_subv& v1, const srvector& v2) {
02541   dotprecision tmp(0.0);
02542   tmp.set_k(dot.get_k());
02543   accumulate(tmp,srvector(v1),v2);
02544   dot += tmp;
02545 }
02546 
02547 inline void accumulate(cidotprecision& dot, const srmatrix_subv& v1, const srvector_slice& v2) {
02548   dotprecision tmp(0.0);
02549   tmp.set_k(dot.get_k());
02550   accumulate(tmp,srvector(v1),v2);
02551   dot += tmp;
02552 }
02553 
02554 inline void accumulate(cidotprecision& dot, const srmatrix_subv& v1, const rvector& v2) {
02555   dotprecision tmp(0.0);
02556   tmp.set_k(dot.get_k());
02557   accumulate(tmp,srvector(v1),v2);
02558   dot += tmp;
02559 }
02560 
02561 inline void accumulate(cidotprecision& dot, const srmatrix_subv& v1, const rvector_slice& v2) {
02562   dotprecision tmp(0.0);
02563   tmp.set_k(dot.get_k());
02564   accumulate(tmp,srvector(v1),v2);
02565   dot += tmp;
02566 }
02567 
02568 inline void accumulate(cidotprecision& dot, const srvector& v1, const srmatrix_subv& v2) {
02569   dotprecision tmp(0.0);
02570   tmp.set_k(dot.get_k());
02571   accumulate(tmp,v1,srvector(v2));
02572   dot += tmp;
02573 }
02574 
02575 inline void accumulate(cidotprecision& dot, const srvector_slice& v1, const srmatrix_subv& v2) {
02576   dotprecision tmp(0.0);
02577   tmp.set_k(dot.get_k());
02578   accumulate(tmp,v1,srvector(v2));
02579   dot += tmp;
02580 }
02581 
02582 inline void accumulate(cidotprecision& dot, const rvector& v1, const srmatrix_subv& v2) {
02583   dotprecision tmp(0.0);
02584   tmp.set_k(dot.get_k());
02585   accumulate(tmp,v1,srvector(v2));
02586   dot += tmp;
02587 }
02588 
02589 inline void accumulate(cidotprecision& dot, const rvector_slice& v1, const srmatrix_subv& v2) {
02590   dotprecision tmp(0.0);
02591   tmp.set_k(dot.get_k());
02592   accumulate(tmp,v1,srvector(v2));
02593   dot += tmp;
02594 }
02595 
02596 }  //namespace cxsc;
02597 
02598 #include "sparsematrix.inl"
02599 
02600 #endif 

Generated on Thu Jun 9 11:22:21 2011 for C-XSC - A C++ Class Library for Extended Scientific Computing by  doxygen 1.4.6