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