ext/libsvm/svm.cpp in rb-libsvm-1.1.4 vs ext/libsvm/svm.cpp in rb-libsvm-1.1.5

- old
+ new

@@ -72,11 +72,11 @@ // request data [0,len) // return some position p where [p,len) need to be filled // (p >= len if nothing needs to be filled) int get_data(const int index, Qfloat **data, int len); - void swap_index(int i, int j); + void swap_index(int i, int j); private: int l; long int size; struct head_t { @@ -442,11 +442,11 @@ void reconstruct_gradient(); virtual int select_working_set(int &i, int &j); virtual double calculate_rho(); virtual void do_shrinking(); private: - bool be_shrunk(int i, double Gmax1, double Gmax2); + bool be_shrunk(int i, double Gmax1, double Gmax2); }; void Solver::swap_index(int i, int j) { Q->swap_index(i,j); @@ -831,11 +831,11 @@ double grad_diff=Gmax+G[j]; if (G[j] >= Gmax2) Gmax2 = G[j]; if (grad_diff > 0) { - double obj_diff; + double obj_diff; double quad_coef = QD[i]+QD[j]-2.0*y[i]*Q_i[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; @@ -855,11 +855,11 @@ double grad_diff= Gmax-G[j]; if (-G[j] >= Gmax2) Gmax2 = -G[j]; if (grad_diff > 0) { - double obj_diff; + double obj_diff; double quad_coef = QD[i]+QD[j]+2.0*y[i]*Q_i[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; @@ -1083,11 +1083,11 @@ double grad_diff=Gmaxp+G[j]; if (G[j] >= Gmaxp2) Gmaxp2 = G[j]; if (grad_diff > 0) { - double obj_diff; + double obj_diff; double quad_coef = QD[ip]+QD[j]-2*Q_ip[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; @@ -1107,11 +1107,11 @@ double grad_diff=Gmaxn-G[j]; if (-G[j] >= Gmaxn2) Gmaxn2 = -G[j]; if (grad_diff > 0) { - double obj_diff; + double obj_diff; double quad_coef = QD[in]+QD[j]-2*Q_in[j]; if (quad_coef > 0) obj_diff = -(grad_diff*grad_diff)/quad_coef; else obj_diff = -(grad_diff*grad_diff)/TAU; @@ -1639,11 +1639,11 @@ // decision_function // struct decision_function { double *alpha; - double rho; + double rho; }; static decision_function svm_train_one( const svm_problem *prob, const svm_parameter *param, double Cp, double Cn) @@ -1720,11 +1720,11 @@ double hiTarget=(prior1+1.0)/(prior1+2.0); double loTarget=1/(prior0+2.0); double *t=Malloc(double,l); double fApB,p,q,h11,h22,h21,g1,g2,det,dA,dB,gd,stepsize; double newA,newB,newf,d1,d2; - int iter; + int iter; // Initial Point and Initial Fun Value A=0.0; B=log((prior0+1.0)/(prior1+1.0)); double fval = 0.0; @@ -1959,11 +1959,11 @@ subparam.weight[0]=Cp; subparam.weight[1]=Cn; struct svm_model *submodel = svm_train(&subprob,&subparam); for(j=begin;j<end;j++) { - svm_predict_values(submodel,prob->x[perm[j]],&(dec_values[perm[j]])); + svm_predict_values(submodel,prob->x[perm[j]],&(dec_values[perm[j]])); // ensure +1 -1 order; reason not using CV subroutine dec_values[perm[j]] *= submodel->label[0]; } svm_free_and_destroy_model(&submodel); svm_destroy_param(&subparam); @@ -2016,11 +2016,11 @@ int l = prob->l; int max_nr_class = 16; int nr_class = 0; int *label = Malloc(int,max_nr_class); int *count = Malloc(int,max_nr_class); - int *data_label = Malloc(int,l); + int *data_label = Malloc(int,l); int i; for(i=0;i<l;i++) { int this_label = (int)prob->y[i]; @@ -2392,13 +2392,13 @@ } } fold_start[0]=0; for (i=1;i<=nr_fold;i++) fold_start[i] = fold_start[i-1]+fold_count[i-1]; - free(start); + free(start); free(label); - free(count); + free(count); free(index); free(fold_count); } else { @@ -2441,21 +2441,21 @@ (param->svm_type == C_SVC || param->svm_type == NU_SVC)) { double *prob_estimates=Malloc(double,svm_get_nr_class(submodel)); for(j=begin;j<end;j++) target[perm[j]] = svm_predict_probability(submodel,prob->x[perm[j]],prob_estimates); - free(prob_estimates); + free(prob_estimates); } else for(j=begin;j<end;j++) target[perm[j]] = svm_predict(submodel,prob->x[perm[j]]); svm_free_and_destroy_model(&submodel); free(subprob.x); free(subprob.y); } free(fold_start); - free(perm); + free(perm); } int svm_get_svm_type(const svm_model *model) { @@ -2619,11 +2619,11 @@ if(prob_estimates[i] > prob_estimates[prob_max_idx]) prob_max_idx = i; for(i=0;i<nr_class;i++) free(pairwise_prob[i]); free(dec_values); - free(pairwise_prob); + free(pairwise_prob); return model->label[prob_max_idx]; } else return svm_predict(model, x); } @@ -2751,37 +2751,29 @@ break; } return line; } -svm_model *svm_load_model(const char *model_file_name) +// +// FSCANF helps to handle fscanf failures. +// Its do-while block avoids the ambiguity when +// if (...) +// FSCANF(); +// is used +// +#define FSCANF(_stream, _format, _var) do{ if (fscanf(_stream, _format, _var) != 1) return false; }while(0) +bool read_model_header(FILE *fp, svm_model* model) { - 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; - model->probA = NULL; - model->probB = NULL; - model->sv_indices = NULL; - model->label = NULL; - model->nSV = NULL; - char cmd[81]; while(1) { - fscanf(fp,"%80s",cmd); + FSCANF(fp,"%80s",cmd); if(strcmp(cmd,"svm_type")==0) { - fscanf(fp,"%80s",cmd); + FSCANF(fp,"%80s",cmd); int i; for(i=0;svm_type_table[i];i++) { if(strcmp(svm_type_table[i],cmd)==0) { @@ -2790,23 +2782,16 @@ } } 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; + return false; } } else if(strcmp(cmd,"kernel_type")==0) { - fscanf(fp,"%80s",cmd); + FSCANF(fp,"%80s",cmd); int i; for(i=0;kernel_type_table[i];i++) { if(strcmp(kernel_type_table[i],cmd)==0) { @@ -2814,88 +2799,109 @@ break; } } 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; + fprintf(stderr,"unknown kernel function.\n"); + return false; } } else if(strcmp(cmd,"degree")==0) - fscanf(fp,"%d",&param.degree); + FSCANF(fp,"%d",&param.degree); else if(strcmp(cmd,"gamma")==0) - fscanf(fp,"%lf",&param.gamma); + FSCANF(fp,"%lf",&param.gamma); else if(strcmp(cmd,"coef0")==0) - fscanf(fp,"%lf",&param.coef0); + FSCANF(fp,"%lf",&param.coef0); else if(strcmp(cmd,"nr_class")==0) - fscanf(fp,"%d",&model->nr_class); + FSCANF(fp,"%d",&model->nr_class); else if(strcmp(cmd,"total_sv")==0) - fscanf(fp,"%d",&model->l); + FSCANF(fp,"%d",&model->l); else if(strcmp(cmd,"rho")==0) { int n = model->nr_class * (model->nr_class-1)/2; model->rho = Malloc(double,n); for(int i=0;i<n;i++) - fscanf(fp,"%lf",&model->rho[i]); + FSCANF(fp,"%lf",&model->rho[i]); } else if(strcmp(cmd,"label")==0) { int n = model->nr_class; model->label = Malloc(int,n); for(int i=0;i<n;i++) - fscanf(fp,"%d",&model->label[i]); + FSCANF(fp,"%d",&model->label[i]); } else if(strcmp(cmd,"probA")==0) { int n = model->nr_class * (model->nr_class-1)/2; model->probA = Malloc(double,n); for(int i=0;i<n;i++) - fscanf(fp,"%lf",&model->probA[i]); + FSCANF(fp,"%lf",&model->probA[i]); } else if(strcmp(cmd,"probB")==0) { int n = model->nr_class * (model->nr_class-1)/2; model->probB = Malloc(double,n); for(int i=0;i<n;i++) - fscanf(fp,"%lf",&model->probB[i]); + FSCANF(fp,"%lf",&model->probB[i]); } else if(strcmp(cmd,"nr_sv")==0) { int n = model->nr_class; model->nSV = Malloc(int,n); for(int i=0;i<n;i++) - fscanf(fp,"%d",&model->nSV[i]); + FSCANF(fp,"%d",&model->nSV[i]); } else if(strcmp(cmd,"SV")==0) { while(1) { int c = getc(fp); - if(c==EOF || c=='\n') break; + if(c==EOF || c=='\n') break; } 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; + return false; } } + return true; + +} + +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); + model->rho = NULL; + model->probA = NULL; + model->probB = NULL; + model->sv_indices = NULL; + model->label = NULL; + model->nSV = NULL; + + // read header + if (!read_model_header(fp, model)) + { + fprintf(stderr, "ERROR: fscanf failed to read model\n"); + setlocale(LC_ALL, old_locale); + free(old_locale); + free(model->rho); + free(model->label); + free(model->nSV); + free(model); + return NULL; + } + // read sv_coef and SV int elements = 0; long pos = ftell(fp);