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
00031 #include <stdio.h>
00032 #include <stdlib.h>
00033 #include <string.h>
00034 #include <math.h>
00035 #include <float.h>
00036
00037 #include "compiler.h"
00038 #include "sba.h"
00039
00040 #ifdef SBA_APPEND_UNDERSCORE_SUFFIX
00041 #define F77_FUNC(func) func ## _
00042 #else
00043 #define F77_FUNC(func) func
00044 #endif
00045
00046
00047
00048
00049
00050 extern int F77_FUNC(dgeqrf)(int *m, int *n, double *a, int *lda, double *tau, double *work, int *lwork, int *info);
00051 extern int F77_FUNC(dorgqr)(int *m, int *n, int *k, double *a, int *lda, double *tau, double *work, int *lwork, int *info);
00052
00053
00054 extern int F77_FUNC(dtrtrs)(char *uplo, char *trans, char *diag, int *n, int *nrhs, double *a, int *lda, double *b, int *ldb, int *info);
00055
00056
00057 extern int F77_FUNC(dpotf2)(char *uplo, int *n, double *a, int *lda, int *info);
00058 extern int F77_FUNC(dpotrf)(char *uplo, int *n, double *a, int *lda, int *info);
00059 extern int F77_FUNC(dpotrs)(char *uplo, int *n, int *nrhs, double *a, int *lda, double *b, int *ldb, int *info);
00060 extern int F77_FUNC(dpotri)(char *uplo, int *n, double *a, int *lda, int *info);
00061
00062
00063 extern int F77_FUNC(dgetrf)(int *m, int *n, double *a, int *lda, int *ipiv, int *info);
00064 extern int F77_FUNC(dgetf2)(int *m, int *n, double *a, int *lda, int *ipiv, int *info);
00065 extern int F77_FUNC(dgetrs)(char *trans, int *n, int *nrhs, double *a, int *lda, int *ipiv, double *b, int *ldb, int *info);
00066 extern int F77_FUNC(dgetri)(int *n, double *a, int *lda, int *ipiv, double *work, int *lwork, int *info);
00067
00068
00069 extern int F77_FUNC(dgesvd)(char *jobu, char *jobvt, int *m, int *n,
00070 double *a, int *lda, double *s, double *u, int *ldu,
00071 double *vt, int *ldvt, double *work, int *lwork,
00072 int *info);
00073
00074
00075 extern int F77_FUNC(dgesdd)(char *jobz, int *m, int *n, double *a, int *lda,
00076 double *s, double *u, int *ldu, double *vt, int *ldvt,
00077 double *work, int *lwork, int *iwork, int *info);
00078
00079
00080
00081 extern int F77_FUNC(dsytrf)(char *uplo, int *n, double *a, int *lda, int *ipiv, double *work, int *lwork, int *info);
00082 extern int F77_FUNC(dsytrs)(char *uplo, int *n, int *nrhs, double *a, int *lda, int *ipiv, double *b, int *ldb, int *info);
00083 extern int F77_FUNC(dsytri)(char *uplo, int *n, double *a, int *lda, int *ipiv, double *work, int *info);
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 int sba_Axb_QR(double *A, double *B, double *x, int m, int iscolmaj)
00105 {
00106 static double *buf=NULL;
00107 static int buf_sz=0, nb=0;
00108
00109 double *a, *r, *tau, *work;
00110 int a_sz, r_sz, tau_sz, tot_sz;
00111 register int i, j;
00112 int info, worksz, nrhs=1;
00113 register double sum;
00114
00115 if(A==NULL){
00116 if(buf) free(buf);
00117 buf=NULL;
00118 buf_sz=0;
00119
00120 return 1;
00121 }
00122
00123
00124 a_sz=(iscolmaj)? 0 : m*m;
00125 r_sz=m*m;
00126 tau_sz=m;
00127 if(!nb){
00128 #ifndef SBA_LS_SCARCE_MEMORY
00129 double tmp;
00130
00131 worksz=-1;
00132 F77_FUNC(dgeqrf)((int *)&m, (int *)&m, NULL, (int *)&m, NULL, (double *)&tmp, (int *)&worksz, (int *)&info);
00133 nb=((int)tmp)/m;
00134 #else
00135 nb=1;
00136 #endif
00137 }
00138 worksz=nb*m;
00139 tot_sz=a_sz + r_sz + tau_sz + worksz;
00140
00141 if(tot_sz>buf_sz){
00142 if(buf) free(buf);
00143
00144 buf_sz=tot_sz;
00145 buf=(double *)malloc(buf_sz*sizeof(double));
00146 if(!buf){
00147 fprintf(stderr, "memory allocation in sba_Axb_QR() failed!\n");
00148 exit(1);
00149 }
00150 }
00151
00152 if(!iscolmaj){
00153 a=buf;
00154
00155 for(i=0; i<m; ++i)
00156 for(j=0; j<m; ++j)
00157 a[i+j*m]=A[i*m+j];
00158 }
00159 else a=A;
00160
00161 r=buf+a_sz;
00162 tau=r+r_sz;
00163 work=tau+tau_sz;
00164
00165
00166 F77_FUNC(dgeqrf)((int *)&m, (int *)&m, a, (int *)&m, tau, work, (int *)&worksz, (int *)&info);
00167
00168 if(info!=0){
00169 if(info<0){
00170 fprintf(stderr, "LAPACK error: illegal value for argument %d of dgeqrf in sba_Axb_QR()\n", -info);
00171 exit(1);
00172 }
00173 else{
00174 fprintf(stderr, "Unknown LAPACK error %d for dgeqrf in sba_Axb_QR()\n", info);
00175 return 0;
00176 }
00177 }
00178
00179
00180 for(i=0; i<r_sz; ++i)
00181 r[i]=a[i];
00182
00183
00184 F77_FUNC(dorgqr)((int *)&m, (int *)&m, (int *)&m, a, (int *)&m, tau, work, (int *)&worksz, (int *)&info);
00185 if(info!=0){
00186 if(info<0){
00187 fprintf(stderr, "LAPACK error: illegal value for argument %d of dorgqr in sba_Axb_QR()\n", -info);
00188 exit(1);
00189 }
00190 else{
00191 fprintf(stderr, "Unknown LAPACK error (%d) in sba_Axb_QR()\n", info);
00192 return 0;
00193 }
00194 }
00195
00196
00197 for(i=0; i<m; ++i){
00198 for(j=0, sum=0.0; j<m; ++j)
00199 sum+=a[i*m+j]*B[j];
00200 x[i]=sum;
00201 }
00202
00203
00204 F77_FUNC(dtrtrs)("U", "N", "N", (int *)&m, (int *)&nrhs, r, (int *)&m, x, (int *)&m, &info);
00205
00206 if(info!=0){
00207 if(info<0){
00208 fprintf(stderr, "LAPACK error: illegal value for argument %d of dtrtrs in sba_Axb_QR()\n", -info);
00209 exit(1);
00210 }
00211 else{
00212 fprintf(stderr, "LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in sba_Axb_QR()\n", info);
00213 return 0;
00214 }
00215 }
00216
00217 return 1;
00218 }
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240 int sba_Axb_QRnoQ(double *A, double *B, double *x, int m, int iscolmaj)
00241 {
00242 static double *buf=NULL;
00243 static int buf_sz=0, nb=0;
00244
00245 double *a, *tau, *work;
00246 int a_sz, tau_sz, tot_sz;
00247 register int i, j;
00248 int info, worksz, nrhs=1;
00249 register double sum;
00250
00251 if(A==NULL){
00252 if(buf) free(buf);
00253 buf=NULL;
00254 buf_sz=0;
00255
00256 return 1;
00257 }
00258
00259
00260 a_sz=(iscolmaj)? 0 : m*m;
00261 tau_sz=m;
00262 if(!nb){
00263 #ifndef SBA_LS_SCARCE_MEMORY
00264 double tmp;
00265
00266 worksz=-1;
00267 F77_FUNC(dgeqrf)((int *)&m, (int *)&m, NULL, (int *)&m, NULL, (double *)&tmp, (int *)&worksz, (int *)&info);
00268 nb=((int)tmp)/m;
00269 #else
00270 nb=1;
00271 #endif
00272 }
00273 worksz=nb*m;
00274 tot_sz=a_sz + tau_sz + worksz;
00275
00276 if(tot_sz>buf_sz){
00277 if(buf) free(buf);
00278
00279 buf_sz=tot_sz;
00280 buf=(double *)malloc(buf_sz*sizeof(double));
00281 if(!buf){
00282 fprintf(stderr, "memory allocation in sba_Axb_QRnoQ() failed!\n");
00283 exit(1);
00284 }
00285 }
00286
00287 if(!iscolmaj){
00288 a=buf;
00289
00290 for(i=0; i<m; ++i)
00291 for(j=0; j<m; ++j)
00292 a[i+j*m]=A[i*m+j];
00293 }
00294 else a=A;
00295
00296 tau=buf+a_sz;
00297 work=tau+tau_sz;
00298
00299
00300 for(i=0; i<m; ++i){
00301 for(j=0, sum=0.0; j<m; ++j)
00302 sum+=a[i*m+j]*B[j];
00303 x[i]=sum;
00304 }
00305
00306
00307 F77_FUNC(dgeqrf)((int *)&m, (int *)&m, a, (int *)&m, tau, work, (int *)&worksz, (int *)&info);
00308
00309 if(info!=0){
00310 if(info<0){
00311 fprintf(stderr, "LAPACK error: illegal value for argument %d of dgeqrf in sba_Axb_QRnoQ()\n", -info);
00312 exit(1);
00313 }
00314 else{
00315 fprintf(stderr, "Unknown LAPACK error %d for dgeqrf in sba_Axb_QRnoQ()\n", info);
00316 return 0;
00317 }
00318 }
00319
00320
00321
00322
00323 F77_FUNC(dtrtrs)("U", "T", "N", (int *)&m, (int *)&nrhs, a, (int *)&m, x, (int *)&m, &info);
00324
00325 if(info!=0){
00326 if(info<0){
00327 fprintf(stderr, "LAPACK error: illegal value for argument %d of dtrtrs in sba_Axb_QRnoQ()\n", -info);
00328 exit(1);
00329 }
00330 else{
00331 fprintf(stderr, "LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in sba_Axb_QRnoQ()\n", info);
00332 return 0;
00333 }
00334 }
00335
00336
00337 F77_FUNC(dtrtrs)("U", "N", "N", (int *)&m, (int *)&nrhs, a, (int *)&m, x, (int *)&m, &info);
00338
00339 if(info!=0){
00340 if(info<0){
00341 fprintf(stderr, "LAPACK error: illegal value for argument %d of dtrtrs in sba_Axb_QRnoQ()\n", -info);
00342 exit(1);
00343 }
00344 else{
00345 fprintf(stderr, "LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in sba_Axb_QRnoQ()\n", info);
00346 return 0;
00347 }
00348 }
00349
00350 return 1;
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373 int sba_Axb_Chol(double *A, double *B, double *x, int m, int iscolmaj)
00374 {
00375 static double *buf=NULL;
00376 static int buf_sz=0;
00377
00378 double *a;
00379 int a_sz, tot_sz;
00380 register int i, j;
00381 int info, nrhs=1;
00382
00383 if(A==NULL){
00384 if(buf) free(buf);
00385 buf=NULL;
00386 buf_sz=0;
00387
00388 return 1;
00389 }
00390
00391
00392 a_sz=(iscolmaj)? 0 : m*m;
00393 tot_sz=a_sz;
00394
00395 if(tot_sz>buf_sz){
00396 if(buf) free(buf);
00397
00398 buf_sz=tot_sz;
00399 buf=(double *)malloc(buf_sz*sizeof(double));
00400 if(!buf){
00401 fprintf(stderr, "memory allocation in sba_Axb_Chol() failed!\n");
00402 exit(1);
00403 }
00404 }
00405
00406 if(!iscolmaj){
00407 a=buf;
00408
00409
00410
00411
00412 for(i=0; i<m; ++i){
00413 a[i]=A[i];
00414 x[i]=B[i];
00415 }
00416 for(j=m*m; i<j; ++i)
00417 a[i]=A[i];
00418 }
00419 else{
00420 a=A;
00421 for(i=0; i<m; ++i)
00422 x[i]=B[i];
00423 }
00424
00425
00426
00427 F77_FUNC(dpotrf)("U", (int *)&m, a, (int *)&m, (int *)&info);
00428
00429 if(info!=0){
00430 if(info<0){
00431 fprintf(stderr, "LAPACK error: illegal value for argument %d of dpotf2/dpotrf in sba_Axb_Chol()\n", -info);
00432 exit(1);
00433 }
00434 else{
00435 fprintf(stderr, "LAPACK error: the leading minor of order %d is not positive definite,\nthe factorization could not be completed for dpotf2/dpotrf in sba_Axb_Chol()\n", info);
00436 return 0;
00437 }
00438 }
00439
00440
00441 #if 1
00442
00443 F77_FUNC(dpotrs)("U", (int *)&m, (int *)&nrhs, a, (int *)&m, x, (int *)&m, &info);
00444 if(info<0){
00445 fprintf(stderr, "LAPACK error: illegal value for argument %d of dpotrs in sba_Axb_Chol()\n", -info);
00446 exit(1);
00447 }
00448 #else
00449
00450 F77_FUNC(dtrtrs)("U", "T", "N", (int *)&m, (int *)&nrhs, a, (int *)&m, x, (int *)&m, &info);
00451
00452 if(info!=0){
00453 if(info<0){
00454 fprintf(stderr, "LAPACK error: illegal value for argument %d of dtrtrs in sba_Axb_Chol()\n", -info);
00455 exit(1);
00456 }
00457 else{
00458 fprintf(stderr, "LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in sba_Axb_Chol()\n", info);
00459 return 0;
00460 }
00461 }
00462
00463
00464 F77_FUNC(dtrtrs)("U", "N", "N", (int *)&m, (int *)&nrhs, a, (int *)&m, x, (int *)&m, &info);
00465
00466 if(info!=0){
00467 if(info<0){
00468 fprintf(stderr, "LAPACK error: illegal value for argument %d of dtrtrs in sba_Axb_Chol()\n", -info);
00469 exit(1);
00470 }
00471 else{
00472 fprintf(stderr, "LAPACK error: the %d-th diagonal element of A is zero (singular matrix) in sba_Axb_Chol()\n", info);
00473 return 0;
00474 }
00475 }
00476 #endif
00477
00478 return 1;
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501 int sba_Axb_LU(double *A, double *B, double *x, int m, int iscolmaj)
00502 {
00503 static double *buf=NULL;
00504 static int buf_sz=0;
00505
00506 int a_sz, ipiv_sz, tot_sz;
00507 register int i, j;
00508 int info, *ipiv, nrhs=1;
00509 double *a;
00510
00511 if(A==NULL){
00512 if(buf) free(buf);
00513 buf=NULL;
00514 buf_sz=0;
00515
00516 return 1;
00517 }
00518
00519
00520 ipiv_sz=m;
00521 a_sz=(iscolmaj)? 0 : m*m;
00522 tot_sz=a_sz*sizeof(double) + ipiv_sz*sizeof(int);
00523
00524 if(tot_sz>buf_sz){
00525 if(buf) free(buf);
00526
00527 buf_sz=tot_sz;
00528 buf=(double *)malloc(buf_sz);
00529 if(!buf){
00530 fprintf(stderr, "memory allocation in sba_Axb_LU() failed!\n");
00531 exit(1);
00532 }
00533 }
00534
00535 if(!iscolmaj){
00536 a=buf;
00537 ipiv=(int *)(a+a_sz);
00538
00539
00540 for(i=0; i<m; ++i){
00541 for(j=0; j<m; ++j)
00542 a[i+j*m]=A[i*m+j];
00543
00544 x[i]=B[i];
00545 }
00546 }
00547 else{
00548 a=A;
00549 for(i=0; i<m; ++i)
00550 x[i]=B[i];
00551 ipiv=(int *)buf;
00552 }
00553
00554
00555 F77_FUNC(dgetrf)((int *)&m, (int *)&m, a, (int *)&m, ipiv, (int *)&info);
00556 if(info!=0){
00557 if(info<0){
00558 fprintf(stderr, "argument %d of dgetrf illegal in sba_Axb_LU()\n", -info);
00559 exit(1);
00560 }
00561 else{
00562 fprintf(stderr, "singular matrix A for dgetrf in sba_Axb_LU()\n");
00563 return 0;
00564 }
00565 }
00566
00567
00568 F77_FUNC(dgetrs)("N", (int *)&m, (int *)&nrhs, a, (int *)&m, ipiv, x, (int *)&m, (int *)&info);
00569 if(info!=0){
00570 if(info<0){
00571 fprintf(stderr, "argument %d of dgetrs illegal in sba_Axb_LU()\n", -info);
00572 exit(1);
00573 }
00574 else{
00575 fprintf(stderr, "unknown error for dgetrs in sba_Axb_LU()\n");
00576 return 0;
00577 }
00578 }
00579
00580 return 1;
00581 }
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 int sba_Axb_SVD(double *A, double *B, double *x, int m, int iscolmaj)
00603 {
00604 static double *buf=NULL;
00605 static int buf_sz=0;
00606 static double eps=-1.0;
00607
00608 register int i, j;
00609 double *a, *u, *s, *vt, *work;
00610 int a_sz, u_sz, s_sz, vt_sz, tot_sz;
00611 double thresh, one_over_denom;
00612 register double sum;
00613 int info, rank, worksz, *iwork, iworksz;
00614
00615 if(A==NULL){
00616 if(buf) free(buf);
00617 buf=NULL;
00618 buf_sz=0;
00619
00620 return 1;
00621 }
00622
00623
00624 #ifndef SBA_LS_SCARCE_MEMORY
00625 worksz=-1;
00626
00627 F77_FUNC(dgesdd)("A", (int *)&m, (int *)&m, NULL, (int *)&m, NULL, NULL, (int *)&m, NULL, (int *)&m,
00628 (double *)&thresh, (int *)&worksz, NULL, &info);
00629
00630
00631 worksz=(int)thresh;
00632 #else
00633 worksz=m*(7*m+4);
00634
00635 #endif
00636 iworksz=8*m;
00637 a_sz=(!iscolmaj)? m*m : 0;
00638 u_sz=m*m; s_sz=m; vt_sz=m*m;
00639
00640 tot_sz=(a_sz + u_sz + s_sz + vt_sz + worksz)*sizeof(double) + iworksz*sizeof(int);
00641
00642 if(tot_sz>buf_sz){
00643 if(buf) free(buf);
00644
00645 buf_sz=tot_sz;
00646 buf=(double *)malloc(buf_sz);
00647 if(!buf){
00648 fprintf(stderr, "memory allocation in sba_Axb_SVD() failed!\n");
00649 exit(1);
00650 }
00651 }
00652
00653 if(!iscolmaj){
00654 a=buf;
00655 u=a+a_sz;
00656
00657 for(i=0; i<m; ++i)
00658 for(j=0; j<m; ++j)
00659 a[i+j*m]=A[i*m+j];
00660 }
00661 else{
00662 a=A;
00663 u=buf;
00664 }
00665
00666 s=u+u_sz;
00667 vt=s+s_sz;
00668 work=vt+vt_sz;
00669 iwork=(int *)(work+worksz);
00670
00671
00672 F77_FUNC(dgesdd)("A", (int *)&m, (int *)&m, a, (int *)&m, s, u, (int *)&m, vt, (int *)&m, work, (int *)&worksz, iwork, &info);
00673
00674
00675
00676 if(info!=0){
00677 if(info<0){
00678 fprintf(stderr, "LAPACK error: illegal value for argument %d of dgesdd/dgesvd in sba_Axb_SVD()\n", -info);
00679 exit(1);
00680 }
00681 else{
00682 fprintf(stderr, "LAPACK error: dgesdd (dbdsdc)/dgesvd (dbdsqr) failed to converge in sba_Axb_SVD() [info=%d]\n", info);
00683
00684 return 0;
00685 }
00686 }
00687
00688 if(eps<0.0){
00689 double aux;
00690
00691
00692 for(eps=1.0; aux=eps+1.0, aux-1.0>0.0; eps*=0.5)
00693 ;
00694 eps*=2.0;
00695 }
00696
00697
00698 memset(a, 0, m*m*sizeof(double));
00699 for(rank=0, thresh=eps*s[0]; rank<m && s[rank]>thresh; ++rank){
00700 one_over_denom=1.0/s[rank];
00701
00702 for(j=0; j<m; ++j)
00703 for(i=0; i<m; ++i)
00704 a[i*m+j]+=vt[rank+i*m]*u[j+rank*m]*one_over_denom;
00705 }
00706
00707
00708 for(i=0; i<m; ++i){
00709 for(j=0, sum=0.0; j<m; ++j)
00710 sum+=a[i*m+j]*B[j];
00711 x[i]=sum;
00712 }
00713
00714 return 1;
00715 }
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738 int sba_Axb_BK(double *A, double *B, double *x, int m, int iscolmaj)
00739 {
00740 static double *buf=NULL;
00741 static int buf_sz=0, nb=0;
00742
00743 int a_sz, ipiv_sz, work_sz, tot_sz;
00744 register int i, j;
00745 int info, *ipiv, nrhs=1;
00746 double *a, *work;
00747
00748 if(A==NULL){
00749 if(buf) free(buf);
00750 buf=NULL;
00751 buf_sz=0;
00752
00753 return 1;
00754 }
00755
00756
00757 ipiv_sz=m;
00758 a_sz=(iscolmaj)? 0 : m*m;
00759 if(!nb){
00760 #ifndef SBA_LS_SCARCE_MEMORY
00761 double tmp;
00762
00763 work_sz=-1;
00764 F77_FUNC(dsytrf)("U", (int *)&m, NULL, (int *)&m, NULL, (double *)&tmp, (int *)&work_sz, (int *)&info);
00765 nb=((int)tmp)/m;
00766 #else
00767 nb=-1;
00768 #endif
00769 }
00770 work_sz=(nb!=-1)? nb*m : 1;
00771 tot_sz=(a_sz + work_sz)*sizeof(double) + ipiv_sz*sizeof(int);
00772
00773 if(tot_sz>buf_sz){
00774 if(buf) free(buf);
00775
00776 buf_sz=tot_sz;
00777 buf=(double *)malloc(buf_sz);
00778 if(!buf){
00779 fprintf(stderr, "memory allocation in sba_Axb_BK() failed!\n");
00780 exit(1);
00781 }
00782 }
00783
00784 if(!iscolmaj){
00785 a=buf;
00786 work=a+a_sz;
00787
00788
00789
00790
00791 for(i=0; i<m; ++i){
00792 a[i]=A[i];
00793 x[i]=B[i];
00794 }
00795 for(j=m*m; i<j; ++i)
00796 a[i]=A[i];
00797 }
00798 else{
00799 a=A;
00800 for(i=0; i<m; ++i)
00801 x[i]=B[i];
00802 work=buf;
00803 }
00804 ipiv=(int *)(work+work_sz);
00805
00806
00807 F77_FUNC(dsytrf)("U", (int *)&m, a, (int *)&m, ipiv, work, (int *)&work_sz, (int *)&info);
00808 if(info!=0){
00809 if(info<0){
00810 fprintf(stderr, "argument %d of dsytrf illegal in sba_Axb_BK()\n", -info);
00811 exit(1);
00812 }
00813 else{
00814 fprintf(stderr, "singular block diagonal matrix D for dsytrf in sba_Axb_BK() [D(%d, %d) is zero]\n", info, info);
00815 return 0;
00816 }
00817 }
00818
00819
00820 F77_FUNC(dsytrs)("U", (int *)&m, (int *)&nrhs, a, (int *)&m, ipiv, x, (int *)&m, (int *)&info);
00821 if(info!=0){
00822 if(info<0){
00823 fprintf(stderr, "argument %d of dsytrs illegal in sba_Axb_BK()\n", -info);
00824 exit(1);
00825 }
00826 else{
00827 fprintf(stderr, "unknown error for dsytrs in sba_Axb_BK()\n");
00828 return 0;
00829 }
00830 }
00831
00832 return 1;
00833 }
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847 int sba_symat_invert_LU(double *A, int m)
00848 {
00849 static double *buf=NULL;
00850 static int buf_sz=0, nb=0;
00851
00852 int a_sz, ipiv_sz, work_sz, tot_sz;
00853 register int i, j;
00854 int info, *ipiv;
00855 double *a, *work;
00856
00857 if(A==NULL){
00858 if(buf) free(buf);
00859 buf=NULL;
00860 buf_sz=0;
00861
00862 return 1;
00863 }
00864
00865
00866 ipiv_sz=m;
00867 a_sz=m*m;
00868 if(!nb){
00869 #ifndef SBA_LS_SCARCE_MEMORY
00870 double tmp;
00871
00872 work_sz=-1;
00873 F77_FUNC(dgetri)((int *)&m, NULL, (int *)&m, NULL, (double *)&tmp, (int *)&work_sz, (int *)&info);
00874 nb=((int)tmp)/m;
00875 #else
00876 nb=1;
00877 #endif
00878 }
00879 work_sz=nb*m;
00880 tot_sz=(a_sz + work_sz)*sizeof(double) + ipiv_sz*sizeof(int);
00881
00882 if(tot_sz>buf_sz){
00883 if(buf) free(buf);
00884
00885 buf_sz=tot_sz;
00886 buf=(double *)malloc(buf_sz);
00887 if(!buf){
00888 fprintf(stderr, "memory allocation in sba_symat_invert_LU() failed!\n");
00889 exit(1);
00890 }
00891 }
00892
00893 a=buf;
00894 work=a+a_sz;
00895 ipiv=(int *)(work+work_sz);
00896
00897
00898 for(i=0; i<m; ++i)
00899 for(j=i; j<m; ++j)
00900 a[i+j*m]=a[j+i*m]=A[i*m+j];
00901
00902
00903 F77_FUNC(dgetrf)((int *)&m, (int *)&m, a, (int *)&m, ipiv, (int *)&info);
00904 if(info!=0){
00905 if(info<0){
00906 fprintf(stderr, "argument %d of dgetrf illegal in sba_symat_invert_LU()\n", -info);
00907 exit(1);
00908 }
00909 else{
00910 fprintf(stderr, "singular matrix A for dgetrf in sba_symat_invert_LU()\n");
00911 return 0;
00912 }
00913 }
00914
00915
00916 F77_FUNC(dgetri)((int *)&m, a, (int *)&m, ipiv, work, (int *)&work_sz, (int *)&info);
00917 if(info!=0){
00918 if(info<0){
00919 fprintf(stderr, "argument %d of dgetri illegal in sba_symat_invert_LU()\n", -info);
00920 exit(1);
00921 }
00922 else{
00923 fprintf(stderr, "singular matrix A for dgetri in sba_symat_invert_LU()\n");
00924 return 0;
00925 }
00926 }
00927
00928
00929 for(i=0; i<m; ++i)
00930 for(j=0; j<=i; ++j)
00931 A[i*m+j]=a[i+j*m];
00932
00933 return 1;
00934 }
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946
00947
00948
00949 int sba_symat_invert_Chol(double *A, int m)
00950 {
00951 static double *buf=NULL;
00952 static int buf_sz=0;
00953
00954 int a_sz, tot_sz;
00955 register int i, j;
00956 int info;
00957 double *a;
00958
00959 if(A==NULL){
00960 if(buf) free(buf);
00961 buf=NULL;
00962 buf_sz=0;
00963
00964 return 1;
00965 }
00966
00967
00968 a_sz=m*m;
00969 tot_sz=a_sz;
00970
00971 if(tot_sz>buf_sz){
00972 if(buf) free(buf);
00973
00974 buf_sz=tot_sz;
00975 buf=(double *)malloc(buf_sz*sizeof(double));
00976 if(!buf){
00977 fprintf(stderr, "memory allocation in sba_symat_invert_Chol() failed!\n");
00978 exit(1);
00979 }
00980 }
00981
00982 a=(double *)buf;
00983
00984
00985 for(i=0, j=a_sz; i<j; ++i)
00986 a[i]=A[i];
00987
00988
00989
00990 F77_FUNC(dpotf2)("L", (int *)&m, a, (int *)&m, (int *)&info);
00991
00992 if(info!=0){
00993 if(info<0){
00994 fprintf(stderr, "LAPACK error: illegal value for argument %d of dpotrf in sba_symat_invert_Chol()\n", -info);
00995 exit(1);
00996 }
00997 else{
00998 fprintf(stderr, "LAPACK error: the leading minor of order %d is not positive definite,\nthe factorization could not be completed for dpotrf in sba_symat_invert_Chol()\n", info);
00999 return 0;
01000 }
01001 }
01002
01003
01004 F77_FUNC(dpotri)("L", (int *)&m, a, (int *)&m, (int *)&info);
01005 if(info!=0){
01006 if(info<0){
01007 fprintf(stderr, "argument %d of dpotri illegal in sba_symat_invert_Chol()\n", -info);
01008 exit(1);
01009 }
01010 else{
01011 fprintf(stderr, "the (%d, %d) element of the factor U or L is zero, singular matrix A for dpotri in sba_symat_invert_Chol()\n", info, info);
01012 return 0;
01013 }
01014 }
01015
01016
01017 for(i=0; i<m; ++i)
01018 for(j=0; j<=i; ++j)
01019 A[i*m+j]=a[i+j*m];
01020
01021 return 1;
01022 }
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037 int sba_symat_invert_BK(double *A, int m)
01038 {
01039 static double *buf=NULL;
01040 static int buf_sz=0, nb=0;
01041
01042 int a_sz, ipiv_sz, work_sz, tot_sz;
01043 register int i, j;
01044 int info, *ipiv;
01045 double *a, *work;
01046
01047 if(A==NULL){
01048 if(buf) free(buf);
01049 buf=NULL;
01050 buf_sz=0;
01051
01052 return 1;
01053 }
01054
01055
01056 ipiv_sz=m;
01057 a_sz=m*m;
01058 if(!nb){
01059 #ifndef SBA_LS_SCARCE_MEMORY
01060 double tmp;
01061
01062 work_sz=-1;
01063 F77_FUNC(dsytrf)("L", (int *)&m, NULL, (int *)&m, NULL, (double *)&tmp, (int *)&work_sz, (int *)&info);
01064 nb=((int)tmp)/m;
01065 #else
01066 nb=-1;
01067 #endif
01068 }
01069 work_sz=(nb!=-1)? nb*m : 1;
01070 work_sz=(work_sz>=m)? work_sz : m;
01071 tot_sz=(a_sz + work_sz)*sizeof(double) + ipiv_sz*sizeof(int);
01072
01073 if(tot_sz>buf_sz){
01074 if(buf) free(buf);
01075
01076 buf_sz=tot_sz;
01077 buf=(double *)malloc(buf_sz);
01078 if(!buf){
01079 fprintf(stderr, "memory allocation in sba_symat_invert_BK() failed!\n");
01080 exit(1);
01081 }
01082 }
01083
01084 a=buf;
01085 work=a+a_sz;
01086 ipiv=(int *)(work+work_sz);
01087
01088
01089 for(i=0, j=a_sz; i<j; ++i)
01090 a[i]=A[i];
01091
01092
01093 F77_FUNC(dsytrf)("L", (int *)&m, a, (int *)&m, ipiv, work, (int *)&work_sz, (int *)&info);
01094 if(info!=0){
01095 if(info<0){
01096 fprintf(stderr, "argument %d of dsytrf illegal in sba_symat_invert_BK()\n", -info);
01097 exit(1);
01098 }
01099 else{
01100 fprintf(stderr, "singular block diagonal matrix D for dsytrf in sba_symat_invert_BK() [D(%d, %d) is zero]\n", info, info);
01101 return 0;
01102 }
01103 }
01104
01105
01106 F77_FUNC(dsytri)("L", (int *)&m, a, (int *)&m, ipiv, work, (int *)&info);
01107 if(info!=0){
01108 if(info<0){
01109 fprintf(stderr, "argument %d of dsytri illegal in sba_symat_invert_BK()\n", -info);
01110 exit(1);
01111 }
01112 else{
01113 fprintf(stderr, "D(%d, %d)=0, matrix is singular and its inverse could not be computed in sba_symat_invert_BK()\n", info, info);
01114 return 0;
01115 }
01116 }
01117
01118
01119 for(i=0; i<m; ++i)
01120 for(j=0; j<=i; ++j)
01121 A[i*m+j]=a[i+j*m];
01122
01123 return 1;
01124 }
01125
01126
01127 #define __CG_LINALG_BLOCKSIZE 8
01128
01129
01130
01131
01132
01133 inline static double dprod(const int n, const double *const x, const double *const y)
01134 {
01135 register int i, j1, j2, j3, j4, j5, j6, j7;
01136 int blockn;
01137 register double sum0=0.0, sum1=0.0, sum2=0.0, sum3=0.0,
01138 sum4=0.0, sum5=0.0, sum6=0.0, sum7=0.0;
01139
01140
01141
01142
01143 blockn = (n / __CG_LINALG_BLOCKSIZE) * __CG_LINALG_BLOCKSIZE;
01144
01145
01146 for(i=0; i<blockn; i+=__CG_LINALG_BLOCKSIZE){
01147 sum0+=x[i]*y[i];
01148 j1=i+1; sum1+=x[j1]*y[j1];
01149 j2=i+2; sum2+=x[j2]*y[j2];
01150 j3=i+3; sum3+=x[j3]*y[j3];
01151 j4=i+4; sum4+=x[j4]*y[j4];
01152 j5=i+5; sum5+=x[j5]*y[j5];
01153 j6=i+6; sum6+=x[j6]*y[j6];
01154 j7=i+7; sum7+=x[j7]*y[j7];
01155 }
01156
01157
01158
01159
01160
01161
01162
01163 if(i<n){
01164
01165
01166
01167
01168 switch(n - i){
01169 case 7 : sum0+=x[i]*y[i]; ++i;
01170 case 6 : sum1+=x[i]*y[i]; ++i;
01171 case 5 : sum2+=x[i]*y[i]; ++i;
01172 case 4 : sum3+=x[i]*y[i]; ++i;
01173 case 3 : sum4+=x[i]*y[i]; ++i;
01174 case 2 : sum5+=x[i]*y[i]; ++i;
01175 case 1 : sum6+=x[i]*y[i]; ++i;
01176 }
01177 }
01178
01179 return sum0+sum1+sum2+sum3+sum4+sum5+sum6+sum7;
01180 }
01181
01182
01183
01184
01185
01186
01187 inline static void daxpy(const int n, double *const z, const double *const x, const double a, const double *const y)
01188 {
01189 register int i, j1, j2, j3, j4, j5, j6, j7;
01190 int blockn;
01191
01192
01193
01194
01195 blockn = (n / __CG_LINALG_BLOCKSIZE) * __CG_LINALG_BLOCKSIZE;
01196
01197
01198 for(i=0; i<blockn; i+=__CG_LINALG_BLOCKSIZE){
01199 z[i]=x[i]+a*y[i];
01200 j1=i+1; z[j1]=x[j1]+a*y[j1];
01201 j2=i+2; z[j2]=x[j2]+a*y[j2];
01202 j3=i+3; z[j3]=x[j3]+a*y[j3];
01203 j4=i+4; z[j4]=x[j4]+a*y[j4];
01204 j5=i+5; z[j5]=x[j5]+a*y[j5];
01205 j6=i+6; z[j6]=x[j6]+a*y[j6];
01206 j7=i+7; z[j7]=x[j7]+a*y[j7];
01207 }
01208
01209
01210
01211
01212
01213
01214
01215 if(i<n){
01216
01217
01218
01219
01220 switch(n - i){
01221 case 7 : z[i]=x[i]+a*y[i]; ++i;
01222 case 6 : z[i]=x[i]+a*y[i]; ++i;
01223 case 5 : z[i]=x[i]+a*y[i]; ++i;
01224 case 4 : z[i]=x[i]+a*y[i]; ++i;
01225 case 3 : z[i]=x[i]+a*y[i]; ++i;
01226 case 2 : z[i]=x[i]+a*y[i]; ++i;
01227 case 1 : z[i]=x[i]+a*y[i]; ++i;
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 int sba_Axb_CG(double *A, double *B, double *x, int m, int niter, double eps, int prec, int iscolmaj)
01255 {
01256 static double *buf=NULL;
01257 static int buf_sz=0;
01258
01259 register int i, j;
01260 register double *aim;
01261 int iter, a_sz, res_sz, d_sz, q_sz, s_sz, wk_sz, z_sz, tot_sz;
01262 double *a, *res, *d, *q, *s, *wk, *z;
01263 double delta0, deltaold, deltanew, alpha, beta, eps_sq=eps*eps;
01264 register double sum;
01265 int rec_res;
01266
01267 if(A==NULL){
01268 if(buf) free(buf);
01269 buf=NULL;
01270 buf_sz=0;
01271
01272 return 1;
01273 }
01274
01275
01276 a_sz=(iscolmaj)? m*m : 0;
01277 res_sz=m; d_sz=m; q_sz=m;
01278 if(prec!=SBA_CG_NOPREC){
01279 s_sz=m; wk_sz=m;
01280 z_sz=(prec==SBA_CG_SSOR)? m : 0;
01281 }
01282 else
01283 s_sz=wk_sz=z_sz=0;
01284
01285 tot_sz=a_sz+res_sz+d_sz+q_sz+s_sz+wk_sz+z_sz;
01286
01287 if(tot_sz>buf_sz){
01288 if(buf) free(buf);
01289
01290 buf_sz=tot_sz;
01291 buf=(double *)malloc(buf_sz*sizeof(double));
01292 if(!buf){
01293 fprintf(stderr, "memory allocation request failed in sba_Axb_CG()\n");
01294 exit(1);
01295 }
01296 }
01297
01298 if(iscolmaj){
01299 a=buf;
01300
01301 for(i=0; i<m; ++i)
01302 for(j=0, aim=a+i*m; j<m; ++j)
01303 aim[j]=A[i+j*m];
01304 }
01305 else a=A;
01306
01307 res=buf+a_sz;
01308 d=res+res_sz;
01309 q=d+d_sz;
01310 if(prec!=SBA_CG_NOPREC){
01311 s=q+q_sz;
01312 wk=s+s_sz;
01313 z=(prec==SBA_CG_SSOR)? wk+wk_sz : NULL;
01314
01315 for(i=0; i<m; ++i){
01316 sum=a[i*m+i];
01317 if(sum>DBL_EPSILON || -sum<-DBL_EPSILON)
01318 wk[i]=1.0/sum;
01319 else
01320 wk[i]=1.0/DBL_EPSILON;
01321 }
01322 }
01323 else{
01324 s=res;
01325 wk=z=NULL;
01326 }
01327
01328 if(niter>0){
01329 for(i=0; i<m; ++i){
01330 x[i]=0.0;
01331 res[i]=B[i];
01332 }
01333 }
01334 else{
01335 niter=-niter;
01336
01337 for(i=0; i<m; ++i){
01338 for(j=0, aim=a+i*m, sum=0.0; j<m; ++j)
01339 sum+=aim[j]*x[j];
01340 res[i]=B[i]-sum;
01341 }
01342 }
01343
01344 switch(prec){
01345 case SBA_CG_NOPREC:
01346 for(i=0, deltanew=0.0; i<m; ++i){
01347 d[i]=res[i];
01348 deltanew+=res[i]*res[i];
01349 }
01350 break;
01351 case SBA_CG_JACOBI:
01352 for(i=0, deltanew=0.0; i<m; ++i){
01353 d[i]=res[i]*wk[i];
01354 deltanew+=res[i]*d[i];
01355 }
01356 break;
01357 case SBA_CG_SSOR:
01358 for(i=0; i<m; ++i){
01359 for(j=0, sum=0.0, aim=a+i*m; j<i; ++j)
01360 sum+=aim[j]*z[j];
01361 z[i]=wk[i]*(res[i]-sum);
01362 }
01363
01364 for(i=m-1; i>=0; --i){
01365 for(j=i+1, sum=0.0, aim=a+i*m; j<m; ++j)
01366 sum+=aim[j]*d[j];
01367 d[i]=z[i]-wk[i]*sum;
01368 }
01369 deltanew=dprod(m, res, d);
01370 break;
01371 default:
01372 fprintf(stderr, "unknown preconditioning option %d in sba_Axb_CG\n", prec);
01373 exit(1);
01374 }
01375
01376 delta0=deltanew;
01377
01378 for(iter=1; deltanew>eps_sq*delta0 && iter<=niter; ++iter){
01379 for(i=0; i<m; ++i){
01380 aim=a+i*m;
01381
01382
01383
01384
01385 q[i]=dprod(m, aim, d);
01386 }
01387
01388
01389
01390
01391
01392 alpha=deltanew/dprod(m, d, q);
01393
01394
01395
01396
01397
01398 daxpy(m, x, x, alpha, d);
01399
01400 if(!(iter%50)){
01401 for(i=0; i<m; ++i){
01402 aim=a+i*m;
01403
01404
01405
01406
01407 res[i]=B[i]-dprod(m, aim, x);
01408 }
01409 rec_res=0;
01410 }
01411 else{
01412
01413
01414
01415
01416 daxpy(m, res, res, -alpha, q);
01417 rec_res=1;
01418 }
01419
01420 if(prec){
01421 switch(prec){
01422 case SBA_CG_JACOBI:
01423 for(i=0; i<m; ++i)
01424 s[i]=res[i]*wk[i];
01425 break;
01426 case SBA_CG_SSOR:
01427 for(i=0; i<m; ++i){
01428 for(j=0, sum=0.0, aim=a+i*m; j<i; ++j)
01429 sum+=aim[j]*z[j];
01430 z[i]=wk[i]*(res[i]-sum);
01431 }
01432
01433 for(i=m-1; i>=0; --i){
01434 for(j=i+1, sum=0.0, aim=a+i*m; j<m; ++j)
01435 sum+=aim[j]*s[j];
01436 s[i]=z[i]-wk[i]*sum;
01437 }
01438 break;
01439 }
01440 }
01441
01442 deltaold=deltanew;
01443
01444
01445
01446
01447 deltanew=dprod(m, res, s);
01448
01449
01450
01451
01452 if(rec_res && deltanew<=eps_sq*delta0){
01453
01454 for(i=0; i<m; ++i){
01455 for(j=0, aim=a+i*m, sum=0.0; j<m; ++j)
01456 sum+=aim[j]*x[j];
01457 res[i]=B[i]-sum;
01458 }
01459 deltanew=dprod(m, res, s);
01460 }
01461
01462 beta=deltanew/deltaold;
01463
01464
01465
01466
01467
01468 daxpy(m, d, s, beta, d);
01469 }
01470
01471 return iter;
01472 }
01473
01474
01475
01476
01477
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488 #if 0
01489 int sba_mat_cholinv(double *A, double *B, int m)
01490 {
01491 static double *buf=NULL;
01492 static int buf_sz=0, nb=0;
01493
01494 int a_sz, ipiv_sz, work_sz, tot_sz;
01495 register int i, j;
01496 int info, *ipiv;
01497 double *a, *work;
01498
01499 if(A==NULL){
01500 if(buf) free(buf);
01501 buf=NULL;
01502 buf_sz=0;
01503
01504 return 1;
01505 }
01506
01507
01508 ipiv_sz=m;
01509 a_sz=m*m;
01510 if(!nb){
01511 #ifndef SBA_LS_SCARCE_MEMORY
01512 double tmp;
01513
01514 work_sz=-1;
01515 F77_FUNC(dgetri)((int *)&m, NULL, (int *)&m, NULL, (double *)&tmp, (int *)&work_sz, (int *)&info);
01516 nb=((int)tmp)/m;
01517 #else
01518 nb=1;
01519 #endif
01520 }
01521 work_sz=nb*m;
01522 tot_sz=(a_sz + work_sz)*sizeof(double) + ipiv_sz*sizeof(int);
01523
01524 if(tot_sz>buf_sz){
01525 if(buf) free(buf);
01526
01527 buf_sz=tot_sz;
01528 buf=(double *)malloc(buf_sz);
01529 if(!buf){
01530 fprintf(stderr, "memory allocation in sba_mat_cholinv() failed!\n");
01531 exit(1);
01532 }
01533 }
01534
01535 a=buf;
01536 work=a+a_sz;
01537 ipiv=(int *)(work+work_sz);
01538
01539
01540
01541 for(i=0; i<m*m; ++i)
01542 a[i]=A[i];
01543
01544
01545 F77_FUNC(dgetf2)((int *)&m, (int *)&m, a, (int *)&m, ipiv, (int *)&info);
01546
01547 if(info!=0){
01548 if(info<0){
01549 fprintf(stderr, "argument %d of dgetf2/dgetrf illegal in sba_mat_cholinv()\n", -info);
01550 exit(1);
01551 }
01552 else{
01553 fprintf(stderr, "singular matrix A for dgetf2/dgetrf in sba_mat_cholinv()\n");
01554 return 0;
01555 }
01556 }
01557
01558
01559 F77_FUNC(dgetri)((int *)&m, a, (int *)&m, ipiv, work, (int *)&work_sz, (int *)&info);
01560 if(info!=0){
01561 if(info<0){
01562 fprintf(stderr, "argument %d of dgetri illegal in sba_mat_cholinv()\n", -info);
01563 exit(1);
01564 }
01565 else{
01566 fprintf(stderr, "singular matrix A for dgetri in sba_mat_cholinv()\n");
01567 return 0;
01568 }
01569 }
01570
01571
01572
01573
01574 F77_FUNC(dpotf2)("U", (int *)&m, a, (int *)&m, (int *)&info);
01575
01576 if(info!=0){
01577 if(info<0){
01578 fprintf(stderr, "LAPACK error: illegal value for argument %d of dpotf2 in sba_mat_cholinv()\n", -info);
01579 exit(1);
01580 }
01581 else{
01582 fprintf(stderr, "LAPACK error: the leading minor of order %d is not positive definite,\n%s\n", info,
01583 "and the Cholesky factorization could not be completed in sba_mat_cholinv()");
01584 return 0;
01585 }
01586 }
01587
01588
01589
01590
01591
01592 for(i=0; i<m; ++i)
01593 for(j=0; j<i; ++j){
01594 a[i+j*m]=a[j+i*m];
01595 a[j+i*m]=0.0;
01596 }
01597 for(i=0; i<m*m; ++i)
01598 B[i]=a[i];
01599
01600 return 1;
01601 }
01602 #endif
01603
01604 int sba_mat_cholinv(double *A, double *B, int m)
01605 {
01606 int a_sz;
01607 register int i, j;
01608 int info;
01609 double *a;
01610
01611 if(A==NULL){
01612 return 1;
01613 }
01614
01615 a_sz=m*m;
01616 a=B;
01617
01618
01619
01620 for(i=0; i<a_sz; ++i)
01621 a[i]=A[i];
01622
01623
01624 F77_FUNC(dpotf2)("U", (int *)&m, a, (int *)&m, (int *)&info);
01625 if(info!=0){
01626 if(info<0){
01627 fprintf(stderr, "argument %d of dpotf2 illegal in sba_mat_cholinv()\n", -info);
01628 exit(1);
01629 }
01630 else{
01631 fprintf(stderr, "LAPACK error: the leading minor of order %d is not positive definite,\n%s\n", info,
01632 "and the Cholesky factorization could not be completed in sba_mat_cholinv()");
01633 return 0;
01634 }
01635 }
01636
01637
01638 F77_FUNC(dpotri)("U", (int *)&m, a, (int *)&m, (int *)&info);
01639 if(info!=0){
01640 if(info<0){
01641 fprintf(stderr, "argument %d of dpotri illegal in sba_mat_cholinv()\n", -info);
01642 exit(1);
01643 }
01644 else{
01645 fprintf(stderr, "the (%d, %d) element of the factor U or L is zero, singular matrix A for dpotri in sba_mat_cholinv()\n", info, info);
01646 return 0;
01647 }
01648 }
01649
01650
01651
01652
01653 F77_FUNC(dpotf2)("U", (int *)&m, a, (int *)&m, (int *)&info);
01654
01655 if(info!=0){
01656 if(info<0){
01657 fprintf(stderr, "LAPACK error: illegal value for argument %d of dpotf2 in sba_mat_cholinv()\n", -info);
01658 exit(1);
01659 }
01660 else{
01661 fprintf(stderr, "LAPACK error: the leading minor of order %d is not positive definite,\n%s\n", info,
01662 "and the Cholesky factorization could not be completed in sba_mat_cholinv()");
01663 return 0;
01664 }
01665 }
01666
01667
01668
01669
01670
01671 for(i=0; i<m; ++i)
01672 for(j=0; j<i; ++j){
01673 a[i+j*m]=a[j+i*m];
01674 a[j+i*m]=0.0;
01675 }
01676
01677 return 1;
01678 }