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