00001
00015 #ifndef FMAT_H
00016 #define FMAT_H
00017
00018 #include "vec.h"
00019 #include <stdlib.h>
00020 #include <assert.h>
00021
00022 #ifdef TNT_USE_REGIONS
00023 #include "region2d.h"
00024 #endif
00025
00027 template <class T>
00028 class Fortran_matrix
00029 {
00030 public:
00031
00032 typedef T value_type;
00033 typedef T element_type;
00034 typedef T* pointer;
00035 typedef T* iterator;
00036 typedef T& reference;
00037 typedef const T* const_iterator;
00038 typedef const T& const_reference;
00039
00040 Subscript lbound() const { return 1;}
00041
00042 enum AllocMode {INTERNAL_ALLOC, EXTERNAL_ALLOC} amode;
00043
00044
00045
00046
00047
00048 protected:
00049 T* v_;
00050 Subscript m_;
00051 Subscript n_;
00052 T** col_;
00053
00054 int MaxSize;
00055
00056
00057
00058
00059
00061 void initialize(Subscript M, Subscript N)
00062 {
00063
00064
00065
00066
00067
00068 if(M == 0 || N == 0)
00069 {
00070 m_ = 0;
00071 n_ = 0;
00072 v_ = NULL;
00073 col_= NULL;
00074 return ;
00075 }
00076
00077 if(amode == INTERNAL_ALLOC) v_ = new T[M*N];
00078 if(amode == EXTERNAL_ALLOC) assert( (M*N) <= this->MaxSize);
00079
00080 col_ = new T*[N];
00081
00082 assert(v_ != NULL);
00083 assert(col_ != NULL);
00084
00085
00086 m_ = M;
00087 n_ = N;
00088 T* p = v_ - 1;
00089 for (Subscript i=0; i<N; i++)
00090 {
00091 col_[i] = p;
00092 p += M ;
00093
00094 }
00095 col_ --;
00096 }
00097
00098 void copy(const T* v)
00099 {
00100 Subscript N = m_ * n_;
00101 Subscript i;
00102
00103 #ifdef TNT_UNROLL_LOOPS
00104 Subscript Nmod4 = N & 4;
00105 Subscript N4 = N - Nmod4;
00106
00107 for (i=0; i<N4; i+=4)
00108 {
00109 v_[i] = v[i];
00110 v_[i+1] = v[i+1];
00111 v_[i+2] = v[i+2];
00112 v_[i+3] = v[i+3];
00113 }
00114
00115 for (i=N4; i< N; i++)
00116 v_[i] = v[i];
00117 #else
00118
00119 for (i=0; i< N; i++)
00120 v_[i] = v[i];
00121 #endif
00122 }
00123
00125 void set(const T& val)
00126 {
00127 Subscript N = m_ * n_;
00128 Subscript i;
00129
00130 #ifdef TNT_UNROLL_LOOPS
00131 Subscript Nmod4 = N & 4;
00132 Subscript N4 = N - Nmod4;
00133
00134 for (i=0; i<N4; i+=4)
00135 {
00136 v_[i] = val;
00137 v_[i+1] = val;
00138 v_[i+2] = val;
00139 v_[i+3] = val;
00140 }
00141
00142 for (i=N4; i< N; i++)
00143 v_[i] = val;
00144 #else
00145
00146 for (i=0; i< N; i++)
00147 v_[i] = val;
00148
00149 #endif
00150 }
00151
00152
00153
00154 void destroy()
00155 {
00156
00157 if (v_ == NULL) return ;
00158
00159
00160 if(amode == INTERNAL_ALLOC)
00161 {
00162 delete [] (v_);
00163 }
00164 col_ ++;
00165 delete [] (col_);
00166 }
00167
00168
00169 public:
00170
00171 T* begin() { return v_; }
00172 const T* begin() const { return v_;}
00173
00174 T* end() { return v_ + m_*n_; }
00175 const T* end() const { return v_ + m_*n_; }
00176
00177
00178
00179
00180 Fortran_matrix() : v_(0), m_(0), n_(0), col_(0),
00181 amode(INTERNAL_ALLOC), MaxSize(0) {}
00182
00183 Fortran_matrix(const Fortran_matrix<T> & A)
00184 {
00185 amode=INTERNAL_ALLOC;
00186 MaxSize = 0;
00187 initialize(A.m_, A.n_);
00188 copy(A.v_);
00189 }
00190
00191 Fortran_matrix(Subscript M, Subscript N, const T& value = T(0))
00192 {
00193 amode=INTERNAL_ALLOC; MaxSize=0;
00194 initialize(M,N);
00195 set(value);
00196 }
00197
00198 Fortran_matrix(Subscript M, Subscript N, T* v,
00199 const int New_amode=0)
00200 {
00201 Set_amode(New_amode);
00202 if(amode == EXTERNAL_ALLOC)
00203 {
00204 MaxSize=M*N;
00205 v_= v;
00206 }
00207 initialize(M,N);
00208 if(amode == INTERNAL_ALLOC) copy(v);
00209 }
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226 Fortran_matrix(Subscript M, Subscript N, char *s)
00227 {
00228 amode=INTERNAL_ALLOC;
00229 initialize(M,N);
00230 istrstream ins(s);
00231
00232 Subscript i, j;
00233
00234 for (i=1; i<=M; i++)
00235 for (j=1; j<=N; j++)
00236 ins >> (*this)(i,j);
00237 }
00238
00239
00240 ~Fortran_matrix()
00241 {
00242 destroy();
00243 }
00244
00245
00246
00247
00248 Fortran_matrix<T>& operator=(const Fortran_matrix<T> &A)
00249 {
00250 if (v_ == A.v_)
00251 return *this;
00252
00253 if (m_ == A.m_ && n_ == A.n_)
00254 copy(A.v_);
00255
00256 else
00257 {
00258 destroy();
00259 initialize(A.m_, A.n_);
00260 copy(A.v_);
00261 }
00262
00263 return *this;
00264 }
00265
00266 Fortran_matrix<T>& operator=(const T& scalar)
00267 {
00268 set(scalar);
00269 return *this;
00270 }
00271
00272
00273 Subscript dim(Subscript d) const
00274 {
00275 #ifdef TNT_BOUNDS_CHECK
00276 assert( d >= 1);
00277 assert( d <= 2);
00278 #endif
00279 return (d==1) ? m_ : ((d==2) ? n_ : 0);
00280 }
00281
00282 Subscript num_rows() const { return m_; }
00283 Subscript num_cols() const { return n_; }
00284
00286 void newsize(Subscript M, Subscript N)
00287 {
00288 if (num_rows() == M && num_cols() == N)
00289 return;
00290
00291 destroy();
00292 initialize(M,N);
00293
00294 return;
00295 }
00296
00298 void Set_amode(int mode)
00299 {
00300 assert(mode == 0 || mode == 1);
00301 if(mode == 0) amode=INTERNAL_ALLOC;
00302 if(mode == 1) amode=EXTERNAL_ALLOC;
00303 }
00304
00305 void SetMaxSize(const int NewMaxSize)
00306 {
00307 MaxSize=NewMaxSize;
00308 }
00309
00310
00312 inline reference operator()(Subscript i, Subscript j)
00313 {
00314 #ifdef TNT_BOUNDS_CHECK
00315 assert(1<=i);
00316 assert(i <= m_) ;
00317 assert(1<=j);
00318 assert(j <= n_);
00319 #endif
00320 return col_[j][i];
00321 }
00322
00323 inline const_reference operator() (Subscript i, Subscript j) const
00324 {
00325 #ifdef TNT_BOUNDS_CHECK
00326 assert(1<=i);
00327 assert(i <= m_) ;
00328 assert(1<=j);
00329 assert(j <= n_);
00330 #endif
00331 return col_[j][i];
00332 }
00333
00335 inline reference operator[](Subscript i)
00336 {
00337 #ifdef TNT_BOUNDS_CHECK
00338 assert(0 <= i);
00339 assert(i < m_*n_) ;
00340 #endif
00341 return v_[i];
00342 }
00343
00344 inline const_reference operator[] (Subscript i) const
00345 {
00346 #ifdef TNT_BOUNDS_CHECK
00347 assert(0 <= i);
00348 assert(i < m_*n_) ;
00349 #endif
00350 return v_[i];
00351 }
00352
00353 inline value_type GetVal(Subscript i, Subscript j) const
00354 {
00355 #ifdef TNT_BOUNDS_CHECK
00356 assert(1<=i);
00357 assert(i <= m_) ;
00358 assert(1<=j);
00359 assert(j <= n_);
00360 #endif
00361 return col_[j][i];
00362 }
00363
00364 inline void SetVal(Subscript i, Subscript j, const value_type new_val)
00365 {
00366 #ifdef TNT_BOUNDS_CHECK
00367 assert(1<=i);
00368 assert(i <= m_) ;
00369 assert(1<=j);
00370 assert(j <= n_);
00371 #endif
00372 col_[j][i] = new_val;
00373 }
00374
00375 inline value_type GetVal_lidx(Subscript i) const
00376 {
00377 #ifdef TNT_BOUNDS_CHECK
00378 assert(1<=i);
00379 assert(i <= m_*n_) ;
00380 #endif
00381 return v_[i];
00382 }
00383
00384 inline void SetVal_lidx(Subscript i, const value_type new_val)
00385 {
00386 #ifdef TNT_BOUNDS_CHECK
00387 assert(1<=i);
00388 assert(i <= m_*n_) ;
00389 #endif
00390 v_[i] = new_val;
00391 }
00392
00393
00394
00395
00396
00397 #if defined(_MSC_VER) || defined(__xlC__)
00398 friend istream& operator>>(istream &s, Fortran_matrix<T> &A);
00399 #else
00400
00401 friend istream& operator>><>(istream &s, Fortran_matrix<T> &A);
00402 #endif
00403
00404 #ifdef TNT_USE_REGIONS
00405
00406 typedef Region2D<Fortran_matrix<T> > Region;
00407 typedef const_Region2D<Fortran_matrix<T>,T > const_Region;
00408
00409 Region operator()(const Index1D &I, const Index1D &J)
00410 {
00411 return Region(*this, I,J);
00412 }
00413
00414 const_Region operator()(const Index1D &I, const Index1D &J) const
00415 {
00416 return const_Region(*this, I,J);
00417 }
00418
00419 #endif
00420
00421
00422 int Print_format(ostream &sout, const char* format) const
00423 {
00424
00425 char buf[120];
00426
00427 sout << m_ << " " << n_ << endl;
00428
00429 for (Subscript i=1; i<= m_; i++)
00430 {
00431 for (Subscript j=1; j<= n_; j++)
00432 {
00433 sprintf(buf, format, (*this)(i,j) );
00434 sout << buf;
00435 }
00436 sout << endl;
00437 }
00438
00439 return 0;
00440 }
00441
00442 int GetSymmPart(pointer dsymm)
00443
00444 {
00445 assert(dsymm != NULL);
00446 assert(m_ == n_);
00447
00448 for (Subscript i=1; i<= m_; i++)
00449 {
00450 for (Subscript j=1; j<= i; j++)
00451 {
00452 (*dsymm)= ((*this)(i,j) + (*this)(j,i))/2;
00453 dsymm++;
00454 }
00455 }
00456 return 1;
00457 }
00458
00459 int GetASymmPart(pointer dasymm)
00460
00461
00462 {
00463 assert(dasymm != NULL);
00464 assert(m_ == n_);
00465
00466 for (Subscript i=1; i<= m_; i++)
00467 {
00468 for (Subscript j=1; j<= i; j++)
00469 {
00470 (*dasymm)= ((*this)(i,j) - (*this)(j,i))/2;
00471 dasymm++;
00472 }
00473 }
00474 return 1;
00475 }
00476
00477 int AddSymmPart(pointer dsymm)
00478
00479
00480 {
00481 assert(dsymm != NULL);
00482 assert(m_ == n_);
00483
00484 for (Subscript i=1; i<= m_; i++)
00485 {
00486 for (Subscript j=1; j<= i; j++)
00487 {
00488 (*this)(i,j)+= (*dsymm);
00489 if(i != j) (*this)(j,i)+= (*dsymm);
00490 dsymm++;
00491 }
00492 }
00493 return 1;
00494 }
00495
00496 int AddASymmPart(pointer dasymm)
00497
00498
00499 {
00500 assert(dasymm != NULL);
00501 assert(m_ == n_);
00502
00503 for (Subscript i=1; i<= m_; i++)
00504 {
00505 for (Subscript j=1; j<= i; j++)
00506 {
00507 (*this)(i,j)-= (*dasymm);
00508 (*this)(j,i)+= (*dasymm);
00509 dasymm++;
00510 }
00511 }
00512 return 1;
00513 }
00514
00515 int Symmetrize()
00516
00517 {
00518 assert(m_ == n_);
00519 if(m_ == 0)
00520 return 1;
00521 for(Subscript i=1; i <= m_; i++)
00522 {
00523 for (Subscript j=1; j< i; j++)
00524 {
00525 (*this)(i,j)= 0.5*((*this)(i,j)+ (*this)(j,i));
00526 }
00527
00528 }
00529 return 1;
00530 }
00531
00532 int ASymmetrize()
00533
00534 {
00535 assert(m_ == n_);
00536 if(m_ == 0)
00537 return 1;
00538 for(Subscript i=1; i <= m_; i++)
00539 {
00540 for (Subscript j=1; j< i; j++)
00541 {
00542 (*this)(i,j)= 0.5*((*this)(i,j) - (*this)(j,i));
00543 (*this)(j,i)=-(*this)(i,j);
00544 }
00545
00546 }
00547 return 1;
00548 }
00549
00550 };
00551
00552
00553
00554
00555 template <class T>
00556 ostream& operator<<(ostream &s, const Fortran_matrix<T> &A)
00557 {
00558 Subscript M=A.num_rows();
00559 Subscript N=A.num_cols();
00560
00561 s << M << " " << N << endl;
00562
00563 for (Subscript i=1; i<=M; i++)
00564 {
00565 for (Subscript j=1; j<=N; j++)
00566 {
00567 s << A(i,j) << " ";
00568 }
00569 s << endl;
00570 }
00571
00572
00573 return s;
00574 }
00575
00576
00577
00578 template <class T>
00579 istream& operator>>(istream &s, Fortran_matrix<T> &A)
00580 {
00581
00582 Subscript M, N;
00583
00584 s >> M >> N;
00585
00586 if ( !(M == A.m_ && N == A.n_) )
00587 {
00588 A.destroy();
00589 A.initialize(M,N);
00590 }
00591
00592
00593 for (Subscript i=1; i<=M; i++)
00594 for (Subscript j=1; j<=N; j++)
00595 {
00596 s >> A(i,j);
00597 }
00598
00599 return s;
00600 }
00601
00602
00603
00604
00605 template <class T>
00606 Fortran_matrix<T> operator+(const Fortran_matrix<T> &A,
00607 const Fortran_matrix<T> &B)
00608 {
00609 Subscript M = A.num_rows();
00610 Subscript N = A.num_cols();
00611
00612 assert(M==B.num_rows());
00613 assert(N==B.num_cols());
00614
00615 Fortran_matrix<T> tmp(M,N);
00616 Subscript i,j;
00617
00618 for (i=1; i<=M; i++)
00619 for (j=1; j<=N; j++)
00620 tmp(i,j) = A(i,j) + B(i,j);
00621
00622 return tmp;
00623 }
00624
00625 template <class T>
00626 Fortran_matrix<T> operator-(const Fortran_matrix<T> &A,
00627 const Fortran_matrix<T> &B)
00628 {
00629 Subscript M = A.num_rows();
00630 Subscript N = A.num_cols();
00631
00632 assert(M==B.num_rows());
00633 assert(N==B.num_cols());
00634
00635 Fortran_matrix<T> tmp(M,N);
00636 Subscript i,j;
00637
00638 for (i=1; i<=M; i++)
00639 for (j=1; j<=N; j++)
00640 tmp(i,j) = A(i,j) - B(i,j);
00641
00642 return tmp;
00643 }
00644
00645
00646
00647
00648
00649 template <class T>
00650 Fortran_matrix<T> mult_element(const Fortran_matrix<T> &A,
00651 const Fortran_matrix<T> &B)
00652 {
00653 Subscript M = A.num_rows();
00654 Subscript N = A.num_cols();
00655
00656 assert(M==B.num_rows());
00657 assert(N==B.num_cols());
00658
00659 Fortran_matrix<T> tmp(M,N);
00660 Subscript i,j;
00661
00662 for (i=1; i<=M; i++)
00663 for (j=1; j<=N; j++)
00664 tmp(i,j) = A(i,j) * B(i,j);
00665
00666 return tmp;
00667 }
00668
00669
00670 template <class T>
00671 Fortran_matrix<T> transpose(const Fortran_matrix<T> &A)
00672 {
00673 Subscript M = A.num_rows();
00674 Subscript N = A.num_cols();
00675
00676 Fortran_matrix<T> S(N,M);
00677 Subscript i, j;
00678
00679 for (i=1; i<=M; i++)
00680 for (j=1; j<=N; j++)
00681 S(j,i) = A(i,j);
00682
00683 return S;
00684 }
00685
00686
00687
00688 template <class T>
00689 inline Fortran_matrix<T> matmult(const Fortran_matrix<T> &A,
00690 const Fortran_matrix<T> &B)
00691 {
00692
00693 #ifdef TNT_BOUNDS_CHECK
00694 assert(A.num_cols() == B.num_rows());
00695 #endif
00696
00697 Subscript M = A.num_rows();
00698 Subscript N = A.num_cols();
00699 Subscript K = B.num_cols();
00700
00701 Fortran_matrix<T> tmp(M,K);
00702 T sum;
00703
00704 for (Subscript i=1; i<=M; i++)
00705 for (Subscript k=1; k<=K; k++)
00706 {
00707 sum = 0;
00708 for (Subscript j=1; j<=N; j++)
00709 sum = sum + A(i,j) * B(j,k);
00710
00711 tmp(i,k) = sum;
00712 }
00713
00714 return tmp;
00715 }
00716
00717 template <class T>
00718 inline Fortran_matrix<T> operator*(const Fortran_matrix<T> &A,
00719 const Fortran_matrix<T> &B)
00720 {
00721 return matmult(A,B);
00722 }
00723
00724 template <class T>
00725 inline int mat_diff(Fortran_matrix<T>& C, Fortran_matrix<T> &A,
00726 Fortran_matrix<T> &B)
00727
00728
00729 {
00730
00731 assert(A.num_cols() == B.num_cols());
00732 assert(A.num_rows() == B.num_rows());
00733
00734 Subscript M = A.num_rows();
00735 Subscript N = A.num_cols();
00736
00737 C.newsize(M,N);
00738
00739 for(Subscript i=1; i <= M; i++)
00740 {
00741 for(Subscript j=1; j <= N; j++)
00742 {
00743 C(i,j)=A(i,j)-B(i,j);
00744 }
00745 }
00746 return 0;
00747 }
00748
00749 template <class T>
00750 inline int mat_add(Fortran_matrix<T>& C, Fortran_matrix<T> &A,
00751 Fortran_matrix<T> &B)
00752
00753
00754 {
00755
00756 assert(A.num_cols() == B.num_cols());
00757 assert(A.num_rows() == B.num_rows());
00758
00759 Subscript M = A.num_rows();
00760 Subscript N = A.num_cols();
00761
00762 C.newsize(M,N);
00763
00764 for(Subscript i=1; i <= M; i++)
00765 {
00766 for(Subscript j=1; j <= N; j++)
00767 {
00768 C(i,j)=A(i,j)+B(i,j);
00769 }
00770 }
00771 return 0;
00772 }
00773
00774
00775
00776 template <class T>
00777 inline int mat_add_unit(Fortran_matrix<T>& C, Fortran_matrix<T> &A,
00778 const T& factor)
00779
00780
00781 {
00782 Subscript N=A.num_rows();
00783 assert(A.num_rows() == A.num_cols());
00784 C.newsize(N,N);
00785 C=A;
00786 for(Subscript i=1; i<=N; i++)
00787 {
00788 C(i,i)=C(i,i)+factor;
00789 }
00790 return 0;
00791 }
00792
00793 template <class T>
00794 T SProd(const Fortran_matrix<T> &A,
00795 const Fortran_matrix<T> &B)
00796
00797 {
00798
00799 assert(A.num_cols() == B.num_cols());
00800 assert(A.num_rows() == B.num_rows());
00801
00802 Subscript M = A.num_rows();
00803 Subscript N = A.num_cols();
00804
00805 T ss;
00806
00807 ss=0;
00808 for(Subscript i=1; i <= M; i++)
00809 {
00810 for(Subscript j=1; j <= N; j++)
00811 {
00812 ss+=A(i,j)*B(i,j);
00813 }
00814 }
00815 return ss;
00816 }
00817
00818
00819 template <class T>
00820 inline int mat_scale(Fortran_matrix<T>& C, Fortran_matrix<T> &A,
00821 const T& factor)
00822
00823
00824 {
00825 Subscript M = A.num_rows();
00826 Subscript N = A.num_cols();
00827
00828 Subscript MN = M*N;
00829
00830 C.newsize(M,N);
00831
00832 const T* a = A.begin();
00833 T* t = C.begin();
00834 T* tend = C.end();
00835
00836 for (; t < tend; t++, a++)
00837 *t = *a * factor;
00838
00839 return 0;
00840 }
00841
00842 template <class T>
00843 inline int mat_copy_scale(Fortran_matrix<T>& C, const Fortran_matrix<T> &A,
00844 const T& factor)
00845
00846
00847 {
00848 Subscript M = A.num_rows();
00849 Subscript N = A.num_cols();
00850
00851 Subscript MN = M*N;
00852
00853 C.newsize(M,N);
00854
00855 const T* a = A.begin();
00856 T* t = C.begin();
00857 T* tend = C.end();
00858
00859 for (; t < tend; t++, a++)
00860 *t = *a * factor;
00861
00862 return 0;
00863 }
00864
00865 template <class T>
00866 inline int matmult(Fortran_matrix<T>& C, const Fortran_matrix<T> &A,
00867 const Fortran_matrix<T> &B)
00868 {
00869 assert(A.num_cols() == B.num_rows());
00870
00871 Subscript M = A.num_rows();
00872 Subscript N = A.num_cols();
00873 Subscript K = B.num_cols();
00874
00875 C.newsize(M,K);
00876
00877 T sum;
00878
00879 const T* row_i;
00880 const T* col_k;
00881
00882 for (Subscript i=1; i<=M; i++)
00883 {
00884 for (Subscript k=1; k<=K; k++)
00885 {
00886 row_i = &A(i,1);
00887 col_k = &B(1,k);
00888 sum = 0;
00889 for (Subscript j=1; j<=N; j++)
00890 {
00891 sum += *row_i * *col_k;
00892 row_i += M;
00893 col_k ++;
00894 }
00895 C(i,k) = sum;
00896 }
00897 }
00898 return 0;
00899 }
00900
00901
00902 template <class T>
00903 NumVector<T> matmult(const Fortran_matrix<T> &A, const NumVector<T> &x)
00904 {
00905
00906 #ifdef TNT_BOUNDS_CHECK
00907 assert(A.num_cols() == x.dim());
00908 #endif
00909
00910 Subscript M = A.num_rows();
00911 Subscript N = A.num_cols();
00912
00913 NumVector<T> tmp(M);
00914 T sum;
00915
00916 for (Subscript i=1; i<=M; i++)
00917 {
00918 sum = 0;
00919 for (Subscript j=1; j<=N; j++)
00920 sum = sum + A(i,j) * x(j);
00921
00922 tmp(i) = sum;
00923 }
00924
00925 return tmp;
00926 }
00927
00928 template <class T>
00929 inline NumVector<T> operator*(const Fortran_matrix<T> &A, const NumVector<T> &x)
00930 {
00931 return matmult(A,x);
00932 }
00933
00934 template <class T>
00935 inline Fortran_matrix<T> operator*(const Fortran_matrix<T> &A, const T &x)
00936 {
00937 Subscript M = A.num_rows();
00938 Subscript N = A.num_cols();
00939
00940 Subscript MN = M*N;
00941
00942 Fortran_matrix<T> res(M,N);
00943 const T* a = A.begin();
00944 T* t = res.begin();
00945 T* tend = res.end();
00946
00947 for (t=res.begin(); t < tend; t++, a++)
00948 *t = *a * x;
00949
00950 return res;
00951 }
00952
00953
00954
00955 template <class T>
00956 void raw_copy(T* to, const T* from, const int nelem)
00957
00958 {
00959 assert(nelem > 0);
00960 assert(to != NULL);
00961 assert(from != NULL);
00962
00963 const T* ref=from;
00964 T* dest=to;
00965 int i=nelem;
00966 for(; i != 0; dest++, ref++, i--)
00967 {
00968 *dest=*ref;
00969 }
00970 }
00971
00972 template <class T>
00973 inline int matmult_T1(Fortran_matrix<T>& C, const Fortran_matrix<T> &A,
00974 const Fortran_matrix<T> &B)
00975
00976 {
00977
00978 assert(A.num_rows() == B.num_rows());
00979
00980 Subscript M = A.num_cols();
00981 Subscript N = A.num_rows();
00982 Subscript K = B.num_cols();
00983
00984 C.newsize(M,K);
00985
00986
00987 T sum;
00988
00989 const T* col_i;
00990 const T* col_k;
00991
00992 for (Subscript i=1; i<=M; i++)
00993 {
00994 for (Subscript k=1; k<=K; k++)
00995 {
00996 col_i = &A(1,i);
00997 col_k = &B(1,k);
00998 sum = 0;
00999 for (Subscript j=1; j<=N; j++)
01000 {
01001 sum += *col_i * *col_k;
01002 col_i ++;
01003 col_k ++;
01004 }
01005
01006 C(i,k) = sum;
01007 }
01008
01009 }
01010
01011 return 0;
01012 }
01013
01014 template <class T>
01015 inline int matmult_T2(Fortran_matrix<T>& C, const Fortran_matrix<T> &A,
01016 const Fortran_matrix<T> &B)
01017
01018 {
01019
01020 assert(A.num_cols() == B.num_cols());
01021
01022 Subscript M = A.num_rows();
01023 Subscript N = A.num_cols();
01024 Subscript K = B.num_rows();
01025
01026 C.newsize(M,K);
01027
01028
01029 T sum;
01030
01031 const T* row_i;
01032 const T* row_k;
01033
01034 for (Subscript i=1; i<=M; i++)
01035 {
01036 for (Subscript k=1; k<=K; k++)
01037 {
01038 row_i = &A(i,1);
01039 row_k = &B(k,1);
01040 sum = 0;
01041 for (Subscript j=1; j<=N; j++)
01042 {
01043 sum += *row_i * *row_k;
01044 row_i += M;
01045 row_k += K;
01046 }
01047
01048 C(i,k) = sum;
01049 }
01050
01051 }
01052
01053 return 0;
01054 }
01055
01056 template<class NumMatrix, class NumVector>
01057 int mat_symm_from_lin(NumMatrix & smat, const NumVector & slin, Subscript n)
01058
01059
01060 {
01061 smat.newsize(n,n);
01062 for(Subscript i=1; i <= n ; i++)
01063 {
01064 for(Subscript j=1; j <= n ; j++)
01065 {
01066 smat(i,j)=((i >= j) ? slin(i*(i-1)/2 + j) : slin(j*(j-1)/2 + i));
01067 }
01068 }
01069 return 1;
01070 }
01071
01072 template<class NumMatrix, class NumVector>
01073 int mat_asymm_from_lin(NumMatrix & smat, NumVector & slin, Subscript n)
01074
01075
01076 {
01077 smat.newsize(n,n);
01078 for(Subscript i=1; i <= n ; i++)
01079 {
01080 for(Subscript j=1; j <= n ; j++)
01081 {
01082 smat(i,j)=((i >= j) ? slin(i*(i-1)/2 + j) : -slin(j*(j-1)/2 + i));
01083 }
01084 }
01085 return 1;
01086 }
01087
01088 #endif
01089