00001 #include "NumericalTools.h"
00002
00003 extern StreamOutput cout;
00004
00008 NumericalTools::NumericalTools()
00009 {
00010 }
00011
00015 NumericalTools::~NumericalTools()
00016 {
00017 }
00018
00033 void NumericalTools::RidgeRegressionMultisolutionSinglecallGELSS ( REAL *A, REAL *b, REAL *x, int n, int m, int k, REAL lambda, bool isRowMajor )
00034 {
00035 int oneInt=1, rank, info;
00036 REAL precision = 1e-15;
00037
00038
00039 int nn = n + m;
00040 int lWork = -1;
00041 REAL workSize[1];
00042 REAL* AA = new REAL[nn*m];
00043 REAL* bb = new REAL[nn*k];
00044 REAL* eigenvals = new REAL[m];
00045
00046 GELSS ( &nn, &m, &k, AA, &nn, bb, &nn, eigenvals, &precision, &rank, workSize, &lWork, &info );
00047
00048 lWork = ( int ) ( workSize[0]+0.5 );
00049 REAL work[lWork];
00050
00051 for ( int i=0;i<n;i++ )
00052 {
00053 for ( int j=0;j<m;j++ )
00054 AA[i + j*nn] = A[i + j*n];
00055 for ( int j=0;j<k;j++ )
00056 bb[i + j*nn] = b[i + j*n];
00057 }
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 REAL lam = sqrt ( lambda* ( REAL ) n );
00068 for ( int i=0;i<m;i++ )
00069 {
00070 for ( int j=0;j<m;j++ )
00071 {
00072 if ( i == j )
00073 AA[j + i*nn + n] = lam;
00074 else
00075 AA[j + i*nn + n] = 0.0;
00076 }
00077 bb[i + n] = 0.0;
00078 }
00079
00080 GELSS ( &nn, &m, &k, AA, &nn, bb, &nn, eigenvals, &precision, &rank, work, &lWork, &info );
00081
00082 for ( int i=0;i<m;i++ )
00083 for ( int j=0;j<k;j++ )
00084 x[i+j*k] = bb[i+j*nn];
00085
00086 if ( AA )
00087 delete[] AA;
00088 AA = 0;
00089 if ( bb )
00090 delete[] bb;
00091 bb = 0;
00092 if ( eigenvals )
00093 delete[] eigenvals;
00094 eigenvals = 0;
00095 }
00096
00110 void NumericalTools::RidgeRegressionMultisolutionMulticall ( REAL *A, REAL *b, REAL *x, int n, int m, int k, REAL lambda, int alloc, bool isRowMajor )
00111 {
00112 static REAL *AA;
00113 static REAL *Ab;
00114 static REAL *AbTrans;
00115 static REAL *eigenvals;
00116 static REAL *work;
00117 static int *iwork;
00118 int oneInt=1, rank, info;
00119 REAL precision = 1e-15;
00120 static int lWork=-1;
00121 static REAL workSize[1];
00122
00123 if ( alloc == ALLOC_MEM )
00124 {
00125 AA = new REAL[m*m];
00126 Ab = new REAL[m*k];
00127 AbTrans = new REAL[m*k];
00128 eigenvals = new REAL[m];
00129 lWork = -1;
00130 GELSS ( &m, &m, &k, AA, &m, Ab, &m, eigenvals, &precision, &rank, workSize, &lWork, &info );
00131
00132 lWork = ( int ) ( workSize[0]+0.5 );
00133 work = new REAL[lWork];
00134
00135 return;
00136 }
00137
00138 if ( alloc == FREE_MEM )
00139 {
00140 if ( work )
00141 delete[] work;
00142 work = 0;
00143 if ( AA )
00144 delete[] AA;
00145 AA = 0;
00146 if ( Ab )
00147 delete[] Ab;
00148 Ab = 0;
00149 if ( AbTrans )
00150 delete[] AbTrans;
00151 AbTrans = 0;
00152 if ( eigenvals )
00153 delete[] eigenvals;
00154 eigenvals = 0;
00155
00156 return;
00157 }
00158
00159 if ( isRowMajor )
00160 CBLAS_GEMM ( CblasRowMajor, CblasTrans, CblasNoTrans, m, m, n, 1.0, A, m, A, m, 0.0, AA, m );
00161 else
00162 CBLAS_GEMM ( CblasColMajor, CblasTrans, CblasNoTrans, m, m, n, 1.0, A, n, A, n, 0.0, AA, m );
00163
00164 for ( int i=0; i < m; i++ )
00165 AA[i+i*m] += ( REAL ) n*lambda;
00166
00167 if ( isRowMajor )
00168 CBLAS_GEMM ( CblasRowMajor, CblasTrans, CblasNoTrans, m, k , n, 1.0, A, m, b, k, 0.0, Ab, k );
00169 else
00170 CBLAS_GEMM ( CblasColMajor, CblasTrans, CblasNoTrans, m, 1 , n, 1.0, A, n, b, n, 0.0, Ab, m );
00171
00172 if ( isRowMajor )
00173 {
00174 for ( int i=0;i<k;i++ )
00175 for ( int j=0;j<m;j++ )
00176 AbTrans[j+i*m] = Ab[i+j*k];
00177 }
00178 else
00179 {
00180 for ( int i=0;i<k;i++ )
00181 for ( int j=0;j<m;j++ )
00182 AbTrans[i+j*k] = Ab[i+j*k];
00183 }
00184
00185 GELSS ( &m, &m, &k, AA, &m, AbTrans, &m, eigenvals, &precision, &rank, work, &lWork, &info );
00186
00187 if ( info != 0 )
00188 cout<<"error equation solver failed to converge: "<<info<<endl;
00189
00190 if ( isRowMajor )
00191 {
00192 for ( int i=0;i<m;i++ )
00193 for ( int j=0;j<k;j++ )
00194 x[j+i*k] = AbTrans[i+j*m];
00195 }
00196 else
00197 {
00198 for ( int i=0;i<m;i++ )
00199 for ( int j=0;j<k;j++ )
00200 x[i+j*m] = AbTrans[i+j*m];
00201 }
00202
00203 }
00204
00218 void NumericalTools::RidgeRegressionMultisolutionSinglecall ( REAL *A, REAL *b, REAL *x, int n, int m, int k, REAL lambda, bool isRowMajor, double* rideModifier )
00219 {
00220 REAL *AA;
00221 REAL *Ab;
00222 REAL *AbTrans;
00223 REAL *eigenvals;
00224
00225 int *iwork;
00226 int oneInt=1, rank, info;
00227 REAL precision = 1e-15;
00228 int lWork=-1;
00229 REAL workSize[1];
00230
00231 AA = new REAL[m*m];
00232 Ab = new REAL[m*k];
00233 AbTrans = new REAL[m*k];
00234 eigenvals = new REAL[m];
00235 lWork = -1;
00236
00237
00238
00239
00240
00241
00242 if ( isRowMajor )
00243 CBLAS_GEMM ( CblasRowMajor, CblasTrans, CblasNoTrans, m, m, n, 1.0, A, m, A, m, 0.0, AA, m );
00244 else
00245 CBLAS_GEMM ( CblasColMajor, CblasTrans, CblasNoTrans, m, m, n, 1.0, A, n, A, n, 0.0, AA, m );
00246
00247 if ( rideModifier )
00248 for ( int i=0; i < m; i++ )
00249 AA[i+i*m] += ( REAL ) n*lambda*rideModifier[i];
00250 else
00251 for ( int i=0; i < m; i++ )
00252 AA[i+i*m] += ( REAL ) n*lambda;
00253
00254 if ( isRowMajor )
00255 CBLAS_GEMM ( CblasRowMajor, CblasTrans, CblasNoTrans, m, k , n, 1.0, A, m, b, k, 0.0, Ab, k );
00256 else
00257 CBLAS_GEMM ( CblasColMajor, CblasTrans, CblasNoTrans, m, 1 , n, 1.0, A, n, b, n, 0.0, Ab, m );
00258
00259 if ( isRowMajor )
00260 {
00261 for ( int i=0;i<k;i++ )
00262 for ( int j=0;j<m;j++ )
00263 AbTrans[j+i*m] = Ab[i+j*k];
00264 }
00265 else
00266 {
00267 for ( int i=0;i<k;i++ )
00268 for ( int j=0;j<m;j++ )
00269 AbTrans[i+j*k] = Ab[i+j*k];
00270 }
00271
00272 int lda = m, nrhs = k, ldb = m;
00273
00274
00275 LAPACK_POTRF ( "U", &m, AA, &lda, &info );
00276
00277
00278 LAPACK_POTRS ( "U", &m, &nrhs, AA, &lda, AbTrans, &ldb, &info );
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291 if ( info != 0 )
00292 cout<<"error equation solver failed to converge: "<<info<<endl;
00293
00294 if ( isRowMajor )
00295 {
00296 for ( int i=0;i<m;i++ )
00297 for ( int j=0;j<k;j++ )
00298 x[j+i*k] = AbTrans[i+j*m];
00299 }
00300 else
00301 {
00302 for ( int i=0;i<m;i++ )
00303 for ( int j=0;j<k;j++ )
00304 x[i+j*m] = AbTrans[i+j*m];
00305 }
00306
00307 if ( AA )
00308 delete[] AA;
00309 AA = 0;
00310 if ( Ab )
00311 delete[] Ab;
00312 Ab = 0;
00313 if ( AbTrans )
00314 delete[] AbTrans;
00315 AbTrans = 0;
00316 if ( eigenvals )
00317 delete[] eigenvals;
00318 eigenvals = 0;
00319 }
00320
00337 void NumericalTools::LogisticRegressionMultisolutionSinglecall ( REAL *A, REAL *b, REAL *x, int n, int m, int k, REAL lambda, REAL offset, REAL scale, bool isRowMajor )
00338 {
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 REAL tolerance = 1e-5;
00393
00394 REAL* xOld = new REAL[m*(k-1)];
00395 REAL* pi = new REAL[n*k];
00396 REAL* eta = new REAL[n*k];
00397 REAL* etaTmp = new REAL[n*(k-1)];
00398 REAL* etaOld = new REAL[n*k];
00399 REAL* mu = new REAL[n*k];
00400 REAL* XWX = new REAL[m*(k-1) * m*(k-1)];
00401 REAL* XWZ = new REAL[m*(k-1)];
00402 REAL* W = new REAL[k*k];
00403 REAL* Z = new REAL[k];
00404 for(int i=0;i<n*k;i++)
00405 {
00406 pi[i] = 1.0 / (REAL)k;
00407 eta[i] = log(pi[i]);
00408 }
00409 for(int i=0;i<m*(k-1);i++)
00410 xOld[i] = 0.0;
00411
00412 for(int epoch=0;epoch<100;epoch++)
00413 {
00414 for(int i=0;i<n*k;i++)
00415 mu[i] = pi[i];
00416 for(int i=0;i<m*(k-1) * m*(k-1);i++)
00417 XWX[i] = 0.0;
00418 for(int i=0;i<m*(k-1);i++)
00419 XWZ[i] = 0.0;
00420
00421 for(int e=0;e<n;e++)
00422 {
00423 REAL *muPtr = mu + e*k, *piPtr = pi + e*k, *etaPtr = eta + e*k, *bPtr = b + e*k, *Aptr = A + e*m;
00424 for(int i=0;i<k;i++)
00425 for(int j=0;j<k;j++)
00426 W[i*k+j] = (i==j? muPtr[i] : 0.0) - muPtr[i] * piPtr[j];
00427 for(int i=0;i<k;i++)
00428 {
00429 REAL sum = 0.0;
00430 for(int j=0;j<k;j++)
00431 sum += etaPtr[j] * W[i+j*k];
00432 Z[i] = sum + (bPtr[i] - muPtr[i]);
00433 }
00434
00435 for(int i=0;i<m*(k-1);i++)
00436 for(int j=0;j<m*(k-1);j++)
00437 XWX[i*m*(k-1) + j] += W[(i/m)*k+j/m] * Aptr[i%m] * Aptr[j%m];
00438 for(int i=0;i<k-1;i++)
00439 for(int j=0;j<m;j++)
00440 XWZ[i*m+j] += Z[i] * Aptr[j];
00441 }
00442
00443 for(int i=0;i<m*(k-1);i++)
00444 XWX[i+i*m*(k-1)] += lambda*(REAL)m*(k-1);
00445
00446 int lda = m*(k-1), nrhs = 1, ldb = m*(k-1), info;
00447
00448 LAPACK_POTRF ( "U", &lda, XWX, &lda, &info );
00449
00450 LAPACK_POTRS ( "U", &lda, &nrhs, XWX, &lda, XWZ, &ldb, &info );
00451 if ( info != 0 )
00452 cout<<"error equation solver failed to converge: "<<info<<endl;
00453 for(int i=0;i<k-1;i++)
00454 for(int j=0;j<m;j++)
00455 x[i+j*(k-1)] = XWZ[j+i*m];
00456
00457
00458
00459
00460 double sum0 = 0.0, sum1 = 0.0, normalizedDiff;
00461 for(int i=0;i<m*(k-1);i++)
00462 {
00463 sum0 += x[i] * x[i];
00464 sum1 += xOld[i] * xOld[i];
00465 }
00466 normalizedDiff = (sum0-sum1)/((double)m*(k-1));
00467
00468 if(normalizedDiff < tolerance)
00469 return;
00470
00471 for(int i=0;i<m*(k-1);i++)
00472 xOld[i] = x[i];
00473
00474 for(int i=0;i<n*k;i++)
00475 etaOld[i] = eta[i];
00476
00477 CBLAS_GEMM ( CblasRowMajor, CblasNoTrans, CblasNoTrans, n, k-1 , m, 1.0, A, m, x, k-1, 0.0, etaTmp, k-1 );
00478
00479 for(int i=0;i<n;i++)
00480 {
00481 for(int j=0;j<k-1;j++)
00482 eta[j+i*k] = etaTmp[j+i*(k-1)];
00483 eta[k-1+i*k] = 0.0;
00484 }
00485
00486 for(int backstep=0;backstep<11;backstep++)
00487 {
00488 for(int i=0;i<n*k;i++)
00489 pi[i] = exp(eta[i]);
00490
00491 for(int i=0;i<n;i++)
00492 {
00493 REAL sum = 0.0;
00494 REAL* ptr = pi + i*k;
00495 for(int j=0;j<k;j++)
00496 sum += ptr[j];
00497 for(int j=0;j<k;j++)
00498 ptr[j] /= sum;
00499 }
00500
00501 uint sum = 0;
00502 for(int i=0;i<n*k;i++)
00503 if(pi[i] > tolerance)
00504 sum++;
00505 if(sum == n*k)
00506 break;
00507 else if(backstep < 10)
00508 {
00509 for(int i=0;i<n*k;i++)
00510 eta[i] = etaOld[i] + (eta[i] - etaOld[i])*0.2;
00511 }
00512 else
00513 {
00514 for(int i=0;i<n*k;i++)
00515 if(pi[i] <= tolerance)
00516 pi[i] = tolerance;
00517 for(int i=0;i<n;i++)
00518 {
00519 REAL sum = 0.0;
00520 REAL* ptr = pi + i*k;
00521 for(int j=0;j<k;j++)
00522 sum += ptr[j];
00523 for(int j=0;j<k;j++)
00524 pi[j] /= sum;
00525 }
00526 for(int i=0;i<n*k;i++)
00527 eta[i] = log(pi[i]);
00528 break;
00529 }
00530 }
00531 }
00532
00533 delete[] xOld;
00534 delete[] pi;
00535 delete[] eta;
00536 delete[] etaTmp;
00537 delete[] etaOld;
00538 delete[] mu;
00539 delete[] XWX;
00540 delete[] XWZ;
00541 delete[] W;
00542 delete[] Z;
00543 }
00544
00562 int NumericalTools::RidgeRegressionNonNegSinglecall ( REAL *A, REAL *b, REAL *x, int n, int m, REAL lamda, REAL eps, int maxIter, bool isRowMajor, int debug )
00563 {
00564 static REAL *r, *tmp, *ATA, *Ab;
00565
00566 r = new REAL[m];
00567 tmp = new REAL[m];
00568 ATA = new REAL[m*m];
00569 Ab = new REAL[m];
00570
00571 int nIter = 0;
00572 unsigned int i;
00573 REAL alpha = 0.0, tmp0, tmp1;
00574 REAL norm = 1.0;
00575
00576 if ( lamda > 0.0 )
00577 {
00578 if ( isRowMajor )
00579 CBLAS_GEMM ( CblasRowMajor, CblasTrans, CblasNoTrans, m, m, n, 1.0, A, m, A, m, 0.0, ATA, m );
00580 else
00581 CBLAS_GEMM ( CblasColMajor, CblasTrans, CblasNoTrans, m, m, n, 1.0, A, n, A, n, 0.0, ATA, m );
00582
00583 if ( isRowMajor )
00584 CBLAS_GEMM ( CblasRowMajor, CblasTrans, CblasNoTrans, m, 1 , n, 1.0, A, m, b, 1, 0.0, Ab, 1 );
00585 else
00586 CBLAS_GEMM ( CblasColMajor, CblasTrans, CblasNoTrans, m, 1 , n, 1.0, A, n, b, n, 0.0, Ab, m );
00587
00588
00589 for ( i=0;i<m;i++ )
00590 ATA[i+i*m] += lamda * ( REAL ) n;
00591
00592 }
00593 else
00594 {
00595 memcpy ( ( char* ) ATA, ( char* ) A, sizeof ( REAL ) *m*m );
00596 memcpy ( ( char* ) Ab, ( char* ) b, sizeof ( REAL ) *m );
00597 }
00598
00599
00600 for ( i=0;i<m;i++ )
00601 x[i] = r[i] = 1.0;
00602
00603 while ( norm>eps )
00604 {
00605 CBLAS_GEMV ( CblasRowMajor, CblasNoTrans, m, m, 1.0, ATA, m, x, 1, 0.0, tmp, 1 );
00606 for ( i=0;i<m;i++ )
00607 r[i] = Ab[i] - tmp[i];
00608 for ( i=0;i<m;i++ )
00609 if ( x[i]==0.0 && r[i]<0.0 )
00610 r[i] = 0.0;
00611 CBLAS_GEMV ( CblasRowMajor, CblasNoTrans, m, m, 1.0, ATA, m, r, 1, 0.0, tmp, 1 );
00612 tmp0 = tmp1 = 0.0;
00613 for ( i=0;i<m;i++ )
00614 {
00615 tmp0 += r[i]*r[i];
00616 tmp1 += r[i]*tmp[i];
00617 }
00618 if ( tmp0!=0.0 && tmp1!=0.0 )
00619 alpha = tmp0 / tmp1;
00620 for ( i=0;i<m;i++ )
00621 {
00622 if ( r[i]<0.0 )
00623 {
00624 tmp0 = -x[i]/r[i];
00625 alpha = alpha<tmp0? alpha : tmp0;
00626 }
00627 }
00628 for ( i=0;i<m;i++ )
00629 x[i] += alpha * r[i];
00630 norm = 0.0;
00631 for ( i=0;i<m;i++ )
00632 {
00633 if ( x[i]<1e-9 )
00634 x[i] = 0.0;
00635 norm += r[i]*r[i];
00636 }
00637 norm = sqrt ( norm );
00638 nIter++;
00639
00640
00641 if ( nIter>=maxIter )
00642 break;
00643
00644 if ( debug )
00645 {
00646 cout<<"norm="<<norm<<" alpha="<<alpha<<endl;
00647 cout<<"r=";
00648 for ( i=0;i<m;i++ ) cout<<r[i]<<" ";
00649 cout<<endl;
00650 cout<<"x=";
00651 for ( i=0;i<m;i++ ) cout<<x[i]<<" ";
00652 cout<<endl;
00653 cout<<"tmp=";
00654 for ( i=0;i<m;i++ ) cout<<r[i]<<" ";
00655 cout<<endl;
00656 cout<<endl;
00657 }
00658 }
00659
00660
00661 for ( i=0;i<m;i++ )
00662 if ( isnan ( x[i] ) || isinf ( x[i] ) )
00663 cout<<"DIVERGENCE of nonNegSolver (nIter="<<nIter<<")"<<endl;
00664
00665 if ( r )
00666 delete[] r;
00667 r = 0;
00668 if ( tmp )
00669 delete[] tmp;
00670 tmp = 0;
00671 if ( ATA )
00672 delete[] ATA;
00673 ATA = 0;
00674 if ( Ab )
00675 delete[] Ab;
00676 Ab = 0;
00677
00678 return nIter;
00679 }
00680
00700 int NumericalTools::RidgeRegressionNonNegmulticall ( REAL *A, REAL *b, REAL *x, int n, int m, REAL lamda, REAL eps, int maxIter, int alloc, bool isRowMajor, int debug )
00701 {
00702 static REAL *r, *tmp, *ATA, *Ab;
00703
00704 if ( alloc == ALLOC_MEM )
00705 {
00706 cout<<"Allocate memory in nonNeg solver"<<endl;
00707 r = new REAL[m];
00708 tmp = new REAL[m];
00709 ATA = new REAL[m*m];
00710 Ab = new REAL[m];
00711 return -1;
00712 }
00713 if ( alloc == FREE_MEM )
00714 {
00715 cout<<"Free memory in nonNeg solver"<<endl;
00716 if ( r )
00717 delete[] r;
00718 r = 0;
00719 if ( tmp )
00720 delete[] tmp;
00721 tmp = 0;
00722 if ( ATA )
00723 delete[] ATA;
00724 ATA = 0;
00725 if ( Ab )
00726 delete[] Ab;
00727 Ab = 0;
00728 return -1;
00729 }
00730
00731 int nIter = 0;
00732 unsigned int i;
00733 REAL alpha = 0.0, tmp0, tmp1;
00734 REAL norm = 1.0;
00735
00736 if ( lamda > 0.0 )
00737 {
00738 if ( isRowMajor )
00739 CBLAS_GEMM ( CblasRowMajor, CblasTrans, CblasNoTrans, m, m, n, 1.0, A, m, A, m, 0.0, ATA, m );
00740 else
00741 CBLAS_GEMM ( CblasColMajor, CblasTrans, CblasNoTrans, m, m, n, 1.0, A, n, A, n, 0.0, ATA, m );
00742
00743 if ( isRowMajor )
00744 CBLAS_GEMM ( CblasRowMajor, CblasTrans, CblasNoTrans, m, 1 , n, 1.0, A, m, b, 1, 0.0, Ab, 1 );
00745 else
00746 CBLAS_GEMM ( CblasColMajor, CblasTrans, CblasNoTrans, m, 1 , n, 1.0, A, n, b, n, 0.0, Ab, m );
00747
00748
00749 for ( i=0;i<m;i++ )
00750 ATA[i+i*m] += lamda * ( REAL ) n;
00751
00752 }
00753 else
00754 {
00755 memcpy ( ( char* ) ATA, ( char* ) A, sizeof ( REAL ) *m*m );
00756 memcpy ( ( char* ) Ab, ( char* ) b, sizeof ( REAL ) *m );
00757 }
00758
00759
00760 for ( i=0;i<m;i++ )
00761 x[i] = r[i] = 1.0;
00762
00763 while ( norm>eps )
00764 {
00765 CBLAS_GEMV ( CblasRowMajor, CblasNoTrans, m, m, 1.0, ATA, m, x, 1, 0.0, tmp, 1 );
00766 for ( i=0;i<m;i++ )
00767 r[i] = Ab[i] - tmp[i];
00768 for ( i=0;i<m;i++ )
00769 if ( x[i]==0.0 && r[i]<0.0 )
00770 r[i] = 0.0;
00771 CBLAS_GEMV ( CblasRowMajor, CblasNoTrans, m, m, 1.0, ATA, m, r, 1, 0.0, tmp, 1 );
00772 tmp0 = tmp1 = 0.0;
00773 for ( i=0;i<m;i++ )
00774 {
00775 tmp0 += r[i]*r[i];
00776 tmp1 += r[i]*tmp[i];
00777 }
00778 if ( tmp0!=0.0 && tmp1!=0.0 )
00779 alpha = tmp0 / tmp1;
00780 for ( i=0;i<m;i++ )
00781 {
00782 if ( r[i]<0.0 )
00783 {
00784 tmp0 = -x[i]/r[i];
00785 alpha = alpha<tmp0? alpha : tmp0;
00786 }
00787 }
00788 for ( i=0;i<m;i++ )
00789 x[i] += alpha * r[i];
00790 norm = 0.0;
00791 for ( i=0;i<m;i++ )
00792 {
00793 if ( x[i]<1e-9 )
00794 x[i] = 0.0;
00795 norm += r[i]*r[i];
00796 }
00797 norm = sqrt ( norm );
00798 nIter++;
00799
00800
00801 if ( nIter>=maxIter )
00802 break;
00803
00804 if ( debug )
00805 {
00806 cout<<"norm="<<norm<<" alpha="<<alpha<<endl;
00807 cout<<"r=";
00808 for ( i=0;i<m;i++ ) cout<<r[i]<<" ";
00809 cout<<endl;
00810 cout<<"x=";
00811 for ( i=0;i<m;i++ ) cout<<x[i]<<" ";
00812 cout<<endl;
00813 cout<<"tmp=";
00814 for ( i=0;i<m;i++ ) cout<<r[i]<<" ";
00815 cout<<endl;
00816 cout<<endl;
00817 }
00818 }
00819
00820
00821 for ( i=0;i<m;i++ )
00822 if ( isnan ( x[i] ) || isinf ( x[i] ) )
00823 cout<<"DIVERGENCE of nonNegSolver (nIter="<<nIter<<")"<<endl;
00824
00825 return nIter;
00826 }
00827
00835 REAL NumericalTools::getNormRandomNumber ( REAL mean, REAL std )
00836 {
00837 REAL x1, x2, w, y1;
00838
00839 do
00840 {
00841 x1 = 2.0 * ( ( REAL ) rand() / ( REAL ) RAND_MAX ) - 1.0;
00842 x2 = 2.0 * ( ( REAL ) rand() / ( REAL ) RAND_MAX ) - 1.0;
00843 w = x1 * x1 + x2 * x2;
00844 }
00845 while ( w >= 1.0 );
00846
00847 w = sqrt ( ( -2.0 * log ( w ) ) / w );
00848 y1 = x1 * w;
00849
00850 y1 *= std;
00851 y1 += mean;
00852
00853 return y1;
00854 }
00855
00863 REAL NumericalTools::getUniformRandomNumber ( REAL min, REAL max )
00864 {
00865 REAL x = ( REAL ) rand() / ( REAL ) RAND_MAX;
00866
00867 x *= ( max-min );
00868 x = min + x;
00869
00870 return x;
00871 }
00872
00880 REAL NumericalTools::clipValue ( REAL value, REAL min, REAL max )
00881 {
00882 if ( value < min )
00883 value = min;
00884 if ( value > max )
00885 value = max;
00886
00887 return value;
00888 }