00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef PROFMATR_CC
00031 #define PROFMATR_CC
00032
00033 #include "profmatr.h"
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00247
00248
00249
00250 profilematrix::profilematrix(int matrix_order,
00251 int *jp_init,
00252 char flag_init,
00253 double *au_init_val,
00254 double *al_init_val,
00255 double *ad_init_val)
00256 {
00257
00258 pc_profilematrix_rep = new profilematrix_rep;
00259
00260 pc_profilematrix_rep->neq = matrix_order;
00261
00262
00263 pc_profilematrix_rep->jp = new int[matrix_order];
00264
00265 for ( int j=0 ; j<pc_profilematrix_rep->neq ; j++ )
00266 pc_profilematrix_rep->jp[j] = jp_init[j];
00267
00268 pc_profilematrix_rep->total_numb = pc_profilematrix_rep->jp[matrix_order-1];
00269
00270
00271 pc_profilematrix_rep->flag = flag_init;
00272
00273
00274 pc_profilematrix_rep->au = new double [(size_t) pc_profilematrix_rep->total_numb];
00275 if (!pc_profilematrix_rep->au)
00276 {
00277 ::printf("\a\nInsufficient memory for pc_profilematrix_rep->au\n");
00278 ::exit(1);
00279 }
00280
00281 if ( pc_profilematrix_rep->flag == 'N' )
00282 {
00283 pc_profilematrix_rep->al = new double [(size_t) pc_profilematrix_rep->total_numb];
00284 if (!pc_profilematrix_rep->al)
00285 {
00286 ::printf("\a\nInsufficient memory for pc_profilematrix_rep->al\n");
00287 ::exit(1);
00288 }
00289 }
00290 else if ( pc_profilematrix_rep->flag == 'S' )
00291 {
00292 pc_profilematrix_rep->al = pc_profilematrix_rep->au;
00293 }
00294 else
00295 {
00296 ::printf("flags not set properly, flag=='S' symmetric; flag=='N' NON(un)symmetric\n");
00297 }
00298
00299 pc_profilematrix_rep->ad = new double [(size_t) pc_profilematrix_rep->neq];
00300 if (!pc_profilematrix_rep->ad)
00301 {
00302 ::printf("\a\nInsufficient memory for pc_profilematrix_rep->ad\n");
00303 ::exit(1);
00304 }
00305
00306
00307 pc_profilematrix_rep->n = 1;
00308
00309
00310
00311
00312 for ( int iau=0 ; iau<pc_profilematrix_rep->total_numb ; iau++ )
00313 pc_profilematrix_rep->au[iau] = au_init_val[iau];
00314
00315 for ( int iad=0 ; iad<pc_profilematrix_rep->neq ; iad++ )
00316 pc_profilematrix_rep->ad[iad] = ad_init_val[iad];
00317
00318 if ( pc_profilematrix_rep->flag == 'N' )
00319 {
00320 for ( int ial=0 ; ial<pc_profilematrix_rep->total_numb ; ial++ )
00321 pc_profilematrix_rep->al[ial] = al_init_val[ial];
00322 }
00323
00324
00325 }
00326
00327
00328
00329 profilematrix::profilematrix(int matrix_order,
00330 int *jp_init,
00331 char flag_init,
00332 double au_init_val,
00333 double al_init_val,
00334 double ad_init_val)
00335 {
00336
00337 pc_profilematrix_rep = new profilematrix_rep;
00338
00339 pc_profilematrix_rep->neq = matrix_order;
00340
00341
00342 pc_profilematrix_rep->jp = new int[matrix_order];
00343
00344 for ( int j=0 ; j<pc_profilematrix_rep->neq ; j++ )
00345 pc_profilematrix_rep->jp[j] = jp_init[j];
00346
00347 pc_profilematrix_rep->total_numb = pc_profilematrix_rep->jp[matrix_order-1];
00348
00349
00350 pc_profilematrix_rep->flag = flag_init;
00351
00352
00353 pc_profilematrix_rep->au = new double [(size_t) pc_profilematrix_rep->total_numb];
00354 if (!pc_profilematrix_rep->au)
00355 {
00356 ::printf("\a\nInsufficient memory for pc_profilematrix_rep->au\n");
00357 ::exit(1);
00358 }
00359
00360 if ( pc_profilematrix_rep->flag == 'N' )
00361 {
00362 pc_profilematrix_rep->al = new double [(size_t) pc_profilematrix_rep->total_numb];
00363 if (!pc_profilematrix_rep->al)
00364 {
00365 ::printf("\a\nInsufficient memory for pc_profilematrix_rep->al\n");
00366 ::exit(1);
00367 }
00368 }
00369 else if ( pc_profilematrix_rep->flag == 'S' )
00370 {
00371 pc_profilematrix_rep->al = pc_profilematrix_rep->au;
00372 }
00373 else
00374 {
00375 ::printf("flags not set properly, flag=='S' symmetric; flag=='N' NON(un)symmetric\n");
00376 }
00377
00378 pc_profilematrix_rep->ad = new double [(size_t) pc_profilematrix_rep->neq];
00379 if (!pc_profilematrix_rep->ad)
00380 {
00381 ::printf("\a\nInsufficient memory for pc_profilematrix_rep->ad\n");
00382 ::exit(1);
00383 }
00384
00385
00386 pc_profilematrix_rep->n = 1;
00387
00388
00389
00390 for ( int iau=0 ; iau<pc_profilematrix_rep->total_numb ; iau++ )
00391 pc_profilematrix_rep->au[iau] = au_init_val;
00392
00393 for ( int iad=0 ; iad<pc_profilematrix_rep->neq ; iad++ )
00394 pc_profilematrix_rep->ad[iad] = ad_init_val;
00395
00396 if ( pc_profilematrix_rep->flag == 'N' )
00397 {
00398 for ( int ial=0 ; ial<pc_profilematrix_rep->total_numb ; ial++ )
00399 pc_profilematrix_rep->al[ial] = al_init_val;
00400 }
00401
00402
00403 }
00404
00405
00406 profilematrix::profilematrix(const profilematrix & x)
00407 {
00408 x.pc_profilematrix_rep->n++;
00409 pc_profilematrix_rep = x.pc_profilematrix_rep;
00410 }
00411
00412
00413
00414
00415 profilematrix::~profilematrix()
00416 {
00417 if (--pc_profilematrix_rep->n == 0)
00418 {
00419
00420
00421
00422
00423
00424 delete [] pc_profilematrix_rep->au;
00425 delete [] pc_profilematrix_rep->ad;
00426 if ( pc_profilematrix_rep->flag == 'N' )
00427 {
00428 delete [] pc_profilematrix_rep->al;
00429 }
00430 delete [] pc_profilematrix_rep->jp;
00431
00432 }
00433 }
00434
00436 profilematrix & profilematrix::operator=(const profilematrix & rval)
00437 {
00438 rval.pc_profilematrix_rep->n++;
00439
00440
00441
00442
00443
00444
00445 if( reference_count(-1) == 0)
00446 {
00447 delete [] pc_profilematrix_rep->au;
00448 delete [] pc_profilematrix_rep->ad;
00449 if ( pc_profilematrix_rep->flag == 'N' )
00450 {
00451 delete [] pc_profilematrix_rep->al;
00452 }
00453 delete [] pc_profilematrix_rep->jp;
00454 delete pc_profilematrix_rep;
00455 }
00456
00457 pc_profilematrix_rep = rval.pc_profilematrix_rep;
00458
00459 return *this;
00460 }
00461
00462
00463 int profilematrix::dimension_of_profile_M(void) const
00464 {
00465 return pc_profilematrix_rep->neq;
00466 }
00467
00468
00469 int * profilematrix::get_jp(void) const
00470 {
00471 return pc_profilematrix_rep->jp;
00472 }
00473
00474
00475
00476 double profilematrix::get_max(void)
00477 {
00478 double max_element = -1000000.0;
00479 for (int i =0; i< pc_profilematrix_rep->neq; i++)
00480
00481 if (pc_profilematrix_rep->ad[i] > max_element)
00482 max_element = pc_profilematrix_rep->ad[i];
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 return max_element;
00505 }
00506
00507
00508
00509
00510 void profilematrix::set_penalty_element(int *eqn_no_shake, int no_of_shake, double max_element)
00511 {
00512
00513 for (int count00 = 0 ; count00 < no_of_shake; count00++)
00514 {
00515
00516
00517
00518 pc_profilematrix_rep->ad[eqn_no_shake[count00]-1] = max_element;
00519
00520 }
00521 }
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00535
00536 profilematrix& profilematrix::operator+=(const profilematrix & rval)
00537 {
00538 long int this_total_numb = this->pc_profilematrix_rep->total_numb;
00539 long int rval_total_numb = rval.pc_profilematrix_rep->total_numb;
00540
00541
00542
00543 if(this_total_numb != rval_total_numb)
00544 {
00545 ::printf("\a\nprofilematrixs of different sizes: += not YET possible\n");
00546 ::exit ( 1 );
00547 }
00548
00549
00550 if ( this->pc_profilematrix_rep->n > 1 )
00551 {
00552
00553 profilematrix_rep * New_pc_profilematrix_rep = new profilematrix_rep;
00554
00555 New_pc_profilematrix_rep->neq = this->pc_profilematrix_rep->neq ;
00556
00557
00558 New_pc_profilematrix_rep->jp = new int[New_pc_profilematrix_rep->neq];
00559
00560 for ( int j=0 ; j<this->pc_profilematrix_rep->neq ; j++ )
00561 New_pc_profilematrix_rep->jp[j] = this->pc_profilematrix_rep->jp[j];
00562
00563 New_pc_profilematrix_rep->total_numb = this->pc_profilematrix_rep->total_numb;
00564
00565
00566 New_pc_profilematrix_rep->flag = this->pc_profilematrix_rep->flag;
00567
00568
00569 New_pc_profilematrix_rep->au = new double [(size_t) New_pc_profilematrix_rep->total_numb];
00570 if (!New_pc_profilematrix_rep->au)
00571 {
00572 ::printf("\a\nInsufficient memory for New_pc_profilematrix_rep->au\n");
00573 ::exit(1);
00574 }
00575
00576 if ( New_pc_profilematrix_rep->flag == 'N' )
00577 {
00578 New_pc_profilematrix_rep->al = new double [(size_t) New_pc_profilematrix_rep->total_numb];
00579 if (!New_pc_profilematrix_rep->al)
00580 {
00581 ::printf("\a\nInsufficient memory for New_pc_profilematrix_rep->al\n");
00582 ::exit(1);
00583 }
00584 }
00585 else if ( New_pc_profilematrix_rep->flag == 'S' )
00586 {
00587 New_pc_profilematrix_rep->al = New_pc_profilematrix_rep->au;
00588 }
00589 else
00590 {
00591 ::printf("flags not set properly, flag=='S' symmetric; flag=='N' NON(un)symmetric\n");
00592 }
00593
00594 New_pc_profilematrix_rep->ad = new double [(size_t) New_pc_profilematrix_rep->neq];
00595 if (!New_pc_profilematrix_rep->ad)
00596 {
00597 ::printf("\a\nInsufficient memory for New_pc_profilematrix_rep->ad\n");
00598 ::exit(1);
00599 }
00600
00601 New_pc_profilematrix_rep->n = 1;
00602
00603
00604
00605
00606 for ( int iau=0 ; iau<this_total_numb ; iau++ )
00607 New_pc_profilematrix_rep->au[iau] = this->pc_profilematrix_rep->au[iau];
00608
00609 for ( int iad=0 ; iad<New_pc_profilematrix_rep->neq ; iad++ )
00610 New_pc_profilematrix_rep->ad[iad] = this->pc_profilematrix_rep->ad[iad];
00611
00612 if ( New_pc_profilematrix_rep->flag == 'N' )
00613 {
00614 for ( int ial=0 ; ial<this_total_numb ; ial++ )
00615 New_pc_profilematrix_rep->al[ial] = this->pc_profilematrix_rep->al[ial];
00616 }
00617 else if ( New_pc_profilematrix_rep->flag == 'S' )
00618 {
00619 New_pc_profilematrix_rep->al = New_pc_profilematrix_rep->au;
00620 }
00621 else
00622 {
00623 ::printf("flags not set properly, flag=='S' symmetric; flag=='N' NON(un)symmetric\n");
00624 }
00625
00626
00627
00628
00629 this->pc_profilematrix_rep = New_pc_profilematrix_rep;
00630
00631 }
00632
00633
00634 for (int kau=0 ; kau<this_total_numb ; kau++)
00635 this->pc_profilematrix_rep->au[kau] += rval.pc_profilematrix_rep->au[kau];
00636 for (int kad=0 ; kad<this->pc_profilematrix_rep->neq ; kad++)
00637 this->pc_profilematrix_rep->ad[kad] += rval.pc_profilematrix_rep->ad[kad];
00638 if ( this->pc_profilematrix_rep->flag == 'N' )
00639 {
00640 for ( int kal=0 ; kal<this_total_numb ; kal++ )
00641 this->pc_profilematrix_rep->al[kal] += rval.pc_profilematrix_rep->al[kal];
00642 }
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 return *this;
00654 }
00655
00656
00657
00658
00659 profilematrix operator+(const profilematrix & lval, const profilematrix & rval)
00660 {
00661 profilematrix result(lval);
00662 result += rval;
00663 return result;
00664 }
00665
00666
00667
00668
00669 profilematrix profilematrix::operator+( double rval)
00670 {
00671
00672
00673 profilematrix add(this->pc_profilematrix_rep->neq,
00674 this->pc_profilematrix_rep->jp,
00675 this->pc_profilematrix_rep->flag,
00676 this->pc_profilematrix_rep->al,
00677 this->pc_profilematrix_rep->au,
00678 this->pc_profilematrix_rep->ad);
00679
00680
00681 for (int kau=0 ; kau<this->pc_profilematrix_rep->total_numb ; kau++)
00682 add.pc_profilematrix_rep->au[kau] += rval;
00683 for (int kad=0 ; kad<this->pc_profilematrix_rep->neq ; kad++)
00684 add.pc_profilematrix_rep->ad[kad] += rval;
00685 if ( this->pc_profilematrix_rep->flag == 'N' )
00686 {
00687 for ( int kal=0 ; kal<this->pc_profilematrix_rep->total_numb ; kal++ )
00688 add.pc_profilematrix_rep->al[kal] += rval;
00689 }
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700 return add;
00701 }
00702
00703
00704
00705 profilematrix& profilematrix::operator-=(const profilematrix & rval)
00706 {
00707 long int this_total_numb = this->pc_profilematrix_rep->total_numb;
00708 long int rval_total_numb = rval.pc_profilematrix_rep->total_numb;
00709
00710 if(this_total_numb != rval_total_numb)
00711 {
00712 ::printf("\a\nprofilematrixs of different sizes: -= not YET possible\n");
00713 ::exit ( 1 );
00714 }
00715
00716
00717 if ( this->pc_profilematrix_rep->n > 1 )
00718 {
00719
00720 profilematrix_rep * New_pc_profilematrix_rep = new profilematrix_rep;
00721
00722 New_pc_profilematrix_rep->neq = this->pc_profilematrix_rep->neq ;
00723
00724
00725 New_pc_profilematrix_rep->jp = new int[New_pc_profilematrix_rep->neq];
00726
00727 for ( int j=0 ; j<this->pc_profilematrix_rep->neq ; j++ )
00728 New_pc_profilematrix_rep->jp[j] = this->pc_profilematrix_rep->jp[j];
00729
00730 New_pc_profilematrix_rep->total_numb = New_pc_profilematrix_rep->total_numb;
00731
00732
00733 New_pc_profilematrix_rep->flag = this->pc_profilematrix_rep->flag;
00734
00735
00736 New_pc_profilematrix_rep->au = new double [(size_t) New_pc_profilematrix_rep->total_numb];
00737 if (!New_pc_profilematrix_rep->au)
00738 {
00739 ::printf("\a\nInsufficient memory for New_pc_profilematrix_rep->au\n");
00740 ::exit(1);
00741 }
00742
00743 if ( New_pc_profilematrix_rep->flag == 'N' )
00744 {
00745 New_pc_profilematrix_rep->al = new double [(size_t) New_pc_profilematrix_rep->total_numb];
00746 if (!New_pc_profilematrix_rep->al)
00747 {
00748 ::printf("\a\nInsufficient memory for New_pc_profilematrix_rep->al\n");
00749 ::exit(1);
00750 }
00751 }
00752 else if ( New_pc_profilematrix_rep->flag == 'S' )
00753 {
00754 New_pc_profilematrix_rep->al = New_pc_profilematrix_rep->au;
00755 }
00756 else
00757 {
00758 ::printf("flags not set properly, flag=='S' symmetric; flag=='N' NON(un)symmetric\n");
00759 }
00760
00761 New_pc_profilematrix_rep->ad = new double [(size_t) New_pc_profilematrix_rep->neq];
00762 if (!New_pc_profilematrix_rep->ad)
00763 {
00764 ::printf("\a\nInsufficient memory for New_pc_profilematrix_rep->ad\n");
00765 ::exit(1);
00766 }
00767
00768 New_pc_profilematrix_rep->n = 1;
00769
00770
00771
00772 for ( int iau=0 ; iau<New_pc_profilematrix_rep->total_numb ; iau++ )
00773 New_pc_profilematrix_rep->au[iau] = this->pc_profilematrix_rep->au[iau];
00774
00775 for ( int iad=0 ; iad<New_pc_profilematrix_rep->neq ; iad++ )
00776 New_pc_profilematrix_rep->au[iad] = this->pc_profilematrix_rep->ad[iad];
00777
00778 if ( New_pc_profilematrix_rep->flag == 'N' )
00779 {
00780 for ( int ial=0 ; ial<New_pc_profilematrix_rep->total_numb ; ial++ )
00781 New_pc_profilematrix_rep->al[ial] = this->pc_profilematrix_rep->al[ial];
00782 }
00783 else if ( New_pc_profilematrix_rep->flag == 'S' )
00784 {
00785 New_pc_profilematrix_rep->al = New_pc_profilematrix_rep->au;
00786 }
00787 else
00788 {
00789 ::printf("flags not set properly, flag=='S' symmetric; flag=='N' NON(un)symmetric\n");
00790 }
00791
00792 this->pc_profilematrix_rep->total_numb--;
00793 this->pc_profilematrix_rep = New_pc_profilematrix_rep;
00794
00795 }
00796
00797 for (int kau=0 ; kau<this->pc_profilematrix_rep->total_numb ; kau++)
00798 this->pc_profilematrix_rep->au[kau] -= rval.pc_profilematrix_rep->au[kau];
00799 for (int kad=0 ; kad<this->pc_profilematrix_rep->neq ; kad++)
00800 this->pc_profilematrix_rep->ad[kad] -= rval.pc_profilematrix_rep->ad[kad];
00801 if ( this->pc_profilematrix_rep->flag == 'N' )
00802 {
00803 for ( int kal=0 ; kal<this->pc_profilematrix_rep->total_numb ; kal++ )
00804 this->pc_profilematrix_rep->al[kal] -= rval.pc_profilematrix_rep->al[kal];
00805 }
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 return *this;
00817 }
00818
00819
00820
00821
00822 profilematrix operator-(const profilematrix & lval, const profilematrix & rval)
00823 {
00824 profilematrix result(lval);
00825 result -= rval;
00826 return result;
00827 }
00828
00829
00830
00831
00832 profilematrix profilematrix::operator-( double rval)
00833 {
00834
00835
00836 profilematrix sub(this->pc_profilematrix_rep->neq,
00837 this->pc_profilematrix_rep->jp,
00838 this->pc_profilematrix_rep->flag,
00839 this->pc_profilematrix_rep->al,
00840 this->pc_profilematrix_rep->au,
00841 this->pc_profilematrix_rep->ad);
00842
00843
00844 for (int kau=0 ; kau<this->pc_profilematrix_rep->total_numb ; kau++)
00845 sub.pc_profilematrix_rep->au[kau] -= rval;
00846 for (int kad=0 ; kad<this->pc_profilematrix_rep->neq ; kad++)
00847 sub.pc_profilematrix_rep->ad[kad] -= rval;
00848 if ( this->pc_profilematrix_rep->flag == 'N' )
00849 {
00850 for ( int kal=0 ; kal<this->pc_profilematrix_rep->total_numb ; kal++ )
00851 sub.pc_profilematrix_rep->al[kal] -= rval;
00852 }
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863 return sub;
00864 }
00865
00866
00867
00868
00869
00870 double * profilematrix::operator*( BJvector & arg)
00871 {
00872 int irow, iau, colht, jp, neq;
00873 neq = this->pc_profilematrix_rep->neq;
00874
00875 if( neq != arg.rows())
00876 error("# rows of second mat must equal "
00877 "# cols of first for multiply#");
00878 double *result;
00879 result = new double [ neq];
00880 if (! result)
00881 {
00882 ::printf("\a\nInsufficient memory for result\n");
00883 ::exit(1);
00884 }
00885
00886 for (int init=0; init<neq; init++)
00887 result[init] = 0.0;
00888
00889
00890
00891
00892
00893 for( int i=0 ; i<neq ; i++ )
00894 {
00895 result[i] += this->pc_profilematrix_rep->ad[i] * arg.val(i+1);
00896
00897 jp = this->pc_profilematrix_rep->jp[i];
00898 if ( i==0 )
00899 {
00900 colht = 0;
00901 }
00902 else
00903 {
00904 colht = this->pc_profilematrix_rep->jp[i]-this->pc_profilematrix_rep->jp[i-1];
00905 }
00906
00907 for( int j=1 ; j<=colht ; j++ )
00908 {
00909
00910
00911 iau = jp - j ;
00912 irow = i -j ;
00913 result[irow] +=this->pc_profilematrix_rep->au[iau] * arg.val(i+1);
00914 result[i] +=this->pc_profilematrix_rep->al[iau] * arg.val(irow+1);
00915
00916 }
00917
00918
00919
00920 }
00921
00922
00923 return result;
00924 }
00925
00926
00927
00928
00929 profilematrix profilematrix::operator*( double rval)
00930 {
00931
00932
00933 profilematrix mult(this->pc_profilematrix_rep->neq,
00934 this->pc_profilematrix_rep->jp,
00935 this->pc_profilematrix_rep->flag,
00936 this->pc_profilematrix_rep->al,
00937 this->pc_profilematrix_rep->au,
00938 this->pc_profilematrix_rep->ad);
00939
00940 for (int kau=0 ; kau<pc_profilematrix_rep->total_numb ; kau++)
00941 mult.pc_profilematrix_rep->au[kau] *= rval;
00942 for (int kad=0 ; kad<this->pc_profilematrix_rep->neq ; kad++)
00943 mult.pc_profilematrix_rep->ad[kad] *= rval;
00944 if ( this->pc_profilematrix_rep->flag == 'N' )
00945 {
00946 for ( int kal=0 ; kal<this->pc_profilematrix_rep->total_numb ; kal++ )
00947 mult.pc_profilematrix_rep->al[kal] *= rval;
00948 }
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966
00967
00968 return mult;
00969 }
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979 double & profilematrix::operator( )(int row, int col) const
00980 {
00981 if( row==col )
00982 {
00983 return this->pc_profilematrix_rep->ad[row-1];
00984 }
00985 else if( row<col )
00986 {
00987 int next_to_diag_memb = *(this->pc_profilematrix_rep->jp+col-1);
00988 int member_of_profile_n = next_to_diag_memb - (col-1) + row;
00989 double *member_of_profile = &(pc_profilematrix_rep->au[member_of_profile_n-1]);
00990 return (*member_of_profile);
00991 }
00992 else
00993 {
00994 int next_to_diag_memb = *(this->pc_profilematrix_rep->jp+row-1);
00995 int member_of_profile_n = next_to_diag_memb - (row-1) + col;
00996 double *member_of_profile = &(pc_profilematrix_rep->al[member_of_profile_n-1]);
00997 return (*member_of_profile);
00998 }
00999
01000
01001
01002
01003
01004 }
01005
01006
01007 double & profilematrix::mval(int row, int col) const
01008 {
01009 if( row==col )
01010 {
01011 return this->pc_profilematrix_rep->ad[row-1];
01012 }
01013 else if( row<col )
01014 {
01015 int next_to_diag_memb = *(this->pc_profilematrix_rep->jp+col-1);
01016 int member_of_profile_n = next_to_diag_memb - (col-1) + row;
01017 double *member_of_profile = &(pc_profilematrix_rep->au[member_of_profile_n-1]);
01018 return (*member_of_profile);
01019 }
01020 else
01021 {
01022 int next_to_diag_memb = *(this->pc_profilematrix_rep->jp+row-1);
01023 int member_of_profile_n = next_to_diag_memb - (row-1) + col;
01024 double *member_of_profile = &(pc_profilematrix_rep->al[member_of_profile_n-1]);
01025 return (*member_of_profile);
01026 }
01027
01028
01029
01030
01031
01032 }
01033
01034
01035
01036
01037
01038
01039
01040
01041 double profilematrix::full_val(int row, int col) const
01042 {
01043 if( row==col )
01044 {
01045 return this->pc_profilematrix_rep->ad[row-1];
01046 }
01047 else if( row<col )
01048 {
01049 int total_column_depth = col-1;
01050 int actual_column_position = row;
01051 int real_column_depth = pc_profilematrix_rep->jp[col-1] -
01052 pc_profilematrix_rep->jp[col-1-1];
01053 int zeros_above_profile =
01054 total_column_depth-real_column_depth;
01055 int how_much_above_profile =
01056 zeros_above_profile-actual_column_position+1;
01057 if ( how_much_above_profile > 0 )
01058 {
01059 double back = 0.0;
01060 return ( back );
01061 }
01062 else
01063 {
01064 int next_to_diag_memb =
01065 *(this->pc_profilematrix_rep->jp+col-1);
01066 int member_of_profile_n =
01067 next_to_diag_memb - total_column_depth + row - 1;
01068 double *member_of_profile =
01069 &(pc_profilematrix_rep->au[member_of_profile_n]);
01070 return (*member_of_profile);
01071 }
01072 }
01073 else if( col<row )
01074 {
01075 int total_row_width = row-1;
01076 int actual_row_position = col;
01077 int real_row_width = pc_profilematrix_rep->jp[row-1] -
01078 pc_profilematrix_rep->jp[row-1-1];
01079 int zeros_left_of_profile =
01080 total_row_width-real_row_width;
01081 int how_much_left_of_profile =
01082 zeros_left_of_profile-actual_row_position+1;
01083 if ( how_much_left_of_profile > 0 )
01084 {
01085 double back = 0.0;
01086 return ( back );
01087 }
01088 else
01089 {
01090 int next_to_diag_memb =
01091 *(this->pc_profilematrix_rep->jp+row-1);
01092 int member_of_profile_n =
01093 next_to_diag_memb - total_row_width + col - 1;
01094 double *member_of_profile =
01095 &(pc_profilematrix_rep->al[member_of_profile_n]);
01096 return (*member_of_profile);
01097 }
01098 }
01099 else return 0.0;
01100 }
01101
01102
01103
01104
01105
01106 double & profilematrix::val(int row, int col)
01107 {
01108
01109 if ( row<=0 && row>=dimension_of_profile_M() && col>=dimension_of_profile_M() )
01110 {
01111 error("index out of range");
01112
01113 }
01114
01115 return (mval(row,col));
01116 }
01117
01118
01119 double profilematrix::cval(int row, int col) const
01120 {
01121 double zero=0.0;
01122 if ( row<=0 && row>=dimension_of_profile_M() && col>=dimension_of_profile_M() )
01123 {
01124 error("index out of range");
01125 return zero;
01126 }
01127
01128 return (mval(row,col));
01129 }
01130
01131
01132
01133 double profilematrix::mmin()
01134 {
01135 double temp;
01136 if ( dimension_of_profile_M()<=0 )
01137 error("bad profilematrix size for min ()");
01138 double minimum = full_val(1,1);
01139 for ( int row=1 ; row<=dimension_of_profile_M() ; row++ )
01140 for ( int col=1 ; col<=dimension_of_profile_M() ; col++ )
01141 if ( (temp=full_val(row,col)) < minimum )
01142 minimum = temp;
01143 return minimum;
01144 }
01145
01146
01147 double profilematrix::mmax()
01148 {
01149 double temp=0.0;
01150 if( dimension_of_profile_M()<=0 )
01151 error("bad profilematrix size for max()");
01152 double maximum = full_val(1,1);
01153 for ( int row=1 ; row<=dimension_of_profile_M() ; row++ )
01154 for ( int col=1 ; col<=dimension_of_profile_M() ; col++ )
01155 {
01156 if ( (temp=full_val(row,col)) > maximum )
01157 maximum = temp;
01158 }
01159 return maximum;
01160 }
01161
01162
01163 double profilematrix::mean()
01164 {
01165 int col = 0;
01166 int row = 1;
01167 double sum = 0;
01168 for ( row=1 ; row<=dimension_of_profile_M() ; row++ )
01169 for ( col=1 ; col<=dimension_of_profile_M() ; col++ )
01170 sum += fabs(full_val(row,col));
01171 return sum/(row*col);
01172 }
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204
01205
01206
01207
01208
01209
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286
01287
01288
01289
01290
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347
01348
01349
01350
01351 void profilematrix::profile_jp_print( void )
01352 {
01353 ::printf("\n jp \n\n " );
01354 for (int count05 = 0 ; count05 < pc_profilematrix_rep->neq ; count05++)
01355 ::printf(" jp %d ", pc_profilematrix_rep->jp[count05] );
01356 }
01357
01358
01359
01360
01361 void profilematrix::profile_al_print( void )
01362 { ::printf("\n al \n\n " );
01363 for (int count05 = 0 ; count05 <pc_profilematrix_rep->jp[pc_profilematrix_rep->neq-1] ; count05++)
01364 {
01365 ::printf(" al %10.3e ", pc_profilematrix_rep->al[count05] );
01366 }
01367 }
01368
01369
01370
01371 void profilematrix::profile_ad_print( void )
01372 { ::printf("\n al \n\n " );
01373 for (int count05 = 0 ; count05 <pc_profilematrix_rep->neq ; count05++)
01374 {
01375 ::printf(" ad %10.3e\n ", pc_profilematrix_rep->ad[count05] );
01376 }
01377 }
01378
01379
01380 void profilematrix::full_print(char *msg)
01381 {
01382 if (*msg) printf("%s\n",msg);
01383 for ( int row=1 ; row<=dimension_of_profile_M() ; row++ )
01384 {
01385 for ( int col=1 ; col<=dimension_of_profile_M() ; col++ )
01386 {
01387 printf( "%+8.3e ", full_val(row,col) );
01388 }
01389 printf("\n");
01390 }
01391 }
01392
01393
01394
01395 void profilematrix::error(char * msg1, char * msg2) const
01396 {
01397 ::fprintf(stderr,"profmatrix error: %s %s\n", msg1, msg2);
01398 exit( 1 );
01399 }
01400
01401
01402
01403
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430 long int profilematrix::total_number(void) const
01431 {
01432 return this->pc_profilematrix_rep->total_numb;
01433 }
01434
01435 void profilematrix::total_number(int number)
01436 {
01437 this->pc_profilematrix_rep->total_numb = number;
01438 }
01439
01440
01441
01442
01443
01444
01445
01446
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460 int profilematrix::reference_count(int up_down)
01461 {
01462 this->pc_profilematrix_rep->n += up_down;
01463 return(this->pc_profilematrix_rep->n);
01464 }
01465
01466 void profilematrix::set_reference_count(int ref_count)
01467 {
01468 this->pc_profilematrix_rep->n=ref_count;
01469 }
01470
01471
01472
01473
01474
01475
01476
01477 void * profilematrix_rep::operator new(size_t s)
01478 {
01479 void *void_pointer;
01480 void_pointer = ::operator new(s);
01481
01482 if (!void_pointer)
01483 {
01484 ::printf("\a\nInsufficient memory\n");
01485 ::exit(1);
01486 }
01487 return void_pointer;
01488 }
01489
01490
01491 void profilematrix_rep::operator delete(void *p)
01492 {
01493
01494
01495
01496 ::operator delete(p);
01497 }
01498
01499
01500
01501
01502
01503
01504
01505
01506
01507
01508
01509
01510 profilematrix & profilematrix::datri(void)
01511 {
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522 double zero = 0.0;
01523 double one = 1.0;
01524 double tol = sqrt(d_macheps());
01525
01526
01527
01528 double dimx = zero;
01529 double dimn = zero;
01530
01531
01532
01533 int j = 1;
01534 for ( j=1 ; j<=pc_profilematrix_rep->neq ; j++ )
01535
01536
01537 if ( dimn < fabs(pc_profilematrix_rep->ad[j-1]) )
01538 dimn = fabs(pc_profilematrix_rep->ad[j-1]);
01539
01540 double dfig = zero;
01541
01542
01543 int jd = 1;
01544
01545
01546 int jr = 0;
01547 int jh = 0;
01548 int is = 0;
01549 int ie = 0;
01550 int id = 0;
01551 int ih = 0;
01552 int jrh = 0;
01553 int idh = 0;
01554 double dd = 0;
01555
01556
01557 double ifig = 0;
01558 double daval = 0.0;
01559
01560
01561 for ( j=1 ; j<=pc_profilematrix_rep->neq ; j++ )
01562 {
01563
01564 jr = jd + 1;
01565
01566 jd = pc_profilematrix_rep->jp[j-1];
01567
01568 jh = jd -jr;
01569
01570 if ( jh > 0 )
01571 {
01572
01573 is = j - jh;
01574
01575 ie = j - 1;
01576
01577
01578 if ( pc_profilematrix_rep->ad[j-1] == zero )
01579 daval = datest((pc_profilematrix_rep->ad+jr-1), jh);
01580
01581 for ( int i=is ; i<=ie ; i++ )
01582 {
01583
01584 jr = jr + 1;
01585
01586 id = pc_profilematrix_rep->jp[i-1];
01587
01588
01589 ih = id - pc_profilematrix_rep->jp[i-1-1];
01590 if (ih >(i-is+1)) ih = i-is+1;
01591
01592 if ( ih > 0 )
01593 {
01594
01595 jrh = jr - ih;
01596
01597 idh = id -ih + 1;
01598
01599 pc_profilematrix_rep->au[jr-1] =
01600 pc_profilematrix_rep->au[jr-1] -
01601 dot((pc_profilematrix_rep->au+jrh-1),
01602 (pc_profilematrix_rep->al+idh-1), ih);
01603
01604 if ( pc_profilematrix_rep->flag == 'N' )
01605 pc_profilematrix_rep->al[jr-1] =
01606 pc_profilematrix_rep->al[jr-1] -
01607 dot((pc_profilematrix_rep->al+jrh-1),
01608 (pc_profilematrix_rep->au+idh-1), ih);
01609
01610 }
01611
01612
01613 }
01614
01615 }
01616
01617
01618 if ( jh >= 0 )
01619 {
01620
01621 dd = pc_profilematrix_rep->ad[j-1];
01622
01623 jr = jd - jh;
01624
01625 jrh = j - jh - 1;
01626
01627 dredu((pc_profilematrix_rep->al+jr-1),
01628 (pc_profilematrix_rep->au+jr-1),
01629 (pc_profilematrix_rep->ad+jrh-1),
01630 (jh+1),
01631 (pc_profilematrix_rep->flag),
01632 (pc_profilematrix_rep->ad+j-1) );
01633
01634
01635 if ( (fabs(pc_profilematrix_rep->ad[j-1])<(tol*fabs(dd))) )
01636 ::printf("***DATRI WARNING 1***\n Loss of at least N digits in reducing diagonal of equation %d\n",j);
01637
01638 if ( (dd<zero) && (pc_profilematrix_rep->ad[j-1]>zero) )
01639 ::printf("***DATRI WARNING 2***\n Sign of diagonal changed when reducing equation %d\n",j);
01640
01641 if ( (dd>zero) && (pc_profilematrix_rep->ad[j-1]<zero) )
01642 ::printf("***DATRI WARNING 2***\n Sign of diagonal changed when reducing equation %d\n",j);
01643
01644 if ( (pc_profilematrix_rep->ad[j-1]==zero) )
01645 ::printf("***DATRI WARNING 3***\n Reduced diagonal is zero for equation %d\n",j);
01646
01647 if ( (dd==zero) && (jh>0) )
01648
01649 if ( (fabs(pc_profilematrix_rep->ad[j-1])<(tol*daval)) )
01650 ::printf("***DATRI WARNING 4***\n Rank failure for zero unreduced diagonal in equation %d\n",j);
01651
01652
01653 }
01654
01655
01656 if ( pc_profilematrix_rep->ad[j-1] != zero )
01657 {
01658
01659
01660 if (dimx < fabs(pc_profilematrix_rep->ad[j-1]))
01661 dimx = fabs(pc_profilematrix_rep->ad[j-1]);
01662
01663
01664 if (dimn > fabs(pc_profilematrix_rep->ad[j-1]))
01665 dimn = fabs(pc_profilematrix_rep->ad[j-1]);
01666
01667
01668 if (dfig <fabs(dd/pc_profilematrix_rep->ad[j-1]))
01669 dfig=fabs(dd/pc_profilematrix_rep->ad[j-1]);
01670
01671 pc_profilematrix_rep->ad[j-1] = one/pc_profilematrix_rep->ad[j-1];
01672
01673 }
01674
01675 }
01676
01677
01678 dd = zero;
01679
01680 if ( dimn != zero ) dd = dimx/dimn;
01681
01682 ifig = log (dfig) + 0.6;
01683
01684 ::printf("\n-------- Condition check:\n D-max %f\n D-min %f\n Ratio %f\n Maximum no. diagonal digits lost: %f\n",
01685 dimx , dimn, dd, ifig);
01686
01687
01688
01689
01690
01691 return *this;
01692 }
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703
01704
01705 double * profilematrix::dasol(double * b)
01706 {
01707
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717 double zero = 0.0;
01718
01719
01720
01721
01722
01723 int jr = 0;
01724 int jh = 0;
01725 double bd = 0.0;
01726 int is = 1;
01727 for ( is=1 ; is<=pc_profilematrix_rep->neq ; is++ )
01728 {
01729 if ( b[is-1] != zero ) break;
01730 }
01731
01732
01733 if ( is > pc_profilematrix_rep->neq )
01734 {
01735 ::printf("***DASOL WARNING 1***\n Zero right-hand-side vector\n");
01736 return b;
01737 }
01738
01739
01740 if ( is < pc_profilematrix_rep->neq )
01741 {
01742
01743
01744
01745 for ( int j=(is+1) ; j<=pc_profilematrix_rep->neq ; j++ )
01746 {
01747
01748 jr = pc_profilematrix_rep->jp[j-1-1];
01749
01750 jh = pc_profilematrix_rep->jp[j-1] - jr;
01751
01752 if ( jh > 0 )
01753 {
01754
01755 b[j-1] = b[j-1] -
01756 dot((pc_profilematrix_rep->al+jr+1-1),
01757 (b+j-jh-1), jh);
01758 }
01759
01760
01761 }
01762
01763 }
01764
01765
01766 double energy = zero;
01767
01768 int j = is;
01769 for ( j=is ; j<=pc_profilematrix_rep->neq ; j++ )
01770 {
01771
01772 bd = b[j-1];
01773
01774 b[j-1] = b[j-1]*pc_profilematrix_rep->ad[j-1];
01775
01776 energy = energy + bd*b[j-1];
01777
01778 }
01779
01780
01781 if ( pc_profilematrix_rep->neq > 1 )
01782 {
01783
01784 for ( j=pc_profilematrix_rep->neq ; j>=2 ; j-- )
01785 {
01786
01787 jr = pc_profilematrix_rep->jp[j-1-1];
01788
01789 jh = pc_profilematrix_rep->jp[j-1] - jr;
01790
01791 if ( jh > 0 )
01792 {
01793
01794 saxpb((pc_profilematrix_rep->au+jr+1-1),
01795 (b+j-jh-1),
01796 (-(b[j-1])),
01797 jh,
01798 (b+j-jh-1) );
01799
01800 }
01801
01802 }
01803
01804 }
01805
01806 return b;
01807
01808
01809 }
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822 double profilematrix::datest(double* au, int jh)
01823 {
01824 double daval = 0.0;
01825 for ( int j=1 ; j<=jh ; j++ )
01826 daval += fabs(au[j-1]);
01827 return daval;
01828 }
01829
01830 double profilematrix::dot(double* a, double* b, int n)
01831 {
01832 double dot = 0.0;
01833 for ( int i=1 ; i<=n ; i++ )
01834 dot += a[i-1]*b[i-1];
01835 return dot;
01836 }
01837
01838
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850
01851
01852
01853
01854
01855
01856
01857
01858
01859
01860
01861
01862 void profilematrix::dredu(double* al,
01863 double* au,
01864 double* ad,
01865 int jh,
01866 char flag,
01867 double* dj)
01868 {
01869 double ud = 0.0;
01870 if ( flag == 'N' )
01871 {
01872 for ( int j=1 ; j<=jh ; j++ )
01873 {
01874 au[j-1] = au[j-1]*ad[j-1];
01875 *dj = *dj - al[j-1]*au[j-1];
01876 al[j-1] = al[j-1]*ad[j-1];
01877 }
01878 }
01879 else
01880 {
01881 for ( int j=1 ; j<=jh ; j++ )
01882 {
01883 ud = au[j-1]*ad[j-1];
01884 *dj = *dj - au[j-1]*ud;
01885 au[j-1] = ud;
01886 }
01887 }
01888 }
01889
01890
01891
01892
01893
01894
01895
01896
01897
01898
01899 void profilematrix::saxpb(double* a,
01900 double* b,
01901 double x,
01902 int jh,
01903 double* c)
01904 {
01905 for ( int k=1 ; k<=jh ; k++ )
01906 c[k-1] = a[k-1] * x + b[k-1];
01907 }
01908
01909
01910 #endif
01911