@@ -480,7 +480,7 @@ class Solver_MCSVM_CS
480
480
public:
481
481
Solver_MCSVM_CS (const problem *prob, int nr_class, double *C, double eps=0.1 , int max_iter=100000 );
482
482
~Solver_MCSVM_CS ();
483
- void Solve (double *w);
483
+ int Solve (double *w);
484
484
private:
485
485
void solve_sub_problem (double A_i, int yi, double C_yi, int active_i, double *alpha_new);
486
486
bool be_shrunk (int i, int m, int yi, double alpha_i, double minG);
@@ -555,7 +555,7 @@ bool Solver_MCSVM_CS::be_shrunk(int i, int m, int yi, double alpha_i, double min
555
555
return false ;
556
556
}
557
557
558
- void Solver_MCSVM_CS::Solve (double *w)
558
+ int Solver_MCSVM_CS::Solve (double *w)
559
559
{
560
560
int i, m, s;
561
561
int iter = 0 ;
@@ -765,6 +765,7 @@ void Solver_MCSVM_CS::Solve(double *w)
765
765
delete [] alpha_index;
766
766
delete [] y_index;
767
767
delete [] active_size_i;
768
+ return iter;
768
769
}
769
770
770
771
// A coordinate descent algorithm for
@@ -797,7 +798,7 @@ void Solver_MCSVM_CS::Solve(double *w)
797
798
#define GETI (i ) (y[i]+1 )
798
799
// To support weights for instances, use GETI(i) (i)
799
800
800
- static void solve_l2r_l1l2_svc (
801
+ static int solve_l2r_l1l2_svc (
801
802
const problem *prob, double *w, double eps,
802
803
double Cp, double Cn, int solver_type, int max_iter)
803
804
{
@@ -983,6 +984,7 @@ static void solve_l2r_l1l2_svc(
983
984
delete [] alpha;
984
985
delete [] y;
985
986
delete [] index;
987
+ return iter;
986
988
}
987
989
988
990
@@ -1014,7 +1016,7 @@ static void solve_l2r_l1l2_svc(
1014
1016
#define GETI (i ) (0 )
1015
1017
// To support weights for instances, use GETI(i) (i)
1016
1018
1017
- static void solve_l2r_l1l2_svr (
1019
+ static int solve_l2r_l1l2_svr (
1018
1020
const problem *prob, double *w, const parameter *param,
1019
1021
int solver_type, int max_iter)
1020
1022
{
@@ -1215,6 +1217,7 @@ static void solve_l2r_l1l2_svr(
1215
1217
delete [] beta;
1216
1218
delete [] QD;
1217
1219
delete [] index;
1220
+ return iter;
1218
1221
}
1219
1222
1220
1223
@@ -1240,7 +1243,7 @@ static void solve_l2r_l1l2_svr(
1240
1243
#define GETI (i ) (y[i]+1 )
1241
1244
// To support weights for instances, use GETI(i) (i)
1242
1245
1243
- void solve_l2r_lr_dual (const problem *prob, double *w, double eps, double Cp, double Cn,
1246
+ int solve_l2r_lr_dual (const problem *prob, double *w, double eps, double Cp, double Cn,
1244
1247
int max_iter)
1245
1248
{
1246
1249
int l = prob->l ;
@@ -1395,6 +1398,7 @@ void solve_l2r_lr_dual(const problem *prob, double *w, double eps, double Cp, do
1395
1398
delete [] alpha;
1396
1399
delete [] y;
1397
1400
delete [] index;
1401
+ return iter;
1398
1402
}
1399
1403
1400
1404
// A coordinate descent algorithm for
@@ -1414,7 +1418,7 @@ void solve_l2r_lr_dual(const problem *prob, double *w, double eps, double Cp, do
1414
1418
#define GETI (i ) (y[i]+1 )
1415
1419
// To support weights for instances, use GETI(i) (i)
1416
1420
1417
- static void solve_l1r_l2_svc (
1421
+ static int solve_l1r_l2_svc (
1418
1422
problem *prob_col, double *w, double eps,
1419
1423
double Cp, double Cn, int max_iter)
1420
1424
{
@@ -1681,6 +1685,7 @@ static void solve_l1r_l2_svc(
1681
1685
delete [] y;
1682
1686
delete [] b;
1683
1687
delete [] xj_sq;
1688
+ return iter;
1684
1689
}
1685
1690
1686
1691
// A coordinate descent algorithm for
@@ -1700,7 +1705,7 @@ static void solve_l1r_l2_svc(
1700
1705
#define GETI (i ) (y[i]+1 )
1701
1706
// To support weights for instances, use GETI(i) (i)
1702
1707
1703
- static void solve_l1r_lr (
1708
+ static int solve_l1r_lr (
1704
1709
const problem *prob_col, double *w, double eps,
1705
1710
double Cp, double Cn, int max_newton_iter)
1706
1711
{
@@ -2061,6 +2066,7 @@ static void solve_l1r_lr(
2061
2066
delete [] exp_wTx_new;
2062
2067
delete [] tau;
2063
2068
delete [] D;
2069
+ return newton_iter;
2064
2070
}
2065
2071
2066
2072
// transpose matrix X from row format to column format
@@ -2211,12 +2217,13 @@ static void group_classes(const problem *prob, int *nr_class_ret, int **label_re
2211
2217
free (data_label);
2212
2218
}
2213
2219
2214
- static void train_one (const problem *prob, const parameter *param, double *w, double Cp, double Cn)
2220
+ static int train_one (const problem *prob, const parameter *param, double *w, double Cp, double Cn)
2215
2221
{
2216
2222
double eps=param->eps ;
2217
2223
int max_iter=param->max_iter ;
2218
2224
int pos = 0 ;
2219
2225
int neg = 0 ;
2226
+ int n_iter;
2220
2227
for (int i=0 ;i<prob->l ;i++)
2221
2228
if (prob->y [i] > 0 )
2222
2229
pos++;
@@ -2240,7 +2247,7 @@ static void train_one(const problem *prob, const parameter *param, double *w, do
2240
2247
fun_obj=new l2r_lr_fun (prob, C);
2241
2248
TRON tron_obj (fun_obj, primal_solver_tol, max_iter);
<
4D1F
tr class="diff-line-row">2242
2249
tron_obj.set_print_string (liblinear_print_string);
2243
- tron_obj.tron (w);
2250
+ n_iter= tron_obj.tron (w);
2244
2251
delete fun_obj;
2245
2252
delete [] C;
2246
2253
break ;
@@ -2258,23 +2265,23 @@ static void train_one(const problem *prob, const parameter *param, double *w, do
2258
2265
fun_obj=new l2r_l2_svc_fun (prob, C);
2259
2266
TRON tron_obj (fun_obj, primal_solver_tol, max_iter);
2260
2267
tron_obj.set_print_string (liblinear_print_string);
2261
- tron_obj.tron (w);
2268
+ n_iter= tron_obj.tron (w);
2262
2269
delete fun_obj;
2263
2270
delete [] C;
2264
2271
break ;
2265
2272
}
2266
2273
case L2R_L2LOSS_SVC_DUAL:
2267
- solve_l2r_l1l2_svc (prob, w, eps, Cp, Cn, L2R_L2LOSS_SVC_DUAL, max_iter);
2274
+ n_iter= solve_l2r_l1l2_svc (prob, w, eps, Cp, Cn, L2R_L2LOSS_SVC_DUAL, max_iter);
2268
2275
break ;
2269
2276
case L2R_L1LOSS_SVC_DUAL:
2270
- solve_l2r_l1l2_svc (prob, w, eps, Cp, Cn, L2R_L1LOSS_SVC_DUAL, max_iter);
2277
+ n_iter= solve_l2r_l1l2_svc (prob, w, eps, Cp, Cn, L2R_L1LOSS_SVC_DUAL, max_iter);
2271
2278
break ;
2272
2279
case L1R_L2LOSS_SVC:
2273
2280
{
2274
2281
problem prob_col;
2275
2282
feature_node *x_space = NULL ;
2276
2283
transpose (prob, &x_space ,&prob_col);
2277
- solve_l1r_l2_svc (&prob_col, w, primal_solver_tol, Cp, Cn, max_iter);
2284
+ n_iter= solve_l1r_l2_svc (&prob_col, w, primal_solver_tol, Cp, Cn, max_iter);
2278
2285
delete [] prob_col.y ;
2279
2286
delete [] prob_col.x ;
2280
2287
delete [] x_space;
@@ -2285,14 +2292,14 @@ static void train_one(const problem *prob, const parameter *param, double *w, do
2285
2292
problem prob_col;
2286
2293
feature_node *x_space = NULL ;
2287
2294
transpose (prob, &x_space ,&prob_col);
2288
- solve_l1r_lr (&prob_col, w, primal_solver_tol, Cp, Cn, max_iter);
2295
+ n_iter= solve_l1r_lr (&prob_col, w, primal_solver_tol, Cp, Cn, max_iter);
2289
2296
delete [] prob_col.y ;
2290
2297
delete [] prob_col.x ;
2291
2298
delete [] x_space;
2292
2299
break ;
2293
2300
}
2294
2301
case L2R_LR_DUAL:
2295
- solve_l2r_lr_dual (prob, w, eps, Cp, Cn, max_iter);
2302
+ n_iter= solve_l2r_lr_dual (prob, w, eps, Cp, Cn, max_iter);
2296
2303
break ;
2297
2304
case L2R_L2LOSS_SVR:
2298
2305
{
@@ -2303,22 +2310,23 @@ static void train_one(const problem *prob, const parameter *param, double *w, do
2303
2310
fun_obj=new l2r_l2_svr_fun (prob, C, param->p );
2304
2311
TRON tron_obj (fun_obj, param->eps , max_iter);
2305
2312
tron_obj.set_print_string (liblinear_print_string);
2306
- tron_obj.tron (w);
2313
+ n_iter= tron_obj.tron (w);
2307
2314
delete fun_obj;
2308
2315
delete [] C;
2309
2316
break ;
2310
2317
2311
2318
}
2312
2319
case L2R_L1LOSS_SVR_DUAL:
2313
- solve_l2r_l1l2_svr (prob, w, param, L2R_L1LOSS_SVR_DUAL, max_iter);
2320
+ n_iter= solve_l2r_l1l2_svr (prob, w, param, L2R_L1LOSS_SVR_DUAL, max_iter);
2314
2321
break ;
2315
2322
case L2R_L2LOSS_SVR_DUAL:
2316
- solve_l2r_l1l2_svr (prob, w, param, L2R_L2LOSS_SVR_DUAL, max_iter);
2323
+ n_iter= solve_l2r_l1l2_svr (prob, w, param, L2R_L2LOSS_SVR_DUAL, max_iter);
2317
2324
break ;
2318
2325
default :
2319
2326
fprintf (stderr, " ERROR: unknown solver_type\n " );
2320
2327
break ;
2321
2328
}
2329
+ return n_iter;
2322
2330
}
2323
2331
2324
2332
//
@@ -2330,6 +2338,7 @@ model* train(const problem *prob, const parameter *param)
2330
2338
int l = prob->l ;
2331
2339
int n = prob->n ;
2332
2340
int w_size = prob->n ;
2341
+ int n_iter;
2333
2342
model *model_ = Malloc (model,1 );
2334
2343
2335
2344
if (prob->bias >=0 )
@@ -2344,9 +2353,10 @@ model* train(const problem *prob, const parameter *param)
2344
2353
param->solver_type == L2R_L2LOSS_SVR_DUAL)
2345
2354
{
2346
2355
model_->w = Malloc (double , w_size);
2356
+ model_->n_iter = Malloc (int , 1 );
2347
2357
model_->nr_class = 2 ;
2348
2358
model_->label = NULL ;
2349
- train_one (prob, param, &model_->w [0 ], 0 , 0 );
2359
+ model_-> n_iter [ 0 ] = train_one (prob, param, &model_->w [0 ], 0 , 0 );
2350
2360
}
2351
2361
else
2352
2362
{
@@ -2398,31 +2408,33 @@ model* train(const problem *prob, const parameter *param)
2398
2408
if (param->solver_type == MCSVM_CS)
2399
2409
{
2400
2410
model_->w =Malloc (double , n*nr_class);
2411
+ model_->n_iter =Malloc (int , 1 );
2401
2412
for (i=0 ;i<nr_class;i++)
2402
2413
for (j=start[i];j<start[i]+count[i];j++)
2403
2414
sub_prob.y [j] = i;
2404
2415
Solver_MCSVM_CS Solver (&sub_prob, nr_class, weighted_C, param->eps );
2405
- Solver.Solve (model_->w );
2416
+ model_-> n_iter [ 0 ]= Solver.Solve (model_->w );
2406
2417
}
2407
2418
else
2408
2419
{
2409
2420
if (nr_class == 2 )
2410
2421
{
2411
2422
model_->w =Malloc (double , w_size);
2412
-
2423
+ model_-> n_iter = Malloc ( int , 1 );
2413
2424
int e0 = start[0 ]+count[0 ];
2414
2425
k=0 ;
2415
2426
for (; k<e0 ; k++)
2416
2427
sub_prob.y [k] = -1 ;
2417
2428
for (; k<sub_prob.l ; k++)
2418
2429
sub_prob.y [k] = +1 ;
2419
2430
2420
- train_one (&sub_prob, param, &model_->w [0 ], weighted_C[1 ], weighted_C[0 ]);
2431
+ model_-> n_iter [ 0 ]= train_one (&sub_prob, param, &model_->w [0 ], weighted_C[1 ], weighted_C[0 ]);
2421
2432
}
2422
2433
else
2423
2434
{
2424
2435
model_->w =Malloc (double , w_size*nr_class);
2425
2436
double *w=Malloc (double , w_size);
2437
+ model_->n_iter =Malloc (int , nr_class);
2426
2438
for (i=0 ;i<nr_class;i++)
2427
2439
{
2428
2440
int si = start[i];
@@ -2436,7 +2448,7 @@ model* train(const problem *prob, const parameter *param)
2436
2448
for (; k<sub_prob.l ; k++)
2437
2449
sub_prob.y [k] = -1 ;
2438
2450
2439
- train_one (&sub_prob, param, w, weighted_C[i], param->C );
2451
+ model_-> n_iter [i]= train_one (&sub_prob, param, w, weighted_C[i], param->C );
2440
2452
2441
2453
for (int j=0 ;j<w_size;j++)
2442
2454
model_->w [j*nr_class+i] = w[j];
@@ -2795,6 +2807,17 @@ void get_labels(const model *model_, int* label)
2795
2807
label[i] = model_->label [i];
2796
2808
}
2797
2809
2810
+ void get_n_iter (const model *model_, int * n_iter)
2811
+ {
2812
+ int labels;
2813
+ labels = model_->nr_class ;
2814
+ if (labels == 2 )
2815
+ labels = 1 ;
2816
+ if (model_->n_iter != NULL )
2817
+ for (int i=0 ;i<labels;i++)
2818
+ n_iter[i] = model_->n_iter [i];
2819
+ }
2820
+
2798
2821
void free_model_content (struct model *model_ptr)
2799
2822
{
2800
2823
if (model_ptr->w != NULL )
0 commit comments