00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00027 #ifndef matpackIII_h
00028 #define matpackIII_h
00029 
00030 #include <iomanip>
00031 #include "matpackI.h"
00032 
00035 class Iterator3D {
00036 public:
00037   
00038   Iterator3D();
00039   Iterator3D(const Iterator3D& o);
00040   Iterator3D(const MatrixView& x, Index stride);
00041 
00042   
00043   Iterator3D& operator++();
00044   bool operator!=(const Iterator3D& other) const;
00045   MatrixView* const operator->();
00046   MatrixView& operator*();
00047   
00048 private:
00050   MatrixView msv;
00052   Index mstride;
00053 };
00054 
00056 class ConstIterator3D {
00057 public:
00058   
00059   ConstIterator3D();
00060   ConstIterator3D(const ConstIterator3D& o);
00061   ConstIterator3D(const ConstMatrixView& x, Index stride);
00062 
00063   
00064   ConstIterator3D& operator++();
00065   bool operator!=(const ConstIterator3D& other) const;
00066   const ConstMatrixView* operator->() const;
00067   const ConstMatrixView& operator*() const;
00068 
00069 private:
00071   ConstMatrixView msv;
00073   Index mstride;
00074 };
00075 
00076 
00077 
00078 class Tensor3;
00079 
00080 
00093 class ConstTensor3View {
00094 public:
00095   
00096   Index npages() const;
00097   Index nrows() const;
00098   Index ncols() const;
00099 
00100   
00101   ConstTensor3View operator()( const Range& p, const Range& r, const Range& c ) const;
00102 
00103   ConstMatrixView  operator()( const Range& p, const Range& r, Index c        ) const;
00104   ConstMatrixView  operator()( const Range& p, Index r,        const Range& c ) const;
00105   ConstMatrixView  operator()( Index p,        const Range& r, const Range& c ) const;
00106 
00107   ConstVectorView  operator()( Index p,        Index r,        const Range& c ) const;
00108   ConstVectorView  operator()( Index p,        const Range& r, Index c        ) const;
00109   ConstVectorView  operator()( const Range& p, Index r,        Index c        ) const;
00110 
00111   Numeric          operator()( Index p,        Index r,        Index c        ) const;
00112 
00113   
00114   ConstIterator3D begin() const;
00115   ConstIterator3D end() const;
00116   
00117   
00118   friend class Tensor3View;
00119 
00120 
00121 protected:
00122   
00123   ConstTensor3View();
00124   ConstTensor3View(Numeric *data,
00125                    const Range& p, const Range& r, const Range& c);
00126   ConstTensor3View(Numeric *data,
00127                    const Range& pp, const Range& pr, const Range& pc,
00128                    const Range& np, const Range& nr, const Range& nc);
00129 
00130   
00131   
00133   Range mpr;
00135   Range mrr;
00137   Range mcr;
00139   Numeric *mdata;
00140 };
00141 
00151 class Tensor3View : public ConstTensor3View {
00152 public:
00153 
00154   
00155   ConstTensor3View operator()( const Range& p, const Range& r, const Range& c ) const;
00156 
00157   ConstMatrixView  operator()( const Range& p, const Range& r, Index c        ) const;
00158   ConstMatrixView  operator()( const Range& p, Index r,        const Range& c ) const;
00159   ConstMatrixView  operator()( Index p,        const Range& r, const Range& c ) const;
00160 
00161   ConstVectorView  operator()( Index p,        Index r,        const Range& c ) const;
00162   ConstVectorView  operator()( Index p,        const Range& r, Index c        ) const;
00163   ConstVectorView  operator()( const Range& p, Index r,        Index c        ) const;
00164 
00165   Numeric          operator()( Index p,        Index r,        Index c        ) const;
00166 
00167   
00168 
00169   Tensor3View operator()( const Range& p, const Range& r, const Range& c );
00170 
00171   MatrixView  operator()( const Range& p, const Range& r, Index c        );
00172   MatrixView  operator()( const Range& p, Index r,        const Range& c );
00173   MatrixView  operator()( Index p,        const Range& r, const Range& c );
00174 
00175   VectorView  operator()( Index p,        Index r,        const Range& c );
00176   VectorView  operator()( Index p,        const Range& r, Index c        );
00177   VectorView  operator()( const Range& p, Index r,        Index c        );
00178 
00179   Numeric&    operator()( Index p,        Index r,        Index c        );
00180 
00181   
00182   ConstIterator3D begin() const;
00183   ConstIterator3D end() const;
00184   
00185   Iterator3D begin();
00186   Iterator3D end();
00187   
00188   
00189   Tensor3View& operator=(const ConstTensor3View& v);
00190   Tensor3View& operator=(const Tensor3View& v);
00191   Tensor3View& operator=(const Tensor3& v);
00192   Tensor3View& operator=(Numeric x);
00193 
00194   
00195   Tensor3View& operator*=(Numeric x);
00196   Tensor3View& operator/=(Numeric x);
00197   Tensor3View& operator+=(Numeric x);
00198   Tensor3View& operator-=(Numeric x);
00199 
00200   Tensor3View& operator*=(const ConstTensor3View& x);
00201   Tensor3View& operator/=(const ConstTensor3View& x);
00202   Tensor3View& operator+=(const ConstTensor3View& x);
00203   Tensor3View& operator-=(const ConstTensor3View& x);
00204 
00205   
00206 
00207 
00208 
00209 
00210 protected:
00211   
00212   Tensor3View();
00213   Tensor3View(Numeric *data, const Range& p, const Range& r, const Range& c);
00214   Tensor3View(Numeric *data,
00215               const Range& pp, const Range& pr, const Range& pc,
00216               const Range& np, const Range& nr, const Range& nc);
00217 };
00218 
00227 class Tensor3 : public Tensor3View {
00228 public:
00229   
00230   Tensor3();
00231   Tensor3(Index p, Index r, Index c);
00232   Tensor3(Index p, Index r, Index c, Numeric fill);
00233   Tensor3(const ConstTensor3View& v);
00234   Tensor3(const Tensor3& v);
00235 
00236   
00237   Tensor3& operator=(const Tensor3& x);
00238   Tensor3& operator=(Numeric x);
00239 
00240   
00241   void resize(Index p, Index r, Index c);
00242 
00243   
00244   ~Tensor3();
00245 };
00246 
00247 
00248 
00249 
00250 
00251 inline void copy(ConstIterator3D origin,
00252                  const ConstIterator3D& end,
00253                  Iterator3D target);
00254 
00255 inline void copy(Numeric x,
00256                  Iterator3D target,
00257                  const Iterator3D& end);
00258 
00259 
00260 
00261 
00262 template<class base>
00263 class Array;
00264 
00266 typedef Array<Tensor3> ArrayOfTensor3;
00267 
00268 
00269 
00270 
00271 
00272 
00274 inline Iterator3D::Iterator3D()
00275 {
00276   
00277 }
00278 
00280 inline Iterator3D::Iterator3D(const Iterator3D& o) :
00281   msv(o.msv), mstride(o.mstride)
00282 {
00283   
00284 }
00285 
00287 inline Iterator3D::Iterator3D(const MatrixView& x, Index stride) :
00288   msv(x), mstride(stride)
00289 {
00290   
00291 }
00292 
00294 inline Iterator3D& Iterator3D::operator++()
00295 {
00296   msv.mdata += mstride;
00297   return *this;
00298 }
00299 
00301 inline bool Iterator3D::operator!=(const Iterator3D& other) const
00302 {
00303   if ( msv.mdata +
00304        msv.mrr.mstart +
00305        msv.mcr.mstart 
00306        !=
00307        other.msv.mdata +
00308        other.msv.mrr.mstart +
00309        other.msv.mcr.mstart )
00310     return true;
00311   else
00312     return false;
00313 }
00314 
00317 inline MatrixView* const Iterator3D::operator->()
00318 {
00319   return &msv;
00320 }
00321 
00323 inline MatrixView& Iterator3D::operator*()
00324 {
00325   return msv;
00326 }
00327 
00328 
00329 
00330 
00332 inline ConstIterator3D::ConstIterator3D()
00333 {
00334   
00335 }
00336 
00338 inline ConstIterator3D::ConstIterator3D(const ConstIterator3D& o) :
00339   msv(o.msv), mstride(o.mstride)
00340 {
00341   
00342 }
00343 
00345 inline ConstIterator3D::ConstIterator3D(const ConstMatrixView& x, Index stride) :
00346   msv(x), mstride(stride)
00347 {
00348   
00349 }
00350 
00352 inline ConstIterator3D& ConstIterator3D::operator++()
00353 {
00354   msv.mdata += mstride;
00355   return *this;
00356 }
00357 
00359 inline bool ConstIterator3D::operator!=(const ConstIterator3D& other) const
00360 {
00361   if ( msv.mdata +
00362        msv.mrr.mstart +
00363        msv.mcr.mstart
00364        !=
00365        other.msv.mdata +
00366        other.msv.mrr.mstart +
00367        other.msv.mcr.mstart )
00368     return true;
00369   else
00370     return false;
00371 }
00372 
00375 inline const ConstMatrixView* ConstIterator3D::operator->() const
00376 {
00377   return &msv;
00378 }
00379 
00381 inline const ConstMatrixView& ConstIterator3D::operator*() const
00382 {
00383   return msv;
00384 }
00385 
00386 
00387 
00388 
00389 
00390 
00392 inline Index ConstTensor3View::npages() const
00393 {
00394   return mpr.mextent;
00395 }
00396 
00398 inline Index ConstTensor3View::nrows() const
00399 {
00400   return mrr.mextent;
00401 }
00402 
00404 inline Index ConstTensor3View::ncols() const
00405 {
00406   return mcr.mextent;
00407 }
00408 
00412 inline ConstTensor3View ConstTensor3View::operator()(const Range& p,
00413                                                      const Range& r,
00414                                                      const Range& c) const
00415 {
00416   return ConstTensor3View(mdata, mpr, mrr, mcr, p, r, c);
00417 }
00418 
00421 inline ConstMatrixView ConstTensor3View::operator()(const Range& p,
00422                                                     const Range& r,
00423                                                     Index c) const
00424 {
00425   
00426   assert( 0 <= c );
00427   assert( c < mcr.mextent );
00428 
00429   return ConstMatrixView(mdata + mcr.mstart + c*mcr.mstride,
00430                          mpr, mrr, 
00431                          p,   r);
00432 }
00433 
00436 inline ConstMatrixView ConstTensor3View::operator()(const Range& p,
00437                                                     Index        r,
00438                                                     const Range& c) const
00439 {
00440   
00441   assert( 0 <= r );
00442   assert( r < mrr.mextent );
00443 
00444   return ConstMatrixView(mdata + mrr.mstart + r*mrr.mstride,
00445                          mpr, mcr, 
00446                          p,   c);
00447 }
00448 
00451 inline ConstMatrixView ConstTensor3View::operator()(Index p,
00452                                                     const Range& r,
00453                                                     const Range& c) const
00454 {
00455   
00456   assert( 0 <= p );
00457   assert( p < mpr.mextent );
00458 
00459   return ConstMatrixView(mdata + mpr.mstart + p*mpr.mstride,
00460                          mrr, mcr, 
00461                          r,   c);
00462 }
00463 
00466 inline ConstVectorView ConstTensor3View::operator()(Index p,
00467                                                     Index r,
00468                                                     const Range& c) const
00469 {
00470   
00471   assert( 0 <= p );
00472   assert( 0 <= r );
00473   assert( p < mpr.mextent );
00474   assert( r < mrr.mextent );
00475 
00476   return ConstVectorView(mdata +
00477                          mpr.mstart + p*mpr.mstride +
00478                          mrr.mstart + r*mrr.mstride,
00479                          mcr, c);
00480 }
00481 
00484 inline ConstVectorView ConstTensor3View::operator()(Index p,
00485                                                     const Range& r,
00486                                                     Index c) const
00487 {
00488   
00489   assert( 0 <= p );
00490   assert( 0 <= c );
00491   assert( p < mpr.mextent );
00492   assert( c < mcr.mextent );
00493 
00494   return ConstVectorView(mdata +
00495                          mpr.mstart + p*mpr.mstride +
00496                          mcr.mstart + c*mcr.mstride,
00497                          mrr, r);
00498 }
00499 
00502 inline ConstVectorView ConstTensor3View::operator()(const Range& p,
00503                                                     Index r,
00504                                                     Index c) const
00505 {
00506   
00507   assert( 0 <= r );
00508   assert( 0 <= c );
00509   assert( r < mrr.mextent );
00510   assert( c < mcr.mextent );
00511 
00512   return ConstVectorView(mdata +
00513                          mrr.mstart + r*mrr.mstride +
00514                          mcr.mstart + c*mcr.mstride,
00515                          mpr, p);
00516 }
00517 
00519 inline Numeric ConstTensor3View::operator()(Index p, Index r, Index c) const
00520 {
00521   
00522   assert( 0<=p );
00523   assert( 0<=r );
00524   assert( 0<=c );
00525   assert( p<mpr.mextent );
00526   assert( r<mrr.mextent );
00527   assert( c<mcr.mextent );
00528 
00529   return *( mdata +
00530             mpr.mstart + p*mpr.mstride +
00531             mrr.mstart + r*mrr.mstride +
00532             mcr.mstart + c*mcr.mstride );
00533 }
00534 
00536 inline ConstIterator3D ConstTensor3View::begin() const
00537 {
00538   return ConstIterator3D(ConstMatrixView(mdata+mpr.mstart,
00539                                          mrr,
00540                                          mcr),
00541                          mpr.mstride);
00542 }
00543 
00545 inline ConstIterator3D ConstTensor3View::end() const
00546 {
00547   return ConstIterator3D( ConstMatrixView(mdata + mpr.mstart +
00548                                           (mpr.mextent)*mpr.mstride,
00549                                           mrr,
00550                                           mcr),
00551                           mpr.mstride );
00552 }
00553 
00556 inline ConstTensor3View::ConstTensor3View() :
00557   mpr(0,0,1), mrr(0,0,1), mcr(0,0,1), mdata(NULL)
00558 {
00559   
00560 }
00561 
00566 inline ConstTensor3View::ConstTensor3View(Numeric *data,
00567                                           const Range& pr,
00568                                           const Range& rr,
00569                                           const Range& cr) :
00570   mpr(pr),
00571   mrr(rr),
00572   mcr(cr),
00573   mdata(data)
00574 {
00575   
00576 }
00577 
00585 inline ConstTensor3View::ConstTensor3View(Numeric *data,
00586                                           const Range& pp,
00587                                           const Range& pr,
00588                                           const Range& pc,
00589                                           const Range& np,
00590                                           const Range& nr,
00591                                           const Range& nc) :
00592   mpr(pp,np),
00593   mrr(pr,nr),
00594   mcr(pc,nc),
00595   mdata(data)
00596 {
00597   
00598 }
00599 
00603 inline std::ostream& operator<<(std::ostream& os, const ConstTensor3View& v)
00604 {
00605   
00606   ConstIterator3D ip=v.begin();
00607   const ConstIterator3D end_page=v.end();
00608 
00609   if ( ip!=end_page )
00610     {
00611       os << *ip;
00612       ++ip;
00613     }
00614 
00615   for ( ; ip!=end_page; ++ip )
00616     {
00617       os << "\n\n";
00618       os << *ip;
00619     }
00620 
00621   return os;
00622 }
00623 
00624 
00625 
00626 
00627 
00632 inline ConstTensor3View Tensor3View::operator()(const Range& p,
00633                                                 const Range& r,
00634                                                 const Range& c) const
00635 {
00636   return ConstTensor3View::operator()(p,r,c);  
00637 }
00638 
00643 inline ConstMatrixView Tensor3View::operator()(const Range& p,
00644                                                     const Range& r,
00645                                                     Index c) const
00646 {
00647   return ConstTensor3View::operator()(p,r,c);  
00648 }
00649 
00654 inline ConstMatrixView Tensor3View::operator()(const Range& p,
00655                                                     Index        r,
00656                                                     const Range& c) const
00657 {
00658   return ConstTensor3View::operator()(p,r,c);  
00659 }
00660 
00665 inline ConstMatrixView Tensor3View::operator()(Index p,
00666                                                     const Range& r,
00667                                                     const Range& c) const
00668 {
00669   return ConstTensor3View::operator()(p,r,c);  
00670 }
00671 
00676 inline ConstVectorView Tensor3View::operator()(Index p,
00677                                                     Index r,
00678                                                     const Range& c) const
00679 {
00680   return ConstTensor3View::operator()(p,r,c);  
00681 }
00682 
00687 inline ConstVectorView Tensor3View::operator()(Index p,
00688                                                     const Range& r,
00689                                                     Index c) const
00690 {
00691   return ConstTensor3View::operator()(p,r,c);  
00692 }
00693 
00698 inline ConstVectorView Tensor3View::operator()(const Range& p,
00699                                                     Index r,
00700                                                     Index c) const
00701 {
00702   return ConstTensor3View::operator()(p,r,c);  
00703 }
00704 
00707 inline Numeric Tensor3View::operator()(Index p, Index r, Index c) const
00708 {
00709   return ConstTensor3View::operator()(p,r,c);  
00710 }
00711 
00715 inline Tensor3View Tensor3View::operator()(const Range& p,
00716                                            const Range& r,
00717                                            const Range& c) 
00718 {
00719   return Tensor3View(mdata, mpr, mrr, mcr, p, r, c);
00720 }
00721 
00724 inline MatrixView Tensor3View::operator()(const Range& p,
00725                                           const Range& r,
00726                                           Index c)
00727 {
00728   
00729   assert( 0 <= c );
00730   assert( c < mcr.mextent );
00731 
00732   return MatrixView(mdata + mcr.mstart + c*mcr.mstride,
00733                     mpr, mrr, 
00734                     p,   r);
00735 }
00736 
00739 inline MatrixView Tensor3View::operator()(const Range& p,
00740                                           Index        r,
00741                                           const Range& c) 
00742 {
00743   
00744   assert( 0 <= r );
00745   assert( r < mrr.mextent );
00746 
00747   return MatrixView(mdata + mrr.mstart + r*mrr.mstride,
00748                     mpr, mcr, 
00749                     p,   c);
00750 }
00751 
00754 inline MatrixView Tensor3View::operator()(Index p,
00755                                           const Range& r,
00756                                           const Range& c) 
00757 {
00758   
00759   assert( 0 <= p );
00760   assert( p < mpr.mextent );
00761 
00762   return MatrixView(mdata + mpr.mstart + p*mpr.mstride,
00763                     mrr, mcr, 
00764                     r,   c);
00765 }
00766 
00769 inline VectorView Tensor3View::operator()(Index p,
00770                                           Index r,
00771                                           const Range& c) 
00772 {
00773   
00774   assert( 0 <= p );
00775   assert( 0 <= r );
00776   assert( p < mpr.mextent );
00777   assert( r < mrr.mextent );
00778 
00779   return VectorView(mdata +
00780                     mpr.mstart + p*mpr.mstride +
00781                     mrr.mstart + r*mrr.mstride,
00782                     mcr, c);
00783 }
00784 
00787 inline VectorView Tensor3View::operator()(Index p,
00788                                           const Range& r,
00789                                           Index c) 
00790 {
00791   
00792   assert( 0 <= p );
00793   assert( 0 <= c );
00794   assert( p < mpr.mextent );
00795   assert( c < mcr.mextent );
00796 
00797   return VectorView(mdata +
00798                     mpr.mstart + p*mpr.mstride +
00799                     mcr.mstart + c*mcr.mstride,
00800                     mrr, r);
00801 }
00802 
00805 inline VectorView Tensor3View::operator()(const Range& p,
00806                                           Index r,
00807                                           Index c)
00808 {
00809   
00810   assert( 0 <= r );
00811   assert( 0 <= c );
00812   assert( r < mrr.mextent );
00813   assert( c < mcr.mextent );
00814 
00815   return VectorView(mdata +
00816                     mrr.mstart + r*mrr.mstride +
00817                     mcr.mstart + c*mcr.mstride,
00818                     mpr, p);
00819 }
00820 
00822 inline Numeric& Tensor3View::operator()(Index p, Index r, Index c) 
00823 {
00824   
00825   assert( 0<=p );
00826   assert( 0<=r );
00827   assert( 0<=c );
00828   assert( p<mpr.mextent );
00829   assert( r<mrr.mextent );
00830   assert( c<mcr.mextent );
00831 
00832   return *( mdata +
00833             mpr.mstart + p*mpr.mstride +
00834             mrr.mstart + r*mrr.mstride +
00835             mcr.mstart + c*mcr.mstride );
00836 }
00837 
00840 inline ConstIterator3D Tensor3View::begin() const
00841 {
00842   return ConstTensor3View::begin();
00843 }
00844 
00846 inline ConstIterator3D Tensor3View::end() const
00847 {
00848   return ConstTensor3View::end();
00849 }
00850 
00852 inline Iterator3D Tensor3View::begin()
00853 {
00854   return Iterator3D(MatrixView(mdata+mpr.mstart,
00855                                mrr,
00856                                mcr),
00857                     mpr.mstride);
00858 }
00859 
00861 inline Iterator3D Tensor3View::end()
00862 {
00863   return Iterator3D( MatrixView(mdata + mpr.mstart +
00864                                 (mpr.mextent)*mpr.mstride,
00865                                 mrr,
00866                                 mcr),
00867                      mpr.mstride );
00868 }
00869 
00874 inline Tensor3View& Tensor3View::operator=(const ConstTensor3View& m)
00875 {
00876   
00877   assert(mpr.mextent==m.mpr.mextent);
00878   assert(mrr.mextent==m.mrr.mextent);
00879   assert(mcr.mextent==m.mcr.mextent);
00880 
00881   copy( m.begin(), m.end(), begin() );
00882   return *this;
00883 }
00884 
00890 inline Tensor3View& Tensor3View::operator=(const Tensor3View& m)
00891 {
00892   
00893   assert(mpr.mextent==m.mpr.mextent);
00894   assert(mrr.mextent==m.mrr.mextent);
00895   assert(mcr.mextent==m.mcr.mextent);
00896 
00897   copy( m.begin(), m.end(), begin() );
00898   return *this;
00899 }
00900 
00904 inline Tensor3View& Tensor3View::operator=(const Tensor3& m)
00905 {
00906   
00907   assert(mpr.mextent==m.mpr.mextent);
00908   assert(mrr.mextent==m.mrr.mextent);
00909   assert(mcr.mextent==m.mcr.mextent);
00910 
00911   copy( m.begin(), m.end(), begin() );
00912   return *this;
00913 }
00914 
00917 inline Tensor3View& Tensor3View::operator=(Numeric x)
00918 {
00919   copy( x, begin(), end() );
00920   return *this;
00921 }
00922 
00923 
00924 
00925 
00926 inline Numeric add(Numeric x, Numeric y)
00927 {
00928   return x+y;
00929 }
00930 
00932 inline Tensor3View& Tensor3View::operator*=(Numeric x)
00933 {
00934   const Iterator3D ep=end();  
00935   for ( Iterator3D p=begin(); p!=ep ; ++p )
00936   {
00937     *p *= x;
00938   }
00939   return *this;
00940 }
00941 
00943 inline Tensor3View& Tensor3View::operator/=(Numeric x)
00944 {
00945   const Iterator3D ep=end();  
00946   for ( Iterator3D p=begin(); p!=ep ; ++p )
00947   {
00948     *p /= x;
00949   }
00950   return *this;
00951 }
00952 
00954 inline Tensor3View& Tensor3View::operator+=(Numeric x)
00955 {
00956   const Iterator3D ep=end();  
00957   for ( Iterator3D p=begin(); p!=ep ; ++p )
00958   {
00959     *p += x;
00960   }
00961   return *this;
00962 }
00963 
00965 inline Tensor3View& Tensor3View::operator-=(Numeric x)
00966 {
00967   const Iterator3D ep=end();  
00968   for ( Iterator3D p=begin(); p!=ep ; ++p )
00969   {
00970     *p -= x;
00971   }
00972   return *this;
00973 }
00974 
00976 inline Tensor3View& Tensor3View::operator*=(const ConstTensor3View& x)
00977 {
00978   assert( npages() == x.npages() );
00979   assert( nrows()  == x.nrows()  );
00980   assert( ncols()  == x.ncols()  );
00981   ConstIterator3D  xp = x.begin();
00982   Iterator3D        p = begin();
00983   const Iterator3D ep = end();
00984   for ( ; p!=ep ; ++p,++xp )
00985     {
00986       *p *= *xp;
00987     }
00988   return *this;
00989 }
00990 
00992 inline Tensor3View& Tensor3View::operator/=(const ConstTensor3View& x)
00993 {
00994   assert( npages() == x.npages() );
00995   assert( nrows()  == x.nrows()  );
00996   assert( ncols()  == x.ncols()  );
00997   ConstIterator3D  xp = x.begin();
00998   Iterator3D        p = begin();
00999   const Iterator3D ep = end();
01000   for ( ; p!=ep ; ++p,++xp )
01001     {
01002       *p /= *xp;
01003     }
01004   return *this;
01005 }
01006 
01008 inline Tensor3View& Tensor3View::operator+=(const ConstTensor3View& x)
01009 {
01010   assert( npages() == x.npages() );
01011   assert( nrows()  == x.nrows()  );
01012   assert( ncols()  == x.ncols()  );
01013   ConstIterator3D  xp = x.begin();
01014   Iterator3D        p = begin();
01015   const Iterator3D ep = end();
01016   for ( ; p!=ep ; ++p,++xp )
01017     {
01018       *p += *xp;
01019     }
01020   return *this;
01021 }
01022 
01024 inline Tensor3View& Tensor3View::operator-=(const ConstTensor3View& x)
01025 {
01026   assert( npages() == x.npages() );
01027   assert( nrows()  == x.nrows()  );
01028   assert( ncols()  == x.ncols()  );
01029   ConstIterator3D  xp = x.begin();
01030   Iterator3D        p = begin();
01031   const Iterator3D ep = end();
01032   for ( ; p!=ep ; ++p,++xp )
01033     {
01034       *p -= *xp;
01035     }
01036   return *this;
01037 }
01038 
01041 inline Tensor3View::Tensor3View() :
01042   ConstTensor3View()
01043 {
01044   
01045 }
01046 
01050 inline Tensor3View::Tensor3View(Numeric *data,
01051                                 const Range& pr,
01052                                 const Range& rr,
01053                                 const Range& cr) :
01054   ConstTensor3View(data, pr, rr, cr)
01055 {
01056   
01057 }
01058 
01070 inline Tensor3View::Tensor3View(Numeric *data,
01071                                 const Range& pp,
01072                                 const Range& pr,
01073                                 const Range& pc,
01074                                 const Range& np,
01075                                 const Range& nr,
01076                                 const Range& nc) :
01077   ConstTensor3View(data,pp,pr,pc,np,nr,nc)
01078 {
01079   
01080 }
01081 
01086 inline void copy(ConstIterator3D origin,
01087                  const ConstIterator3D& end,
01088                  Iterator3D target)
01089 {
01090   for ( ; origin!=end ; ++origin,++target )
01091     {
01092       
01093       
01094       copy(origin->begin(),
01095            origin->end(),
01096            target->begin());
01097     }
01098 }
01099 
01101 inline void copy(Numeric x,
01102                  Iterator3D target,
01103                  const Iterator3D& end)
01104 {
01105   for ( ; target!=end ; ++target )
01106     {
01107       
01108       
01109       copy(x,target->begin(),target->end());
01110     }
01111 }
01112 
01113 
01114 
01115 
01116 
01118 inline Tensor3::Tensor3() :
01119   Tensor3View::Tensor3View()
01120 {
01121   
01122   
01123   
01124   
01125 }
01126 
01129 inline Tensor3::Tensor3(Index p, Index r, Index c) :
01130   Tensor3View( new Numeric[p*r*c],
01131              Range(0,p,r*c),
01132              Range(0,r,c),
01133              Range(0,c))
01134 {
01135   
01136 }
01137 
01139 inline Tensor3::Tensor3(Index p, Index r, Index c, Numeric fill) :
01140   Tensor3View( new Numeric[p*r*c],
01141               Range(0,p,r*c),
01142               Range(0,r,c),
01143               Range(0,c))
01144 {
01145   
01146   
01147   for ( Numeric *x=mdata; x<mdata+p*r*c; ++x )
01148     *x = fill;
01149 }
01150 
01153 inline Tensor3::Tensor3(const ConstTensor3View& m) :
01154   Tensor3View( new Numeric[m.npages()*m.nrows()*m.ncols()],
01155              Range( 0, m.npages(), m.nrows()*m.ncols() ),
01156              Range( 0, m.nrows(), m.ncols() ),
01157              Range( 0, m.ncols() ) )
01158 {
01159   copy(m.begin(),m.end(),begin());
01160 }
01161 
01164 inline Tensor3::Tensor3(const Tensor3& m) :
01165   Tensor3View( new Numeric[m.npages()*m.nrows()*m.ncols()],
01166              Range( 0, m.npages(), m.nrows()*m.ncols() ),
01167              Range( 0, m.nrows(), m.ncols() ),
01168              Range( 0, m.ncols() ) )
01169 {
01170   
01171   
01172   
01173   
01174   
01175   copy(m.begin(),m.end(),begin());
01176 }
01177 
01188 inline Tensor3& Tensor3::operator=(const Tensor3& m)
01189 {
01190   
01191   
01192 
01193   
01194   
01195   if ( 0 == mcr.mextent )
01196     {
01197       
01198       resize( m.mpr.mextent, m.mrr.mextent, m.mcr.mextent ); 
01199     }
01200   else
01201     {
01202       
01203       assert( mpr.mextent==m.mpr.mextent );
01204       assert( mrr.mextent==m.mrr.mextent );
01205       assert( mcr.mextent==m.mcr.mextent );
01206     }
01207 
01208   copy( m.begin(), m.end(), begin() );
01209   return *this;
01210 }
01211 
01214 inline Tensor3& Tensor3::operator=(Numeric x)
01215 {
01216   copy( x, begin(), end() );
01217   return *this;
01218 }
01219 
01223 inline void Tensor3::resize(Index p, Index r, Index c)
01224 {
01225   assert( 0<=p );
01226   assert( 0<=r );
01227   assert( 0<=c );
01228 
01229   if ( mpr.mextent!=p ||
01230        mrr.mextent!=r ||
01231        mcr.mextent!=c )
01232     {
01233       delete mdata;
01234       mdata = new Numeric[p*r*c];
01235 
01236       mpr.mstart = 0;
01237       mpr.mextent = p;
01238       mpr.mstride = r*c;
01239 
01240       mrr.mstart = 0;
01241       mrr.mextent = r;
01242       mrr.mstride = c;
01243 
01244       mcr.mstart = 0;
01245       mcr.mextent = c;
01246       mcr.mstride = 1;
01247     }
01248 }
01249 
01252 inline Tensor3::~Tensor3()
01253 {
01254 
01255 
01256   delete [] mdata;
01257 }
01258 
01259 
01275 inline void transform( Tensor3View y,
01276                        double (&my_func)(double),
01277                        ConstTensor3View x )
01278 {
01279   
01280   assert( y.npages() == x.npages() );
01281   assert( y.nrows()  == x.nrows()  );
01282   assert( y.ncols()  == x.ncols()  );
01283 
01284   const ConstIterator3D xe = x.end();
01285   ConstIterator3D       xi = x.begin();
01286   Iterator3D            yi = y.begin();
01287   for ( ; xi!=xe; ++xi, ++yi )
01288     {
01289       
01290       
01291       transform(*yi,my_func,*xi);
01292     }
01293 }
01294 
01296 inline Numeric max(const ConstTensor3View& x)
01297 {
01298   const ConstIterator3D xe = x.end();
01299   ConstIterator3D       xi = x.begin();
01300 
01301   
01302   Numeric themax = max(*xi);
01303   ++xi;
01304 
01305   for ( ; xi!=xe ; ++xi )
01306     {
01307       
01308       
01309       Numeric maxi = max(*xi);
01310       if ( maxi > themax )
01311         themax = maxi;
01312     }
01313 
01314   return themax;
01315 }
01316 
01318 inline Numeric min(const ConstTensor3View& x)
01319 {
01320   const ConstIterator3D xe = x.end();
01321   ConstIterator3D       xi = x.begin();
01322 
01323   
01324   Numeric themin = min(*xi);
01325   ++xi;
01326 
01327   for ( ; xi!=xe ; ++xi )
01328     {
01329       
01330       
01331       Numeric mini = min(*xi);
01332       if ( mini < themin )
01333         themin = mini;
01334     }
01335 
01336   return themin;
01337 }
01338 
01339 
01340 
01341 #endif    // matpackIII_h