File indexing completed on 2025-01-30 10:22:09
0001
0002
0003
0004 #ifndef ROOT_Math_SMatrix_icc
0005 #define ROOT_Math_SMatrix_icc
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 #ifndef ROOT_Math_SMatrix
0038 #error "Do not use SMatrix.icc directly. #include \"Math/SMatrix.h\" instead."
0039 #endif
0040
0041 #include <iostream>
0042 #include <iomanip>
0043 #include <assert.h>
0044
0045
0046
0047
0048
0049
0050 #include "Math/Dfact.h"
0051 #include "Math/Dinv.h"
0052 #include "Math/Functions.h"
0053 #include "Math/HelperOps.h"
0054 #include "Math/StaticCheck.h"
0055
0056
0057
0058
0059
0060
0061
0062 namespace ROOT {
0063
0064 namespace Math {
0065
0066
0067
0068
0069
0070
0071 template <class T, unsigned int D1, unsigned int D2, class R>
0072 SMatrix<T,D1,D2,R>::SMatrix() {
0073
0074 for(unsigned int i=0; i<R::kSize; ++i) fRep.Array()[i] = 0;
0075 }
0076
0077
0078 template <class T, unsigned int D1, unsigned int D2, class R>
0079 SMatrix<T,D1,D2,R>::SMatrix( SMatrixIdentity ) {
0080 for(unsigned int i=0; i<R::kSize; ++i)
0081 fRep.Array()[i] = 0;
0082 if (D1 <= D2) {
0083 for(unsigned int i=0; i<D1; ++i)
0084 fRep[i*D2+i] = 1;
0085 }
0086 else {
0087 for(unsigned int i=0; i<D2; ++i)
0088 fRep[i*D2+i] = 1;
0089 }
0090 }
0091
0092 template <class T, unsigned int D1, unsigned int D2, class R>
0093 SMatrix<T,D1,D2,R>::SMatrix(const SMatrix<T,D1,D2,R>& rhs) {
0094 fRep = rhs.fRep;
0095 }
0096
0097
0098 template <class T, unsigned int D1, unsigned int D2, class R>
0099 template <class R2>
0100 SMatrix<T,D1,D2,R>::SMatrix(const SMatrix<T,D1,D2,R2>& rhs) {
0101 operator=(rhs);
0102 }
0103
0104
0105 template <class T, unsigned int D1, unsigned int D2, class R>
0106 template <class A, class R2>
0107 SMatrix<T,D1,D2,R>::SMatrix(const Expr<A,T,D1,D2,R2>& rhs) {
0108 operator=(rhs);
0109 }
0110
0111
0112
0113
0114
0115 template <class T, unsigned int D1, unsigned int D2, class R>
0116 template <class InputIterator>
0117 SMatrix<T,D1,D2,R>::SMatrix(InputIterator ibegin, InputIterator iend, bool triang, bool lower) {
0118
0119 for(unsigned int i=0; i<R::kSize; ++i) fRep.Array()[i] = 0;
0120 AssignItr<T,D1,D2,R>::Evaluate(*this,ibegin,iend,triang,lower);
0121 }
0122
0123 template <class T, unsigned int D1, unsigned int D2, class R>
0124 template <class InputIterator>
0125 SMatrix<T,D1,D2,R>::SMatrix(InputIterator ibegin, unsigned int size, bool triang, bool lower) {
0126
0127 assert( size <= R::kSize);
0128 for(unsigned int i=0; i<R::kSize; ++i) fRep.Array()[i] = 0;
0129 AssignItr<T,D1,D2,R>::Evaluate(*this,ibegin,ibegin+size,triang,lower,false);
0130 }
0131
0132
0133
0134
0135
0136
0137 template <class T, unsigned int D1, unsigned int D2, class R>
0138 SMatrix<T,D1,D2,R>::SMatrix(const T& rhs) {
0139 STATIC_CHECK( kSize == 1,SMatrix_NOT_of_size_1 );
0140 fRep[0] = rhs;
0141 }
0142
0143 template <class T, unsigned int D1, unsigned int D2, class R>
0144 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator=(const T& rhs) {
0145 STATIC_CHECK( kSize == 1,SMatrix_NOT_of_size_1 );
0146 fRep[0] = rhs;
0147 return *this;
0148 }
0149
0150
0151
0152
0153 template <class T, unsigned int D1, unsigned int D2, class R>
0154 template <class M>
0155 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator=(const M& rhs) {
0156 fRep = rhs.fRep;
0157 return *this;
0158 }
0159
0160 template <class T, unsigned int D1, unsigned int D2, class R>
0161 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator=(const SMatrix<T,D1,D2,R>& rhs) {
0162 fRep = rhs.fRep;
0163 return *this;
0164 }
0165
0166 template <class T, unsigned int D1, unsigned int D2, class R>
0167 template <class A, class R2>
0168 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator=(const Expr<A,T,D1,D2,R2>& rhs) {
0169
0170 Assign<T,D1,D2,A,R,R2>::Evaluate(*this, rhs);
0171 return *this;
0172 }
0173
0174
0175
0176 template <class T, unsigned int D1, unsigned int D2, class R>
0177 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator= ( SMatrixIdentity ) {
0178 for(unsigned int i=0; i<R::kSize; ++i)
0179 fRep.Array()[i] = 0;
0180 if (D1 <= D2) {
0181 for(unsigned int i=0; i<D1; ++i)
0182 fRep[i*D2+i] = 1;
0183 }
0184 else {
0185 for(unsigned int i=0; i<D2; ++i)
0186 fRep[i*D2+i] = 1;
0187 }
0188 return *this;
0189 }
0190
0191
0192
0193
0194
0195
0196 template <class T, unsigned int D1, unsigned int D2, class R>
0197 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator+=(const T& rhs) {
0198
0199 for(unsigned int i=0; i<R::kSize; ++i) {
0200 fRep.Array()[i] += rhs;
0201 }
0202 return *this;
0203 }
0204
0205 template <class T, unsigned int D1, unsigned int D2, class R>
0206 template <class R2>
0207 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator+=(const SMatrix<T,D1,D2,R2>& rhs) {
0208
0209
0210 fRep += rhs.fRep;
0211 return *this;
0212 }
0213
0214
0215 template <class T, unsigned int D1, unsigned int D2, class R>
0216 template <class A, class R2>
0217 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator+=(const Expr<A,T,D1,D2,R2>& rhs) {
0218
0219 PlusEquals<T,D1,D2,A,R,R2>::Evaluate(*this, rhs);
0220 return *this;
0221 }
0222
0223
0224
0225
0226
0227 template <class T, unsigned int D1, unsigned int D2, class R>
0228 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator-=(const T& rhs) {
0229
0230 for(unsigned int i=0; i<R::kSize; ++i) {
0231 fRep.Array()[i] -= rhs;
0232 }
0233 return *this;
0234 }
0235
0236 template <class T, unsigned int D1, unsigned int D2, class R>
0237 template <class R2>
0238 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator-=(const SMatrix<T,D1,D2,R2>& rhs) {
0239
0240
0241 fRep -= rhs.fRep;
0242 return *this;
0243 }
0244
0245
0246 template <class T, unsigned int D1, unsigned int D2, class R>
0247 template <class A, class R2>
0248 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator-=(const Expr<A,T,D1,D2,R2>& rhs) {
0249
0250 MinusEquals<T,D1,D2,A,R,R2>::Evaluate(*this, rhs);
0251 return *this;
0252 }
0253
0254
0255
0256
0257 template <class T, unsigned int D1, unsigned int D2, class R>
0258 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator*=(const T& rhs) {
0259
0260 for(unsigned int i=0; i<R::kSize; ++i) {
0261 fRep.Array()[i] *= rhs;
0262 }
0263 return *this;
0264 }
0265
0266 template <class T, unsigned int D1, unsigned int D2, class R>
0267 template <class R2>
0268 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator*=(const SMatrix<T,D1,D2,R2>& rhs) {
0269
0270
0271 return operator=(*this * rhs);
0272 }
0273
0274 template <class T, unsigned int D1, unsigned int D2, class R>
0275 template <class A, class R2>
0276 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator*=(const Expr<A,T,D1,D2,R2>& rhs) {
0277
0278
0279 return operator=(*this * rhs);
0280 }
0281
0282
0283
0284
0285
0286 template <class T, unsigned int D1, unsigned int D2, class R>
0287 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::operator/=(const T& rhs) {
0288
0289 for(unsigned int i=0; i<R::kSize; ++i) {
0290 fRep.Array()[i] /= rhs;
0291 }
0292 return *this;
0293 }
0294
0295
0296
0297
0298 template <class T, unsigned int D1, unsigned int D2, class R>
0299 bool SMatrix<T,D1,D2,R>::operator==(const T& rhs) const {
0300 bool rc = true;
0301 for(unsigned int i=0; i<R::kSize; ++i) {
0302 rc = rc && (fRep.Array()[i] == rhs);
0303 }
0304 return rc;
0305 }
0306
0307 template <class T, unsigned int D1, unsigned int D2, class R>
0308 template <class R2>
0309 bool SMatrix<T,D1,D2,R>::operator==(const SMatrix<T,D1,D2,R2>& rhs) const {
0310 return fRep == rhs.fRep;
0311 }
0312
0313 template <class T, unsigned int D1, unsigned int D2, class R>
0314 template <class A, class R2>
0315 bool SMatrix<T,D1,D2,R>::operator==(const Expr<A,T,D1,D2,R2>& rhs) const {
0316 bool rc = true;
0317 for(unsigned int i=0; i<D1*D2; ++i) {
0318 rc = rc && (fRep[i] == rhs.apply(i));
0319 }
0320 return rc;
0321 }
0322
0323
0324
0325
0326 template <class T, unsigned int D1, unsigned int D2, class R>
0327 inline bool SMatrix<T,D1,D2,R>::operator!=(const T& rhs) const {
0328 return !operator==(rhs);
0329 }
0330
0331 template <class T, unsigned int D1, unsigned int D2, class R>
0332 inline bool SMatrix<T,D1,D2,R>::operator!=(const SMatrix<T,D1,D2,R>& rhs) const {
0333 return !operator==(rhs);
0334 }
0335
0336 template <class T, unsigned int D1, unsigned int D2, class R>
0337 template <class A, class R2>
0338 inline bool SMatrix<T,D1,D2,R>::operator!=(const Expr<A,T,D1,D2,R2>& rhs) const {
0339 return !operator==(rhs);
0340 }
0341
0342
0343
0344
0345
0346 template <class T, unsigned int D1, unsigned int D2, class R>
0347 bool SMatrix<T,D1,D2,R>::operator>(const T& rhs) const {
0348 bool rc = true;
0349 for(unsigned int i=0; i<D1*D2; ++i) {
0350 rc = rc && (fRep[i] > rhs);
0351 }
0352 return rc;
0353 }
0354
0355 template <class T, unsigned int D1, unsigned int D2, class R>
0356 template <class R2>
0357 bool SMatrix<T,D1,D2,R>::operator>(const SMatrix<T,D1,D2,R2>& rhs) const {
0358 bool rc = true;
0359 for(unsigned int i=0; i<D1*D2; ++i) {
0360 rc = rc && (fRep[i] > rhs.fRep[i]);
0361 }
0362 return rc;
0363 }
0364
0365 template <class T, unsigned int D1, unsigned int D2, class R>
0366 template <class A, class R2>
0367 bool SMatrix<T,D1,D2,R>::operator>(const Expr<A,T,D1,D2,R2>& rhs) const {
0368 bool rc = true;
0369 for(unsigned int i=0; i<D1*D2; ++i) {
0370 rc = rc && (fRep[i] > rhs.apply(i));
0371 }
0372 return rc;
0373 }
0374
0375
0376
0377
0378 template <class T, unsigned int D1, unsigned int D2, class R>
0379 bool SMatrix<T,D1,D2,R>::operator<(const T& rhs) const {
0380 bool rc = true;
0381 for(unsigned int i=0; i<D1*D2; ++i) {
0382 rc = rc && (fRep[i] < rhs);
0383 }
0384 return rc;
0385 }
0386
0387 template <class T, unsigned int D1, unsigned int D2, class R>
0388 template <class R2>
0389 bool SMatrix<T,D1,D2,R>::operator<(const SMatrix<T,D1,D2,R2>& rhs) const {
0390 bool rc = true;
0391 for(unsigned int i=0; i<D1*D2; ++i) {
0392 rc = rc && (fRep[i] < rhs.fRep[i]);
0393 }
0394 return rc;
0395 }
0396
0397 template <class T, unsigned int D1, unsigned int D2, class R>
0398 template <class A, class R2>
0399 bool SMatrix<T,D1,D2,R>::operator<(const Expr<A,T,D1,D2,R2>& rhs) const {
0400 bool rc = true;
0401 for(unsigned int i=0; i<D1*D2; ++i) {
0402 rc = rc && (fRep[i] < rhs.apply(i));
0403 }
0404 return rc;
0405 }
0406
0407
0408
0409
0410
0411 template <class T, unsigned int D1, unsigned int D2, class R>
0412 inline bool SMatrix<T,D1,D2,R>::Invert() {
0413 STATIC_CHECK( D1 == D2,SMatrix_not_square);
0414 return Inverter<D1,D2>::Dinv((*this).fRep);
0415 }
0416
0417
0418 template <class T, unsigned int D1, unsigned int D2, class R>
0419 inline SMatrix<T,D1,D2,R> SMatrix<T,D1,D2,R>::Inverse(int & ifail) const {
0420 SMatrix<T,D1,D2,R> tmp(*this);
0421 bool ok = tmp.Invert();
0422 ifail = 0;
0423 if (!ok) ifail = 1;
0424 return tmp;
0425 }
0426
0427
0428 template <class T, unsigned int D1, unsigned int D2, class R>
0429 inline bool SMatrix<T,D1,D2,R>::InvertFast() {
0430 STATIC_CHECK( D1 == D2,SMatrix_not_square);
0431 return FastInverter<D1,D2>::Dinv((*this).fRep);
0432 }
0433
0434
0435 template <class T, unsigned int D1, unsigned int D2, class R>
0436 inline SMatrix<T,D1,D2,R> SMatrix<T,D1,D2,R>::InverseFast(int & ifail) const {
0437 SMatrix<T,D1,D2,R> tmp(*this);
0438 bool ok = tmp.InvertFast();
0439 ifail = 0;
0440 if (!ok) ifail = 1;
0441 return tmp;
0442 }
0443
0444
0445 template <class T, unsigned int D1, unsigned int D2, class R>
0446 inline bool SMatrix<T,D1,D2, R>::InvertChol() {
0447 STATIC_CHECK( D1 == D2,SMatrix_not_square);
0448 return CholInverter<D1>::Dinv((*this).fRep);
0449 }
0450
0451 template <class T, unsigned int D1, unsigned int D2, class R>
0452 inline SMatrix<T,D1,D2, R> SMatrix<T,D1,D2, R>::InverseChol(int &ifail) const {
0453 SMatrix<T,D1,D2,R > tmp(*this);
0454 bool ok = tmp.InvertChol();
0455 ifail = 0;
0456 if (!ok) ifail = 1;
0457 return tmp;
0458 }
0459
0460
0461
0462
0463
0464
0465 template <class T, unsigned int D1, unsigned int D2, class R>
0466 inline bool SMatrix<T,D1,D2,R>::Det(T& det) {
0467 STATIC_CHECK( D1 == D2,SMatrix_not_square);
0468
0469
0470 return Determinant<D1,D2>::Dfact(fRep, det);
0471 }
0472 template <class T, unsigned int D1, unsigned int D2, class R>
0473 inline bool SMatrix<T,D1,D2,R>::Det2(T& det) const {
0474 SMatrix<T,D1,D2,R> tmp(*this);
0475 return tmp.Det(det);
0476 }
0477
0478
0479
0480
0481
0482 template <class T, unsigned int D1, unsigned int D2, class R>
0483 template <unsigned int D>
0484 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::Place_in_row(const SVector<T,D>& rhs,
0485 unsigned int row,
0486 unsigned int col) {
0487
0488 assert(col+D <= D2);
0489
0490 for(unsigned int i=row*D2+col, j=0; j<D; ++i, ++j) {
0491 fRep[i] = rhs.apply(j);
0492 }
0493 return *this;
0494 }
0495
0496
0497
0498
0499 template <class T, unsigned int D1, unsigned int D2, class R>
0500 template <class A, unsigned int D>
0501 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::Place_in_row(const VecExpr<A,T,D>& rhs,
0502 unsigned int row,
0503 unsigned int col) {
0504
0505 assert(col+D <= D2);
0506
0507 for(unsigned int i=row*D2+col, j=0; j<D; ++i, ++j) {
0508 fRep[i] = rhs.apply(j);
0509 }
0510 return *this;
0511 }
0512
0513
0514
0515
0516 template <class T, unsigned int D1, unsigned int D2, class R>
0517 template <unsigned int D>
0518 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::Place_in_col(const SVector<T,D>& rhs,
0519 unsigned int row,
0520 unsigned int col) {
0521
0522 assert(row+D <= D1);
0523
0524 for(unsigned int i=row*D2+col, j=0; j<D; i+=D2, ++j) {
0525 fRep[i] = rhs.apply(j);
0526 }
0527 return *this;
0528 }
0529
0530
0531
0532
0533 template <class T, unsigned int D1, unsigned int D2, class R>
0534 template <class A, unsigned int D>
0535 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::Place_in_col(const VecExpr<A,T,D>& rhs,
0536 unsigned int row,
0537 unsigned int col) {
0538
0539 assert(row+D <= D1);
0540
0541 for(unsigned int i=row*D2+col, j=0; j<D; i+=D2, ++j) {
0542 fRep[i] = rhs.apply(j);
0543 }
0544 return *this;
0545 }
0546
0547
0548
0549
0550 template <class T, unsigned int D1, unsigned int D2, class R>
0551 template <unsigned int D3, unsigned int D4, class R2>
0552 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::Place_at(const SMatrix<T,D3,D4,R2>& rhs,
0553 unsigned int row,
0554 unsigned int col) {
0555 PlaceMatrix<T,D1,D2,D3,D4,R,R2>::Evaluate(*this,rhs,row,col);
0556 return *this;
0557 }
0558
0559
0560
0561
0562 template <class T, unsigned int D1, unsigned int D2, class R>
0563 template <class A, unsigned int D3, unsigned int D4, class R2>
0564 SMatrix<T,D1,D2,R>& SMatrix<T,D1,D2,R>::Place_at(const Expr<A,T,D3,D4,R2>& rhs,
0565 unsigned int row,
0566 unsigned int col) {
0567 PlaceExpr<T,D1,D2,D3,D4,A,R,R2>::Evaluate(*this,rhs,row,col);
0568 return *this;
0569 }
0570
0571
0572
0573
0574 template <class T, unsigned int D1, unsigned int D2, class R>
0575 SVector<T,D2> SMatrix<T,D1,D2,R>::Row(unsigned int therow) const {
0576
0577 const unsigned int offset = therow*D2;
0578
0579 SVector<T,D2> tmp;
0580 for(unsigned int i=0; i<D2; ++i) {
0581 tmp[i] = fRep[offset+i];
0582 }
0583 return tmp;
0584 }
0585
0586
0587
0588
0589 template <class T, unsigned int D1, unsigned int D2, class R>
0590 SVector<T,D1> SMatrix<T,D1,D2,R>::Col(unsigned int thecol) const {
0591
0592 SVector<T,D1> tmp;
0593 for(unsigned int i=0; i<D1; ++i) {
0594 tmp[i] = fRep[thecol+i*D2];
0595 }
0596 return tmp;
0597 }
0598
0599
0600
0601
0602 template <class T, unsigned int D1, unsigned int D2, class R>
0603 std::ostream& SMatrix<T,D1,D2,R>::Print(std::ostream& os) const {
0604 const std::ios_base::fmtflags prevFmt = os.setf(std::ios::right,std::ios::adjustfield);
0605
0606
0607 os << "[ ";
0608 for (unsigned int i=0; i < D1; ++i) {
0609 for (unsigned int j=0; j < D2; ++j) {
0610 os << std::setw(12) << fRep[i*D2+j];
0611 if ((!((j+1)%12)) && (j < D2-1))
0612 os << std::endl << " ...";
0613 }
0614 if (i != D1 - 1)
0615 os << std::endl << " ";
0616 }
0617 os << " ]";
0618
0619 if (prevFmt != os.flags() ) os.setf(prevFmt, std::ios::adjustfield);
0620 return os;
0621 }
0622
0623
0624
0625
0626 template <class T, unsigned int D1, unsigned int D2, class R>
0627 inline T SMatrix<T,D1,D2,R>::apply(unsigned int i) const { return fRep[i]; }
0628
0629 template <class T, unsigned int D1, unsigned int D2, class R>
0630 inline const T* SMatrix<T,D1,D2,R>::Array() const { return fRep.Array(); }
0631
0632 template <class T, unsigned int D1, unsigned int D2, class R>
0633 inline T* SMatrix<T,D1,D2,R>::Array() { return fRep.Array(); }
0634
0635
0636
0637
0638 template <class T, unsigned int D1, unsigned int D2, class R>
0639 inline const T& SMatrix<T,D1,D2,R>::operator()(unsigned int i, unsigned int j) const {
0640 return fRep(i,j);
0641 }
0642
0643 template <class T, unsigned int D1, unsigned int D2, class R>
0644 inline T& SMatrix<T,D1,D2,R>::operator()(unsigned int i, unsigned int j) {
0645 return fRep(i,j);
0646 }
0647
0648
0649
0650
0651
0652 template <class T, unsigned int D1, unsigned int D2, class R>
0653 inline const T& SMatrix<T,D1,D2,R>::At(unsigned int i, unsigned int j) const {
0654 assert(i < D1);
0655 assert(j < D2);
0656 return fRep(i,j);
0657 }
0658
0659 template <class T, unsigned int D1, unsigned int D2, class R>
0660 inline T& SMatrix<T,D1,D2,R>::At(unsigned int i, unsigned int j) {
0661 assert(i < D1);
0662 assert(j < D2);
0663 return fRep(i,j);
0664 }
0665
0666
0667
0668
0669 template <class T, unsigned int D1, unsigned int D2, class R>
0670 inline T * SMatrix<T,D1,D2,R>::begin() {
0671 return fRep.Array();
0672 }
0673
0674 template <class T, unsigned int D1, unsigned int D2, class R>
0675 inline T * SMatrix<T,D1,D2,R>::end() {
0676 return fRep.Array() + R::kSize;
0677 }
0678
0679 template <class T, unsigned int D1, unsigned int D2, class R>
0680 inline const T * SMatrix<T,D1,D2,R>::begin() const {
0681 return fRep.Array();
0682 }
0683
0684 template <class T, unsigned int D1, unsigned int D2, class R>
0685 inline const T * SMatrix<T,D1,D2,R>::end() const {
0686 return fRep.Array() + R::kSize;
0687 }
0688
0689
0690 template <class T, unsigned int D1, unsigned int D2, class R>
0691 template <class InputIterator>
0692 void SMatrix<T,D1,D2,R>::SetElements(InputIterator ibegin, InputIterator iend, bool triang, bool lower) {
0693
0694 AssignItr<T,D1,D2,R>::Evaluate(*this,ibegin,iend,triang,lower);
0695 }
0696
0697 template <class T, unsigned int D1, unsigned int D2, class R>
0698 template <class InputIterator>
0699 void SMatrix<T,D1,D2,R>::SetElements(InputIterator ibegin, unsigned int size, bool triang, bool lower) {
0700
0701 assert( size <= R::kSize);
0702 AssignItr<T,D1,D2,R>::Evaluate(*this,ibegin,ibegin+size,triang,lower,false);
0703 }
0704
0705
0706
0707
0708
0709
0710 template <class T, unsigned int D1, unsigned int D2, class R>
0711 template <class SubVector>
0712 SubVector SMatrix<T,D1,D2,R>::SubRow(unsigned int therow, unsigned int col0 ) const {
0713
0714 const unsigned int offset = therow*D2 + col0;
0715
0716 STATIC_CHECK( SubVector::kSize <= D2,SVector_dimension_too_small);
0717 assert(col0 + SubVector::kSize <= D2);
0718
0719 SubVector tmp;
0720 for(unsigned int i=0; i<SubVector::kSize; ++i) {
0721 tmp[i] = fRep[offset+i];
0722 }
0723 return tmp;
0724 }
0725
0726 template <class T, unsigned int D1, unsigned int D2, class R>
0727 template <class SubVector>
0728 SubVector SMatrix<T,D1,D2,R>::SubCol(unsigned int thecol, unsigned int row0 ) const {
0729
0730 const unsigned int offset = thecol + row0*D1;
0731
0732 STATIC_CHECK( SubVector::kSize <= D1,SVector_dimension_too_small);
0733 assert(row0 + SubVector::kSize <= D1);
0734
0735 SubVector tmp;
0736 for(unsigned int i=0; i<SubVector::kSize; ++i) {
0737 tmp[i] = fRep[offset+i*D1];
0738 }
0739 return tmp;
0740 }
0741
0742
0743 template <class T, unsigned int D1, unsigned int D2, class R>
0744 template <class SubMatrix>
0745 SubMatrix SMatrix<T,D1,D2,R>::Sub(unsigned int row0, unsigned int col0) const {
0746
0747 SubMatrix tmp;
0748 RetrieveMatrix<T,SubMatrix::kRows, SubMatrix::kCols, D1, D2, typename SubMatrix::rep_type, R>::Evaluate
0749 (tmp,*this,row0,col0);
0750 return tmp;
0751 }
0752
0753
0754 template <class T, unsigned int D1, unsigned int D2, class R>
0755 SVector<T,D1> SMatrix<T,D1,D2,R>::Diagonal( ) const {
0756
0757
0758 STATIC_CHECK( D1 == D2,SMatrix_NOT_square );
0759
0760 SVector<T,D1> tmp;
0761 for(unsigned int i=0; i<D1; ++i) {
0762 tmp[i] = fRep[ i*D2 + i];
0763 }
0764 return tmp;
0765 }
0766
0767
0768 template <class T, unsigned int D1, unsigned int D2, class R>
0769 template <class Vector>
0770 void SMatrix<T,D1,D2,R>::SetDiagonal( const Vector & v) {
0771
0772
0773 STATIC_CHECK( ( ( D1 <= D2) && Vector::kSize == D1 ) ||
0774 ( ( D2 < D1 ) && Vector::kSize == D2 ), SVector_size_NOT_correct );
0775
0776
0777 for(unsigned int i=0; i<Vector::kSize; ++i) {
0778 fRep[ i*D2 + i] = v[i];
0779 }
0780 }
0781
0782
0783 template <class T, unsigned int D1, unsigned int D2, class R>
0784 T SMatrix<T,D1,D2,R>::Trace( ) const {
0785 unsigned int diagSize = D1;
0786 if (D2 < D1) diagSize = D2;
0787 T trace = 0;
0788 for(unsigned int i=0; i< diagSize; ++i) {
0789 trace += fRep[ i*D2 + i] ;
0790 }
0791 return trace;
0792 }
0793
0794
0795 template <class T, unsigned int D1, unsigned int D2, class R>
0796 #ifndef UNSUPPORTED_TEMPLATE_EXPRESSION
0797 SVector<T, D1 * (D2 +1)/2 > SMatrix<T,D1,D2,R>::UpperBlock( ) const {
0798 #else
0799 template <class SubVector>
0800 SubVector SMatrix<T,D1,D2,R>::UpperBlock( ) const {
0801 #endif
0802
0803 STATIC_CHECK( D1 == D2,SMatrix_NOT_square );
0804
0805 #ifndef UNSUPPORTED_TEMPLATE_EXPRESSION
0806 SVector<T, D1 * (D2 +1)/2 > tmp;
0807 #else
0808
0809 STATIC_CHECK( SubVector::kSize == D1*(D1+1)/2,SVector_Wrong_Size );
0810 SubVector tmp;
0811 #endif
0812
0813 int k = 0;
0814 for(unsigned int i=0; i<D1; ++i) {
0815 for(unsigned int j=i; j<D2; ++j) {
0816 tmp[k] = fRep[ i*D2 + j];
0817 k++;
0818 }
0819 }
0820 return tmp;
0821 }
0822
0823
0824 template <class T, unsigned int D1, unsigned int D2, class R>
0825 #ifndef UNSUPPORTED_TEMPLATE_EXPRESSION
0826 SVector<T, D1 * (D2 +1)/2 > SMatrix<T,D1,D2,R>::LowerBlock( ) const {
0827 #else
0828 template <class SubVector>
0829 SubVector SMatrix<T,D1,D2,R>::LowerBlock( ) const {
0830 #endif
0831
0832
0833 STATIC_CHECK( D1 == D2,SMatrix_NOT_square );
0834
0835 #ifndef UNSUPPORTED_TEMPLATE_EXPRESSION
0836 SVector<T, D1 * (D2 +1)/2 > tmp;
0837 #else
0838
0839 STATIC_CHECK( SubVector::kSize == D1*(D1+1)/2,SVector_Wrong_Size );
0840 SubVector tmp;
0841 #endif
0842
0843 int k = 0;
0844 for(unsigned int i=0; i<D1; ++i) {
0845 for(unsigned int j=0; j<=i; ++j) {
0846 tmp[k] = fRep[ i*D2 + j];
0847 k++;
0848 }
0849 }
0850 return tmp;
0851 }
0852
0853
0854
0855
0856 template <class T, unsigned int D1, unsigned int D2, class R>
0857 #ifndef UNSUPPORTED_TEMPLATE_EXPRESSION
0858 SMatrix<T,D1,D2,R>::SMatrix(const SVector<T, D1*(D2+1)/2 > & v, bool lower ) {
0859 #else
0860 template <unsigned int N>
0861 SMatrix<T,D1,D2,R>::SMatrix(const SVector<T, N > & v, bool lower ) {
0862 #endif
0863
0864
0865 STATIC_CHECK( D1 == D2,SMatrix_NOT_square );
0866
0867 #ifdef UNSUPPORTED_TEMPLATE_EXPRESSION
0868 STATIC_CHECK( N == D1*(D1+1)/2,SVector_Wrong_Size );
0869 #endif
0870
0871 int k = 0;
0872 if (lower) {
0873
0874 for(unsigned int i=0; i<D1; ++i) {
0875 for(unsigned int j=0; j<=i; ++j) {
0876 fRep[ i*D2 + j] = v[k];
0877 if ( i != j) fRep[ j*D2 + i] = v[k];
0878 k++;
0879 }
0880 }
0881 } else {
0882
0883 for(unsigned int i=0; i<D1; ++i) {
0884 for(unsigned int j=i; j<D2; ++j) {
0885 fRep[ i*D2 + j] = v[k];
0886 if ( i != j) fRep[ j*D2 + i] = v[k];
0887 k++;
0888 }
0889 }
0890 }
0891 }
0892
0893
0894 template <class T, unsigned int D1, unsigned int D2, class R>
0895 bool SMatrix<T,D1,D2,R>::IsInUse( const T * p) const {
0896 return p == fRep.Array();
0897 }
0898
0899
0900
0901
0902 }
0903
0904 }
0905
0906
0907
0908 #endif