00001 #include "arraybse.h"
00002 #include "vecbse.h"
00003 #include "matbse.h"
00004 #include "vecbse.h"
00005 #include "bnengine.h"
00006 #include "blas.h"
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 CAMmatrixBase::CAMmatrixBase()
00032 : Structure()
00033 {
00034 DataP = 0;
00035 typeValue = 0;
00036 referenceFlag = 0;
00037 matrixBaseReferenceCount = 0;
00038 }
00039
00040 CAMmatrixBase::CAMmatrixBase(int d_type)
00041 : Structure()
00042 {
00043 DataP = 0;
00044 typeValue = d_type;
00045 referenceFlag = 0;
00046 matrixBaseReferenceCount = 0;
00047 }
00048
00049 CAMmatrixBase::CAMmatrixBase(const CAMmatrixBase& A)
00050 :Structure(A.Structure)
00051 {
00052 if(A.DataP == 0)
00053 {DataP = 0;}
00054 else
00055 {
00056 if(A.referenceFlag == 1)
00057 {DataP = A.DataP; }
00058 else if(A.DataP->getTemporaryFlag() == 1)
00059 {
00060 DataP = new CAMdataHandler(*(A.DataP));
00061 DataP ->setReferenceCount(1);
00062 }
00063 else
00064 {
00065 A.Structure.initializeMinStructure(Structure);
00066 DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType());
00067 DataP->setReferenceCount(1);
00068
00069
00070
00071 CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP);
00072
00073
00074
00075 }
00076 }
00077 typeValue = A.typeValue;
00078 referenceFlag = 0;
00079 matrixBaseReferenceCount = 0;
00080 }
00081
00082
00083
00084
00085
00086
00087 CAMmatrixBase::CAMmatrixBase(int d_type, const CAMrange& R1, const CAMrange& R2)
00088 :Structure(R1,R2)
00089 {
00090 DataP = new CAMdataHandler(Structure.getFullDataCount(),d_type);
00091 DataP->setReferenceCount(1);
00092 referenceFlag = 0;
00093 matrixBaseReferenceCount = 0;
00094 }
00095
00096
00097
00098
00099
00100
00101 CAMmatrixBase::~CAMmatrixBase()
00102 {
00103 if(DataP != 0)
00104 {
00105 DataP->decrementReferenceCount();
00106 if(DataP->getReferenceCount() < 0)
00107 {
00108 cerr << " Error : Reference Count < 0" << endl;
00109 }
00110 if(DataP->getReferenceCount() == 0) delete DataP;
00111 }
00112 }
00113 void CAMmatrixBase::operator =(double value)
00114 {
00115
00116
00117
00118 if(DataP == 0)
00119 {
00120 Structure.initialize(_(1,1),_(1,1));
00121 DataP = new CAMdataHandler(1,CAMType::typeDouble);
00122 DataP->setReferenceCount(1);
00123 referenceFlag = 0;
00124 matrixBaseReferenceCount = 0;
00125 }
00126 else
00127 {
00128 CAMstructureBase AStructure(_(1,1),_(1,1));
00129 if(Structure.isStrictConformingTo(AStructure) != 1)
00130 {CAMmatrixBase::nonConformingMessage(Structure,AStructure);}
00131 }
00132
00133 CAMbinaryEngine::doubleAequalToAlpha(Structure, *DataP, value);
00134 }
00135 void CAMmatrixBase::operator =( const CAMmatrixBase& A)
00136 {
00137
00138
00139
00140 if(DataP == 0)
00141 {
00142 A.Structure.initializeMinStructure(Structure);
00143 DataP = new CAMdataHandler(Structure.getFullDataCount(),typeValue);
00144 DataP->setReferenceCount(1);
00145 typeValue = CAMType::typeDouble;
00146 referenceFlag = 0;
00147 matrixBaseReferenceCount = 0;
00148 }
00149 else
00150 {
00151 if(Structure.isStrictConformingTo(A.Structure) != 1)
00152 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00153 }
00154
00155 CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP);
00156 }
00157 void CAMmatrixBase::operator =( const CAMvectorBase& A)
00158 {
00159
00160
00161
00162 if(DataP == 0)
00163 {
00164 A.Structure.initializeMinStructure(Structure);
00165 DataP = new CAMdataHandler(Structure.getFullDataCount(),typeValue);
00166 DataP->setReferenceCount(1);
00167 typeValue = CAMType::typeDouble;
00168 referenceFlag = 0;
00169 matrixBaseReferenceCount = 0;
00170 }
00171 else
00172 {
00173 if(Structure.isStrictConformingTo(A.Structure) != 1)
00174 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00175 }
00176
00177 CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP);
00178 }
00179
00180
00181
00182
00183
00184 ostream& operator <<(ostream& out_stream, const CAMmatrixBase& A)
00185 {
00186 const long* beginPtr = A.Structure.indexBegin.getDataPointer();
00187 const long* endPtr = A.Structure.indexEnd.getDataPointer();
00188 const long* stridePtr = A.Structure.indexStride.getDataPointer();
00189
00190 int saveWidth=out_stream.width();
00191 double OutValue;
00192
00193 long i1, i2;
00194 for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr)
00195 {
00196 for(i2 = *(beginPtr+1); i2 <= *(endPtr +1); i2 += *(stridePtr+1))
00197 {
00198
00199 out_stream.width(saveWidth);
00200 OutValue =*((double*)A.getDataPointer(i1,i2));
00201 if(OutValue < 0 )
00202 out_stream << OutValue <<" ";
00203 else
00204 out_stream << " " << OutValue <<" ";
00205
00206
00207 }
00208
00209 out_stream << endl;
00210 }
00211 return(out_stream);
00212
00213 }
00214 istream& operator >>(istream& in_stream, CAMmatrixBase& A)
00215 {
00216 const long* beginPtr = A.Structure.indexBegin.getDataPointer();
00217 const long* endPtr = A.Structure.indexEnd.getDataPointer();
00218 const long* stridePtr = A.Structure.indexStride.getDataPointer();
00219
00220 long i1, i2;
00221 for(i1 = *beginPtr; i1 <= *endPtr; i1 += *stridePtr)
00222 {
00223 for(i2 = *(beginPtr+1); i2 <= *(endPtr +1); i2 += *(stridePtr+1))
00224 {
00225
00226 if( !( in_stream >> *((double*)A.getDataPointer(i1,i2))))
00227 CAMarrayBase::inputSizeError();
00228
00229
00230 }}
00231 return(in_stream);
00232
00233 }
00234
00235
00236
00237
00238
00239
00240
00241 void CAMmatrixBase::initialize()
00242 {
00243 Structure.initialize();
00244 if(DataP != 0)
00245 {
00246 DataP->decrementReferenceCount();
00247 if(DataP->getReferenceCount() == 0) delete DataP;
00248 }
00249 DataP = 0;
00250 typeValue = 0;
00251 referenceFlag = 0;
00252 matrixBaseReferenceCount = 0;
00253 }
00254
00255 void CAMmatrixBase::initialize(int d_type)
00256 {
00257 Structure.initialize();
00258 if(DataP != 0)
00259 {
00260 DataP->decrementReferenceCount();
00261 if(DataP->getReferenceCount() == 0) delete DataP;
00262 }
00263 DataP = 0;
00264 typeValue = d_type;
00265 referenceFlag = 0;
00266 matrixBaseReferenceCount = 0;
00267 }
00268
00269 void CAMmatrixBase::initialize(const CAMmatrixBase& A)
00270 {
00271
00272
00273
00274 if(DataP != 0)
00275 {
00276 DataP->decrementReferenceCount();
00277 if(DataP->getReferenceCount() == 0) delete DataP;
00278 }
00279
00280 if(A.DataP != 0)
00281 {
00282 A.Structure.initializeMinStructure(Structure);
00283
00284 DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType());
00285 DataP->setReferenceCount(1);
00286 CAMbinaryEngine::doubleAequalToB(Structure, *DataP, A.Structure, *A.DataP);
00287 }
00288 else
00289 {
00290 DataP = 0;
00291 Structure.initialize();
00292 }
00293
00294 typeValue = A.typeValue;
00295 referenceFlag = 0;
00296 matrixBaseReferenceCount = 0;
00297 }
00298
00299 void CAMmatrixBase::initialize(int d_type, const CAMrange& R1, const CAMrange& R2)
00300 {
00301 Structure.initialize(R1,R2);
00302
00303 if(DataP != 0)
00304 {
00305 DataP->decrementReferenceCount();
00306 if(DataP->getReferenceCount() == 0) delete DataP;
00307 }
00308
00309 DataP = new CAMdataHandler(Structure.getFullDataCount(),d_type);
00310 DataP->setReferenceCount(1);
00311 referenceFlag = 0;
00312 matrixBaseReferenceCount = 0;
00313 }
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 void CAMmatrixBase::initializeReturnArgument(const CAMmatrixBase& A)
00324 {
00325 A.Structure.initializeMinStructure(Structure);
00326 DataP = new CAMdataHandler(Structure.getFullDataCount(),A.DataP->getDataType());
00327 DataP->setReferenceCount(1);
00328 }
00329 void CAMmatrixBase::initializeReturnArgument(const CAMstructureBase& S, int dataT)
00330 {
00331 S.initializeMinStructure(Structure);
00332 DataP = new CAMdataHandler(Structure.getFullDataCount(), dataT);
00333 DataP->setReferenceCount(1);
00334 }
00335 void CAMmatrixBase::initializeMinDuplicate(const CAMmatrixBase& A)
00336 {
00337
00338 if(A.DataP == 0) return;
00339
00340 long i;
00341 long icount = 0;
00342 long dimension = 0;
00343
00344 for(i = 1; i <= A.Structure.getDimension(); i++)
00345 if(A.Structure[i].getIndexCount() != 1) dimension++;
00346
00347
00348 if(dimension == 0) dimension = 1;
00349 Structure.initialize(dimension);
00350
00351
00352 for(i = 1; i <= A.Structure.getDimension(); i++)
00353 {
00354 if(A.Structure[i].getIndexCount() != 1)
00355 {
00356 Structure.indexBegin[icount] = 1;
00357 Structure.indexBeginBase[icount] = 1;
00358 Structure.indexEndBase[icount] = A.Structure[i].getIndexCount();
00359 Structure.indexEnd[icount] = A.Structure[i].getIndexCount();
00360 Structure.indexStride[icount] = 1;
00361 icount++;
00362 }
00363 }
00364
00365 if(icount == 0)
00366 {
00367 Structure.indexBegin[icount] = 1;
00368 Structure.indexBeginBase[icount] = 1;
00369 Structure.indexEndBase[icount] = 1;
00370 Structure.indexEnd[icount] = 1;
00371 Structure.indexStride[icount] = 1;
00372 }
00373 DataP = new CAMdataHandler(Structure.getFullDataCount(), A.typeValue);
00374 DataP->setReferenceCount(1);
00375
00376
00377
00378 *this = A;
00379 }
00380
00381
00382
00383
00384
00385 CAMmatrixBase CAMmatrixBase::operator-() const
00386 {
00387
00388
00389
00390 CAMmatrixBase S;
00391 S.initializeReturnArgument(*this);
00392
00393 CAMbinaryEngine::doubleAequalToMinusB(S.Structure, *S.DataP, Structure, *DataP);
00394 S.setTemporaryFlag();
00395 return S;
00396 }
00397
00398 CAMmatrixBase CAMmatrixBase::operator+(const CAMmatrixBase& A) const
00399 {
00400 if(Structure.isStrictConformingTo(A.Structure) != 1)
00401 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00402
00403
00404
00405 CAMmatrixBase S;
00406 S.initializeReturnArgument(A.Structure,A.DataP->getDataType());
00407
00408 CAMbinaryEngine::doubleCequalAplusB(Structure, *DataP, A.Structure, *A.DataP,
00409 S.Structure, *S.DataP);
00410
00411 S.setTemporaryFlag();
00412 return S;
00413 }
00414
00415 CAMmatrixBase CAMmatrixBase::operator+(const CAMvectorBase& A) const
00416 {
00417 if(Structure.isStrictConformingTo(A.Structure) != 1)
00418 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00419
00420
00421
00422 CAMmatrixBase S;
00423 S.initializeReturnArgument(A.Structure,A.DataP->getDataType());
00424
00425 CAMbinaryEngine::doubleCequalAplusB(Structure, *DataP, A.Structure, *A.DataP,
00426 S.Structure, *S.DataP);
00427
00428 S.setTemporaryFlag();
00429 return S;
00430 }
00431 CAMmatrixBase CAMmatrixBase::operator-(const CAMmatrixBase& A) const
00432 {
00433 if(Structure.isStrictConformingTo(A.Structure) != 1)
00434 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00435
00436
00437
00438 CAMmatrixBase S;
00439 S.initializeReturnArgument(A.Structure,A.DataP->getDataType());
00440
00441 CAMbinaryEngine::doubleCequalAminusB(Structure, *DataP, A.Structure, *A.DataP,
00442 S.Structure, *S.DataP);
00443
00444 S.setTemporaryFlag();
00445 return S;
00446 }
00447 CAMmatrixBase CAMmatrixBase::operator-(const CAMvectorBase& A) const
00448 {
00449 if(Structure.isStrictConformingTo(A.Structure) != 1)
00450 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00451
00452
00453
00454 CAMmatrixBase S;
00455 S.initializeReturnArgument(A.Structure,A.DataP->getDataType());
00456
00457 CAMbinaryEngine::doubleCequalAminusB(Structure, *DataP, A.Structure, *A.DataP,
00458 S.Structure, *S.DataP);
00459
00460 S.setTemporaryFlag();
00461 return S;
00462 }
00463 CAMmatrixBase CAMmatrixBase::operator*(const CAMmatrixBase& A) const
00464 {
00465 if(Structure.isMatrixOpConformingTo(A.Structure) != 1)
00466 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00467
00468
00469
00470
00471
00472
00473 int STempFlag = 0;
00474 int TTempFlag = 0;
00475
00476 CAMmatrixBase* S;
00477 CAMmatrixBase* T;
00478
00479 if(Structure.isSubset() == 0)
00480 { S = (CAMmatrixBase*)this;}
00481 else
00482 {
00483 STempFlag = 1;
00484 S = new CAMmatrixBase();
00485 S->initializeReturnArgument(*this);
00486 *S = *this;
00487 }
00488
00489 if(A.Structure.isSubset() == 0)
00490 { T = (CAMmatrixBase*)&A;}
00491 else
00492 {
00493 TTempFlag = 1;
00494 T = new CAMmatrixBase();
00495 T->initializeReturnArgument(A);
00496 *T = A;
00497 }
00498
00499
00500
00501 long Rows = (*S).Structure[1].getIndexCount();
00502 long Cols = A.Structure[2].getIndexCount();
00503
00504 CAMrange R1( (*S).Structure[1].getIndexBase(),
00505 (*S).Structure[1].getIndexBase() + Rows - 1);
00506
00507 CAMrange R2(A.Structure[2].getIndexBase(),
00508 A.Structure[2].getIndexBase() + Cols - 1);
00509
00510 CAMmatrixBase R(CAMType::typeDouble,R1, R2);
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521 char transa = 'n';
00522 char transb = 'n';
00523
00524 long m = R.Structure[1].getIndexCount();
00525 long n = R.Structure[2].getIndexCount();
00526 long k = (*S).Structure[2].getIndexCount();
00527
00528 double* s = (double*)((*S).getDataPointer());
00529 double* t = (double*)((*T).getDataPointer());
00530 double* r = (double*)( R.getDataPointer());
00531
00532 long lds = (*S).Structure[1].getIndexCount();
00533 long ldt = (*T).Structure[1].getIndexCount();
00534 long ldr = R.Structure[1].getIndexCount();
00535
00536 double alpha = 1.0;
00537 double beta = 0.0;
00538
00539 short f1 = 1;
00540 short f2 = 1;
00541
00542 dgemm_(&transa, &transb, &m, &n, &k, &alpha, s, &lds, t, &ldt,
00543 &beta, r, &ldr,f1,f2);
00544
00545
00546
00547 if(STempFlag == 1) delete S;
00548 if(TTempFlag == 1) delete T;
00549
00550 R.setTemporaryFlag();
00551 return R;
00552 }
00553
00554
00555
00556 CAMvectorBase CAMmatrixBase::operator*(const CAMvectorBase& A) const
00557 {
00558 if(Structure.isMatrixOpConformingTo(A.Structure) != 1)
00559 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00560
00561
00562
00563
00564
00565
00566 int STempFlag = 0;
00567 int TTempFlag = 0;
00568
00569 CAMmatrixBase* S;
00570 CAMvectorBase* T;
00571
00572 if(Structure.isSubset() == 0)
00573 { S = (CAMmatrixBase*)this;}
00574 else
00575 {
00576 STempFlag = 1;
00577 S = new CAMmatrixBase();
00578 S->initializeReturnArgument(*this);
00579 *S = *this;
00580 }
00581
00582 if(A.Structure.isSubset() == 0)
00583 { T = (CAMvectorBase*)&A;}
00584 else
00585 {
00586 TTempFlag = 1;
00587 T = new CAMvectorBase();
00588 T->initializeReturnArgument(A);
00589 *T = A;
00590 }
00591
00592
00593
00594 long Rows = (S->operator[](1)).getIndexCount();
00595 long Cols = A.Structure[2].getIndexCount();
00596
00597 CAMrange R1((S->operator[](1)).getIndexBase(),
00598 (S->operator[](1)).getIndexBase() + Rows - 1);
00599
00600 CAMrange R2(A.Structure[2].getIndexBase(),
00601 A.Structure[2].getIndexBase() + Cols - 1);
00602
00603 CAMvectorBase R;
00604 if(R1.length() == 1)
00605 {R.initialize(CAMType::typeDouble,R2);}
00606 else
00607 {R.initialize(CAMType::typeDouble,R1);}
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619 char transa = 'n';
00620 char transb = 'n';
00621
00622 long m = R.Structure[1].getIndexCount();
00623 long n = R.Structure[2].getIndexCount();
00624 long k = (*S).Structure[2].getIndexCount();
00625
00626 double* s = (double*)((*S).getDataPointer());
00627 double* t = (double*)((*T).getDataPointer());
00628 double* r = (double*)( R.getDataPointer());
00629
00630 long lds = (*S).Structure[1].getIndexCount();
00631 long ldt = (*T).Structure[1].getIndexCount();
00632 long ldr = R.Structure[1].getIndexCount();
00633
00634 double alpha = 1.0;
00635 double beta = 0.0;
00636
00637 short f1 = 1;
00638 short f2 = 1;
00639
00640 dgemm_(&transa, &transb, &m, &n, &k, &alpha, s, &lds, t, &ldt,
00641 &beta, r, &ldr,f1,f2);
00642
00643
00644
00645 if(STempFlag == 1) delete S;
00646 if(TTempFlag == 1) delete T;
00647
00648 R.setTemporaryFlag();
00649 return R;
00650 }
00651 CAMmatrixBase CAMmatrixBase::operator/(const CAMmatrixBase& A) const
00652 {
00653 if(Structure.isMatrixOpConformingTo(A.Structure) != 1)
00654 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00655
00656 if(Structure[1].getIndexCount() !=
00657 Structure[2].getIndexCount())
00658 {CAMmatrixBase::nonSquareMessage();}
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668 int STempFlag = 0;
00669 int TTempFlag = 0;
00670
00671 CAMmatrixBase* S;
00672 CAMmatrixBase* T;
00673
00674 if(Structure.isSubset() == 0)
00675 { S = (CAMmatrixBase*)this;}
00676 else
00677 {
00678 STempFlag = 1;
00679 S = new CAMmatrixBase();
00680 S->initializeReturnArgument(*this);
00681 *S = *this;
00682 }
00683
00684 if(A.Structure.isSubset() == 0)
00685 { T = (CAMmatrixBase*)&A;}
00686 else
00687 {
00688 TTempFlag = 1;
00689 T = new CAMmatrixBase();
00690 T->initializeReturnArgument(A);
00691 *T = A;
00692 }
00693
00694
00695
00696 long Rows = (*S).Structure[1].getIndexCount();
00697 long Cols = A.Structure[2].getIndexCount();
00698
00699 CAMrange R1((*S).Structure[1].getIndexBase(),
00700 (*S).Structure[1].getIndexBase() + Rows - 1);
00701
00702 CAMrange R2(A.Structure[2].getIndexBase(),
00703 A.Structure[2].getIndexBase() + Cols - 1);
00704
00705 CAMmatrixBase R(CAMType::typeDouble,R1, R2);
00706
00707
00708
00709
00710
00711
00712
00713 char FACT = 'N';
00714 char TRANS = 'N';
00715 long N = Rows;
00716 long NRHS = Cols;
00717
00718 double* s = (double*)((*S).getDataPointer());
00719 double* t = (double*)((*T).getDataPointer());
00720 double* r = (double*)( R.getDataPointer());
00721
00722 long LDS = N;
00723 long LDT = N;
00724 long LDR = N;
00725
00726
00727 double* SF = new double[N*N];
00728 long LDSF = N;
00729
00730 long* IPIV = new long[N];
00731
00732 char EQUED = 'N';
00733
00734 double* RS = new double[N];
00735 double* C = new double[N];
00736
00737
00738 double* FERR = new double[NRHS];
00739 double* BERR = new double[NRHS];
00740 double* WORK = new double[4*N];
00741 long* IWORK = new long[N];
00742
00743 double RCOND = 0;
00744
00745
00746 long INFO = 0;
00747
00748 short f1a = 1;
00749 short f1b = 1;
00750 short f1c = 1;
00751
00752 dgesvx_(&FACT,&TRANS,&N,&NRHS,s,&LDS,SF,&LDSF,IPIV,
00753 &EQUED,RS,C,t,&LDT,r,&LDR,&RCOND, FERR, BERR, WORK,
00754 IWORK,&INFO, f1a, f1b, f1c);
00755
00756
00757
00758 if(INFO != 0)
00759 {
00760 if(INFO <= N)
00761 {
00762 cerr << " Matrix Singular " << endl;
00763 cerr << " LU Factorization Stopped at Step " << INFO << endl;
00764 cerr << " No Solution Returned " << endl;
00765 }
00766
00767 if(INFO ==(N +1))
00768 {
00769 cerr << " Matrix Singular or Badly Conditioned " << endl;
00770 cerr << " Computed Solution May Be Inaccurate " << endl;
00771 cerr << " Condition Number = " << 1.0/RCOND << endl;
00772 }
00773 }
00774
00775
00776
00777
00778 delete [] IWORK;
00779 delete [] WORK;
00780 delete [] BERR;
00781 delete [] FERR;
00782 delete [] C;
00783 delete [] RS;
00784 delete [] SF;
00785 delete [] IPIV;
00786
00787 if(STempFlag == 1) delete S;
00788 if(TTempFlag == 1) delete T;
00789
00790 R.setTemporaryFlag();
00791 return R;
00792 }
00793 CAMvectorBase CAMmatrixBase::operator/(const CAMvectorBase& A) const
00794 {
00795 if(Structure.isMatrixOpConformingTo(A.Structure) != 1)
00796 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00797
00798 if((this)->operator[](1).getIndexCount() !=
00799 (this)->operator[](1).getIndexCount())
00800 {CAMmatrixBase::nonSquareMessage();}
00801
00802
00803
00804
00805
00806
00807
00808
00809 int STempFlag = 0;
00810 int TTempFlag = 0;
00811
00812 CAMmatrixBase* S;
00813 CAMvectorBase* T;
00814
00815 if(Structure.isSubset() == 0)
00816 { S = (CAMmatrixBase*)this;}
00817 else
00818 {
00819 STempFlag = 1;
00820 S = new CAMmatrixBase();
00821 S->initializeReturnArgument(*this);
00822 *S = *this;
00823 }
00824
00825 if(A.Structure.isSubset() == 0)
00826 { T = (CAMvectorBase*)&A;}
00827 else
00828 {
00829 TTempFlag = 1;
00830 T = new CAMvectorBase();
00831 T->initializeReturnArgument(A);
00832 *T = A;
00833 }
00834
00835
00836
00837 long Rows = (S->operator[](1)).getIndexCount();
00838 long Cols = A.Structure[2].getIndexCount();
00839
00840 CAMrange R1((S->operator[](1)).getIndexBase(),
00841 (S->operator[](1)).getIndexBase() + Rows - 1);
00842
00843 CAMrange R2(A.Structure[2].getIndexBase(),
00844 A.Structure[2].getIndexBase() + Cols - 1);
00845
00846 CAMvectorBase R;
00847 if(R1.length() == 1)
00848 {R.initialize(CAMType::typeDouble,R2);}
00849 else
00850 {R.initialize(CAMType::typeDouble,R1);}
00851
00852
00853
00854
00855
00856
00857
00858 char FACT = 'N';
00859 char TRANS = 'N';
00860 long N = Rows;
00861 long NRHS = Cols;
00862
00863 double* s = (double*)((*S).getDataPointer());
00864 double* t = (double*)((*T).getDataPointer());
00865 double* r = (double*)( R.getDataPointer());
00866
00867 long LDS = N;
00868 long LDT = N;
00869 long LDR = N;
00870
00871
00872 double* SF = new double[N*N];
00873 long LDSF = N;
00874
00875 long* IPIV = new long[N];
00876
00877 char EQUED = 'B';
00878
00879 double* RS = new double[N];
00880 double* C = new double[N];
00881
00882
00883 double* FERR = new double[NRHS];
00884 double* BERR = new double[NRHS];
00885 double* WORK = new double[4*N];
00886 long* IWORK = new long[N];
00887
00888 double RCOND = 0;
00889
00890
00891 long INFO = 0;
00892
00893 short f1a = 1;
00894 short f1b = 1;
00895 short f1c = 1;
00896
00897 dgesvx_(&FACT,&TRANS,&N,&NRHS,s,&LDS,SF,&LDSF,IPIV,
00898 &EQUED,RS,C,t,&LDT,r,&LDR,&RCOND, FERR, BERR, WORK,
00899 IWORK,&INFO, f1a, f1b, f1c);
00900
00901
00902
00903 if(INFO != 0)
00904 {
00905 if(INFO <= N)
00906 {
00907 cerr << " Matrix Singular " << endl;
00908 cerr << " LU Factorization Stopped at Step " << INFO << endl;
00909 cerr << " No Solution Returned " << endl;
00910 }
00911
00912 if(INFO ==(N +1))
00913 {
00914 cerr << " Matrix Singular or Badly Conditioned " << endl;
00915 cerr << " Computed Solution May Be Inaccurate " << endl;
00916 cerr << " Condition Number = " << 1.0/RCOND << endl;
00917 }
00918 }
00919
00920
00921
00922
00923 delete [] IWORK;
00924 delete [] WORK;
00925 delete [] BERR;
00926 delete [] FERR;
00927 delete [] C;
00928 delete [] RS;
00929 delete [] SF;
00930 delete [] IPIV;
00931
00932 if(STempFlag == 1) delete S;
00933 if(TTempFlag == 1) delete T;
00934
00935 R.setTemporaryFlag();
00936 return R;
00937 }
00938
00939
00940
00941
00942
00943
00944 void CAMmatrixBase::operator+=(const CAMmatrixBase& A)
00945 {
00946 if(Structure.isStrictConformingTo(A.Structure) != 1)
00947 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00948
00949
00950
00951
00952 CAMbinaryEngine::doubleAplusEqualB(Structure, *DataP, A.Structure, *A.DataP);
00953 }
00954
00955
00956
00957
00958
00959
00960 void CAMmatrixBase::operator+=(const CAMvectorBase& A)
00961 {
00962 if(Structure.isStrictConformingTo(A.Structure) != 1)
00963 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00964
00965
00966
00967
00968 CAMbinaryEngine::doubleAplusEqualB(Structure, *DataP, A.Structure, *A.DataP);
00969 }
00970 void CAMmatrixBase::operator-=(const CAMmatrixBase& A)
00971 {
00972 if(Structure.isStrictConformingTo(A.Structure) != 1)
00973 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00974
00975
00976
00977
00978 CAMbinaryEngine::doubleAminusEqualB(Structure, *DataP, A.Structure, *A.DataP);
00979 }
00980 void CAMmatrixBase::operator-=(const CAMvectorBase& A)
00981 {
00982 if(Structure.isStrictConformingTo(A.Structure) != 1)
00983 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00984
00985
00986
00987
00988 CAMbinaryEngine::doubleAminusEqualB(Structure, *DataP, A.Structure, *A.DataP);
00989 }
00990 void CAMmatrixBase::operator*=(const CAMmatrixBase& A)
00991 {
00992 if((Structure.isMatrixOpConformingTo(A.Structure) != 1)||
00993 (A.Structure.isMatrixOpConformingTo(Structure) != 1))
00994 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
00995 (*this) = (*this) * A;
00996 }
00997 void CAMmatrixBase::operator*=(const CAMvectorBase& A)
00998 {
00999 if((Structure.isMatrixOpConformingTo(A.Structure) != 1)||
01000 (A.Structure.isMatrixOpConformingTo(Structure) != 1))
01001 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
01002 (*this) = (*this) * A;
01003 }
01004
01005 void CAMmatrixBase::operator/=(const CAMmatrixBase& A)
01006 {
01007 if((Structure.isMatrixOpConformingTo(A.Structure) != 1)||
01008 (A.Structure.isMatrixOpConformingTo(Structure) != 1))
01009 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
01010 (*this) = (*this)/A;
01011 }
01012
01013 void CAMmatrixBase::operator/=(const CAMvectorBase& A)
01014 {
01015 if((Structure.isMatrixOpConformingTo(A.Structure) != 1)||
01016 (A.Structure.isMatrixOpConformingTo(Structure) != 1))
01017 {CAMmatrixBase::nonConformingMessage(Structure,A.Structure);}
01018 (*this) = (*this)/A;
01019 }
01020
01021 CAMmatrixBase CAMmatrixBase::transpose() const
01022 {
01023
01024
01025
01026 CAMmatrixBase S(CAMType::typeDouble,
01027 _(Structure[2].getIndexBase(),Structure[2].getIndexBound()),
01028 _(Structure[1].getIndexBase(),Structure[1].getIndexBound()));
01029
01030 CAMstructureBase ASubset(Structure);
01031 CAMstructureBase BSubset(S.Structure);
01032
01033 long i;
01034 for(i = Structure[1].getIndexBase();
01035 i <= Structure[1].getIndexBound();i++)
01036 {
01037 ASubset.setStructureSubset(i,_);
01038 BSubset.setStructureSubset(_,i);
01039 CAMbinaryEngine::doubleAequalToB(BSubset, *S.DataP, ASubset, *DataP);
01040 }
01041 S.setTemporaryFlag();
01042 return S;
01043 }
01044
01045 CAMmatrixBase CAMmatrixBase::operator~() const
01046 {
01047
01048
01049
01050
01051 CAMmatrixBase S(CAMType::typeDouble,
01052 _(Structure[2].getIndexBase(),Structure[2].getIndexBound()),
01053 _(Structure[1].getIndexBase(),Structure[1].getIndexBound()));
01054
01055 CAMstructureBase ASubset(Structure);
01056 CAMstructureBase BSubset(S.Structure);
01057
01058 long i;
01059 for(i = Structure[1].getIndexBase();
01060 i <= Structure[1].getIndexBound();i++)
01061 {
01062 ASubset.setStructureSubset(i,_);
01063 BSubset.setStructureSubset(_,i);
01064 CAMbinaryEngine::doubleAequalToB(BSubset, *S.DataP, ASubset, *DataP);
01065 }
01066 S.setTemporaryFlag();
01067 return S;
01068 }
01069
01070
01071
01072
01073
01074 CAMmatrixBase CAMmatrixBase::operator +(const double value) const
01075 {
01076
01077
01078
01079 CAMstructureBase AStructure(_(1,1));
01080 if(Structure.isStrictConformingTo(AStructure) != 1)
01081 {CAMmatrixBase::nonConformingMessage(Structure,AStructure);}
01082
01083 CAMmatrixBase S(*this);
01084 CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *(S.DataP), value);
01085
01086 S.setTemporaryFlag();
01087 return S;
01088 }
01089 CAMmatrixBase operator +(const double value, const CAMmatrixBase& A)
01090 {
01091
01092
01093
01094 CAMstructureBase BStructure(_(1,1));
01095 if(A.Structure.isStrictConformingTo(BStructure) != 1)
01096 {CAMmatrixBase::nonConformingMessage(A.Structure,BStructure);}
01097
01098 CAMmatrixBase S(A);
01099 CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *(S.DataP), value);
01100
01101 S.setTemporaryFlag();
01102 return S;
01103 }
01104
01105 CAMmatrixBase CAMmatrixBase::operator -(const double value) const
01106 {
01107
01108
01109
01110 CAMstructureBase AStructure(_(1,1));
01111 if(Structure.isStrictConformingTo(AStructure) != 1)
01112 {CAMmatrixBase::nonConformingMessage(Structure,AStructure);}
01113
01114 CAMmatrixBase S(*this);
01115 CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *(S.DataP), value);
01116
01117 S.setTemporaryFlag();
01118 return S;
01119 }
01120
01121 CAMmatrixBase operator -(const double value, const CAMmatrixBase& A)
01122 {
01123
01124
01125
01126 CAMstructureBase BStructure(_(1,1));
01127 if(A.Structure.isStrictConformingTo(BStructure) != 1)
01128 {CAMmatrixBase::nonConformingMessage(A.Structure,BStructure);}
01129
01130 CAMmatrixBase S(A);
01131 CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *(S.DataP), value);
01132
01133 S.setTemporaryFlag();
01134 return S;
01135 }
01136
01137 void CAMmatrixBase::operator +=(const double value)
01138 {
01139
01140
01141
01142 CAMstructureBase AStructure(_(1,1));
01143 if(Structure.isStrictConformingTo(AStructure) != 1)
01144 {CAMmatrixBase::nonConformingMessage(Structure,AStructure);}
01145
01146 CAMbinaryEngine::doubleAplusEqualAlpha(Structure, *(DataP), value);
01147 }
01148
01149 void CAMmatrixBase::operator -=(const double value)
01150 {
01151
01152
01153
01154 CAMstructureBase AStructure(_(1,1));
01155 if(Structure.isStrictConformingTo(AStructure) != 1)
01156 {CAMmatrixBase::nonConformingMessage(Structure,AStructure);}
01157
01158 CAMbinaryEngine::doubleAminusEqualAlpha(Structure, *(DataP), value);
01159 }
01160
01161 CAMmatrixBase CAMmatrixBase::operator*(double value) const
01162 {
01163
01164
01165
01166 CAMmatrixBase S(*this);
01167 CAMbinaryEngine::doubleAtimesEqualAlpha(S.Structure, *S.DataP, value);
01168 S.setTemporaryFlag();
01169 return S;
01170 }
01171
01172 CAMmatrixBase operator *(double value, const CAMmatrixBase& A)
01173 {
01174
01175
01176
01177 CAMmatrixBase S(A);
01178 CAMbinaryEngine::doubleAtimesEqualAlpha(S.Structure, *S.DataP, value);
01179 S.setTemporaryFlag();
01180 return S;
01181 }
01182
01183 CAMmatrixBase CAMmatrixBase::operator /(double value) const
01184 {
01185
01186
01187
01188 CAMmatrixBase S(*this);
01189 CAMbinaryEngine::doubleAdivideEqualAlpha(S.Structure, *S.DataP, value);
01190 S.setTemporaryFlag();
01191 return S;
01192 }
01193
01194 CAMmatrixBase operator /(double value, const CAMmatrixBase& A)
01195 {
01196
01197
01198
01199 CAMmatrixBase S(A);
01200 CAMbinaryEngine::doubleAdivideEqualAlpha(S.Structure, *S.DataP, value);
01201 S.setTemporaryFlag();
01202 return S;
01203 }
01204
01205 void CAMmatrixBase::operator *=(double value)
01206 {
01207
01208
01209
01210 CAMbinaryEngine::doubleAtimesEqualAlpha(Structure, *DataP, value);
01211 }
01212
01213 void CAMmatrixBase::operator /=(double value)
01214 {
01215 CAMbinaryEngine::doubleAdivideEqualAlpha(Structure, *DataP, value);
01216 }
01217
01218
01219
01220 void CAMmatrixBase::setToValue(double value)
01221 {
01222
01223
01224
01225 CAMbinaryEngine::doubleAequalToAlpha(Structure, *DataP, value);
01226 }
01227
01228 CAMmatrixBase CAMmatrixBase::plusValue(double value)
01229 {
01230
01231
01232
01233 CAMmatrixBase S(*this);
01234 CAMbinaryEngine::doubleAplusEqualAlpha(S.Structure, *S.DataP, value);
01235 S.setTemporaryFlag();
01236 return S;
01237 }
01238
01239 CAMmatrixBase CAMmatrixBase::minusValue(double value)
01240 {
01241
01242
01243
01244 CAMmatrixBase S(*this);
01245 CAMbinaryEngine::doubleAminusEqualAlpha(S.Structure, *S.DataP, value);
01246 S.setTemporaryFlag();
01247 return S;
01248 }
01249
01250
01251
01252
01253
01254
01255 void CAMmatrixBase::exchangeContentsWith(CAMmatrixBase& B)
01256 {
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267 CAMstructureBase S_temp(Structure);
01268 CAMdataHandler* DataP_temp = DataP;
01269 int typeValue_temp = typeValue;
01270 int referenceFlag_temp = referenceFlag;
01271 long matrixBaseReferenceCount_temp = matrixBaseReferenceCount;
01272
01273 Structure.initialize(B.Structure);
01274 DataP = B.DataP;
01275 typeValue = B.typeValue;
01276 referenceFlag = B.referenceFlag;
01277 matrixBaseReferenceCount = B.matrixBaseReferenceCount;
01278
01279 B.Structure.initialize(S_temp);
01280 B.DataP = DataP_temp;
01281 B.typeValue = typeValue_temp;
01282 B.referenceFlag = referenceFlag_temp;
01283 B.matrixBaseReferenceCount = matrixBaseReferenceCount_temp;
01284 }
01285
01286 void CAMmatrixBase::initializeReferenceDuplicate(const CAMmatrixBase& B)
01287 {
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298 if(DataP != 0)
01299 {
01300 DataP->decrementReferenceCount();
01301 if(DataP->getReferenceCount() == 0) delete DataP;
01302 }
01303
01304 Structure.initialize(B.Structure);
01305 DataP = B.DataP;
01306 DataP->incrementReferenceCount();
01307 DataP->incrementReferenceCount();
01308 typeValue = B.typeValue;
01309 referenceFlag = 1;
01310 matrixBaseReferenceCount = 0;
01311 }
01312
01313
01314
01315
01316
01317 CAMarrayBase CAMmatrixBase::asArray() const
01318 {
01319 CAMarrayBase S;
01320 if(DataP == 0) return S;
01321
01322 CAMrange R1(Structure[1].getIndexBase(),Structure[1].getIndexBound());
01323 CAMrange R2(Structure[2].getIndexBase(),Structure[2].getIndexBound());
01324
01325
01326 S.initialize(CAMType::typeDouble, R1,R2);
01327 CAMbinaryEngine::doubleAequalToB(S.Structure, *(S.DataP), Structure, *DataP);
01328
01329
01330 S.setTemporaryFlag();
01331 return S;
01332 }
01333 CAMvectorBase CAMmatrixBase::asVector() const
01334 {
01335 CAMvectorBase S;
01336 if(DataP == 0) return S;
01337
01338 CAMrange R1;
01339 long i;
01340 long dimension = 0;
01341
01342 for(i = 1; i <= getDimension(); i++)
01343 {
01344 if(Structure[i].getIndexCount() != 1)
01345 {
01346 dimension++;
01347 if(dimension == 1)
01348 R1.initialize(Structure[i].getIndexBase(),Structure[i].getIndexBound());
01349 }
01350 }
01351 switch (dimension)
01352 {
01353 case 0 :
01354 R1.initialize(Structure[1].getIndexBase(),Structure[1].getIndexBound());
01355 break;
01356
01357 case 1 :
01358 break;
01359 default :
01360 CAMmatrixBase::objectConversionError(Structure);
01361
01362 }
01363
01364
01365 S.initialize(CAMType::typeDouble, R1);
01366 CAMbinaryEngine::doubleAequalToB(S.Structure, *(S.DataP), Structure, *DataP);
01367
01368
01369 S.setTemporaryFlag();
01370 return S;
01371 }
01372
01373
01374
01375
01376
01377 CAMstructureBase& CAMmatrixBase::operator[](long i)
01378 {
01379 if((i < 0)||(i > Structure.dataDimension))
01380 {CAMstructureBase::illegalDimension(i, Structure.dataDimension);}
01381
01382 Structure.exchangeReferenceIndex(i);
01383
01384 return Structure;
01385 }
01386
01387 const CAMstructureBase& CAMmatrixBase::operator[](long i) const
01388 {
01389 if((i < 0)||(i > Structure.dataDimension))
01390 {CAMstructureBase::illegalDimension(i, Structure.dataDimension);}
01391
01392 Structure.exchangeReferenceIndex(i);
01393
01394 return Structure;
01395 }
01396
01397 void* CAMmatrixBase::getDataPointer(long i1, long i2) const
01398 {
01399 const long* beginPtr = Structure.indexBeginBase.getDataPointer();
01400 const long* endPtr = Structure.indexEndBase.getDataPointer();
01401
01402
01403
01404 double* dataPtr = (double*)(DataP->dataPointer);
01405
01406 long offset;
01407 offset = (i1 - *(beginPtr))
01408 + ((*(endPtr) - *(beginPtr)) + 1)*(i2 - *(beginPtr + 1));
01409
01410
01411 return (void*)(dataPtr + offset);
01412 }
01413
01414
01415
01416
01417
01418
01419 void CAMmatrixBase::incrementReferenceCount()
01420 {
01421 if(matrixBaseReferenceCount == 0) CAMmatrixBase::referenceCountError();
01422 matrixBaseReferenceCount++;
01423 }
01424
01425 void CAMmatrixBase::referenceCountError()
01426 {
01427 cerr << " Cannot Use Reference Counting on Objects New\'d by the Compiler " << endl;
01428 CAMmvaExit();
01429 }
01430
01431
01432
01433
01434
01435
01436
01437 void CAMmatrixBase::indexCheck(const CAMstructureBase &S, long i1, long i2)
01438 {
01439 if(S.dataDimension != 2)
01440 {
01441 cerr << " Error : Incorrect Matrix Array Index Dimension " << endl;
01442 cerr << " Object Dimension = " << S.dataDimension
01443 << "--- Dimension Used = "<< 2 << endl;
01444 CAMmvaExit();
01445 }
01446 const long* indexBeginP = S.indexBegin.getDataPointer();
01447 const long* indexEndP = S.indexEnd.getDataPointer();
01448 if((i1 < *indexBeginP)||(i1 > *indexEndP))
01449 {
01450 CAMmatrixBase::indexErrorMessage(1, *(indexBeginP), *(indexEndP), i1);
01451 }
01452 if((i2 < *(indexBeginP +1))||(i2 > *(indexEndP+1)))
01453 {
01454 CAMmatrixBase::indexErrorMessage(2, *(indexBeginP+1), *(indexEndP+1), i2);
01455 }
01456 }
01457
01458
01459
01460
01461
01462 void CAMmatrixBase::indexErrorMessage(long indexDimension, long base, long bound, long index)
01463 {
01464 cerr << " Error : Index " << indexDimension << " Out of Range " << endl;
01465
01466 cerr << " Current Index Range :(" << base << ", " << bound << ")" << endl;
01467 cerr << " Index Used : " << index << endl;
01468 CAMmvaExit();
01469 }
01470 void CAMmatrixBase::nonConformingMessage(const CAMstructureBase& A, const CAMstructureBase& B)
01471 {
01472 long i;
01473 cerr << endl;
01474 cerr << "Error : Object Dimensions not Compatable with Operation " << endl << endl;
01475 cerr << "Left Operand Dimensions : ";
01476 cerr << A[1].getIndexCount();
01477 for(i = 2; i <= A.dataDimension; i++)
01478 cerr << " x " << A[i].getIndexCount() ;
01479 cerr << endl << endl;
01480 cerr << "Right Operand Dimensions : ";
01481 cerr << B[1].getIndexCount();
01482 for(i = 2; i <= B.dataDimension; i++)
01483 cerr << " x " << B[i].getIndexCount();
01484 cerr << endl << endl;
01485 CAMmvaExit();
01486 }
01487 void CAMmatrixBase::doubleConversionError(const CAMstructureBase& A)
01488 {
01489 long i;
01490 cerr << endl;
01491 cerr << "Dimensions not Compatable with Conversion to Double " << endl << endl;
01492 cerr << "Operand Dimensions : ";
01493 cerr << A[1].getIndexCount();
01494 for(i = 2; i <= A.dataDimension; i++)
01495 cerr << " x " << A[i].getIndexCount() ;
01496 cerr << endl << endl;
01497 CAMmvaExit();
01498 }
01499
01500 void CAMmatrixBase::nonSquareMessage()
01501 {
01502 cerr << endl;
01503 cerr << "Matrix is not square : dimensions incompatable with matrix solve " << endl << endl;
01504 CAMmvaExit();
01505 }
01506
01507 void CAMmatrixBase::objectConversionError(const CAMstructureBase& A)
01508 {
01509 long i;
01510 cerr << endl;
01511 cerr << " Dimensions not Compatable with Conversion Operator " << endl << endl;
01512 cerr << "Operand Dimensions : ";
01513 cerr << A[1].getIndexCount();
01514 for(i = 2; i <= A.dataDimension; i++)
01515 cerr << " x " << A[i].getIndexCount() ;
01516 cerr << endl << endl;
01517 CAMmvaExit();
01518 }
01519 void CAMmatrixBase::nullOperandError()
01520 {
01521 cerr << endl;
01522 cerr << " Error : Null Object Used As Operand " << endl;
01523 CAMmvaExit();
01524 }
01525 void CAMmatrixBase::nullOperandError(char* Operation)
01526 {
01527 cerr << endl;
01528 cerr << " Error : Null Object Used As Operand With "<< Operation << endl;
01529 CAMmvaExit();
01530 }
01531 void CAMmatrixBase::inputSizeError()
01532 {
01533 cerr << endl;
01534 cerr << " Input error : Insufficient # of data elements in input stream " << endl;
01535 CAMmvaExit();
01536 }
01537
01538
01539
01540
01541
01542
01543
01544
01545
01546
01547
01548
01549
01550
01551
01552