00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00025 #include "matpackI.h"
00026 #include "exceptions.h"
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 Range::Range(Index start, Index extent, Index stride) :
00043 mstart(start), mextent(extent), mstride(stride)
00044 {
00045
00046 assert( 0<=mstart );
00047
00048
00049
00050 assert( 0<=mextent );
00051
00052
00053
00054 }
00055
00058 Range::Range(Index start, Joker, Index stride) :
00059 mstart(start), mextent(-1), mstride(stride)
00060 {
00061
00062 assert( 0<=mstart );
00063 }
00064
00068 Range::Range(Joker, Index stride) :
00069 mstart(0), mextent(-1), mstride(stride)
00070 {
00071
00072 }
00073
00079 Range::Range(Index max_size, const Range& r) :
00080 mstart(r.mstart),
00081 mextent(r.mextent),
00082 mstride(r.mstride)
00083 {
00084
00085 assert( 0<=mstart );
00086
00087 assert( mstart<max_size );
00088
00089
00090 assert( 0!=mstride);
00091
00092
00093 if ( mextent<0 )
00094 {
00095 if ( 0<mstride )
00096 mextent = 1 + (max_size-1-mstart)/mstride;
00097 else
00098 mextent = 1 + (0-mstart)/mstride;
00099 }
00100 else
00101 {
00102 #ifndef NDEBUG
00103
00104 Index fin = mstart+(mextent-1)*mstride;
00105 assert( 0 <= fin );
00106 assert( fin < max_size );
00107 #endif
00108 }
00109 }
00110
00116 Range::Range(const Range& p, const Range& n) :
00117 mstart(p.mstart + n.mstart*p.mstride),
00118 mextent(n.mextent),
00119 mstride(p.mstride*n.mstride)
00120 {
00121
00122
00123
00124
00125
00126
00127
00128 Index prev_fin = p.mstart+(p.mextent-1)*p.mstride;
00129
00130
00131 assert( p.mstart<=mstart );
00132
00133 assert( mstart<=prev_fin );
00134
00135
00136 assert( 0!=mstride);
00137
00138
00139 if ( mextent<0 )
00140 {
00141 if ( 0<mstride )
00142 mextent = 1 + (prev_fin-mstart)/mstride;
00143 else
00144 mextent = 1 + (p.mstart-mstart)/mstride;
00145 }
00146 else
00147 {
00148 #ifndef NDEBUG
00149
00150 Index fin = mstart+(mextent-1)*mstride;
00151 assert( p.mstart <= fin );
00152 assert( fin <= prev_fin );
00153 #endif
00154 }
00155
00156 }
00157
00158
00159
00160
00170 Index ConstVectorView::nelem() const
00171 {
00172 return mrange.mextent;
00173 }
00174
00176 Numeric ConstVectorView::sum() const
00177 {
00178 Numeric s=0;
00179 ConstIterator1D i = begin();
00180 const ConstIterator1D e = end();
00181
00182 for ( ; i!=e; ++i )
00183 s += *i;
00184
00185 return s;
00186 }
00187
00191 ConstVectorView ConstVectorView::operator[](const Range& r) const
00192 {
00193 return ConstVectorView(mdata, mrange, r);
00194 }
00195
00197 ConstIterator1D ConstVectorView::begin() const
00198 {
00199 return ConstIterator1D(mdata+mrange.mstart, mrange.mstride);
00200 }
00201
00203 ConstIterator1D ConstVectorView::end() const
00204 {
00205 return ConstIterator1D( mdata +
00206 mrange.mstart +
00207 (mrange.mextent)*mrange.mstride,
00208 mrange.mstride );
00209 }
00210
00212 ConstVectorView::operator ConstMatrixView() const
00213 {
00214 return ConstMatrixView(mdata,mrange,Range(mrange.mstart,1));
00215 }
00216
00224 ConstVectorView::ConstVectorView(const Numeric& a) :
00225 mrange(0,1), mdata(&const_cast<Numeric&>(a))
00226 {
00227
00228 }
00229
00232 ConstVectorView::ConstVectorView() :
00233 mrange(0,0), mdata(NULL)
00234 {
00235
00236 }
00237
00240 ConstVectorView::ConstVectorView( Numeric *data,
00241 const Range& range) :
00242 mrange(range),
00243 mdata(data)
00244 {
00245
00246 }
00247
00258 ConstVectorView::ConstVectorView( Numeric *data,
00259 const Range& p,
00260 const Range& n) :
00261 mrange(p,n),
00262 mdata(data)
00263 {
00264
00265 }
00266
00270 ostream& operator<<(ostream& os, const ConstVectorView& v)
00271 {
00272 ConstIterator1D i=v.begin();
00273 const ConstIterator1D end=v.end();
00274
00275 if ( i!=end )
00276 {
00277 os << setw(3) << *i;
00278 ++i;
00279 }
00280 for ( ; i!=end ; ++i )
00281 {
00282 os << " " << setw(3) << *i;
00283 }
00284
00285 return os;
00286 }
00287
00288
00289
00290
00291
00294 VectorView::VectorView (const Vector&)
00295 {
00296 throw runtime_error("Creating a VectorView from a const Vector is not allowed.");
00297
00298
00299
00300
00301
00302 }
00303
00305 VectorView::VectorView (Vector& v)
00306 {
00307 mdata = v.mdata;
00308 mrange = v.mrange;
00309 }
00310
00315 ConstVectorView VectorView::operator[](const Range& r) const
00316 {
00317 return ConstVectorView::operator[](r);
00318 }
00319
00323 VectorView VectorView::operator[](const Range& r)
00324 {
00325 return VectorView(mdata, mrange, r);
00326 }
00327
00331 ConstIterator1D VectorView::begin() const
00332 {
00333 return ConstVectorView::begin();
00334 }
00335
00339 ConstIterator1D VectorView::end() const
00340 {
00341 return ConstVectorView::end();
00342 }
00343
00345 Iterator1D VectorView::begin()
00346 {
00347 return Iterator1D(mdata+mrange.mstart, mrange.mstride);
00348 }
00349
00351 Iterator1D VectorView::end()
00352 {
00353 return Iterator1D( mdata +
00354 mrange.mstart +
00355 (mrange.mextent)*mrange.mstride,
00356 mrange.mstride );
00357 }
00358
00363 VectorView& VectorView::operator=(const ConstVectorView& v)
00364 {
00365
00366
00367
00368 assert(mrange.mextent==v.mrange.mextent);
00369
00370 copy( v.begin(), v.end(), begin() );
00371
00372 return *this;
00373 }
00374
00380 VectorView& VectorView::operator=(const VectorView& v)
00381 {
00382
00383
00384
00385 assert(mrange.mextent==v.mrange.mextent);
00386
00387 copy( v.begin(), v.end(), begin() );
00388
00389 return *this;
00390 }
00391
00394 VectorView& VectorView::operator=(const Vector& v)
00395 {
00396
00397
00398
00399 assert(mrange.mextent==v.mrange.mextent);
00400
00401 copy( v.begin(), v.end(), begin() );
00402
00403 return *this;
00404 }
00405
00408 VectorView& VectorView::operator=(Numeric x)
00409 {
00410 copy( x, begin(), end() );
00411 return *this;
00412 }
00413
00415 VectorView VectorView::operator*=(Numeric x)
00416 {
00417 const Iterator1D e=end();
00418 for ( Iterator1D i=begin(); i!=e ; ++i )
00419 *i *= x;
00420 return *this;
00421 }
00422
00424 VectorView VectorView::operator/=(Numeric x)
00425 {
00426 const Iterator1D e=end();
00427 for ( Iterator1D i=begin(); i!=e ; ++i )
00428 *i /= x;
00429 return *this;
00430 }
00431
00433 VectorView VectorView::operator+=(Numeric x)
00434 {
00435 const Iterator1D e=end();
00436 for ( Iterator1D i=begin(); i!=e ; ++i )
00437 *i += x;
00438 return *this;
00439 }
00440
00442 VectorView VectorView::operator-=(Numeric x)
00443 {
00444 const Iterator1D e=end();
00445 for ( Iterator1D i=begin(); i!=e ; ++i )
00446 *i -= x;
00447 return *this;
00448 }
00449
00451 VectorView VectorView::operator*=(const ConstVectorView& x)
00452 {
00453 assert( nelem()==x.nelem() );
00454
00455 ConstIterator1D s=x.begin();
00456
00457 Iterator1D i=begin();
00458 const Iterator1D e=end();
00459
00460 for ( ; i!=e ; ++i,++s )
00461 *i *= *s;
00462 return *this;
00463 }
00464
00466 VectorView VectorView::operator/=(const ConstVectorView& x)
00467 {
00468 assert( nelem()==x.nelem() );
00469
00470 ConstIterator1D s=x.begin();
00471
00472 Iterator1D i=begin();
00473 const Iterator1D e=end();
00474
00475 for ( ; i!=e ; ++i,++s )
00476 *i /= *s;
00477 return *this;
00478 }
00479
00481 VectorView VectorView::operator+=(const ConstVectorView& x)
00482 {
00483 assert( nelem()==x.nelem() );
00484
00485 ConstIterator1D s=x.begin();
00486
00487 Iterator1D i=begin();
00488 const Iterator1D e=end();
00489
00490 for ( ; i!=e ; ++i,++s )
00491 *i += *s;
00492 return *this;
00493 }
00494
00496 VectorView VectorView::operator-=(const ConstVectorView& x)
00497 {
00498 assert( nelem()==x.nelem() );
00499
00500 ConstIterator1D s=x.begin();
00501
00502 Iterator1D i=begin();
00503 const Iterator1D e=end();
00504
00505 for ( ; i!=e ; ++i,++s )
00506 *i -= *s;
00507 return *this;
00508 }
00509
00511 VectorView::operator MatrixView()
00512 {
00513 return MatrixView(mdata,mrange,Range(mrange.mstart,1));
00514 }
00515
00522 const Numeric * VectorView::get_c_array() const
00523 {
00524 if (mrange.mstart != 0 || mrange.mstride != 1)
00525 throw runtime_error("A VectorView can only be converted to a plain C-array if mrange.mstart == 0 and mrange.mstride == 1");
00526
00527 return mdata;
00528 }
00529
00536 Numeric * VectorView::get_c_array()
00537 {
00538 if (mrange.mstart != 0 || mrange.mstride != 1)
00539 throw runtime_error("A VectorView can only be converted to a plain C-array if mrange.mstart == 0 and mrange.mstride == 1");
00540
00541 return mdata;
00542 }
00543
00547 VectorView::VectorView(Numeric& a) :
00548 ConstVectorView(a)
00549 {
00550
00551 }
00552
00555 VectorView::VectorView() :
00556 ConstVectorView()
00557 {
00558
00559 }
00560
00563 VectorView::VectorView(Numeric *data,
00564 const Range& range) :
00565 ConstVectorView(data,range)
00566 {
00567
00568 }
00569
00580 VectorView::VectorView(Numeric *data,
00581 const Range& p,
00582 const Range& n) :
00583 ConstVectorView(data,p,n)
00584 {
00585
00586 }
00587
00592 void copy(ConstIterator1D origin,
00593 const ConstIterator1D& end,
00594 Iterator1D target)
00595 {
00596 for ( ; origin!=end ; ++origin,++target )
00597 *target = *origin;
00598 }
00599
00601 void copy(Numeric x,
00602 Iterator1D target,
00603 const Iterator1D& end)
00604 {
00605 for ( ; target!=end ; ++target )
00606 *target = x;
00607 }
00608
00609
00610
00611
00612
00614 Vector::Vector()
00615 {
00616
00617 }
00618
00620 Vector::Vector(Index n) :
00621 VectorView( new Numeric[n],
00622 Range(0,n))
00623 {
00624
00625 }
00626
00628 Vector::Vector(Index n, Numeric fill) :
00629 VectorView( new Numeric[n],
00630 Range(0,n))
00631 {
00632
00633
00634 const Numeric *stop = mdata+n;
00635 for ( Numeric *x=mdata; x<stop; ++x )
00636 *x = fill;
00637 }
00638
00647 Vector::Vector(Numeric start, Index extent, Numeric stride) :
00648 VectorView( new Numeric[extent],
00649 Range(0,extent))
00650 {
00651
00652 Numeric x = start;
00653 Iterator1D i=begin();
00654 const Iterator1D e=end();
00655 for ( ; i!=e; ++i )
00656 {
00657 *i = x;
00658 x += stride;
00659 }
00660 }
00661
00667 Vector::Vector(const ConstVectorView& v) :
00668 VectorView( new Numeric[v.nelem()],
00669 Range(0,v.nelem()))
00670 {
00671 copy(v.begin(),v.end(),begin());
00672 }
00673
00676 Vector::Vector(const Vector& v) :
00677 VectorView( new Numeric[v.nelem()],
00678 Range(0,v.nelem()))
00679 {
00680 copy(v.begin(),v.end(),begin());
00681 }
00682
00684
00708 Vector& Vector::operator=(const Vector& v)
00709 {
00710
00711 resize( v.nelem() );
00712 copy( v.begin(), v.end(), begin() );
00713 return *this;
00714 }
00715
00717
00733 Vector& Vector::operator=(const Array<Numeric>& x)
00734 {
00735 resize( x.nelem() );
00736 VectorView::operator=(x);
00737 return *this;
00738 }
00739
00742 Vector& Vector::operator=(Numeric x)
00743 {
00744 VectorView::operator=(x);
00745 return *this;
00746 }
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758
00762 void Vector::resize(Index n)
00763 {
00764 assert( 0<=n );
00765 if ( mrange.mextent != n )
00766 {
00767 delete[] mdata;
00768 mdata = new Numeric[n];
00769 mrange.mstart = 0;
00770 mrange.mextent = n;
00771 mrange.mstride = 1;
00772 }
00773 }
00774
00777 Vector::~Vector()
00778 {
00779 delete[] mdata;
00780 }
00781
00782
00783
00784
00785
00787 Index ConstMatrixView::nrows() const
00788 {
00789 return mrr.mextent;
00790 }
00791
00793 Index ConstMatrixView::ncols() const
00794 {
00795 return mcr.mextent;
00796 }
00797
00801 ConstMatrixView ConstMatrixView::operator()(const Range& r,
00802 const Range& c) const
00803 {
00804 return ConstMatrixView(mdata, mrr, mcr, r, c);
00805 }
00806
00812 ConstVectorView ConstMatrixView::operator()(const Range& r, Index c) const
00813 {
00814
00815 assert( 0 <= c );
00816 assert( c < mcr.mextent );
00817
00818 return ConstVectorView(mdata + mcr.mstart + c*mcr.mstride,
00819 mrr, r);
00820 }
00821
00827 ConstVectorView ConstMatrixView::operator()(Index r, const Range& c) const
00828 {
00829
00830 assert( 0 <= r );
00831 assert( r < mrr.mextent );
00832
00833 return ConstVectorView(mdata + mrr.mstart + r*mrr.mstride,
00834 mcr, c);
00835 }
00836
00838 ConstIterator2D ConstMatrixView::begin() const
00839 {
00840 return ConstIterator2D(ConstVectorView(mdata+mrr.mstart,
00841 mcr),
00842 mrr.mstride);
00843 }
00844
00846 ConstIterator2D ConstMatrixView::end() const
00847 {
00848 return ConstIterator2D( ConstVectorView(mdata + mrr.mstart + (mrr.mextent)*mrr.mstride,
00849 mcr),
00850 mrr.mstride );
00851 }
00852
00855 ConstMatrixView::ConstMatrixView() :
00856 mrr(0,0,1), mcr(0,0,1), mdata(NULL)
00857 {
00858
00859 }
00860
00864 ConstMatrixView::ConstMatrixView( Numeric *data,
00865 const Range& rr,
00866 const Range& cr) :
00867 mrr(rr),
00868 mcr(cr),
00869 mdata(data)
00870 {
00871
00872 }
00873
00888 ConstMatrixView::ConstMatrixView( Numeric *data,
00889 const Range& pr, const Range& pc,
00890 const Range& nr, const Range& nc) :
00891 mrr(pr,nr),
00892 mcr(pc,nc),
00893 mdata(data)
00894 {
00895
00896 }
00897
00905 ostream& operator<<(ostream& os, const ConstMatrixView& v)
00906 {
00907
00908 ConstIterator2D ir=v.begin();
00909 const ConstIterator2D end_row=v.end();
00910
00911 if ( ir!=end_row )
00912 {
00913 ConstIterator1D ic = ir->begin();
00914 const ConstIterator1D end_col = ir->end();
00915
00916 if ( ic!=end_col )
00917 {
00918 os << setw(3) << *ic;
00919 ++ic;
00920 }
00921 for ( ; ic!=end_col ; ++ic )
00922 {
00923 os << " " << setw(3) << *ic;
00924 }
00925 ++ir;
00926 }
00927 for ( ; ir!=end_row ; ++ir )
00928 {
00929 ConstIterator1D ic = ir->begin();
00930 const ConstIterator1D end_col = ir->end();
00931
00932 os << "\n";
00933 if ( ic!=end_col )
00934 {
00935 os << setw(3) << *ic;
00936 ++ic;
00937 }
00938 for ( ; ic!=end_col ; ++ic )
00939 {
00940 os << " " << setw(3) << *ic;
00941 }
00942 }
00943
00944 return os;
00945 }
00946
00947
00948
00949
00950
00955 ConstMatrixView MatrixView::operator()(const Range& r, const Range& c) const
00956 {
00957 return ConstMatrixView::operator()(r,c);
00958 }
00959
00966 ConstVectorView MatrixView::operator()(const Range& r, Index c) const
00967 {
00968 return ConstMatrixView::operator()(r,c);
00969 }
00970
00977 ConstVectorView MatrixView::operator()(Index r, const Range& c) const
00978 {
00979 return ConstMatrixView::operator()(r,c);
00980 }
00981
00985 MatrixView MatrixView::operator()(const Range& r, const Range& c)
00986 {
00987 return MatrixView(mdata, mrr, mcr, r, c);
00988 }
00989
00994 VectorView MatrixView::operator()(const Range& r, Index c)
00995 {
00996
00997 assert( 0 <= c );
00998 assert( c < mcr.mextent );
00999
01000 return VectorView(mdata + mcr.mstart + c*mcr.mstride,
01001 mrr, r);
01002 }
01003
01008 VectorView MatrixView::operator()(Index r, const Range& c)
01009 {
01010
01011 assert( 0 <= r );
01012 assert( r < mrr.mextent );
01013
01014 return VectorView(mdata + mrr.mstart + r*mrr.mstride,
01015 mcr, c);
01016 }
01017
01020 ConstIterator2D MatrixView::begin() const
01021 {
01022 return ConstMatrixView::begin();
01023 }
01024
01026 ConstIterator2D MatrixView::end() const
01027 {
01028 return ConstMatrixView::end();
01029 }
01030
01032 Iterator2D MatrixView::begin()
01033 {
01034 return Iterator2D(VectorView(mdata+mrr.mstart, mcr),
01035 mrr.mstride);
01036 }
01037
01039 Iterator2D MatrixView::end()
01040 {
01041 return Iterator2D( VectorView(mdata + mrr.mstart + (mrr.mextent)*mrr.mstride,
01042 mcr),
01043 mrr.mstride );
01044 }
01045
01050 MatrixView& MatrixView::operator=(const ConstMatrixView& m)
01051 {
01052
01053 assert(mrr.mextent==m.mrr.mextent);
01054 assert(mcr.mextent==m.mcr.mextent);
01055
01056 copy( m.begin(), m.end(), begin() );
01057 return *this;
01058 }
01059
01065 MatrixView& MatrixView::operator=(const MatrixView& m)
01066 {
01067
01068 assert(mrr.mextent==m.mrr.mextent);
01069 assert(mcr.mextent==m.mcr.mextent);
01070
01071 copy( m.begin(), m.end(), begin() );
01072 return *this;
01073 }
01074
01078 MatrixView& MatrixView::operator=(const Matrix& m)
01079 {
01080
01081 assert(mrr.mextent==m.mrr.mextent);
01082 assert(mcr.mextent==m.mcr.mextent);
01083
01084 copy( m.begin(), m.end(), begin() );
01085 return *this;
01086 }
01087
01092 MatrixView& MatrixView::operator=(const ConstVectorView& v)
01093 {
01094
01095 assert( mrr.mextent==v.nelem() );
01096 assert( mcr.mextent==1 );
01097
01098 ConstMatrixView dummy(v);
01099 copy( dummy.begin(), dummy.end(), begin() );
01100 return *this;
01101 }
01102
01105 MatrixView& MatrixView::operator=(Numeric x)
01106 {
01107 copy( x, begin(), end() );
01108 return *this;
01109 }
01110
01112 MatrixView& MatrixView::operator*=(Numeric x)
01113 {
01114 const Iterator2D er=end();
01115 for ( Iterator2D r=begin(); r!=er ; ++r )
01116 {
01117 const Iterator1D ec = r->end();
01118 for ( Iterator1D c = r->begin(); c!=ec ; ++c )
01119 *c *= x;
01120 }
01121 return *this;
01122 }
01123
01125 MatrixView& MatrixView::operator/=(Numeric x)
01126 {
01127 const Iterator2D er=end();
01128 for ( Iterator2D r=begin(); r!=er ; ++r )
01129 {
01130 const Iterator1D ec = r->end();
01131 for ( Iterator1D c = r->begin(); c!=ec ; ++c )
01132 *c /= x;
01133 }
01134 return *this;
01135 }
01136
01138 MatrixView& MatrixView::operator+=(Numeric x)
01139 {
01140 const Iterator2D er=end();
01141 for ( Iterator2D r=begin(); r!=er ; ++r )
01142 {
01143 const Iterator1D ec = r->end();
01144 for ( Iterator1D c = r->begin(); c!=ec ; ++c )
01145 *c += x;
01146 }
01147 return *this;
01148 }
01149
01151 MatrixView& MatrixView::operator-=(Numeric x)
01152 {
01153 const Iterator2D er=end();
01154 for ( Iterator2D r=begin(); r!=er ; ++r )
01155 {
01156 const Iterator1D ec = r->end();
01157 for ( Iterator1D c = r->begin(); c!=ec ; ++c )
01158 *c -= x;
01159 }
01160 return *this;
01161 }
01162
01169 const Numeric *MatrixView::get_c_array() const
01170 {
01171 if (mrr.mstart != 0 || mrr.mstride != mcr.mextent
01172 || mcr.mstart != 0 || mcr.mstride != 1)
01173 throw runtime_error("A MatrixView can only be converted to a plain C-array if mrr.mstart == 0 and mrr.mstride == mcr.extent and mcr.mstart == 0 and mcr.mstride == 1");
01174
01175 return mdata;
01176 }
01177
01184 Numeric *MatrixView::get_c_array()
01185 {
01186 if (mrr.mstart != 0 || mrr.mstride != mcr.mextent
01187 || mcr.mstart != 0 || mcr.mstride != 1)
01188 throw runtime_error("A MatrixView can only be converted to a plain C-array if mrr.mstart == 0 and mrr.mstride == mcr.extent and mcr.mstart == 0 and mcr.mstride == 1");
01189
01190 return mdata;
01191 }
01192
01194 MatrixView& MatrixView::operator*=(const ConstMatrixView& x)
01195 {
01196 assert(nrows()==x.nrows());
01197 assert(ncols()==x.ncols());
01198 ConstIterator2D sr = x.begin();
01199 Iterator2D r = begin();
01200 const Iterator2D er = end();
01201 for ( ; r!=er ; ++r,++sr )
01202 {
01203 ConstIterator1D sc = sr->begin();
01204 Iterator1D c = r->begin();
01205 const Iterator1D ec = r->end();
01206 for ( ; c!=ec ; ++c,++sc )
01207 *c *= *sc;
01208 }
01209 return *this;
01210 }
01211
01213 MatrixView& MatrixView::operator/=(const ConstMatrixView& x)
01214 {
01215 assert(nrows()==x.nrows());
01216 assert(ncols()==x.ncols());
01217 ConstIterator2D sr = x.begin();
01218 Iterator2D r = begin();
01219 const Iterator2D er = end();
01220 for ( ; r!=er ; ++r,++sr )
01221 {
01222 ConstIterator1D sc = sr->begin();
01223 Iterator1D c = r->begin();
01224 const Iterator1D ec = r->end();
01225 for ( ; c!=ec ; ++c,++sc )
01226 *c /= *sc;
01227 }
01228 return *this;
01229 }
01230
01232 MatrixView& MatrixView::operator+=(const ConstMatrixView& x)
01233 {
01234 assert(nrows()==x.nrows());
01235 assert(ncols()==x.ncols());
01236 ConstIterator2D sr = x.begin();
01237 Iterator2D r = begin();
01238 const Iterator2D er = end();
01239 for ( ; r!=er ; ++r,++sr )
01240 {
01241 ConstIterator1D sc = sr->begin();
01242 Iterator1D c = r->begin();
01243 const Iterator1D ec = r->end();
01244 for ( ; c!=ec ; ++c,++sc )
01245 *c += *sc;
01246 }
01247 return *this;
01248 }
01249
01251 MatrixView& MatrixView::operator-=(const ConstMatrixView& x)
01252 {
01253 assert(nrows()==x.nrows());
01254 assert(ncols()==x.ncols());
01255 ConstIterator2D sr = x.begin();
01256 Iterator2D r = begin();
01257 const Iterator2D er = end();
01258 for ( ; r!=er ; ++r,++sr )
01259 {
01260 ConstIterator1D sc = sr->begin();
01261 Iterator1D c = r->begin();
01262 const Iterator1D ec = r->end();
01263 for ( ; c!=ec ; ++c,++sc )
01264 *c -= *sc;
01265 }
01266 return *this;
01267 }
01268
01270 MatrixView& MatrixView::operator*=(const ConstVectorView& x)
01271 {
01272 assert(nrows()==x.nelem());
01273 assert(ncols()==1);
01274 ConstIterator1D sc = x.begin();
01275 Iterator2D r = begin();
01276 const Iterator2D er = end();
01277 for ( ; r!=er ; ++r,++sc )
01278 {
01279 Iterator1D c = r->begin();
01280 *c *= *sc;
01281 }
01282 return *this;
01283 }
01284
01286 MatrixView& MatrixView::operator/=(const ConstVectorView& x)
01287 {
01288 assert(nrows()==x.nelem());
01289 assert(ncols()==1);
01290 ConstIterator1D sc = x.begin();
01291 Iterator2D r = begin();
01292 const Iterator2D er = end();
01293 for ( ; r!=er ; ++r,++sc )
01294 {
01295 Iterator1D c = r->begin();
01296 *c /= *sc;
01297 }
01298 return *this;
01299 }
01300
01302 MatrixView& MatrixView::operator+=(const ConstVectorView& x)
01303 {
01304 assert(nrows()==x.nelem());
01305 assert(ncols()==1);
01306 ConstIterator1D sc = x.begin();
01307 Iterator2D r = begin();
01308 const Iterator2D er = end();
01309 for ( ; r!=er ; ++r,++sc )
01310 {
01311 Iterator1D c = r->begin();
01312 *c += *sc;
01313 }
01314 return *this;
01315 }
01316
01318 MatrixView& MatrixView::operator-=(const ConstVectorView& x)
01319 {
01320 assert(nrows()==x.nelem());
01321 assert(ncols()==1);
01322 ConstIterator1D sc = x.begin();
01323 Iterator2D r = begin();
01324 const Iterator2D er = end();
01325 for ( ; r!=er ; ++r,++sc )
01326 {
01327 Iterator1D c = r->begin();
01328 *c -= *sc;
01329 }
01330 return *this;
01331 }
01332
01335 MatrixView::MatrixView() :
01336 ConstMatrixView()
01337 {
01338
01339 }
01340
01344 MatrixView::MatrixView(Numeric *data,
01345 const Range& rr,
01346 const Range& cr) :
01347 ConstMatrixView(data, rr, cr)
01348 {
01349
01350 }
01351
01366 MatrixView::MatrixView(Numeric *data,
01367 const Range& pr, const Range& pc,
01368 const Range& nr, const Range& nc) :
01369 ConstMatrixView(data,pr,pc,nr,nc)
01370 {
01371
01372 }
01373
01383 void copy(ConstIterator2D origin,
01384 const ConstIterator2D& end,
01385 Iterator2D target)
01386 {
01387 for ( ; origin!=end ; ++origin,++target )
01388 {
01389 ConstIterator1D o = origin->begin();
01390 const ConstIterator1D e = origin->end();
01391 Iterator1D t = target->begin();
01392 for ( ; o!=e ; ++o,++t )
01393 *t = *o;
01394 }
01395 }
01396
01398 void copy(Numeric x,
01399 Iterator2D target,
01400 const Iterator2D& end)
01401 {
01402 for ( ; target!=end ; ++target )
01403 {
01404 Iterator1D t = target->begin();
01405 const Iterator1D e = target->end();
01406 for ( ; t!=e ; ++t )
01407 *t = x;
01408 }
01409 }
01410
01411
01412
01413
01414
01416 Matrix::Matrix() :
01417 MatrixView::MatrixView()
01418 {
01419
01420
01421
01422
01423 }
01424
01427 Matrix::Matrix(Index r, Index c) :
01428 MatrixView( new Numeric[r*c],
01429 Range(0,r,c),
01430 Range(0,c))
01431 {
01432
01433 }
01434
01436 Matrix::Matrix(Index r, Index c, Numeric fill) :
01437 MatrixView( new Numeric[r*c],
01438 Range(0,r,c),
01439 Range(0,c))
01440 {
01441
01442
01443 const Numeric *stop = mdata+r*c;
01444 for ( Numeric *x=mdata; x<stop; ++x )
01445 *x = fill;
01446 }
01447
01450 Matrix::Matrix(const ConstMatrixView& m) :
01451 MatrixView( new Numeric[m.nrows()*m.ncols()],
01452 Range( 0, m.nrows(), m.ncols() ),
01453 Range( 0, m.ncols() ) )
01454 {
01455 copy(m.begin(),m.end(),begin());
01456 }
01457
01460 Matrix::Matrix(const Matrix& m) :
01461 MatrixView( new Numeric[m.nrows()*m.ncols()],
01462 Range( 0, m.nrows(), m.ncols() ),
01463 Range( 0, m.ncols() ) )
01464 {
01465
01466
01467
01468
01469 copy(m.begin(),m.end(),begin());
01470 }
01471
01473
01497 Matrix& Matrix::operator=(const Matrix& m)
01498 {
01499
01500
01501
01502 resize( m.mrr.mextent, m.mcr.mextent );
01503
01504 copy( m.begin(), m.end(), begin() );
01505 return *this;
01506 }
01507
01510 Matrix& Matrix::operator=(Numeric x)
01511 {
01512 copy( x, begin(), end() );
01513 return *this;
01514 }
01515
01517
01529 Matrix& Matrix::operator=(const ConstVectorView& v)
01530 {
01531 resize( v.nelem(), 1 );
01532 ConstMatrixView dummy(v);
01533 copy( dummy.begin(), dummy.end(), begin() );
01534 return *this;
01535 }
01536
01540 void Matrix::resize(Index r, Index c)
01541 {
01542 assert( 0<=r );
01543 assert( 0<=c );
01544
01545 if ( mrr.mextent!=r || mcr.mextent!=c )
01546 {
01547 delete[] mdata;
01548 mdata = new Numeric[r*c];
01549
01550 mrr.mstart = 0;
01551 mrr.mextent = r;
01552 mrr.mstride = c;
01553
01554 mcr.mstart = 0;
01555 mcr.mextent = c;
01556 mcr.mstride = 1;
01557 }
01558 }
01559
01562 Matrix::~Matrix()
01563 {
01564
01565
01566 delete[] mdata;
01567 }
01568
01569
01570
01571
01573 Numeric operator*(const ConstVectorView& a, const ConstVectorView& b)
01574 {
01575
01576 assert( a.nelem() == b.nelem() );
01577
01578 const ConstIterator1D ae = a.end();
01579 ConstIterator1D ai = a.begin();
01580 ConstIterator1D bi = b.begin();
01581
01582 Numeric res = 0;
01583 for ( ; ai!=ae ; ++ai, ++bi )
01584 res += (*ai) * (*bi);
01585
01586 return res;
01587 }
01588
01598 void mult( VectorView y,
01599 const ConstMatrixView& M,
01600 const ConstVectorView& x )
01601 {
01602
01603 assert( y.mrange.mextent == M.mrr.mextent );
01604 assert( M.mcr.mextent == x.mrange.mextent );
01605 assert( M.mcr.mextent != 0 && M.mrr.mextent != 0);
01606
01607
01608 Numeric *mdata = M.mdata + M.mcr.mstart + M.mrr.mstart;
01609 Numeric *xdata = x.mdata + x.mrange.mstart;
01610 Numeric *yelem = y.mdata + y.mrange.mstart;
01611
01612 Index i = M.mrr.mextent;
01613 while (i--)
01614 {
01615 Numeric *melem = mdata;
01616 Numeric *xelem = xdata;
01617
01618
01619
01620
01621 *yelem = *melem * *xelem;
01622
01623 Index j = M.mcr.mextent;
01624 while (--j)
01625 {
01626 melem += M.mcr.mstride;
01627 xelem += x.mrange.mstride;
01628 *yelem += *melem * *xelem;
01629 }
01630
01631 mdata += M.mrr.mstride;
01632 yelem += y.mrange.mstride;
01633 }
01634 }
01635
01636
01643 void mult( MatrixView A,
01644 const ConstMatrixView& B,
01645 const ConstMatrixView& C )
01646 {
01647
01648 assert( A.nrows() == B.nrows() );
01649 assert( A.ncols() == C.ncols() );
01650 assert( B.ncols() == C.nrows() );
01651
01652
01653
01654 ConstMatrixView CT = transpose(C);
01655
01656 const Iterator2D ae = A.end();
01657 Iterator2D ai = A.begin();
01658 ConstIterator2D bi = B.begin();
01659
01660
01661 for ( ; ai!=ae ; ++ai, ++bi )
01662 {
01663 const Iterator1D ace = ai->end();
01664 Iterator1D aci = ai->begin();
01665 ConstIterator2D cti = CT.begin();
01666
01667
01668
01669
01670 for ( ; aci!=ace ; ++aci, ++cti )
01671 {
01672
01673
01674 *aci = (*bi) * (*cti);
01675 }
01676 }
01677 }
01678
01680 ConstMatrixView transpose(ConstMatrixView m)
01681 {
01682 return ConstMatrixView(m.mdata, m.mcr, m.mrr);
01683 }
01684
01687 MatrixView transpose(MatrixView m)
01688 {
01689 return MatrixView(m.mdata, m.mcr, m.mrr);
01690 }
01691
01712 void transform( VectorView y,
01713 double (&my_func)(double),
01714 ConstVectorView x )
01715 {
01716
01717 assert( y.nelem()==x.nelem() );
01718
01719 const ConstIterator1D xe = x.end();
01720 ConstIterator1D xi = x.begin();
01721 Iterator1D yi = y.begin();
01722 for ( ; xi!=xe; ++xi, ++yi )
01723 *yi = my_func(*xi);
01724 }
01725
01744 void transform( MatrixView y,
01745 double (&my_func)(double),
01746 ConstMatrixView x )
01747 {
01748
01749 assert( y.nrows()==x.nrows() );
01750 assert( y.ncols()==x.ncols() );
01751
01752 const ConstIterator2D rxe = x.end();
01753 ConstIterator2D rx = x.begin();
01754 Iterator2D ry = y.begin();
01755 for ( ; rx!=rxe; ++rx, ++ry )
01756 {
01757 const ConstIterator1D cxe = rx->end();
01758 ConstIterator1D cx = rx->begin();
01759 Iterator1D cy = ry->begin();
01760 for ( ; cx!=cxe; ++cx, ++cy )
01761 *cy = my_func(*cx);
01762 }
01763 }
01764
01766 Numeric max(const ConstVectorView& x)
01767 {
01768
01769 Numeric max = x[0];
01770
01771 const ConstIterator1D xe = x.end();
01772 ConstIterator1D xi = x.begin();
01773
01774 for ( ; xi!=xe ; ++xi )
01775 {
01776 if ( *xi > max )
01777 max = *xi;
01778 }
01779
01780 return max;
01781 }
01782
01784 Numeric max(const ConstMatrixView& x)
01785 {
01786
01787 Numeric max = x(0,0);
01788
01789 const ConstIterator2D rxe = x.end();
01790 ConstIterator2D rx = x.begin();
01791
01792 for ( ; rx!=rxe ; ++rx )
01793 {
01794 const ConstIterator1D cxe = rx->end();
01795 ConstIterator1D cx = rx->begin();
01796
01797 for ( ; cx!=cxe ; ++cx )
01798 if ( *cx > max )
01799 max = *cx;
01800 }
01801
01802 return max;
01803 }
01804
01806 Numeric min(const ConstVectorView& x)
01807 {
01808
01809 Numeric min = x[0];
01810
01811 const ConstIterator1D xe = x.end();
01812 ConstIterator1D xi = x.begin();
01813
01814 for ( ; xi!=xe ; ++xi )
01815 {
01816 if ( *xi < min )
01817 min = *xi;
01818 }
01819
01820 return min;
01821 }
01822
01824 Numeric min(const ConstMatrixView& x)
01825 {
01826
01827 Numeric min = x(0,0);
01828
01829 const ConstIterator2D rxe = x.end();
01830 ConstIterator2D rx = x.begin();
01831
01832 for ( ; rx!=rxe ; ++rx )
01833 {
01834 const ConstIterator1D cxe = rx->end();
01835 ConstIterator1D cx = rx->begin();
01836
01837 for ( ; cx!=cxe ; ++cx )
01838 if ( *cx < min )
01839 min = *cx;
01840 }
01841
01842 return min;
01843 }
01844
01846 Numeric mean(const ConstVectorView& x)
01847 {
01848
01849 Numeric mean = 0;
01850
01851 const ConstIterator1D xe = x.end();
01852 ConstIterator1D xi = x.begin();
01853
01854 for ( ; xi!=xe ; ++xi ) mean += *xi;
01855
01856 mean /= (Numeric)x.nelem();
01857
01858 return mean;
01859 }
01860
01862 Numeric mean(const ConstMatrixView& x)
01863 {
01864
01865 Numeric mean = 0;
01866
01867 const ConstIterator2D rxe = x.end();
01868 ConstIterator2D rx = x.begin();
01869
01870 for ( ; rx!=rxe ; ++rx )
01871 {
01872 const ConstIterator1D cxe = rx->end();
01873 ConstIterator1D cx = rx->begin();
01874
01875 for ( ; cx!=cxe ; ++cx ) mean += *cx;
01876 }
01877
01878 mean /= (Numeric)(x.nrows()*x.ncols());
01879
01880 return mean;
01881 }
01882
01892 VectorView& VectorView::operator=(const Array<Numeric>& v)
01893 {
01894
01895
01896
01897 assert(mrange.mextent==v.nelem());
01898
01899
01900 Array<Numeric>::const_iterator i=v.begin();
01901 const Array<Numeric>::const_iterator e=v.end();
01902
01903 Iterator1D target = begin();
01904
01905 for ( ; i!=e ; ++i,++target )
01906 *target = *i;
01907
01908 return *this;
01909 }
01910
01912
01913 #ifndef NDEBUG
01914
01928 Numeric debug_matrixview_get_elem (MatrixView& mv, Index r, Index c)
01929 {
01930 return mv(r, c);
01931 }
01932
01933 #endif
01935
01936