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