/* * Fill an svm_problem struct. problem->x will be malloc'd. */ void set_problem(struct svm_problem *problem, char *X, char *Y, char *sample_weight, npy_intp *dims, int kernel_type) { if (problem == NULL) return; problem->l = (int) dims[0]; /* number of samples */ problem->y = (double *) Y; problem->x = dense_to_libsvm((double *) X, dims); /* implicit call to malloc */ problem->W = (double *) sample_weight; }
/* * Create and return a svm_problem struct. It is up to the user to free resulting * structure. */ struct svm_problem * set_problem(char *X, char *Y, npy_intp *dims, int kernel_type) { struct svm_problem *problem; problem = (struct svm_problem *) malloc(sizeof(struct svm_problem)); if (problem == NULL) return NULL; problem->l = (int) dims[0]; /* number of samples */ problem->y = (double *) Y; problem->x = dense_to_libsvm((double *) X, dims); if (problem->x == NULL) { free(problem); return NULL; } return problem; }
int copy_predict_values(char *predict, struct svm_model *model, npy_intp *predict_dims, char *dec_values, int nr_class) { npy_intp i; struct svm_node *predict_nodes; predict_nodes = dense_to_libsvm((double *) predict, predict_dims); if (predict_nodes == NULL) return -1; for(i=0; i<predict_dims[0]; ++i) { svm_predict_values(model, &predict_nodes[i], ((double *) dec_values) + i*nr_class); } free(predict_nodes); return 0; }
int copy_predict_proba(char *predict, struct svm_model *model, npy_intp *predict_dims, char *dec_values) { npy_intp i, n, m; struct svm_node *predict_nodes; n = predict_dims[0]; m = (npy_intp) model->nr_class; predict_nodes = dense_to_libsvm((double *) predict, predict_dims); if (predict_nodes == NULL) return -1; for(i=0; i<n; ++i) { svm_predict_probability(model, &predict_nodes[i], ((double *) dec_values) + i*m); } free(predict_nodes); return 0; }
/* * Predict using model. * * It will return -1 if we run out of memory. */ int copy_predict(char *predict, struct svm_model *model, npy_intp *predict_dims, char *dec_values) { double *t = (double *) dec_values; struct svm_node *predict_nodes; npy_intp i; predict_nodes = dense_to_libsvm((double *) predict, predict_dims); if (predict_nodes == NULL) return -1; for(i=0; i<predict_dims[0]; ++i) { *t = svm_predict(model, &predict_nodes[i]); ++t; } free(predict_nodes); return 0; }
/* * Create and return an instance of svm_model. * * The copy of model->sv_coef should be straightforward, but * unfortunately to represent a matrix numpy and libsvm use different * approaches, so it requires some iteration. * * Possible issue: on 64 bits, the number of columns that numpy can * store is a long, but libsvm enforces this number (model->l) to be * an int, so we might have numpy matrices that do not fit into libsvm's * data structure. * */ struct svm_model *set_model(struct svm_parameter *param, int nr_class, char *SV, npy_intp *SV_dims, char *support, npy_intp *support_dims, npy_intp *sv_coef_strides, char *sv_coef, char *rho, char *nSV, char *label, char *probA, char *probB) { struct svm_model *model; double *dsv_coef = (double *) sv_coef; int i, m; m = nr_class * (nr_class-1)/2; if ((model = malloc(sizeof(struct svm_model))) == NULL) goto model_error; if ((model->nSV = malloc(nr_class * sizeof(int))) == NULL) goto nsv_error; if ((model->label = malloc(nr_class * sizeof(int))) == NULL) goto label_error; if ((model->sv_coef = malloc((nr_class-1)*sizeof(double *))) == NULL) goto sv_coef_error; if ((model->rho = malloc( m * sizeof(double))) == NULL) goto rho_error; model->nr_class = nr_class; model->param = *param; model->l = (int) support_dims[0]; if (param->kernel_type == PRECOMPUTED) { if ((model->SV = malloc ((model->l) * sizeof(struct svm_node))) == NULL) goto SV_error; for (i=0; i<model->l; ++i) { model->SV[i].ind = ((int *) support)[i]; model->SV[i].values = NULL; } } else { model->SV = dense_to_libsvm((double *) SV, SV_dims); } /* * regression and one-class does not use nSV, label. * TODO: does this provoke memory leaks (we just malloc'ed them)? */ if (param->svm_type < 2) { memcpy(model->nSV, nSV, model->nr_class * sizeof(int)); memcpy(model->label, label, model->nr_class * sizeof(int)); } for (i=0; i < model->nr_class-1; i++) { model->sv_coef[i] = dsv_coef + i*(model->l); } for (i=0; i<m; ++i) { (model->rho)[i] = -((double *) rho)[i]; } /* * just to avoid segfaults, these features are not wrapped but * svm_destroy_model will try to free them. */ if (param->probability) { if ((model->probA = malloc(m * sizeof(double))) == NULL) goto probA_error; memcpy(model->probA, probA, m * sizeof(double)); if ((model->probB = malloc(m * sizeof(double))) == NULL) goto probB_error; memcpy(model->probB, probB, m * sizeof(double)); } else { model->probA = NULL; model->probB = NULL; } /* We'll free SV ourselves */ model->free_sv = 0; return model; probB_error: free(model->probA); probA_error: free(model->SV); SV_error: free(model->rho); rho_error: free(model->sv_coef); sv_coef_error: free(model->label); label_error: free(model->nSV); nsv_error: free(model); model_error: return NULL; }