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);