00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <stdlib.h>
00015 #include <string.h>
00016 #include <math.h>
00017
00018 #include <shogun/structure/libp3bm.h>
00019 #include <shogun/lib/external/libqp.h>
00020 #include <shogun/lib/Time.h>
00021
00022 namespace shogun
00023 {
00024 static const uint32_t QPSolverMaxIter=0xFFFFFFFF;
00025 static const float64_t epsilon=0.0;
00026
00027 static float64_t *H, *H2;
00028 static uint32_t BufSize;
00029
00030
00031
00032
00033 static const float64_t *get_col( uint32_t i)
00034 {
00035 return( &H2[ BufSize*i ] );
00036 }
00037
00038 bmrm_return_value_T svm_ppbm_solver(
00039 CStructuredModel* model,
00040 float64_t* W,
00041 float64_t TolRel,
00042 float64_t TolAbs,
00043 float64_t _lambda,
00044 uint32_t _BufSize,
00045 bool cleanICP,
00046 uint32_t cleanAfter,
00047 float64_t K,
00048 uint32_t Tmax,
00049 bool verbose)
00050 {
00051 bmrm_return_value_T ppbmrm;
00052 libqp_state_T qp_exitflag={0, 0, 0, 0}, qp_exitflag_good={0, 0, 0, 0};
00053 float64_t *b, *b2, *beta, *beta_good, *beta_start, *diag_H, *diag_H2;
00054 float64_t R, *subgrad, *A, QPSolverTolRel, C=1.0;
00055 float64_t *prevW, *wt, alpha, alpha_start, alpha_good=0.0, Fd_alpha0=0.0;
00056 float64_t lastFp, wdist, gamma=0.0;
00057 floatmax_t rsum, sq_norm_W, sq_norm_Wdiff, sq_norm_prevW, eps;
00058 uint32_t *I, *I2, *I_start, *I_good, *ICPcounter, *ACPs, cntICP=0, cntACP=0;
00059 uint8_t S=1;
00060 uint32_t nDim=model->get_dim();
00061 float64_t **ICPs;
00062 uint32_t nCP_new=0, qp_cnt=0;
00063 bmrm_ll *CPList_head, *CPList_tail, *cp_ptr, *cp_ptr2, *cp_list=NULL;
00064 float64_t *A_1=NULL, *A_2=NULL, *H_buff;
00065 bool *map=NULL, tuneAlpha=true, flag=true, alphaChanged=false, isThereGoodSolution=false;
00066
00067 CTime ttime;
00068 float64_t tstart, tstop;
00069
00070
00071 tstart=ttime.cur_time_diff(false);
00072
00073 BufSize=_BufSize;
00074 QPSolverTolRel=1e-9;
00075
00076 H=NULL;
00077 b=NULL;
00078 beta=NULL;
00079 A=NULL;
00080 subgrad=NULL;
00081 diag_H=NULL;
00082 I=NULL;
00083 ICPcounter=NULL;
00084 ICPs=NULL;
00085 ACPs=NULL;
00086 prevW=NULL;
00087 wt=NULL;
00088 H_buff=NULL;
00089 diag_H2=NULL;
00090 b2=NULL;
00091 I2=NULL;
00092 H2=NULL;
00093 I_good=NULL;
00094 I_start=NULL;
00095 beta_start=NULL;
00096 beta_good=NULL;
00097
00098 alpha=0.0;
00099
00100 H= (float64_t*) LIBBMRM_CALLOC(BufSize*BufSize, sizeof(float64_t));
00101
00102 A= (float64_t*) LIBBMRM_CALLOC(nDim*BufSize, sizeof(float64_t));
00103
00104 b= (float64_t*) LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
00105
00106 beta= (float64_t*) LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
00107
00108 subgrad= (float64_t*) LIBBMRM_CALLOC(nDim, sizeof(float64_t));
00109
00110 diag_H= (float64_t*) LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
00111
00112 I= (uint32_t*) LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
00113
00114 ICPcounter= (uint32_t*) LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
00115
00116 ICPs= (float64_t**) LIBBMRM_CALLOC(BufSize, sizeof(float64_t*));
00117
00118 ACPs= (uint32_t*) LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
00119
00120 cp_list= (bmrm_ll*) LIBBMRM_CALLOC(1, sizeof(bmrm_ll));
00121
00122 prevW= (float64_t*) LIBBMRM_CALLOC(nDim, sizeof(float64_t));
00123
00124 wt= (float64_t*) LIBBMRM_CALLOC(nDim, sizeof(float64_t));
00125
00126 if (H==NULL || A==NULL || b==NULL || beta==NULL || subgrad==NULL ||
00127 diag_H==NULL || I==NULL || ICPcounter==NULL || ICPs==NULL ||
00128 ACPs==NULL || cp_list==NULL || prevW==NULL || wt==NULL)
00129 {
00130 ppbmrm.exitflag=-2;
00131 goto cleanup;
00132 }
00133
00134 map= (bool*) LIBBMRM_CALLOC(BufSize, sizeof(bool));
00135
00136 if (map==NULL)
00137 {
00138 ppbmrm.exitflag=-2;
00139 goto cleanup;
00140 }
00141
00142 memset( (bool*) map, true, BufSize);
00143
00144
00145 H_buff= (float64_t*) LIBBMRM_CALLOC(BufSize*BufSize, sizeof(float64_t));
00146
00147 if (H_buff==NULL)
00148 {
00149 ppbmrm.exitflag=-2;
00150 goto cleanup;
00151 }
00152
00153
00154 beta_start= (float64_t*) LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
00155
00156 beta_good= (float64_t*) LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
00157
00158 b2= (float64_t*) LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
00159
00160 diag_H2= (float64_t*) LIBBMRM_CALLOC(BufSize, sizeof(float64_t));
00161
00162 H2= (float64_t*) LIBBMRM_CALLOC(BufSize*BufSize, sizeof(float64_t));
00163
00164 I_start= (uint32_t*) LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
00165
00166 I_good= (uint32_t*) LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
00167
00168 I2= (uint32_t*) LIBBMRM_CALLOC(BufSize, sizeof(uint32_t));
00169
00170 if (beta_start==NULL || beta_good==NULL || b2==NULL || diag_H2==NULL ||
00171 I_start==NULL || I_good==NULL || I2==NULL || H2==NULL)
00172 {
00173 ppbmrm.exitflag=-2;
00174 goto cleanup;
00175 }
00176
00177 ppbmrm.hist_Fp.resize_vector(BufSize);
00178 ppbmrm.hist_Fd.resize_vector(BufSize);
00179 ppbmrm.hist_wdist.resize_vector(BufSize);
00180
00181
00182 R = model->risk(subgrad, W);
00183
00184 ppbmrm.nCP=0;
00185 ppbmrm.nIter=0;
00186 ppbmrm.exitflag=0;
00187
00188 b[0]=-R;
00189
00190
00191 LIBBMRM_MEMCPY(A, subgrad, nDim*sizeof(float64_t));
00192 map[0]=false;
00193 cp_list->address=&A[0];
00194 cp_list->idx=0;
00195 cp_list->prev=NULL;
00196 cp_list->next=NULL;
00197 CPList_head=cp_list;
00198 CPList_tail=cp_list;
00199
00200
00201 sq_norm_W=0.0;
00202 sq_norm_Wdiff=0.0;
00203
00204 for (uint32_t j=0; j<nDim; ++j)
00205 {
00206 b[0]+=subgrad[j]*W[j];
00207 sq_norm_W+=W[j]*W[j];
00208 sq_norm_Wdiff+=(W[j]-prevW[j])*(W[j]-prevW[j]);
00209 }
00210
00211 ppbmrm.Fp=R+0.5*_lambda*sq_norm_W + alpha*sq_norm_Wdiff;
00212 ppbmrm.Fd=-LIBBMRM_PLUS_INF;
00213 lastFp=ppbmrm.Fp;
00214 wdist=CMath::sqrt(sq_norm_Wdiff);
00215
00216 K = (sq_norm_W == 0.0) ? 0.4 : 0.01*CMath::sqrt(sq_norm_W);
00217
00218 LIBBMRM_MEMCPY(prevW, W, nDim*sizeof(float64_t));
00219
00220 tstop=ttime.cur_time_diff(false);
00221
00222
00223 ppbmrm.hist_Fp[0]=ppbmrm.Fp;
00224 ppbmrm.hist_Fd[0]=ppbmrm.Fd;
00225 ppbmrm.hist_wdist[0]=wdist;
00226
00227
00228
00229 if (verbose)
00230 SG_SPRINT("%4d: tim=%.3lf, Fp=%lf, Fd=%lf, R=%lf, K=%lf\n",
00231 ppbmrm.nIter, tstop-tstart, ppbmrm.Fp, ppbmrm.Fd, R, K);
00232
00233
00234
00235 while (ppbmrm.exitflag==0)
00236 {
00237 tstart=ttime.cur_time_diff(false);
00238 ppbmrm.nIter++;
00239
00240
00241
00242 if (ppbmrm.nCP>0)
00243 {
00244 A_2=get_cutting_plane(CPList_tail);
00245 cp_ptr=CPList_head;
00246
00247 for (uint32_t i=0; i<ppbmrm.nCP; ++i)
00248 {
00249 A_1=get_cutting_plane(cp_ptr);
00250 cp_ptr=cp_ptr->next;
00251 rsum=0.0;
00252
00253 for (uint32_t j=0; j<nDim; ++j)
00254 {
00255 rsum+=A_1[j]*A_2[j];
00256 }
00257
00258 H[LIBBMRM_INDEX(i, ppbmrm.nCP, BufSize)]=rsum;
00259 }
00260
00261 for (uint32_t i=0; i<ppbmrm.nCP; ++i)
00262 {
00263 H[LIBBMRM_INDEX(ppbmrm.nCP, i, BufSize)]=
00264 H[LIBBMRM_INDEX(i, ppbmrm.nCP, BufSize)];
00265 }
00266 }
00267
00268 rsum=0.0;
00269 A_2=get_cutting_plane(CPList_tail);
00270
00271 for (uint32_t i=0; i<nDim; ++i)
00272 rsum+=A_2[i]*A_2[i];
00273
00274 H[LIBBMRM_INDEX(ppbmrm.nCP, ppbmrm.nCP, BufSize)]=rsum;
00275
00276 diag_H[ppbmrm.nCP]=H[LIBBMRM_INDEX(ppbmrm.nCP, ppbmrm.nCP, BufSize)];
00277 I[ppbmrm.nCP]=1;
00278
00279 ppbmrm.nCP++;
00280 beta[ppbmrm.nCP]=0.0;
00281
00282
00283
00284
00285 flag=true;
00286 isThereGoodSolution=false;
00287 LIBBMRM_MEMCPY(beta_start, beta, ppbmrm.nCP*sizeof(float64_t));
00288 LIBBMRM_MEMCPY(I_start, I, ppbmrm.nCP*sizeof(uint32_t));
00289 qp_cnt=0;
00290 alpha_good=alpha;
00291
00292 if (tuneAlpha)
00293 {
00294 alpha_start=alpha; alpha=0.0;
00295 beta[ppbmrm.nCP]=0.0;
00296 LIBBMRM_MEMCPY(I2, I_start, ppbmrm.nCP*sizeof(uint32_t));
00297 I2[ppbmrm.nCP]=1;
00298
00299
00300 cp_ptr=CPList_head;
00301
00302 for (uint32_t i=0; i<ppbmrm.nCP; ++i)
00303 {
00304 rsum=0.0;
00305 A_1=get_cutting_plane(cp_ptr);
00306 cp_ptr=cp_ptr->next;
00307
00308 for (uint32_t j=0; j<nDim; ++j)
00309 rsum+=A_1[j]*prevW[j];
00310
00311 b2[i]=b[i]-((2*alpha)/(_lambda+2*alpha))*rsum;
00312 diag_H2[i]=diag_H[i]/(_lambda+2*alpha);
00313
00314 for (uint32_t j=0; j<ppbmrm.nCP; ++j)
00315 H2[LIBBMRM_INDEX(i, j, BufSize)]=
00316 H[LIBBMRM_INDEX(i, j, BufSize)]/(_lambda+2*alpha);
00317 }
00318
00319
00320 qp_exitflag=libqp_splx_solver(&get_col, diag_H2, b2, &C, I2, &S, beta,
00321 ppbmrm.nCP, QPSolverMaxIter, 0.0, QPSolverTolRel, -LIBBMRM_PLUS_INF, 0);
00322 ppbmrm.qp_exitflag=qp_exitflag.exitflag;
00323 qp_cnt++;
00324 Fd_alpha0=-qp_exitflag.QP;
00325
00326
00327 for (uint32_t i=0; i<nDim; ++i)
00328 {
00329 rsum=0.0;
00330 cp_ptr=CPList_head;
00331
00332 for (uint32_t j=0; j<ppbmrm.nCP; ++j)
00333 {
00334 A_1=get_cutting_plane(cp_ptr);
00335 cp_ptr=cp_ptr->next;
00336 rsum+=A_1[i]*beta[j];
00337 }
00338
00339 wt[i]=(2*alpha*prevW[i] - rsum)/(_lambda+2*alpha);
00340 }
00341
00342 sq_norm_Wdiff=0.0;
00343
00344 for (uint32_t i=0; i<nDim; ++i)
00345 sq_norm_Wdiff+=(wt[i]-prevW[i])*(wt[i]-prevW[i]);
00346
00347 if (CMath::sqrt(sq_norm_Wdiff) <= K)
00348 {
00349 flag=false;
00350
00351 if (alpha!=alpha_start)
00352 alphaChanged=true;
00353 }
00354 else
00355 {
00356 alpha=alpha_start;
00357 }
00358
00359 while(flag)
00360 {
00361 LIBBMRM_MEMCPY(I2, I_start, ppbmrm.nCP*sizeof(uint32_t));
00362 LIBBMRM_MEMCPY(beta, beta_start, ppbmrm.nCP*sizeof(float64_t));
00363 I2[ppbmrm.nCP]=1;
00364 beta[ppbmrm.nCP]=0.0;
00365
00366
00367 cp_ptr=CPList_head;
00368
00369 for (uint32_t i=0; i<ppbmrm.nCP; ++i)
00370 {
00371 rsum=0.0;
00372 A_1=get_cutting_plane(cp_ptr);
00373 cp_ptr=cp_ptr->next;
00374
00375 for (uint32_t j=0; j<nDim; ++j)
00376 rsum+=A_1[j]*prevW[j];
00377
00378 b2[i]=b[i]-((2*alpha)/(_lambda+2*alpha))*rsum;
00379 diag_H2[i]=diag_H[i]/(_lambda+2*alpha);
00380
00381 for (uint32_t j=0; j<ppbmrm.nCP; ++j)
00382 H2[LIBBMRM_INDEX(i, j, BufSize)]=H[LIBBMRM_INDEX(i, j, BufSize)]/(_lambda+2*alpha);
00383 }
00384
00385
00386 qp_exitflag=libqp_splx_solver(&get_col, diag_H2, b2, &C, I2, &S, beta,
00387 ppbmrm.nCP, QPSolverMaxIter, 0.0, QPSolverTolRel, -LIBBMRM_PLUS_INF, 0);
00388 ppbmrm.qp_exitflag=qp_exitflag.exitflag;
00389 qp_cnt++;
00390
00391
00392 for (uint32_t i=0; i<nDim; ++i)
00393 {
00394 rsum=0.0;
00395 cp_ptr=CPList_head;
00396
00397 for (uint32_t j=0; j<ppbmrm.nCP; ++j)
00398 {
00399 A_1=get_cutting_plane(cp_ptr);
00400 cp_ptr=cp_ptr->next;
00401 rsum+=A_1[i]*beta[j];
00402 }
00403
00404 wt[i]=(2*alpha*prevW[i] - rsum)/(_lambda+2*alpha);
00405 }
00406
00407 sq_norm_Wdiff=0.0;
00408 for (uint32_t i=0; i<nDim; ++i)
00409 sq_norm_Wdiff+=(wt[i]-prevW[i])*(wt[i]-prevW[i]);
00410
00411 if (CMath::sqrt(sq_norm_Wdiff) > K)
00412 {
00413
00414
00415
00416 if (isThereGoodSolution)
00417 {
00418 LIBBMRM_MEMCPY(beta, beta_good, ppbmrm.nCP*sizeof(float64_t));
00419 LIBBMRM_MEMCPY(I2, I_good, ppbmrm.nCP*sizeof(uint32_t));
00420 alpha=alpha_good;
00421 qp_exitflag=qp_exitflag_good;
00422 flag=false;
00423 }
00424 else
00425 {
00426 if (alpha == 0)
00427 {
00428 alpha=1.0;
00429 alphaChanged=true;
00430 }
00431 else
00432 {
00433 alpha*=2;
00434 alphaChanged=true;
00435 }
00436 }
00437 }
00438 else
00439 {
00440 if (alpha > 0)
00441 {
00442
00443 LIBBMRM_MEMCPY(beta_good, beta, ppbmrm.nCP*sizeof(float64_t));
00444 LIBBMRM_MEMCPY(I_good, I2, ppbmrm.nCP*sizeof(uint32_t));
00445 alpha_good=alpha;
00446 qp_exitflag_good=qp_exitflag;
00447 isThereGoodSolution=true;
00448
00449 if (alpha!=1.0)
00450 {
00451 alpha/=2.0;
00452 alphaChanged=true;
00453 }
00454 else
00455 {
00456 alpha=0.0;
00457 alphaChanged=true;
00458 }
00459 }
00460 else
00461 {
00462 flag=false;
00463 }
00464 }
00465 }
00466 }
00467 else
00468 {
00469 alphaChanged=false;
00470 LIBBMRM_MEMCPY(I2, I_start, ppbmrm.nCP*sizeof(uint32_t));
00471 LIBBMRM_MEMCPY(beta, beta_start, ppbmrm.nCP*sizeof(float64_t));
00472
00473
00474 cp_ptr=CPList_head;
00475
00476 for (uint32_t i=0; i<ppbmrm.nCP; ++i)
00477 {
00478 rsum=0.0;
00479 A_1=get_cutting_plane(cp_ptr);
00480 cp_ptr=cp_ptr->next;
00481
00482 for (uint32_t j=0; j<nDim; ++j)
00483 rsum+=A_1[j]*prevW[j];
00484
00485 b2[i]=b[i]-((2*alpha)/(_lambda+2*alpha))*rsum;
00486 diag_H2[i]=diag_H[i]/(_lambda+2*alpha);
00487
00488 for (uint32_t j=0; j<ppbmrm.nCP; ++j)
00489 H2[LIBBMRM_INDEX(i, j, BufSize)]=
00490 H[LIBBMRM_INDEX(i, j, BufSize)]/(_lambda+2*alpha);
00491 }
00492
00493 qp_exitflag=libqp_splx_solver(&get_col, diag_H2, b2, &C, I2, &S, beta,
00494 ppbmrm.nCP, QPSolverMaxIter, 0.0, QPSolverTolRel, -LIBBMRM_PLUS_INF, 0);
00495 ppbmrm.qp_exitflag=qp_exitflag.exitflag;
00496 qp_cnt++;
00497 }
00498
00499
00500
00501
00502 ppbmrm.nzA=0;
00503
00504 for (uint32_t aaa=0; aaa<ppbmrm.nCP; ++aaa)
00505 {
00506 if (beta[aaa]>epsilon)
00507 {
00508 ++ppbmrm.nzA;
00509 ICPcounter[aaa]=0;
00510 }
00511 else
00512 {
00513 ICPcounter[aaa]+=1;
00514 }
00515 }
00516
00517
00518 for (uint32_t i=0; i<nDim; ++i)
00519 {
00520 rsum=0.0;
00521 cp_ptr=CPList_head;
00522
00523 for (uint32_t j=0; j<ppbmrm.nCP; ++j)
00524 {
00525 A_1=get_cutting_plane(cp_ptr);
00526 cp_ptr=cp_ptr->next;
00527 rsum+=A_1[i]*beta[j];
00528 }
00529
00530 W[i]=(2*alpha*prevW[i]-rsum)/(_lambda+2*alpha);
00531 }
00532
00533
00534 R = model->risk(subgrad, W);
00535 b[ppbmrm.nCP]=-R;
00536 add_cutting_plane(&CPList_tail, map, A,
00537 find_free_idx(map, BufSize), subgrad, nDim);
00538
00539 sq_norm_W=0.0;
00540 sq_norm_Wdiff=0.0;
00541 sq_norm_prevW=0.0;
00542
00543 for (uint32_t j=0; j<nDim; ++j)
00544 {
00545 b[ppbmrm.nCP]+=subgrad[j]*W[j];
00546 sq_norm_W+=W[j]*W[j];
00547 sq_norm_Wdiff+=(W[j]-prevW[j])*(W[j]-prevW[j]);
00548 sq_norm_prevW+=prevW[j]*prevW[j];
00549 }
00550
00551
00552 ppbmrm.Fp=R+0.5*_lambda*sq_norm_W + alpha*sq_norm_Wdiff;
00553 ppbmrm.Fd=-qp_exitflag.QP+((alpha*_lambda)/(_lambda + 2*alpha))*sq_norm_prevW;
00554
00555
00556 if (alphaChanged)
00557 {
00558 eps=1.0-(ppbmrm.Fd/ppbmrm.Fp);
00559 gamma=(lastFp*(1-eps)-Fd_alpha0)/(Tmax*(1-eps));
00560 }
00561
00562 if ((lastFp-ppbmrm.Fp) <= gamma)
00563 {
00564 tuneAlpha=true;
00565 }
00566 else
00567 {
00568 tuneAlpha=false;
00569 }
00570
00571
00572 if (alpha==0.0)
00573 {
00574 if (ppbmrm.Fp-ppbmrm.Fd<=TolRel*LIBBMRM_ABS(ppbmrm.Fp))
00575 ppbmrm.exitflag=1;
00576
00577 if (ppbmrm.Fp-ppbmrm.Fd<=TolAbs)
00578 ppbmrm.exitflag=2;
00579 }
00580
00581 if (ppbmrm.nCP>=BufSize)
00582 ppbmrm.exitflag=-1;
00583
00584 tstop=ttime.cur_time_diff(false);
00585
00586
00587 sq_norm_Wdiff=0.0;
00588
00589 for (uint32_t i=0; i<nDim; ++i)
00590 {
00591 sq_norm_Wdiff+=(W[i]-prevW[i])*(W[i]-prevW[i]);
00592 }
00593
00594 wdist=CMath::sqrt(sq_norm_Wdiff);
00595
00596
00597 ppbmrm.hist_Fp[ppbmrm.nIter]=ppbmrm.Fp;
00598 ppbmrm.hist_Fd[ppbmrm.nIter]=ppbmrm.Fd;
00599 ppbmrm.hist_wdist[ppbmrm.nIter]=wdist;
00600
00601
00602 if (verbose)
00603 SG_SPRINT("%4d: tim=%.3lf, Fp=%lf, Fd=%lf, (Fp-Fd)=%lf, (Fp-Fd)/Fp=%lf, R=%lf, nCP=%d, nzA=%d, wdist=%lf, alpha=%lf, qp_cnt=%d, gamma=%lf, tuneAlpha=%d\n",
00604 ppbmrm.nIter, tstop-tstart, ppbmrm.Fp, ppbmrm.Fd, ppbmrm.Fp-ppbmrm.Fd,
00605 (ppbmrm.Fp-ppbmrm.Fd)/ppbmrm.Fp, R, ppbmrm.nCP, ppbmrm.nzA, wdist, alpha,
00606 qp_cnt, gamma, tuneAlpha);
00607
00608
00609 if (ppbmrm.nCP>=BufSize)
00610 {
00611 ppbmrm.exitflag=-2;
00612 SG_SERROR("Buffer exceeded.\n");
00613 }
00614
00615
00616 LIBBMRM_MEMCPY(prevW, W, nDim*sizeof(float64_t));
00617 lastFp=ppbmrm.Fp;
00618
00619
00620 if (cleanICP)
00621 {
00622
00623 cntICP=0;
00624 cntACP=0;
00625 cp_ptr=CPList_head;
00626 uint32_t tmp_idx=0;
00627
00628 while (cp_ptr != CPList_tail)
00629 {
00630 if (ICPcounter[tmp_idx++]>=cleanAfter)
00631 {
00632 ICPs[cntICP++]=cp_ptr->address;
00633 }
00634 else
00635 {
00636 ACPs[cntACP++]=tmp_idx-1;
00637 }
00638
00639 cp_ptr=cp_ptr->next;
00640 }
00641
00642
00643 if (cntICP > 0)
00644 {
00645 nCP_new=ppbmrm.nCP-cntICP;
00646
00647 for (uint32_t i=0; i<cntICP; ++i)
00648 {
00649 tmp_idx=0;
00650 cp_ptr=CPList_head;
00651
00652 while(cp_ptr->address != ICPs[i])
00653 {
00654 cp_ptr=cp_ptr->next;
00655 tmp_idx++;
00656 }
00657
00658 remove_cutting_plane(&CPList_head, &CPList_tail, map, ICPs[i]);
00659
00660 LIBBMRM_MEMMOVE(b+tmp_idx, b+tmp_idx+1,
00661 (ppbmrm.nCP-tmp_idx)*sizeof(float64_t));
00662 LIBBMRM_MEMMOVE(beta+tmp_idx, beta+tmp_idx+1,
00663 (ppbmrm.nCP-tmp_idx)*sizeof(float64_t));
00664 LIBBMRM_MEMMOVE(diag_H+tmp_idx, diag_H+tmp_idx+1,
00665 (ppbmrm.nCP-tmp_idx)*sizeof(float64_t));
00666 LIBBMRM_MEMMOVE(I+tmp_idx, I+tmp_idx+1,
00667 (ppbmrm.nCP-tmp_idx)*sizeof(uint32_t));
00668 LIBBMRM_MEMMOVE(ICPcounter+tmp_idx, ICPcounter+tmp_idx+1,
00669 (ppbmrm.nCP-tmp_idx)*sizeof(uint32_t));
00670 }
00671
00672
00673 for (uint32_t i=0; i < nCP_new; ++i)
00674 {
00675 for (uint32_t j=0; j < nCP_new; ++j)
00676 {
00677 H_buff[LIBBMRM_INDEX(i, j, BufSize)]=
00678 H[LIBBMRM_INDEX(ACPs[i], ACPs[j], BufSize)];
00679 }
00680 }
00681
00682 for (uint32_t i=0; i<nCP_new; ++i)
00683 for (uint32_t j=0; j<nCP_new; ++j)
00684 H[LIBBMRM_INDEX(i, j, BufSize)]=H_buff[LIBBMRM_INDEX(i, j, BufSize)];
00685
00686 ppbmrm.nCP=nCP_new;
00687 }
00688 }
00689 }
00690
00691 ppbmrm.hist_Fp.resize_vector(ppbmrm.nIter);
00692 ppbmrm.hist_Fd.resize_vector(ppbmrm.nIter);
00693 ppbmrm.hist_wdist.resize_vector(ppbmrm.nIter);
00694
00695 cp_ptr=CPList_head;
00696
00697 while(cp_ptr!=NULL)
00698 {
00699 cp_ptr2=cp_ptr;
00700 cp_ptr=cp_ptr->next;
00701 LIBBMRM_FREE(cp_ptr2);
00702 cp_ptr2=NULL;
00703 }
00704
00705 cp_list=NULL;
00706
00707 cleanup:
00708
00709 LIBBMRM_FREE(H);
00710 LIBBMRM_FREE(b);
00711 LIBBMRM_FREE(beta);
00712 LIBBMRM_FREE(A);
00713 LIBBMRM_FREE(subgrad);
00714 LIBBMRM_FREE(diag_H);
00715 LIBBMRM_FREE(I);
00716 LIBBMRM_FREE(ICPcounter);
00717 LIBBMRM_FREE(ICPs);
00718 LIBBMRM_FREE(ACPs);
00719 LIBBMRM_FREE(H_buff);
00720 LIBBMRM_FREE(map);
00721 LIBBMRM_FREE(prevW);
00722 LIBBMRM_FREE(wt);
00723 LIBBMRM_FREE(beta_start);
00724 LIBBMRM_FREE(beta_good);
00725 LIBBMRM_FREE(I_start);
00726 LIBBMRM_FREE(I_good);
00727 LIBBMRM_FREE(I2);
00728 LIBBMRM_FREE(b2);
00729 LIBBMRM_FREE(diag_H2);
00730 LIBBMRM_FREE(H2);
00731
00732 if (cp_list)
00733 LIBBMRM_FREE(cp_list);
00734
00735 return(ppbmrm);
00736 }
00737 }