svmpredict.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include "../svm.h"
5 
6 #include "mex.h"
7 #include "svm_model_matlab.h"
8 
9 #ifdef MX_API_VER
10 #if MX_API_VER < 0x07030000
11 typedef int mwIndex;
12 #endif
13 #endif
14 
15 #define CMD_LEN 2048
16 
17 void read_sparse_instance(const mxArray *prhs, int index, struct svm_node *x)
18 {
19  int i, j, low, high;
20  mwIndex *ir, *jc;
21  double *samples;
22 
23  ir = mxGetIr(prhs);
24  jc = mxGetJc(prhs);
25  samples = mxGetPr(prhs);
26 
27  // each column is one instance
28  j = 0;
29  low = (int)jc[index], high = (int)jc[index+1];
30  for(i=low;i<high;i++)
31  {
32  x[j].index = (int)ir[i] + 1;
33  x[j].value = samples[i];
34  j++;
35  }
36  x[j].index = -1;
37 }
38 
39 static void fake_answer(mxArray *plhs[])
40 {
41  plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL);
42  plhs[1] = mxCreateDoubleMatrix(0, 0, mxREAL);
43  plhs[2] = mxCreateDoubleMatrix(0, 0, mxREAL);
44 }
45 
46 void predict(mxArray *plhs[], const mxArray *prhs[], struct svm_model *model, const int predict_probability)
47 {
48  int label_vector_row_num, label_vector_col_num;
49  int feature_number, testing_instance_number;
50  int instance_index;
51  double *ptr_instance, *ptr_label, *ptr_predict_label;
52  double *ptr_prob_estimates, *ptr_dec_values, *ptr;
53  struct svm_node *x;
54  mxArray *pplhs[1]; // transposed instance sparse matrix
55 
56  int correct = 0;
57  int total = 0;
58  double error = 0;
59  double sump = 0, sumt = 0, sumpp = 0, sumtt = 0, sumpt = 0;
60 
61  int svm_type=svm_get_svm_type(model);
62  int nr_class=svm_get_nr_class(model);
63  double *prob_estimates=NULL;
64 
65  // prhs[1] = testing instance matrix
66  feature_number = (int)mxGetN(prhs[1]);
67  testing_instance_number = (int)mxGetM(prhs[1]);
68  label_vector_row_num = (int)mxGetM(prhs[0]);
69  label_vector_col_num = (int)mxGetN(prhs[0]);
70 
71  if(label_vector_row_num!=testing_instance_number)
72  {
73  mexPrintf("Length of label vector does not match # of instances.\n");
74  fake_answer(plhs);
75  return;
76  }
77  if(label_vector_col_num!=1)
78  {
79  mexPrintf("label (1st argument) should be a vector (# of column is 1).\n");
80  fake_answer(plhs);
81  return;
82  }
83 
84  ptr_instance = mxGetPr(prhs[1]);
85  ptr_label = mxGetPr(prhs[0]);
86 
87  // transpose instance matrix
88  if(mxIsSparse(prhs[1]))
89  {
90  if(model->param.kernel_type == PRECOMPUTED)
91  {
92  // precomputed kernel requires dense matrix, so we make one
93  mxArray *rhs[1], *lhs[1];
94  rhs[0] = mxDuplicateArray(prhs[1]);
95  if(mexCallMATLAB(1, lhs, 1, rhs, "full"))
96  {
97  mexPrintf("Error: cannot full testing instance matrix\n");
98  fake_answer(plhs);
99  return;
100  }
101  ptr_instance = mxGetPr(lhs[0]);
102  mxDestroyArray(rhs[0]);
103  }
104  else
105  {
106  mxArray *pprhs[1];
107  pprhs[0] = mxDuplicateArray(prhs[1]);
108  if(mexCallMATLAB(1, pplhs, 1, pprhs, "transpose"))
109  {
110  mexPrintf("Error: cannot transpose testing instance matrix\n");
111  fake_answer(plhs);
112  return;
113  }
114  }
115  }
116 
117  if(predict_probability)
118  {
119  if(svm_type==NU_SVR || svm_type==EPSILON_SVR)
120  mexPrintf("Prob. model for test data: target value = predicted value + z,\nz: Laplace distribution e^(-|z|/sigma)/(2sigma),sigma=%g\n",svm_get_svr_probability(model));
121  else
122  prob_estimates = (double *) malloc(nr_class*sizeof(double));
123  }
124 
125  plhs[0] = mxCreateDoubleMatrix(testing_instance_number, 1, mxREAL);
126  if(predict_probability)
127  {
128  // prob estimates are in plhs[2]
129  if(svm_type==C_SVC || svm_type==NU_SVC)
130  plhs[2] = mxCreateDoubleMatrix(testing_instance_number, nr_class, mxREAL);
131  else
132  plhs[2] = mxCreateDoubleMatrix(0, 0, mxREAL);
133  }
134  else
135  {
136  // decision values are in plhs[2]
137  if(svm_type == ONE_CLASS ||
138  svm_type == EPSILON_SVR ||
139  svm_type == NU_SVR ||
140  nr_class == 1) // if only one class in training data, decision values are still returned.
141  plhs[2] = mxCreateDoubleMatrix(testing_instance_number, 1, mxREAL);
142  else
143  plhs[2] = mxCreateDoubleMatrix(testing_instance_number, nr_class*(nr_class-1)/2, mxREAL);
144  }
145 
146  ptr_predict_label = mxGetPr(plhs[0]);
147  ptr_prob_estimates = mxGetPr(plhs[2]);
148  ptr_dec_values = mxGetPr(plhs[2]);
149  x = (struct svm_node*)malloc((feature_number+1)*sizeof(struct svm_node) );
150  for(instance_index=0;instance_index<testing_instance_number;instance_index++)
151  {
152  int i;
153  double target_label, predict_label;
154 
155  target_label = ptr_label[instance_index];
156 
157  if(mxIsSparse(prhs[1]) && model->param.kernel_type != PRECOMPUTED) // prhs[1]^T is still sparse
158  read_sparse_instance(pplhs[0], instance_index, x);
159  else
160  {
161  for(i=0;i<feature_number;i++)
162  {
163  x[i].index = i+1;
164  x[i].value = ptr_instance[testing_instance_number*i+instance_index];
165  }
166  x[feature_number].index = -1;
167  }
168 
169  if(predict_probability)
170  {
171  if(svm_type==C_SVC || svm_type==NU_SVC)
172  {
173  predict_label = svm_predict_probability(model, x, prob_estimates);
174  ptr_predict_label[instance_index] = predict_label;
175  for(i=0;i<nr_class;i++)
176  ptr_prob_estimates[instance_index + i * testing_instance_number] = prob_estimates[i];
177  } else {
178  predict_label = svm_predict(model,x);
179  ptr_predict_label[instance_index] = predict_label;
180  }
181  }
182  else
183  {
184  if(svm_type == ONE_CLASS ||
185  svm_type == EPSILON_SVR ||
186  svm_type == NU_SVR)
187  {
188  double res;
189  predict_label = svm_predict_values(model, x, &res);
190  ptr_dec_values[instance_index] = res;
191  }
192  else
193  {
194  double *dec_values = (double *) malloc(sizeof(double) * nr_class*(nr_class-1)/2);
195  predict_label = svm_predict_values(model, x, dec_values);
196  if(nr_class == 1)
197  ptr_dec_values[instance_index] = 1;
198  else
199  for(i=0;i<(nr_class*(nr_class-1))/2;i++)
200  ptr_dec_values[instance_index + i * testing_instance_number] = dec_values[i];
201  free(dec_values);
202  }
203  ptr_predict_label[instance_index] = predict_label;
204  }
205 
206  if(predict_label == target_label)
207  ++correct;
208  error += (predict_label-target_label)*(predict_label-target_label);
209  sump += predict_label;
210  sumt += target_label;
211  sumpp += predict_label*predict_label;
212  sumtt += target_label*target_label;
213  sumpt += predict_label*target_label;
214  ++total;
215  }
216  if(svm_type==NU_SVR || svm_type==EPSILON_SVR)
217  {
218  mexPrintf("Mean squared error = %g (regression)\n",error/total);
219  mexPrintf("Squared correlation coefficient = %g (regression)\n",
220  ((total*sumpt-sump*sumt)*(total*sumpt-sump*sumt))/
221  ((total*sumpp-sump*sump)*(total*sumtt-sumt*sumt))
222  );
223  }
224  else
225  mexPrintf("Accuracy = %g%% (%d/%d) (classification)\n",
226  (double)correct/total*100,correct,total);
227 
228  // return accuracy, mean squared error, squared correlation coefficient
229  plhs[1] = mxCreateDoubleMatrix(3, 1, mxREAL);
230  ptr = mxGetPr(plhs[1]);
231  ptr[0] = (double)correct/total*100;
232  ptr[1] = error/total;
233  ptr[2] = ((total*sumpt-sump*sumt)*(total*sumpt-sump*sumt))/
234  ((total*sumpp-sump*sump)*(total*sumtt-sumt*sumt));
235 
236  free(x);
237  if(prob_estimates != NULL)
238  free(prob_estimates);
239 }
240 
242 {
243  mexPrintf(
244  "Usage: [predicted_label, accuracy, decision_values/prob_estimates] = svmpredict(testing_label_vector, testing_instance_matrix, model, 'libsvm_options')\n"
245  "Parameters:\n"
246  " model: SVM model structure from svmtrain.\n"
247  " libsvm_options:\n"
248  " -b probability_estimates: whether to predict probability estimates, 0 or 1 (default 0); one-class SVM not supported yet\n"
249  "Returns:\n"
250  " predicted_label: SVM prediction output vector.\n"
251  " accuracy: a vector with accuracy, mean squared error, squared correlation coefficient.\n"
252  " prob_estimates: If selected, probability estimate vector.\n"
253  );
254 }
255 
256 void mexFunction( int nlhs, mxArray *plhs[],
257  int nrhs, const mxArray *prhs[] )
258 {
259  int prob_estimate_flag = 0;
260  struct svm_model *model;
261 
262  if(nrhs > 4 || nrhs < 3)
263  {
264  exit_with_help();
265  fake_answer(plhs);
266  return;
267  }
268 
269  if(!mxIsDouble(prhs[0]) || !mxIsDouble(prhs[1])) {
270  mexPrintf("Error: label vector and instance matrix must be double\n");
271  fake_answer(plhs);
272  return;
273  }
274 
275  if(mxIsStruct(prhs[2]))
276  {
277  const char *error_msg;
278 
279  // parse options
280  if(nrhs==4)
281  {
282  int i, argc = 1;
283  char cmd[CMD_LEN], *argv[CMD_LEN/2];
284 
285  // put options in argv[]
286  mxGetString(prhs[3], cmd, mxGetN(prhs[3]) + 1);
287  if((argv[argc] = strtok(cmd, " ")) != NULL)
288  while((argv[++argc] = strtok(NULL, " ")) != NULL)
289  ;
290 
291  for(i=1;i<argc;i++)
292  {
293  if(argv[i][0] != '-') break;
294  if(++i>=argc)
295  {
296  exit_with_help();
297  fake_answer(plhs);
298  return;
299  }
300  switch(argv[i-1][1])
301  {
302  case 'b':
303  prob_estimate_flag = atoi(argv[i]);
304  break;
305  default:
306  mexPrintf("Unknown option: -%c\n", argv[i-1][1]);
307  exit_with_help();
308  fake_answer(plhs);
309  return;
310  }
311  }
312  }
313 
314  model = matlab_matrix_to_model(prhs[2], &error_msg);
315  if (model == NULL)
316  {
317  mexPrintf("Error: can't read model: %s\n", error_msg);
318  fake_answer(plhs);
319  return;
320  }
321 
322  if(prob_estimate_flag)
323  {
324  if(svm_check_probability_model(model)==0)
325  {
326  mexPrintf("Model does not support probabiliy estimates\n");
327  fake_answer(plhs);
329  return;
330  }
331  }
332  else
333  {
334  if(svm_check_probability_model(model)!=0)
335  mexPrintf("Model supports probability estimates, but disabled in predicton.\n");
336  }
337 
338  predict(plhs, prhs, model, prob_estimate_flag);
339  // destroy model
341  }
342  else
343  {
344  mexPrintf("model file should be a struct array\n");
345  fake_answer(plhs);
346  }
347 
348  return;
349 }
void exit_with_help()
Definition: svmpredict.c:241
string cmd
Definition: easy.py:48
void read_sparse_instance(const mxArray *prhs, int index, struct svm_node *x)
Definition: svmpredict.c:17
Definition: svm.h:25
double value
Definition: svm.h:15
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
Definition: svmpredict.c:256
void predict(mxArray *plhs[], const mxArray *prhs[], struct svm_model *model, const int predict_probability)
Definition: svmpredict.c:46
Definition: svm.h:25
double svm_get_svr_probability(const svm_model *model)
Definition: svm.cpp:2447
Definition: svm.h:52
def svm_predict(y, x, m, options="")
Definition: svmutil.py:164
struct svm_node * x
Definition: svm-predict.c:8
Definition: svm.h:25
static void fake_answer(mxArray *plhs[])
Definition: svmpredict.c:39
int svm_get_nr_class(const svm_model *model)
Definition: svm.cpp:2435
int svm_check_probability_model(const svm_model *model)
Definition: svm.cpp:3098
index
Definition: subset.py:58
int predict_probability
Definition: svm-predict.c:12
struct svm_model * matlab_matrix_to_model(const mxArray *matlab_struct, const char **msg)
void svm_free_and_destroy_model(svm_model **model_ptr_ptr)
Definition: svm.cpp:2961
double svm_predict_values(const svm_model *model, const svm_node *x, double *dec_values)
Definition: svm.cpp:2459
double svm_predict_probability(const svm_model *model, const svm_node *x, double *prob_estimates)
Definition: svm.cpp:2550
struct svm_parameter param
Definition: svm.h:54
#define CMD_LEN
Definition: svmpredict.c:15
int index
Definition: svm.h:14
int svm_get_svm_type(const svm_model *model)
Definition: svm.cpp:2430
Definition: svm.h:25
Definition: svm.h:12
struct svm_model * model
Definition: svmtrain.c:58
int kernel_type
Definition: svm.h:31


haf_grasping
Author(s): David Fischinger
autogenerated on Mon Jun 10 2019 13:28:43