00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00040
00041 #include <algorithm>
00042 #include <set>
00043 #include <iostream>
00044 #include <cmath>
00045 #include "matpackII.h"
00046
00047
00048
00049
00050
00052 Index Sparse::nrows() const
00053 {
00054 return mrr;
00055 }
00056
00058 Index Sparse::ncols() const
00059 {
00060 return mcr;
00061 }
00062
00064 Index Sparse::nnz() const
00065 {
00066 return *(mcolptr->end()-1);
00067 }
00068
00069
00070
00071
00073
00089 Numeric& Sparse::rw(Index r, Index c)
00090 {
00091
00092 assert( 0<=r );
00093 assert( 0<=c );
00094 assert( r<mrr );
00095 assert( c<mcr );
00096
00097
00098 Index i = (*mcolptr)[c];
00099
00100
00101
00102
00103 const Index end = (*mcolptr)[c+1];
00104
00105
00106
00107
00108
00109 for ( ; i<end; ++i )
00110 {
00111 Index rowi = (*mrowind)[i];
00112 if ( r < rowi )
00113 break;
00114 if ( r == rowi )
00115 return (*mdata)[i];
00116 }
00117
00118
00119
00120
00121
00122
00123 for ( vector<Index>::iterator j = mcolptr->begin() + c + 1;
00124 j < mcolptr->end();
00125 ++j )
00126 ++(*j);
00127
00128
00129
00130
00131
00132 mrowind->insert( mrowind->begin()+i, r );
00133 return *( mdata->insert( mdata->begin()+i, 0 ) );
00134 }
00135
00137
00148 Numeric Sparse::operator() (Index r, Index c) const
00149 { return this->ro(r, c); }
00150
00152
00166 Numeric Sparse::ro (Index r, Index c) const
00167 {
00168
00169 assert( 0<=r );
00170 assert( 0<=c );
00171 assert( r<mrr );
00172 assert( c<mcr );
00173
00174
00175 Index begin = (*mcolptr)[c];
00176
00177
00178
00179
00180 const Index end = (*mcolptr)[c+1];
00181
00182
00183
00184
00185 for ( Index i=begin; i<end; ++i )
00186 {
00187 Index rowi = (*mrowind)[i];
00188 if ( r < rowi )
00189 return 0;
00190 if ( r == rowi )
00191 return (*mdata)[i];
00192 }
00193 return 0;
00194 }
00195
00196
00197
00198
00199
00201
00205 Sparse::Sparse() :
00206 mdata(NULL),
00207 mrowind(NULL),
00208 mcolptr(NULL),
00209 mrr(0),
00210 mcr(0)
00211 {
00212
00213 }
00214
00216
00234 Sparse::Sparse(Index r, Index c) :
00235 mdata(new vector<Numeric>),
00236 mrowind(new vector<Index>),
00237 mcolptr(new vector<Index>(c+1,0)),
00238 mrr(r),
00239 mcr(c)
00240 {
00241
00242 }
00243
00244
00246
00254 Sparse::Sparse(const Sparse& m) :
00255 mdata(new vector<Numeric>(*m.mdata)),
00256 mrowind(new vector<Index>(*m.mrowind)),
00257 mcolptr(new vector<Index>(*m.mcolptr)),
00258 mrr(m.mrr),
00259 mcr(m.mcr)
00260 {
00261
00262
00263
00264 }
00265
00266
00268
00274 Sparse::~Sparse()
00275 {
00276 delete mdata;
00277 delete mrowind;
00278 delete mcolptr;
00279 }
00280
00282
00296 void Sparse::insert_row(Index r, Vector v)
00297 {
00298
00299 assert( 0<=r );
00300 assert( r<mrr );
00301 assert( v.nelem()==mcr );
00302
00303
00304 Index vnnz=0;
00305 for (Index i=0; i<v.nelem(); i++)
00306 {
00307 if (v[i]!=0)
00308 {
00309 vnnz++;
00310 }
00311 }
00312
00313
00314
00315
00316 Index rnnz = vnnz - count(mrowind->begin(),mrowind->end(),r);
00317 vector<Index> mrowind_ref(mrowind->size());
00318 copy(mrowind->begin(), mrowind->end(), mrowind_ref.begin());
00319 vector<Numeric> mdata_ref(mdata->size());
00320 copy(mdata->begin(), mdata->end(), mdata_ref.begin());
00321 mrowind->resize(mrowind_ref.size()+rnnz);
00322 mdata->resize(mdata_ref.size()+rnnz);
00323
00324
00325
00326 vector<Index>::iterator mrowind_it = mrowind->begin();
00327 vector<Numeric>::iterator mdata_it = mdata->begin();
00328
00329
00330 Index colptr_mod = 0;
00331
00332
00333 for (Index i=0; i<v.nelem(); i++)
00334 {
00335
00336
00337 vector<Numeric>::iterator dstart =
00338 mdata_ref.begin()+(*mcolptr)[i];
00339 vector<Numeric>::iterator dend =
00340 mdata_ref.begin()+(*mcolptr)[i+1];
00341 vector<Index>::iterator rstart =
00342 mrowind_ref.begin()+(*mcolptr)[i];
00343 vector<Index>::iterator rend =
00344 mrowind_ref.begin()+(*mcolptr)[i+1];
00345
00346
00347
00348 (*mcolptr)[i] = colptr_mod;
00349
00350 if (v[i]!=0)
00351 {
00352
00353
00354 vector<Index>::iterator rpos = find(rstart,rend,r);
00355 vector<Numeric>::iterator dpos = dstart+(rpos-rstart);
00356 if (rpos!=rend)
00357 {
00358
00359
00360 *dpos = v[i];
00361
00362
00363 copy(rstart,rend,mrowind_it);
00364 copy(dstart,dend,mdata_it);
00365
00366
00367 mrowind_it += rend-rstart;
00368 mdata_it += dend-dstart;
00369
00370
00371 colptr_mod = (*mcolptr)[i]+(rend-rstart);
00372 }
00373 else
00374 {
00375
00376
00377 rpos = find_if(rstart,rend,bind2nd(greater<Index>(),r));
00378 dpos = dstart+(rpos-rstart);
00379
00380
00381 copy(rstart,rpos,mrowind_it);
00382 copy(dstart,dpos,mdata_it);
00383
00384
00385
00386 mrowind_it += rpos-rstart;
00387 mdata_it += dpos-dstart;
00388
00389
00390
00391 *mrowind_it = r;
00392 *mdata_it = v[i];
00393
00394
00395
00396 mrowind_it++;
00397 mdata_it++;
00398
00399
00400 copy(rpos,rend,mrowind_it);
00401 copy(dpos,dend,mdata_it);
00402
00403
00404 mrowind_it += rend-rpos;
00405 mdata_it += dend-dpos;
00406
00407
00408 colptr_mod = (*mcolptr)[i]+(rend-rstart+1);
00409 }
00410 }
00411 else
00412 {
00413
00414
00415 vector<Index>::iterator rpos = find(rstart,rend,r);
00416 vector<Numeric>::iterator dpos = dstart+(rpos-rstart);
00417 if (rpos!=rend)
00418 {
00419
00420
00421 remove_copy(rstart,rend,mrowind_it, *rpos);
00422 remove_copy(dstart,dend,mdata_it, *dpos);
00423
00424
00425 mrowind_it += rend-rstart-1;
00426 mdata_it += dend-dstart-1;
00427
00428
00429 colptr_mod = (*mcolptr)[i]+(rend-rstart-1);
00430 }
00431 else
00432 {
00433
00434
00435 copy(rstart,rend,mrowind_it);
00436 copy(dstart,dend,mdata_it);
00437
00438
00439 mrowind_it += rend-rstart;
00440 mdata_it += dend-dstart;
00441
00442
00443 colptr_mod = (*mcolptr)[i]+(rend-rstart);
00444 }
00445 }
00446 }
00447
00448 *(mcolptr->end()-1) = colptr_mod;
00449
00450
00451
00452
00453 }
00454
00456
00467 void Sparse::make_I( Index r, Index c)
00468 {
00469 assert( 0<=r );
00470 assert( 0<=c );
00471
00472
00473 Index n = min(r,c);
00474
00475
00476 delete mcolptr;
00477 mcolptr = new vector<Index>( c+1, n);
00478 delete mrowind;
00479 mrowind = new vector<Index>(n);
00480 delete mdata;
00481 mdata = new vector<Numeric>(n,1.0);
00482
00483
00484
00485 vector<Index>::iterator rit = mrowind->begin();
00486 vector<Index>::iterator cit = mcolptr->begin();
00487 for( Index i=0; i<n; i++ ) {
00488 *rit++ = i;
00489 *cit++ = i;
00490 }
00491
00492 mrr = r;
00493 mcr = c;
00494 }
00495
00497
00509 void Sparse::resize(Index r, Index c)
00510 {
00511 assert( 0<=r );
00512 assert( 0<=c );
00513 if ( mrr!=r || mcr!=c )
00514 {
00515 delete mdata;
00516 mdata = new vector<Numeric>;
00517 delete mrowind;
00518 mrowind = new vector<Index>;
00519 delete mcolptr;
00520 mcolptr = new vector<Index>(c+1,0);
00521
00522 mrr = r;
00523 mcr = c;
00524 }
00525 }
00526
00528
00544 Sparse& Sparse::operator=(const Sparse& m)
00545 {
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555 if (mdata!=NULL)
00556 {
00557 assert (mrowind!=NULL);
00558 assert (mcolptr!=NULL);
00559
00560 delete mdata;
00561 delete mrowind;
00562 delete mcolptr;
00563
00564 mdata = NULL;
00565 mrowind = NULL;
00566 mcolptr = NULL;
00567 }
00568
00569 mrr = m.mrr;
00570 mcr = m.mcr;
00571
00572 if (m.mdata!=NULL)
00573 {
00574 mdata = new vector<Numeric>(*m.mdata);
00575 mrowind = new vector<Index>(*m.mrowind);
00576 mcolptr = new vector<Index>(*m.mcolptr);
00577 }
00578
00579 return *this;
00580 }
00581
00583
00592 ostream& operator<<(ostream& os, const Sparse& v)
00593 {
00594 for (size_t c=0; c<v.mcolptr->size()-1; ++c)
00595 {
00596
00597 Index begin = (*v.mcolptr)[c];
00598
00599
00600
00601
00602 const Index end = (*v.mcolptr)[c+1];
00603
00604
00605 for ( Index i=begin; i<end; ++i )
00606 {
00607
00608 Index r = (*v.mrowind)[i];
00609
00610
00611 os << setw(3) << r << " "
00612 << setw(3) << c << " "
00613 << setw(3) << (*v.mdata)[i] << "\n";
00614 }
00615 }
00616
00617 return os;
00618 }
00619
00620
00621
00623
00634 void abs( Sparse& A,
00635 const Sparse& B )
00636 {
00637
00638 assert( A.nrows() == B.nrows() );
00639 assert( A.ncols() == B.ncols() );
00640
00641
00642
00643 A.mdata->resize( B.mdata->size() );
00644 Index end = B.mdata->size();
00645 for (Index i=0; i<end; i++)
00646 {
00647 (*A.mdata)[i] = fabs((*B.mdata)[i]);
00648 }
00649
00650
00651 A.mcolptr->resize( B.mcolptr->size() );
00652 copy(B.mcolptr->begin(), B.mcolptr->end(), A.mcolptr->begin());
00653 A.mrowind->resize( B.mrowind->size() );
00654 copy(B.mrowind->begin(), B.mrowind->end(), A.mrowind->begin());
00655
00656 }
00657
00659
00676 void mult( VectorView y,
00677 const Sparse& M,
00678 ConstVectorView x )
00679 {
00680
00681 assert( y.nelem() == M.nrows() );
00682 assert( M.ncols() == x.nelem() );
00683
00684
00685 y = 0.0;
00686
00687
00688
00689 for (size_t c=0; c<M.mcolptr->size()-1; ++c)
00690 {
00691
00692 Index begin = (*M.mcolptr)[c];
00693
00694
00695
00696
00697 const Index end = (*M.mcolptr)[c+1];
00698
00699
00700 for ( Index i=begin; i<end; ++i )
00701 {
00702
00703 Index r = (*M.mrowind)[i];
00704
00705
00706 y[r] += (*M.mdata)[i] * x[c];
00707 }
00708 }
00709 }
00710
00712
00729 void mult( MatrixView A,
00730 const Sparse& B,
00731 ConstMatrixView C )
00732 {
00733
00734 assert( A.nrows() == B.nrows() );
00735 assert( A.ncols() == C.ncols() );
00736 assert( B.ncols() == C.nrows() );
00737
00738
00739 A = 0.0;
00740
00741
00742 for (size_t c=0; c<B.mcolptr->size()-1; ++c)
00743 {
00744
00745 Index begin = (*B.mcolptr)[c];
00746
00747
00748
00749
00750 const Index end = (*B.mcolptr)[c+1];
00751
00752
00753 for ( Index i=begin; i<end; ++i )
00754 {
00755
00756 Index r = (*B.mrowind)[i];
00757
00758
00759
00760 for (Index j=0; j<C.ncols(); j++)
00761 {
00762
00763
00764
00765
00766 A(r,j) += (*B.mdata)[i] * C(c,j);
00767 }
00768 }
00769 }
00770 }
00771
00772
00774
00785 void transpose( Sparse& A,
00786 const Sparse& B )
00787 {
00788
00789 assert( A.nrows() == B.ncols() );
00790 assert( A.ncols() == B.nrows() );
00791
00792
00793
00794
00795 A.mdata->resize( B.mdata->size() );
00796 A.mrowind->resize( B.mrowind->size() );
00797
00798
00799
00800
00801
00802 vector<Index>::iterator startrow, stoprow;
00803 startrow = min_element( B.mrowind->begin(), B.mrowind->end() );
00804 stoprow = max_element( B.mrowind->begin(), B.mrowind->end() );
00805
00806
00807
00808
00809 A.mcolptr->assign( A.mcr+1, 0 );
00810 for (Index i=*startrow; i<=*stoprow; i++)
00811 {
00812 Index n = count( B.mrowind->begin(), B.mrowind->end(), i);
00813
00814
00815
00816 (*A.mcolptr)[i+1] = (*A.mcolptr)[i] + n;
00817 }
00818
00819
00820
00821
00822
00823 vector<Numeric>::iterator dataA_it = A.mdata->begin();
00824 vector<Index>::iterator rowindA_it = A.mrowind->begin();
00825
00826
00827
00828 for (size_t c=0; c<A.mcolptr->size(); ++c)
00829 {
00830
00831
00832 for (size_t i=0; i<B.mcolptr->size()-1; i++)
00833 {
00834
00835
00836 vector<Index>::iterator elem_it =
00837 find(B.mrowind->begin()+*(B.mcolptr->begin()+i),
00838 B.mrowind->begin()+*(B.mcolptr->begin()+i+1), Index (c));
00839
00840
00841 if (elem_it != B.mrowind->begin()+*(B.mcolptr->begin()+i+1))
00842 {
00843 *rowindA_it = i;
00844 rowindA_it++;
00845
00846
00847
00848
00849 Index diff = elem_it - B.mrowind->begin();
00850 vector<Numeric>::iterator elemdata_it=B.mdata->begin() + diff;
00851 *dataA_it = *elemdata_it;
00852 dataA_it++;
00853 }
00854 }
00855 }
00856 }
00857
00858
00860
00875 void mult( Sparse& A,
00876 const Sparse& B,
00877 const Sparse& C )
00878 {
00879
00880 assert( A.nrows() == B.nrows() );
00881 assert( A.ncols() == C.ncols() );
00882 assert( B.ncols() == C.nrows() );
00883 A.mcolptr->assign( A.mcr+1, 0);
00884 A.mrowind->clear();
00885 A.mdata->clear();
00886
00887
00888
00889
00890 Sparse Bt(B.ncols(), B.nrows());
00891
00892
00893 transpose(Bt,B);
00894
00895
00896
00897
00898 for (size_t c=0; c<C.mcolptr->size()-1; ++c)
00899 {
00900
00901
00902
00903
00904 for (size_t b=0; b<Bt.mcolptr->size()-1; ++b)
00905 {
00906
00907
00908 set<Index> colintersec;
00909 set_intersection(C.mrowind->begin()+*(C.mcolptr->begin()+c),
00910 C.mrowind->begin()+*(C.mcolptr->begin()+c+1),
00911 Bt.mrowind->begin()+*(Bt.mcolptr->begin()+b),
00912 Bt.mrowind->begin()+*(Bt.mcolptr->begin()+b+1),
00913 inserter(colintersec, colintersec.begin()));
00914
00915
00916
00917 if (!colintersec.empty())
00918 {
00919 Numeric tempA = 0.0;
00920 for (set<Index>::iterator i=colintersec.begin();
00921 i!=colintersec.end(); ++i)
00922 {
00923
00924
00925
00926
00927
00928
00929
00930 vector<Index>::iterator rowindBt_it =
00931 find(Bt.mrowind->begin()+*(Bt.mcolptr->begin()+b),
00932 Bt.mrowind->begin()+*(Bt.mcolptr->begin()+b+1), *i);
00933 vector<Index>::iterator rowindC_it =
00934 find(C.mrowind->begin()+*(C.mcolptr->begin()+c),
00935 C.mrowind->begin()+*(C.mcolptr->begin()+c+1), *i);
00936
00937 vector<Numeric>::iterator dataBt_it =
00938 Bt.mdata->begin()+(rowindBt_it-Bt.mrowind->begin());
00939 vector<Numeric>::iterator dataC_it =
00940 C.mdata->begin()+(rowindC_it-C.mrowind->begin());
00941
00942 tempA += *dataBt_it * *dataC_it;
00943 }
00944 A.rw(b,c) = tempA;
00945 }
00946 }
00947 }
00948 }
00949