ext/rb-libsvm/svm.cpp in rb-libsvm-1.0.5 vs ext/rb-libsvm/svm.cpp in rb-libsvm-1.0.6

- old
+ new

@@ -3,10 +3,12 @@ #include <stdlib.h> #include <ctype.h> #include <float.h> #include <string.h> #include <stdarg.h> +#include <limits.h> +#include <locale.h> #include "svm.h" int libsvm_version = LIBSVM_VERSION; typedef float Qfloat; typedef signed char schar; #ifndef min @@ -40,11 +42,11 @@ { fputs(s,stdout); fflush(stdout); } static void (*svm_print_string) (const char *) = &print_string_stdout; -#if 1 +#if 0 static void info(const char *fmt,...) { char buf[BUFSIZ]; va_list ap; va_start(ap,fmt); @@ -472,11 +474,11 @@ for(j=0;j<active_size;j++) if(is_free(j)) nr_free++; if(2*nr_free < active_size) - info("\nWarning: using -h 0 may be faster\n"); + info("\nWARNING: using -h 0 may be faster\n"); if (nr_free*l > 2*active_size*(l-active_size)) { for(i=active_size;i<l;i++) { @@ -554,13 +556,14 @@ } // optimization step int iter = 0; + int max_iter = max(10000000, l>INT_MAX/100 ? INT_MAX : 100*l); int counter = min(l,1000)+1; - - while(1) + + while(iter < max_iter) { // show progress and do shrinking if(--counter == 0) { @@ -574,11 +577,11 @@ { // reconstruct the whole gradient reconstruct_gradient(); // reset active set size and check active_size = l; - // info("*"); + info("*"); if(select_working_set(i,j)!=0) break; else counter = 1; // do shrinking next iteration } @@ -723,10 +726,22 @@ G_bar[k] += C_j * Q_j[k]; } } } + if(iter >= max_iter) + { + if(active_size < l) + { + // reconstruct the whole gradient to calculate objective value + reconstruct_gradient(); + active_size = l; + info("*"); + } + info("\nWARNING: reaching max number of iterations"); + } + // calculate rho si->rho = calculate_rho(); // calculate objective value @@ -754,11 +769,11 @@ }*/ si->upper_bound_p = Cp; si->upper_bound_n = Cn; - // info("\noptimization finished, #iter = %d\n",iter); + info("\noptimization finished, #iter = %d\n",iter); delete[] p; delete[] y; delete[] alpha; delete[] alpha_status; @@ -927,11 +942,11 @@ if(unshrink == false && Gmax1 + Gmax2 <= eps*10) { unshrink = true; reconstruct_gradient(); active_size = l; - // info("*"); + info("*"); } for(i=0;i<active_size;i++) if (be_shrunk(i, Gmax1, Gmax2)) { @@ -1446,11 +1461,11 @@ double sum_alpha=0; for(i=0;i<l;i++) sum_alpha += alpha[i]; if (Cp==Cn) - // info("nu = %f\n", sum_alpha/(Cp*prob->l)); + info("nu = %f\n", sum_alpha/(Cp*prob->l)); for(i=0;i<l;i++) alpha[i] *= y[i]; delete[] minus_ones; @@ -1496,11 +1511,11 @@ Solver_NU s; s.Solve(l, SVC_Q(*prob,*param,y), zeros, y, alpha, 1.0, 1.0, param->eps, si, param->shrinking); double r = si->r; - // info("C = %f\n",1/r); + info("C = %f\n",1/r); for(i=0;i<l;i++) alpha[i] *= y[i]/r; si->rho /= r; @@ -1573,11 +1588,11 @@ for(i=0;i<l;i++) { alpha[i] = alpha2[i] - alpha2[i+l]; sum_alpha += fabs(alpha[i]); } - // info("nu = %f\n",sum_alpha/(param->C*l)); + info("nu = %f\n",sum_alpha/(param->C*l)); delete[] alpha2; delete[] linear_term; delete[] y; } @@ -1608,11 +1623,11 @@ Solver_NU s; s.Solve(2*l, SVR_Q(*prob,*param), linear_term, y, alpha2, C, C, param->eps, si, param->shrinking); - // info("epsilon = %f\n",-si->r); + info("epsilon = %f\n",-si->r); for(i=0;i<l;i++) alpha[i] = alpha2[i] - alpha2[i+l]; delete[] alpha2; @@ -1652,11 +1667,11 @@ case NU_SVR: solve_nu_svr(prob,param,alpha,&si); break; } - // info("obj = %f, rho = %f\n",si.obj,si.rho); + info("obj = %f, rho = %f\n",si.obj,si.rho); // output SVs int nSV = 0; int nBSV = 0; @@ -1676,11 +1691,11 @@ ++nBSV; } } } - // info("nSV = %d, nBSV = %d\n",nSV,nBSV); + info("nSV = %d, nBSV = %d\n",nSV,nBSV); decision_function f; f.alpha = alpha; f.rho = si.rho; return f; @@ -2112,11 +2127,14 @@ int *start = NULL; int *count = NULL; int *perm = Malloc(int,l); // group training data of the same class - svm_group_classes(prob,&nr_class,&label,&start,&count,perm); + svm_group_classes(prob,&nr_class,&label,&start,&count,perm); + if(nr_class == 1) + info("WARNING: training data in only one class. See README for details.\n"); + svm_node **x = Malloc(svm_node *,l); int i; for(i=0;i<l;i++) x[i] = prob->x[perm[i]]; @@ -2130,11 +2148,11 @@ int j; for(j=0;j<nr_class;j++) if(param->weight_label[i] == label[j]) break; if(j == nr_class) - fprintf(stderr,"warning: class label %d specified in weight is not found\n", param->weight_label[i]); + fprintf(stderr,"WARNING: class label %d specified in weight is not found\n", param->weight_label[i]); else weighted_C[j] *= param->weight[i]; } // train k*(k-1)/2 models @@ -2230,11 +2248,11 @@ } model->nSV[i] = nSV; nz_count[i] = nSV; } - // info("Total nSV = %d\n",total_sv); + info("Total nSV = %d\n",total_sv); model->l = total_sv; model->SV = Malloc(svm_node *,total_sv); p = 0; for(i=0;i<l;i++) @@ -2438,17 +2456,18 @@ } } double svm_predict_values(const svm_model *model, const svm_node *x, double* dec_values) { + int i; if(model->param.svm_type == ONE_CLASS || model->param.svm_type == EPSILON_SVR || model->param.svm_type == NU_SVR) { double *sv_coef = model->sv_coef[0]; double sum = 0; - for(int i=0;i<model->l;i++) + for(i=0;i<model->l;i++) sum += sv_coef[i] * Kernel::k_function(x,model->SV[i],model->param); sum -= model->rho[0]; *dec_values = sum; if(model->param.svm_type == ONE_CLASS) @@ -2456,11 +2475,10 @@ else return sum; } else { - int i; int nr_class = model->nr_class; int l = model->l; double *kvalue = Malloc(double,l); for(i=0;i<l;i++) @@ -2581,10 +2599,13 @@ int svm_save_model(const char *model_file_name, const svm_model *model) { FILE *fp = fopen(model_file_name,"w"); if(fp==NULL) return -1; + char *old_locale = strdup(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, "C"); + const svm_parameter& param = model->param; fprintf(fp,"svm_type %s\n", svm_type_table[param.svm_type]); fprintf(fp,"kernel_type %s\n", kernel_type_table[param.kernel_type]); @@ -2659,10 +2680,14 @@ fprintf(fp,"%d:%.8g ",p->index,p->value); p++; } fprintf(fp, "\n"); } + + setlocale(LC_ALL, old_locale); + free(old_locale); + if (ferror(fp) != 0 || fclose(fp) != 0) return -1; else return 0; } static char *line = NULL; @@ -2688,11 +2713,14 @@ svm_model *svm_load_model(const char *model_file_name) { FILE *fp = fopen(model_file_name,"rb"); if(fp==NULL) return NULL; - + + char *old_locale = strdup(setlocale(LC_ALL, NULL)); + setlocale(LC_ALL, "C"); + // read parameters svm_model *model = Malloc(svm_model,1); svm_parameter& param = model->param; model->rho = NULL; @@ -2719,10 +2747,13 @@ } } if(svm_type_table[i] == NULL) { fprintf(stderr,"unknown svm type.\n"); + + setlocale(LC_ALL, old_locale); + free(old_locale); free(model->rho); free(model->label); free(model->nSV); free(model); return NULL; @@ -2741,10 +2772,13 @@ } } if(kernel_type_table[i] == NULL) { fprintf(stderr,"unknown kernel function.\n"); + + setlocale(LC_ALL, old_locale); + free(old_locale); free(model->rho); free(model->label); free(model->nSV); free(model); return NULL; @@ -2805,10 +2839,13 @@ break; } else { fprintf(stderr,"unknown text in model file: [%s]\n",cmd); + + setlocale(LC_ALL, old_locale); + free(old_locale); free(model->rho); free(model->label); free(model->nSV); free(model); return NULL; @@ -2877,26 +2914,29 @@ } x_space[j++].index = -1; } free(line); + setlocale(LC_ALL, old_locale); + free(old_locale); + if (ferror(fp) != 0 || fclose(fp) != 0) return NULL; model->free_sv = 1; // XXX return model; } void svm_free_model_content(svm_model* model_ptr) { - if(model_ptr->free_sv && model_ptr->l > 0 && model_ptr->SV != NULL) - free((void *)(model_ptr->SV[0])); - if(model_ptr->sv_coef) - { - for(int i=0;i<model_ptr->nr_class-1;i++) - free(model_ptr->sv_coef[i]); - } + if(model_ptr->free_sv && model_ptr->l > 0 && model_ptr->SV != NULL) + free((void *)(model_ptr->SV[0])); + if(model_ptr->sv_coef) + { + for(int i=0;i<model_ptr->nr_class-1;i++) + free(model_ptr->sv_coef[i]); + } free(model_ptr->SV); model_ptr->SV = NULL; free(model_ptr->sv_coef); @@ -2918,15 +2958,15 @@ model_ptr->nSV = NULL; } void svm_free_and_destroy_model(svm_model** model_ptr_ptr) { - if(model_ptr_ptr != NULL && *model_ptr_ptr != NULL) - { - svm_free_model_content(*model_ptr_ptr); + if(model_ptr_ptr != NULL && *model_ptr_ptr != NULL) + { + svm_free_model_content(*model_ptr_ptr); free(*model_ptr_ptr); - *model_ptr_ptr = NULL; - } + *model_ptr_ptr = NULL; + } } void svm_destroy_param(svm_parameter* param) { free(param->weight_label);