ext/libsvm/libsvm.c in rb-libsvm-1.0.11 vs ext/libsvm/libsvm.c in rb-libsvm-1.1.0

- old
+ new

@@ -20,11 +20,11 @@ } /* Libsvm::Node */ static struct svm_node *node_new() { struct svm_node *n; - n = (struct svm_node *) calloc(1,sizeof(struct svm_node)); + n = calloc(1,sizeof(struct svm_node)); if(n == NULL) return NULL; return n; } @@ -45,11 +45,11 @@ rx_def_accessor(cNode,struct svm_node,double,value); /* Libsvm::Problem */ static struct svm_problem *problem_new() { struct svm_problem *n; - n = (struct svm_problem *) calloc(1,sizeof(struct svm_problem)); + n = calloc(1,sizeof(struct svm_problem)); if(n == NULL) return NULL; return n; } @@ -79,11 +79,11 @@ int example_ary_len, j; VALUE node; /* allocate memory for it */ example_ary_len = rx_ary_size(example_ary); - x = (struct svm_node *)calloc(example_ary_len+1,sizeof(struct svm_node)); + x = calloc(example_ary_len+1,sizeof(struct svm_node)); if(x == 0) { rb_raise(rb_eNoMemError, "on Libsvm::Node allocation" " %s:%i", __FILE__,__LINE__); } /* loop it's element nodes */ for(j = 0; j < example_ary_len; ++j) { @@ -98,17 +98,16 @@ } static struct svm_node **examples_ary_to_internal(VALUE examples_ary) { struct svm_node **x; - struct svm_node *node_struct; - VALUE nodes_ary, node; - int nodes_ary_len, i; + VALUE nodes_ary; + int i; int num = rx_ary_size(examples_ary); - x = (struct svm_node **)calloc(num,sizeof(struct svm_node *)); + x = calloc(num,sizeof(struct svm_node *)); if(x == 0) { rb_raise(rb_eNoMemError, "%s:%i", __FILE__,__LINE__); } for(i = 0; i < num; ++i) { @@ -131,14 +130,11 @@ If those 2 don't match in length and ArgumentError is raised. */ static VALUE cProblem_examples_set(VALUE obj,VALUE labels_ary,VALUE examples_ary) { struct svm_problem *prob; - struct svm_node *node_struct; - /* VALUE num;*/ - int i, nodes_ary_len; - VALUE label, node, nodes_ary; + int i; int num = rx_ary_size(labels_ary); if(num != rx_ary_size(examples_ary)) { rb_raise(rb_eArgError, "Number of labels (%i) does not match number of features (%i).", num, rx_ary_size(examples_ary)); @@ -152,11 +148,11 @@ free(*(prob->x+i)); } free(prob->x); } - prob->y = (double *)calloc(num,sizeof(double)); + prob->y = calloc(num,sizeof(double)); if(prob->y == 0) { rb_raise(rb_eNoMemError, "%s:%i", __FILE__,__LINE__); } for(i = 0; i < num; ++i) { @@ -180,18 +176,18 @@ struct svm_problem *prob; struct svm_node *node, *node_copy; double label; struct svm_node *features; VALUE labels_ary, examples_ary, example_ary, v_node, result; - int i,n; + int i; Data_Get_Struct(problem, struct svm_problem, prob); labels_ary = rb_ary_new2(prob->l); examples_ary = rb_ary_new2(prob->l); - features = (struct svm_node *)calloc(prob->l, sizeof(struct svm_node)); + features = calloc(prob->l, sizeof(struct svm_node)); if(features == 0) { rb_raise(rb_eNoMemError, "on allocating Libsvm::Node" " %s:%i", __FILE__,__LINE__); } for(i = 0; i < prob->l; ++i) { @@ -199,11 +195,11 @@ rb_ary_push(labels_ary,rb_float_new(label)); node = *(prob->x+i); /* example start pointer */ example_ary = rb_ary_new(); while(node->index != -1) { - node_copy = (struct svm_node *)malloc(sizeof(struct svm_node)); + node_copy = malloc(sizeof(struct svm_node)); if(node_copy == 0) { rb_raise(rb_eNoMemError, "on allocating Libsvm::Node" " %s:%i", __FILE__,__LINE__); } memcpy(node_copy,node,sizeof(struct svm_node)); v_node = Data_Wrap_Struct(cNode,0,node_free,node_copy); @@ -222,11 +218,11 @@ /* SvmParameter */ static struct svm_parameter *parameter_new() { struct svm_parameter *n; - n = (struct svm_parameter *) calloc(1,sizeof(struct svm_parameter)); + n = calloc(1,sizeof(struct svm_parameter)); if(n == NULL) return NULL; return n; } @@ -268,24 +264,23 @@ just set nr_weight to 0. */ static VALUE cSvmParameter_label_weights_set(VALUE obj,VALUE weight_hash) { struct svm_parameter *param; - int i,len,weight_label; - double weight; + int i; VALUE keys,key,val; Data_Get_Struct(obj,struct svm_parameter,param); if(param->nr_weight > 0) { free(param->weight); free(param->weight_label); } param->nr_weight = rx_hash_size(weight_hash); - param->weight = (double *)calloc(param->nr_weight,sizeof(double)); - param->weight_label = (int *)calloc(param->nr_weight,sizeof(int)); + param->weight = calloc(param->nr_weight,sizeof(double)); + param->weight_label = calloc(param->nr_weight,sizeof(int)); keys = rb_funcall(weight_hash, rb_intern("keys"),0); for(i = 0; i < param->nr_weight; ++i) { key = rb_ary_entry(keys,i); @@ -351,10 +346,40 @@ class = svm_predict(model, x); return rb_float_new(class); } +static VALUE cModel_predict_probability(VALUE obj,VALUE example) { + struct svm_node *x; + struct svm_model *model; + double class; + double *c_estimates; + VALUE estimates; + VALUE target; + int i; + + x = example_to_internal(example); + Data_Get_Struct(obj, struct svm_model, model); + c_estimates = calloc(model->nr_class, sizeof(double)); + if(c_estimates == 0) { + rb_raise(rb_eNoMemError, "on predict probability estimates allocation" " %s:%i", __FILE__,__LINE__); + } + + class = svm_predict_probability(model, x, c_estimates); + + estimates = rb_ary_new(); + for (i = 0; i < model->nr_class; i++) + rb_ary_push(estimates, rx_from_double(c_estimates[i])); + + free(c_estimates); + + target = rb_ary_new(); + rb_ary_push(target, rb_float_new(class)); + rb_ary_push(target, estimates); + return target; +} + static VALUE cModel_save(VALUE obj, VALUE filename) { const struct svm_model *model; const char *path; int rc; @@ -404,11 +429,11 @@ Data_Get_Struct(parameter, struct svm_parameter, param); nr_fold = NUM2INT(num_fold); target = rb_ary_new2(prob->l); - target_ptr = (double *)calloc(prob->l, sizeof(double)); + target_ptr = calloc(prob->l, sizeof(double)); if(target_ptr == 0) { rb_raise(rb_eNoMemError, "on cross-validation result allocation" " %s:%i", __FILE__,__LINE__); } svm_cross_validation(prob, param, nr_fold, target_ptr); @@ -464,19 +489,10 @@ rb_define_singleton_method(cModel, "load", cModel_class_load, 1); rb_define_method(cModel, "save", cModel_save, 1); rb_define_method(cModel, "svm_type", cModel_svm_type, 0); rb_define_method(cModel, "classes", cModel_classes, 0); rb_define_method(cModel, "predict", cModel_predict, 1); - - /* - Not covered, for various reasons: - TODO - void svm_get_labels(const struct svm_model *model, int *label); - SVR? - double svm_get_svr_probability(const struct svm_model *model); - SVR? - double svm_predict_probability(const struct svm_model *model, const struct svm_node *x, double* prob_estimates); - Model holds reference to this, so when to use it? - void svm_destroy_param(struct svm_parameter *param); - SVR? - int svm_check_probability_model(const struct svm_model *model); - */ + rb_define_method(cModel, "predict_probability", cModel_predict_probability, 1); mKernelType = rb_define_module_under(mLibsvm, "KernelType"); rb_define_const(mKernelType, "LINEAR", INT2NUM(LINEAR)); rb_define_const(mKernelType, "POLY", INT2NUM(POLY)); rb_define_const(mKernelType, "RBF", INT2NUM(RBF));