00001
00006
00007
00008
00009
00010
00011
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());
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) {
00141 i_size = CTBmin(mi_ncol-i_dia,mi_nrow);
00142 p_data = m_rbuf + i_dia;
00143 } else {
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;
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) {
00244 if (i_nrow < mi_nrow) {
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) {
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 {
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);
00259 m_rbuf.Resize(i_nrow*i_ncol);
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) {
00283 if (i_nrow < mi_nrow) {
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) {
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 {
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);
00298 m_rbuf.Resize(i_nrow*i_ncol);
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());
00335 m_rbuf.DestructRange(0,i_size);
00336 m_rbuf.Resize(0);
00337 m_rbuf.Grab(rhs.m_rbuf);
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();
00441 CTBrawBuffer<T> old_rbuf(m_rbuf,true);
00442
00443 m_rbuf.Resize(i_cap);
00444
00445 for (CTBint i = 0; i < i_size; i++) {
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