Main Page   Modules   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages   Examples  

CTBmatrix.cxx

Go to the documentation of this file.
00001 
00006 /*----------------------------------------------------------------------------*/
00007 /* C Tool Box: Designed and implemented by:                                   */
00008 /*    Walter F.J. Mueller   Gesellschaft fuer Schwerionenforschung (GSI)      */
00009 /*                          Planckstrasse 1, D-64291 Darmstadt, Germany       */
00010 /*                  Email:  W.F.J.Mueller@gsi.de                              */
00011 /*                  WWW:    http://www-kp3.gsi.de/www/kp3/people/mueller.html */
00012 /*------------------------------------------+---------------------------------*/
00013 
00014 #include <assert.h>
00015 
00016 #include "CTB.hxx"
00017 #include "CTB_Trace.hxx"
00018 #include "CTBnum.hxx"
00019 #include "CTBosFill.hxx"
00020 #include "CTBexceptionIndexRange.hxx"
00021 #include "CTBswap.hxx"
00022 #include "CTBmatrix.hxx"
00023 
00042 //------------------------------------------+-----------------------------------
00044 
00045 template <class T>
00046 CTBmatrix<T>::CTBmatrix(CTBint i_nrow, CTBint i_ncol)
00047   : m_rbuf(i_nrow*i_ncol),
00048     mi_nrow(0),
00049     mi_ncol(0)
00050 {
00051   CTB_Trace("CTBmatrix(CTBint,CTBint)");
00052 
00053   m_rbuf.ConstructRange(0,i_nrow*i_ncol);
00054   mi_nrow = i_nrow;
00055   mi_ncol = i_ncol;
00056 }
00057 
00058 //------------------------------------------+-----------------------------------
00060 
00061 template <class T>
00062 CTBmatrix<T>::CTBmatrix(CTBint i_nrow, CTBint i_ncol, const T& def)
00063   : m_rbuf(i_nrow*i_ncol),
00064     mi_nrow(0),
00065     mi_ncol(0)
00066 {
00067   CTB_Trace("CTBmatrix(CTBint,CTBint,const T&)");
00068 
00069   m_rbuf.ConstructRange(0,i_nrow*i_ncol,def);
00070   mi_nrow = i_nrow;
00071   mi_ncol = i_ncol;
00072 }
00073 
00074 //------------------------------------------+-----------------------------------
00076 
00077 template <class T>
00078 CTBmatrix<T>::CTBmatrix(CTBint i_nrow, CTBint i_ncol,
00079                         const T& def, const T& defdiag)
00080   : m_rbuf(i_nrow*i_ncol),
00081     mi_nrow(0),
00082     mi_ncol(0)
00083 {
00084   CTB_Trace("CTBmatrix(CTBint,CTBint,const T&,const T&)");
00085   CTBint i_quad = CTBmin(i_nrow,i_ncol);
00086 
00087   m_rbuf.ConstructRange(0,i_nrow*i_ncol,def);
00088   mi_nrow = i_nrow;
00089   mi_ncol = i_ncol;
00090   for (CTBint i = 0; i < i_quad; i++) m_rbuf[i*mi_ncol + i] = defdiag;
00091 }
00092 
00093 //------------------------------------------+-----------------------------------
00095 
00096 template <class T>
00097 CTBmatrix<T>::CTBmatrix(const CTBmatrix<T>& rhs)
00098   : m_rbuf(rhs.Size()),
00099     mi_nrow(0),
00100     mi_ncol(0)
00101 {
00102   CTB_Trace("CTBmatrix(const CTBmatrix&)");
00103 
00104   m_rbuf.ConstructRange(0,rhs.Size(),(const T*) rhs);
00105   mi_nrow = rhs.mi_nrow;
00106   mi_ncol = rhs.mi_ncol;
00107 }
00108 
00109 //------------------------------------------+-----------------------------------
00111 
00112 template <class T>
00113 CTBmatrix<T>::~CTBmatrix()
00114 {
00115   CTB_Trace("~CTBmatrix()");
00116   CTBint i_size = Size();
00117   
00118   assert(i_size <= m_rbuf.Capacity());      // !?! size <= capacity
00119   m_rbuf.DestructRange(0,i_size);
00120 }
00121 
00122 //------------------------------------------+-----------------------------------
00124 
00133 template <class T>
00134 CTBvectorDsc<T> CTBmatrix<T>::Diagonal(CTBint i_dia)
00135 {
00136   CTB_Trace("CTBmatrix::Diagonal(CTBint)");
00137   CTBint i_size;
00138   T*     p_data;
00139   
00140   if (i_dia >= 0) {                         // upper triangle
00141     i_size = CTBmin(mi_ncol-i_dia,mi_nrow);
00142     p_data = m_rbuf + i_dia;
00143   } else {                                  // lower triangle
00144     i_size = CTBmin(mi_nrow+i_dia,mi_ncol);
00145     p_data = m_rbuf + (-i_dia*mi_ncol);
00146   }
00147 
00148   if (i_size < 0) i_size = 0;               // non existing diagonal requested
00149 
00150   return CTBvectorDsc<T>(p_data,i_size,mi_ncol+1);
00151 }
00152 
00153 //------------------------------------------+-----------------------------------
00155 
00156 template <class T>
00157 void CTBmatrix<T>::SwapRow(CTBint i_r1, CTBint i_r2)
00158 {
00159   CTB_Trace("CTBmatrix::SwapRow(CTBint,CTBint)");
00160 
00161   if (i_r1 >= 0 && i_r1 < mi_nrow && 
00162       i_r2 >= 0 && i_r2 < mi_nrow &&
00163       i_r1 != i_r2) {
00164     T* p_r1 = &m_rbuf[i_r1*mi_ncol];
00165     T* p_r2 = &m_rbuf[i_r2*mi_ncol];
00166 
00167     for (CTBint j=0; j < mi_ncol; j++) {
00168       CTBswap(*p_r1,*p_r2);
00169       p_r1 += 1;
00170       p_r2 += 1;
00171     }
00172   }
00173 
00174   return;
00175 }
00176 
00177 //------------------------------------------+-----------------------------------
00179 
00180 template <class T>
00181 void CTBmatrix<T>::SwapColumn(CTBint i_c1, CTBint i_c2)
00182 {
00183   CTB_Trace("CTBmatrix::SwapColumn(CTBint,CTBint)");
00184 
00185   if (i_c1 >= 0 && i_c1 < mi_ncol && 
00186       i_c2 >= 0 && i_c2 < mi_ncol &&
00187       i_c1 != i_c2) {
00188     T* p_c1 = &m_rbuf[i_c1];
00189     T* p_c2 = &m_rbuf[i_c2];
00190 
00191     for (CTBint i=0; i < mi_nrow; i++) {
00192       CTBswap(*p_c1,*p_c2);
00193       p_c1 += mi_ncol;
00194       p_c2 += mi_ncol;
00195     }
00196   }
00197 
00198   return;
00199 }
00200 
00201 //------------------------------------------+-----------------------------------
00203 
00207 template <class T>
00208 T& CTBmatrix<T>::At(CTBint i_row, CTBint i_col)
00209 {
00210   CTB_Trace("CTBmatrix::At(CTBint,CTBint)");
00211   if (i_row < 0 || i_row >= mi_nrow) 
00212     throw CTBexceptionIndexRange(i_row,mi_nrow,"CTBmatrix::At(irow,...)");
00213   if (i_col < 0 || i_col >= mi_ncol) 
00214     throw CTBexceptionIndexRange(i_col,mi_ncol,"CTBmatrix::At(...,icol)");
00215   return m_rbuf[i_row*mi_ncol + i_col];
00216 }
00217 
00218 //------------------------------------------+-----------------------------------
00220 
00224 template <class T>
00225 const T& CTBmatrix<T>::At(CTBint i_row, CTBint i_col) const
00226 {
00227   CTB_Trace("CTBmatrix::At(CTBint,CTBint)");
00228   if (i_row < 0 || i_row >= mi_nrow) 
00229     throw CTBexceptionIndexRange(i_row,mi_nrow,"CTBmatrix::At(irow,...)");
00230   if (i_col < 0 || i_col >= mi_ncol) 
00231     throw CTBexceptionIndexRange(i_col,mi_ncol,"CTBmatrix::At(...,icol)");
00232   return m_rbuf[i_row*mi_ncol + i_col];
00233 }
00234 
00235 //------------------------------------------+-----------------------------------
00237 
00238 template <class T>
00239 void CTBmatrix<T>::Resize(CTBint i_nrow, CTBint i_ncol)
00240 {
00241   CTB_Trace("CTBmatrix::Resize(CTBint,CTBint)");
00242 
00243   if (mi_ncol == i_ncol) {                  // number of columns unchanged
00244     if (i_nrow < mi_nrow) {                 // downsize number of rows
00245       m_rbuf.DestructRange(i_nrow*mi_ncol,(mi_nrow-i_nrow)*mi_ncol);
00246       mi_nrow = i_nrow;
00247     } else if (i_nrow > mi_nrow) {          // upsize number of rows
00248       if (i_nrow*mi_ncol > Capacity()) ChangeCapacity(i_nrow*mi_ncol);
00249       m_rbuf.ConstructRange(mi_nrow*mi_ncol,(i_nrow-mi_nrow)*mi_ncol);
00250       mi_nrow = i_nrow;
00251     }
00252     
00253   } else {                                  // number of columns changed
00254     CTBint i_rmin = CTBmin(i_nrow,mi_nrow);
00255     CTBint i_cmin = CTBmin(i_ncol,mi_ncol);
00256     CTBrawBuffer<T> old_rbuf;
00257 
00258     old_rbuf.Grab(m_rbuf);                  // grab old data array
00259     m_rbuf.Resize(i_nrow*i_ncol);           // allocate a new one
00260 
00261     for (CTBint i_row = 0; i_row < i_rmin; i_row++) {
00262       m_rbuf.GrabConstructRange(i_row*i_ncol,i_cmin,old_rbuf+i_row*mi_ncol);
00263       m_rbuf.ConstructRange(i_row*i_ncol+i_cmin,i_ncol-i_cmin);
00264     }
00265     old_rbuf.DestructRange(0,mi_nrow*mi_ncol);
00266     m_rbuf.ConstructRange(i_rmin*i_ncol,(i_nrow-i_rmin)*i_ncol);
00267     mi_nrow = i_nrow;
00268     mi_ncol = i_ncol;
00269   }
00270 
00271   return;
00272 }
00273 
00274 //------------------------------------------+-----------------------------------
00276 
00277 template <class T>
00278 void CTBmatrix<T>::Resize(CTBint i_nrow, CTBint i_ncol, const T& def)
00279 {
00280   CTB_Trace("CTBmatrix::Resize(CTBint,CTBint,const T&)");
00281 
00282   if (mi_ncol == i_ncol) {                  // number of columns unchanged
00283     if (i_nrow < mi_nrow) {                 // downsize number of rows
00284       m_rbuf.DestructRange(i_nrow*mi_ncol,(mi_nrow-i_nrow)*mi_ncol);
00285       mi_nrow = i_nrow;
00286     } else if (i_nrow > mi_nrow) {          // upsize number of rows
00287       if (i_nrow*mi_ncol > Capacity()) ChangeCapacity(i_nrow*mi_ncol);
00288       m_rbuf.ConstructRange(mi_nrow*mi_ncol,(i_nrow-mi_nrow)*mi_ncol,def);
00289       mi_nrow = i_nrow;
00290     }
00291     
00292   } else {                                  // number of columns changed
00293     CTBint i_rmin = CTBmin(i_nrow,mi_nrow);
00294     CTBint i_cmin = CTBmin(i_ncol,mi_ncol);
00295     CTBrawBuffer<T> old_rbuf;
00296 
00297     old_rbuf.Grab(m_rbuf);                  // grab old data array
00298     m_rbuf.Resize(i_nrow*i_ncol);           // allocate a new one
00299 
00300     for (CTBint i_row = 0; i_row < i_rmin; i_row++) {
00301       m_rbuf.GrabConstructRange(i_row*i_ncol,i_cmin,old_rbuf+i_row*mi_ncol);
00302       m_rbuf.ConstructRange(i_row*i_ncol+i_cmin,i_ncol-i_cmin,def);
00303     }
00304     old_rbuf.DestructRange(0,mi_nrow*mi_ncol);
00305     m_rbuf.ConstructRange(i_rmin*i_ncol,(i_nrow-i_rmin)*i_ncol,def);
00306     mi_nrow = i_nrow;
00307     mi_ncol = i_ncol;
00308   }
00309 
00310   return;
00311 }
00312 
00313 //------------------------------------------+-----------------------------------
00315 
00316 template <class T>
00317 void CTBmatrix<T>::IncreaseCapacity(CTBint i_cap)
00318 {
00319   if (i_cap > Capacity()) ChangeCapacity(CTBmax(i_cap,CTBmax(4,2*Capacity())));
00320   return;
00321 }
00322 
00323 //------------------------------------------+-----------------------------------
00325 
00329 template <class T>
00330 void CTBmatrix<T>::Grab(CTBmatrix<T>& rhs)
00331 {
00332   CTBint i_size = Size();
00333   
00334   assert(i_size <= m_rbuf.Capacity());      // !?! size <= capacity
00335   m_rbuf.DestructRange(0,i_size);           // destroy old stuff
00336   m_rbuf.Resize(0);                         // drop old buffer
00337   m_rbuf.Grab(rhs.m_rbuf);                  // finally grab rhs
00338   mi_nrow     = rhs.mi_nrow;
00339   mi_ncol     = rhs.mi_ncol;
00340   rhs.mi_nrow = 0;
00341   rhs.mi_ncol = 0;
00342   return;
00343 }
00344 
00345 //------------------------------------------+-----------------------------------
00347 
00348 template <class T>
00349 void CTBmatrix<T>::Dump(int i_indent, ostream& os, const char* p_text) const
00350 {
00351   CTBosFill bl(i_indent);
00352   
00353   os << bl << "--CTBmatrix<T> ";
00354   if (p_text) os << p_text;
00355   os << " @ " << this << endl;
00356   os << bl << "  mi_nrow:       " << mi_nrow << endl;
00357   os << bl << "  mi_ncol:       " << mi_ncol << endl;
00358   m_rbuf.Dump(i_indent+2,os);
00359   return;
00360 }
00361 
00362 //------------------------------------------+-----------------------------------
00364 
00365 template <class T>
00366 CTBmatrix<T>& CTBmatrix<T>::operator=(const T& rhs)
00367 {
00368   CTB_Trace("CTBmatrix::operator=(const T&)");
00369 
00370   m_rbuf.Copy(0,Size(),rhs);
00371   return *this;
00372 }
00373 
00374 //------------------------------------------+-----------------------------------
00376 
00385 template <class T>
00386 CTBmatrix<T>& CTBmatrix<T>::operator=(const CTBmatrix<T>& rhs)
00387 {
00388   CTB_Trace("CTBmatrix::operator=(const CTBmatrix&)");
00389 
00390   m_rbuf.DestructRange(0,Size());
00391   mi_nrow = 0;
00392   mi_ncol = 0;
00393   
00394   EnsureCapacity(rhs.Size());
00395 
00396   m_rbuf.ConstructRange(0,rhs.Size(),(const T*) rhs);
00397   mi_nrow = rhs.mi_nrow;
00398   mi_ncol = rhs.mi_ncol;
00399   return *this;
00400 }
00401 
00402 //------------------------------------------+-----------------------------------
00404  
00405 template <class T>
00406 CTBmatrix<T>& CTBmatrix<T>::operator=(const CTBmatrixCDsc<T>& rhs)
00407 {
00408   CTB_Trace("CTBmatrix::operator=(const CTBmatrixCDsc&)");
00409   CTBint i_nrow = rhs.NRow();
00410   CTBint i_ncol = rhs.NColumn();
00411   CTBint i_size = i_nrow * i_ncol;
00412   T*     p_ele;
00413 
00414   m_rbuf.DestructRange(0,Size());
00415   mi_nrow = 0;
00416   mi_ncol = 0;
00417   
00418   EnsureCapacity(i_size);
00419 
00420   p_ele = m_rbuf;
00421   for (CTBint i = 0; i < i_nrow; i++) {
00422     for (CTBint j = 0; j < i_ncol; j++) {
00423       m_rbuf.Construct(p_ele,rhs(i,j));
00424       p_ele += 1;
00425     }
00426   }
00427   
00428   mi_nrow = i_nrow;
00429   mi_ncol = i_ncol;
00430   return *this;
00431 }
00432 
00433 //------------------------------------------+-----------------------------------
00435 
00436 template <class T>
00437 void CTBmatrix<T>::ChangeCapacity(CTBint i_cap)
00438 {
00439   CTB_Trace("CTBmatrix::ChangeCapacity(CTBint)");
00440   CTBint i_size = Size();                   // matrix size
00441   CTBrawBuffer<T> old_rbuf(m_rbuf,true);    // grab old rawbuffer
00442 
00443   m_rbuf.Resize(i_cap);                     // new buffer
00444 
00445   for (CTBint i = 0; i < i_size; i++) {     // copy and release elements
00446     m_rbuf.GrabConstruct(i,old_rbuf[i]);
00447     old_rbuf.Destruct(i);
00448   }
00449   return;
00450 }
00451 
00452 //------------------------------------------+-----------------------------------
00453 #if (defined(CTB__NoInline) || defined(CTBmatrix__NoInline))
00454 #define inline
00455 #include "CTBmatrix.icc"
00456 #undef  inline
00457 #endif

Generated at Fri Oct 24 18:11:29 2003 for CTBbase by doxygen1.2.9-20010812 written by Dimitri van Heesch, © 1997-2001