00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef SMatrix_H
00023 #define SMatrix_H
00024 #if HAVE_CONFIG
00025 #include <config.h>
00026 #endif
00027
00028 #include <iostream>
00029 #include "SVector.h"
00030 #include "lapack_wrapper.h"
00031 #include "blas_wrapper.h"
00032
00033
00034 using namespace std;
00035
00036
00043 class SMatrix
00044 {
00045 public:
00046 friend class TMatrix;
00047 private:
00052 int n_1;
00053
00054
00059 int n_2;
00060
00065 float* pArray;
00066
00071 float* tmpArray;
00072
00076 float temp;
00077
00081 int one;
00082
00083 public:
00089 int dim1(){return n_1;}
00090
00096 int dim2(){return n_2;}
00097
00103 int size(){return n_1*n_2;}
00104
00109 float* array(){return pArray;}
00110
00115 void transpose()
00116 {
00117 if(n_1 !=n_2)
00118 {
00119 cerr << " Transpose only for square matrix ! " << endl;
00120 exit(1);
00121 }
00122 for(int i=0;i<n_1;i++)
00123 for(int j=0;j<i;j++)
00124 {
00125 temp=pArray[j+i*n_1];
00126 pArray[j+i*n_1]=pArray[i+j*n_1];
00127 pArray[i+j*n_1]=temp;
00128 }
00129 }
00130
00131
00138 void allocate(int i, int j)
00139 {
00140 if( n_1 != i || n_2 != j )
00141 {
00142 deallocate();
00143
00144 n_1 = i;
00145 n_2 = j;
00146
00147 if(n_1 >= 1 && n_2 >= 1)
00148 pArray = new float[n_1*n_2];
00149 else
00150 pArray = 0;
00151 }
00152 }
00153
00154
00159 void deallocate()
00160 {
00161 if(n_2>0 && n_1>0)
00162 {
00163 delete [] pArray;
00164 }
00165 pArray = 0;
00166
00167 n_1 = 0;
00168 n_2 = 0;
00169 }
00170
00171
00176 void operator=(const SMatrix & rhs)
00177 {
00178 int tot=n_1*n_2;
00179 #ifdef DEBUG
00180 if(n_1 != rhs.n_1 || n_2 != rhs.n_2) allocate(rhs.n_1,rhs.n_2);
00181 #endif
00182
00183 F77_FUNC(scopy,SCOPY)(&tot,rhs.pArray,&one,pArray,&one);
00184 }
00185
00186
00191 void operator=(const float C)
00192 {
00193 for(int i=0; i<n_1*n_2;i++) pArray[i] = C;
00194 }
00195
00200 void operator*=(float C)
00201 {
00202 int tot=n_1*n_2;
00203 F77_FUNC(sscal,SSCAL)(&tot,&C,pArray,&one);
00204 }
00205
00210 void operator/=(const float C)
00211 {
00212 int tot=n_1*n_2;
00213 float inv=1.0/C;
00214 F77_FUNC(sscal,SSCAL)(&tot,&inv,pArray,&one);
00215 }
00216
00217
00222 SMatrix(){pArray = 0; n_1 = 0; n_2 = 0; one = 1;}
00223
00224
00232 SMatrix(int i, int j) {pArray = 0; n_1 = 0; n_2 = 0; one=1; allocate(i,j);}
00233
00234
00241 SMatrix( const SMatrix & rhs)
00242 {
00243 n_1 = 0;
00244 n_2 = 0;
00245 pArray = 0;
00246 allocate(rhs.n_1,rhs.n_2);
00247 int tot=n_1*n_2;
00248 one=1;
00249 F77_FUNC(scopy,SCOPY)(&tot,rhs.pArray,&one,pArray,&one);
00250 }
00251
00252
00257 ~SMatrix(){deallocate();}
00258
00262 float SumAll()
00263 {
00264 float sum=0;
00265 for(int i=0;i<n_1*n_2;i++) sum+=pArray[i];
00266 return sum;
00267 }
00268
00272 float Trace()
00273 {
00274 #ifdef DEBUG
00275 if(n_1 !=n_2)
00276 {
00277 cerr << " Trace only for Squared SMatrix ! " << endl;
00278 exit(1);
00279 }
00280 #endif
00281 float sum=0;
00282 for(int i=0;i<n_1;i++) sum+=pArray[i*n_1+i];
00283 return sum;
00284 }
00285
00289 void setrow(int irow,SVector &vector)
00290 {
00291 #ifdef DEBUG
00292 if(vector.n_1!=n_2 || irow>=n_1)
00293 {
00294 cerr << " ERROR! dimension array copying row! " << endl;
00295 exit(1);
00296 }
00297 #endif
00298 F77_FUNC(scopy,SCOPY)(&n_2,vector.pArray,&one,pArray+irow,&n_1);
00299 }
00300
00304 void setrow(int irow,float *vector)
00305 {
00306 F77_FUNC(scopy,SCOPY)(&n_2,vector,&one,pArray+irow,&n_1);
00307 }
00308
00312 void setrow(int irow,float *vector,int lda)
00313 {
00314 F77_FUNC(scopy,SCOPY)(&n_2,vector,&lda,pArray+irow,&n_1);
00315 }
00316
00320 void setcol(int icol, const SVector & vector)
00321 {
00322 #ifdef DEBUG
00323 if(vector.n_1!=n_1 || icol>=n_2)
00324 {
00325 cerr << " ERROR! dimension array copying coloumn! " << endl;
00326 exit(1);
00327 }
00328 #endif
00329 F77_FUNC(scopy,SCOPY)(&n_1,vector.pArray,&one,pArray+icol*n_1,&one);
00330 }
00331
00335 void setcol(int icol,float *vector)
00336 {
00337 #ifdef DEBUG
00338 if(icol>=n_2)
00339 {
00340 cerr << " ERROR! dimension array copying coloumn! " << endl;
00341 exit(1);
00342 }
00343 #endif
00344 F77_FUNC(scopy,SCOPY)(&n_1,vector,&one,pArray+icol*n_1,&one);
00345 }
00346
00350 void row_scale(int irow, float C)
00351 {
00352 #ifdef DEBUG
00353 if(irow>=n_1)
00354 {
00355 cerr << " ERROR! dimension array in row_scale! " << endl;
00356 exit(1);
00357 }
00358 #endif
00359 F77_FUNC(sscal,SSCAL)(&n_2,&C,pArray+irow,&n_1);
00360 }
00361
00362
00363
00364
00368 float rowdot(int irow, const SVector & vector)
00369 {
00370 #ifdef DEBUG
00371 if(vector.n_1!=n_2 || irow>=n_1)
00372 {
00373 cerr << " ERROR! dimension array in row dot! " << endl;
00374 exit(1);
00375 }
00376 #endif
00377 return F77_FUNC(sdot,SDOT)(&n_2,pArray+irow,&n_1,vector.pArray,&one);
00378 }
00379
00383 float coldot(int icol, const SVector &vector)
00384 {
00385 #ifdef DEBUG
00386 if(vector.n_1!=n_1 || icol>=n_2)
00387 {
00388 cerr << " ERROR! dimension array in coloumn dot! " << endl;
00389 exit(1);
00390 }
00391 #endif
00392 return F77_FUNC(sdot,SDOT)(&n_1,pArray+icol*n_1,&one,vector.pArray,&one);
00393 }
00394
00398 void col_scale(int icol, float C)
00399 {
00400 #ifdef DEBUG
00401 if(icol>=n_2)
00402 {
00403 cerr << " ERROR! dimension array in col_rescale! " << endl;
00404 exit(1);
00405 }
00406 #endif
00407 F77_FUNC(sscal,SSCAL)(&n_1,&C,pArray+icol*n_1,&one);
00408 }
00409
00410
00414 float rowdot(int irow, float *vector)
00415 {
00416 return F77_FUNC(sdot,SDOT)(&n_2,pArray+irow,&n_1,vector,&one);
00417 }
00418
00422 float coldot(int icol, float *vector)
00423 {
00424 return F77_FUNC(sdot,SDOT)(&n_1,pArray+icol*n_1,&one,vector,&one);
00425 }
00426
00427
00428
00432 float *row_pointer(int irow)
00433 {
00434 #ifdef DEBUG
00435 if(irow>=n_1)
00436 {
00437 cerr << " ERROR! dimension array getting a row! " << endl;
00438 exit(1);
00439 }
00440 #endif
00441 return(pArray+irow);
00442 }
00443
00447 SVector row(int irow)
00448 {
00449 #ifdef DEBUG
00450 if(irow>=n_1)
00451 {
00452 cerr << " ERROR! dimension array getting a row! " << endl;
00453 exit(1);
00454 }
00455 #endif
00456 SVector TEMP(n_2);
00457 F77_FUNC(scopy,SCOPY)(&n_2,pArray+irow,&n_1,TEMP.pArray,&one);
00458 return TEMP;
00459 }
00460
00461
00462
00463
00467 float *col_pointer(int icol)
00468 {
00469 #ifdef DEBUG
00470 if(icol>=n_2)
00471 {
00472 cerr << " ERROR! dimension array getting a coloumn! " << endl;
00473 exit(1);
00474 }
00475 #endif
00476 return(pArray+icol*n_1);
00477 }
00478
00479
00480
00484 SVector col(int icol)
00485 {
00486 #ifdef DEBUG
00487 if(icol>=n_2)
00488 {
00489 cerr << " ERROR! dimension array getting a coloumn! " << endl;
00490 exit(1);
00491 }
00492 #endif
00493 SVector TEMP(n_1);
00494 F77_FUNC(scopy,SCOPY)(&n_1,pArray+icol*n_1,&one,TEMP.pArray,&one);
00495 return TEMP;
00496 }
00497
00501 float SumRow(const int irow)
00502 {
00503 #ifdef DEBUG
00504 if(irow>=n_1)
00505 {
00506 cerr << " ERROR! dimension array getting a row! " << endl;
00507 exit(1);
00508 }
00509 #endif
00510 float sum=0;
00511 for(int i=0;i<n_2;i++) sum+=pArray[irow+i*n_1];
00512 return sum;
00513 }
00514
00515
00519 float SumCol(const int icol)
00520 {
00521 #ifdef DEBUG
00522 if(icol>=n_2)
00523 {
00524 cerr << " ERROR! dimension array getting a row! " << endl;
00525 exit(1);
00526 }
00527 #endif
00528 float sum=0;
00529 for(int i=0;i<n_1;i++) sum+=pArray[i+icol*n_1];
00530 return sum;
00531 }
00532
00533
00534
00535
00536
00541 SMatrix operator+( const SMatrix & rhs)
00542 {
00543 #ifdef DEBUG
00544 if( n_1 != rhs.n_1 || n_2 !=rhs.n_2 )
00545 {
00546 cerr << "ERROR: incorrect sizes for two SMatrix's in SMatrix+"
00547 << "SMatrix" << endl;
00548 exit(1);
00549 }
00550 if( n_1 <= 0 || n_2 <=0 )
00551 {
00552 cerr << "ERROR: SMatrix of size 0 used in SMatrix+SMatrix" << endl;
00553 exit(1);
00554 }
00555 #endif
00556 int tot=n_1*n_2;
00557 float d_one=1.0;
00558 SMatrix A(n_1,n_2);
00559 F77_FUNC(scopy,SCOPY)(&tot,pArray,&one,A.pArray,&one);
00560 F77_FUNC(saxpy,SAXPY)(&tot,&d_one,rhs.pArray,&one,A.pArray,&one);
00561 return A;
00562 }
00563
00564
00569 SMatrix operator-( const SMatrix & rhs)
00570 {
00571 #ifdef DEBUG
00572 if( n_1 != rhs.n_1 || n_2 !=rhs.n_2 )
00573 {
00574 cerr << "ERROR: incorrect sizes for two SMatrix's in SMatrix-"
00575 << "SMatrix" << endl;
00576 exit(1);
00577 }
00578 if( n_1 <= 0 || n_2 <=0)
00579 {
00580 cerr << "ERROR: SMatrix of size 0 used in SMatrix-SMatrix" << endl;
00581 exit(1);
00582 }
00583 #endif
00584 SMatrix A(n_1,n_2);
00585 int tot=n_1*n_2;
00586 float d_m_one=-1.0;
00587 F77_FUNC(scopy,SCOPY)(&tot,pArray,&one,A.pArray,&one);
00588 F77_FUNC(saxpy,SAXPY)(&tot,&d_m_one,rhs.pArray,&one,A.pArray,&one);
00589 return A;
00590 }
00591
00592
00596 float & operator()(int i,int j)
00597 {
00598 #ifdef DEBUG
00599 if(i>=n_1 || j>=n_2)
00600 {
00601 cerr << " ERROR! index out of range! "
00602 << "("<<i<<","<<j<<")" << endl;
00603 exit(1);
00604 }
00605 #endif
00606 return pArray[i+j*n_1];
00607 }
00608
00609
00614 friend ostream& operator<<(ostream & strm, const SMatrix & rhs)
00615 {
00616 for(int i=0; i<rhs.n_1;i++)
00617 {
00618 for(int j=0; j<rhs.n_2; j++)
00619 {
00620 strm << rhs.pArray[i+j*rhs.n_1] << "\t";
00621 }
00622 strm << endl;
00623 }
00624 return strm;
00625 }
00626
00627 };
00628
00629 #endif