svm_model_matlab.c
Go to the documentation of this file.
1 #include <stdlib.h>
2 #include <string.h>
3 #include "../svm.h"
4 
5 #include "mex.h"
6 
7 #ifdef MX_API_VER
8 #if MX_API_VER < 0x07030000
9 typedef int mwIndex;
10 #endif
11 #endif
12 
13 #define NUM_OF_RETURN_FIELD 11
14 
15 #define Malloc(type,n) (type *)malloc((n)*sizeof(type))
16 
17 static const char *field_names[] =
18 {
19  "Parameters",
20  "nr_class",
21  "totalSV",
22  "rho",
23  "Label",
24  "sv_indices",
25  "ProbA",
26  "ProbB",
27  "nSV",
28  "sv_coef",
29  "SVs"
30 };
31 
32 const char *model_to_matlab_structure(mxArray *plhs[], int num_of_feature, struct svm_model *model)
33 {
34  int i, j, n;
35  double *ptr;
36  mxArray *return_model, **rhs;
37  int out_id = 0;
38 
39  rhs = (mxArray **)mxMalloc(sizeof(mxArray *)*NUM_OF_RETURN_FIELD);
40 
41  // Parameters
42  rhs[out_id] = mxCreateDoubleMatrix(5, 1, mxREAL);
43  ptr = mxGetPr(rhs[out_id]);
44  ptr[0] = model->param.svm_type;
45  ptr[1] = model->param.kernel_type;
46  ptr[2] = model->param.degree;
47  ptr[3] = model->param.gamma;
48  ptr[4] = model->param.coef0;
49  out_id++;
50 
51  // nr_class
52  rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
53  ptr = mxGetPr(rhs[out_id]);
54  ptr[0] = model->nr_class;
55  out_id++;
56 
57  // total SV
58  rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
59  ptr = mxGetPr(rhs[out_id]);
60  ptr[0] = model->l;
61  out_id++;
62 
63  // rho
64  n = model->nr_class * (model->nr_class - 1) / 2;
65  rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL);
66  ptr = mxGetPr(rhs[out_id]);
67  for (i = 0; i < n; i++)
68  ptr[i] = model->rho[i];
69  out_id++;
70 
71  // Label
72  if (model->label)
73  {
74  rhs[out_id] = mxCreateDoubleMatrix(model->nr_class, 1, mxREAL);
75  ptr = mxGetPr(rhs[out_id]);
76  for (i = 0; i < model->nr_class; i++)
77  ptr[i] = model->label[i];
78  }
79  else
80  rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL);
81  out_id++;
82 
83  // sv_indices
84  if (model->sv_indices)
85  {
86  rhs[out_id] = mxCreateDoubleMatrix(model->l, 1, mxREAL);
87  ptr = mxGetPr(rhs[out_id]);
88  for (i = 0; i < model->l; i++)
89  ptr[i] = model->sv_indices[i];
90  }
91  else
92  rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL);
93  out_id++;
94 
95  // probA
96  if (model->probA != NULL)
97  {
98  rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL);
99  ptr = mxGetPr(rhs[out_id]);
100  for (i = 0; i < n; i++)
101  ptr[i] = model->probA[i];
102  }
103  else
104  rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL);
105  out_id ++;
106 
107  // probB
108  if (model->probB != NULL)
109  {
110  rhs[out_id] = mxCreateDoubleMatrix(n, 1, mxREAL);
111  ptr = mxGetPr(rhs[out_id]);
112  for (i = 0; i < n; i++)
113  ptr[i] = model->probB[i];
114  }
115  else
116  rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL);
117  out_id++;
118 
119  // nSV
120  if (model->nSV)
121  {
122  rhs[out_id] = mxCreateDoubleMatrix(model->nr_class, 1, mxREAL);
123  ptr = mxGetPr(rhs[out_id]);
124  for (i = 0; i < model->nr_class; i++)
125  ptr[i] = model->nSV[i];
126  }
127  else
128  rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL);
129  out_id++;
130 
131  // sv_coef
132  rhs[out_id] = mxCreateDoubleMatrix(model->l, model->nr_class - 1, mxREAL);
133  ptr = mxGetPr(rhs[out_id]);
134  for (i = 0; i < model->nr_class - 1; i++)
135  for (j = 0; j < model->l; j++)
136  ptr[(i * (model->l)) + j] = model->sv_coef[i][j];
137  out_id++;
138 
139  // SVs
140  {
141  int ir_index, nonzero_element;
142  mwIndex *ir, *jc;
143  mxArray *pprhs[1], *pplhs[1];
144 
145  if (model->param.kernel_type == PRECOMPUTED)
146  {
147  nonzero_element = model->l;
148  num_of_feature = 1;
149  }
150  else
151  {
152  nonzero_element = 0;
153  for (i = 0; i < model->l; i++)
154  {
155  j = 0;
156  while (model->SV[i][j].index != -1)
157  {
158  nonzero_element++;
159  j++;
160  }
161  }
162  }
163 
164  // SV in column, easier accessing
165  rhs[out_id] = mxCreateSparse(num_of_feature, model->l, nonzero_element, mxREAL);
166  ir = mxGetIr(rhs[out_id]);
167  jc = mxGetJc(rhs[out_id]);
168  ptr = mxGetPr(rhs[out_id]);
169  jc[0] = ir_index = 0;
170  for (i = 0; i < model->l; i++)
171  {
172  if (model->param.kernel_type == PRECOMPUTED)
173  {
174  // make a (1 x model->l) matrix
175  ir[ir_index] = 0;
176  ptr[ir_index] = model->SV[i][0].value;
177  ir_index++;
178  jc[i + 1] = jc[i] + 1;
179  }
180  else
181  {
182  int x_index = 0;
183  while (model->SV[i][x_index].index != -1)
184  {
185  ir[ir_index] = model->SV[i][x_index].index - 1;
186  ptr[ir_index] = model->SV[i][x_index].value;
187  ir_index++, x_index++;
188  }
189  jc[i + 1] = jc[i] + x_index;
190  }
191  }
192  // transpose back to SV in row
193  pprhs[0] = rhs[out_id];
194  if (mexCallMATLAB(1, pplhs, 1, pprhs, "transpose"))
195  return "cannot transpose SV matrix";
196  rhs[out_id] = pplhs[0];
197  out_id++;
198  }
199 
200  /* Create a struct matrix contains NUM_OF_RETURN_FIELD fields */
201  return_model = mxCreateStructMatrix(1, 1, NUM_OF_RETURN_FIELD, field_names);
202 
203  /* Fill struct matrix with input arguments */
204  for (i = 0; i < NUM_OF_RETURN_FIELD; i++)
205  mxSetField(return_model, 0, field_names[i], mxDuplicateArray(rhs[i]));
206  /* return */
207  plhs[0] = return_model;
208  mxFree(rhs);
209 
210  return NULL;
211 }
212 
213 struct svm_model *matlab_matrix_to_model(const mxArray *matlab_struct, const char **msg)
214 {
215  int i, j, n, num_of_fields;
216  double *ptr;
217  int id = 0;
218  struct svm_node *x_space;
219  struct svm_model *model;
220  mxArray **rhs;
221 
222  num_of_fields = mxGetNumberOfFields(matlab_struct);
223  if (num_of_fields != NUM_OF_RETURN_FIELD)
224  {
225  *msg = "number of return field is not correct";
226  return NULL;
227  }
228  rhs = (mxArray **) mxMalloc(sizeof(mxArray *)*num_of_fields);
229 
230  for (i = 0; i < num_of_fields; i++)
231  rhs[i] = mxGetFieldByNumber(matlab_struct, 0, i);
232 
233  model = Malloc(struct svm_model, 1);
234  model->rho = NULL;
235  model->probA = NULL;
236  model->probB = NULL;
237  model->label = NULL;
238  model->sv_indices = NULL;
239  model->nSV = NULL;
240  model->free_sv = 1; // XXX
241 
242  ptr = mxGetPr(rhs[id]);
243  model->param.svm_type = (int)ptr[0];
244  model->param.kernel_type = (int)ptr[1];
245  model->param.degree = (int)ptr[2];
246  model->param.gamma = ptr[3];
247  model->param.coef0 = ptr[4];
248  id++;
249 
250  ptr = mxGetPr(rhs[id]);
251  model->nr_class = (int)ptr[0];
252  id++;
253 
254  ptr = mxGetPr(rhs[id]);
255  model->l = (int)ptr[0];
256  id++;
257 
258  // rho
259  n = model->nr_class * (model->nr_class - 1) / 2;
260  model->rho = (double*) malloc(n * sizeof(double));
261  ptr = mxGetPr(rhs[id]);
262  for (i = 0; i < n; i++)
263  model->rho[i] = ptr[i];
264  id++;
265 
266  // label
267  if (mxIsEmpty(rhs[id]) == 0)
268  {
269  model->label = (int*) malloc(model->nr_class * sizeof(int));
270  ptr = mxGetPr(rhs[id]);
271  for (i = 0; i < model->nr_class; i++)
272  model->label[i] = (int)ptr[i];
273  }
274  id++;
275 
276  // sv_indices
277  if (mxIsEmpty(rhs[id]) == 0)
278  {
279  model->sv_indices = (int*) malloc(model->l * sizeof(int));
280  ptr = mxGetPr(rhs[id]);
281  for (i = 0; i < model->l; i++)
282  model->sv_indices[i] = (int)ptr[i];
283  }
284  id++;
285 
286  // probA
287  if (mxIsEmpty(rhs[id]) == 0)
288  {
289  model->probA = (double*) malloc(n * sizeof(double));
290  ptr = mxGetPr(rhs[id]);
291  for (i = 0; i < n; i++)
292  model->probA[i] = ptr[i];
293  }
294  id++;
295 
296  // probB
297  if (mxIsEmpty(rhs[id]) == 0)
298  {
299  model->probB = (double*) malloc(n * sizeof(double));
300  ptr = mxGetPr(rhs[id]);
301  for (i = 0; i < n; i++)
302  model->probB[i] = ptr[i];
303  }
304  id++;
305 
306  // nSV
307  if (mxIsEmpty(rhs[id]) == 0)
308  {
309  model->nSV = (int*) malloc(model->nr_class * sizeof(int));
310  ptr = mxGetPr(rhs[id]);
311  for (i = 0; i < model->nr_class; i++)
312  model->nSV[i] = (int)ptr[i];
313  }
314  id++;
315 
316  // sv_coef
317  ptr = mxGetPr(rhs[id]);
318  model->sv_coef = (double**) malloc((model->nr_class - 1) * sizeof(double));
319  for (i = 0 ; i < model->nr_class - 1 ; i++)
320  model->sv_coef[i] = (double*) malloc((model->l) * sizeof(double));
321  for (i = 0; i < model->nr_class - 1; i++)
322  for (j = 0; j < model->l; j++)
323  model->sv_coef[i][j] = ptr[i * (model->l) + j];
324  id++;
325 
326  // SV
327  {
328  int sr, sc, elements;
329  int num_samples;
330  mwIndex *ir, *jc;
331  mxArray *pprhs[1], *pplhs[1];
332 
333  // transpose SV
334  pprhs[0] = rhs[id];
335  if (mexCallMATLAB(1, pplhs, 1, pprhs, "transpose"))
336  {
338  *msg = "cannot transpose SV matrix";
339  return NULL;
340  }
341  rhs[id] = pplhs[0];
342 
343  sr = (int)mxGetN(rhs[id]);
344  sc = (int)mxGetM(rhs[id]);
345 
346  ptr = mxGetPr(rhs[id]);
347  ir = mxGetIr(rhs[id]);
348  jc = mxGetJc(rhs[id]);
349 
350  num_samples = (int)mxGetNzmax(rhs[id]);
351 
352  elements = num_samples + sr;
353 
354  model->SV = (struct svm_node **) malloc(sr * sizeof(struct svm_node *));
355  x_space = (struct svm_node *)malloc(elements * sizeof(struct svm_node));
356 
357  // SV is in column
358  for (i = 0; i < sr; i++)
359  {
360  int low = (int)jc[i], high = (int)jc[i + 1];
361  int x_index = 0;
362  model->SV[i] = &x_space[low + i];
363  for (j = low; j < high; j++)
364  {
365  model->SV[i][x_index].index = (int)ir[j] + 1;
366  model->SV[i][x_index].value = ptr[j];
367  x_index++;
368  }
369  model->SV[i][x_index].index = -1;
370  }
371 
372  id++;
373  }
374  mxFree(rhs);
375 
376  return model;
377 }
int * nSV
Definition: svm.h:67
static const char * field_names[]
double value
Definition: svm.h:15
int l
Definition: svm.h:56
struct svm_node ** SV
Definition: svm.h:57
double * probB
Definition: svm.h:61
#define Malloc(type, n)
double * probA
Definition: svm.h:60
int nr_class
Definition: svm.h:55
Definition: svm.h:52
#define NUM_OF_RETURN_FIELD
struct svm_model * matlab_matrix_to_model(const mxArray *matlab_struct, const char **msg)
int * label
Definition: svm.h:66
void svm_free_and_destroy_model(svm_model **model_ptr_ptr)
Definition: svm.cpp:3013
struct svm_parameter param
Definition: svm.h:54
int * sv_indices
Definition: svm.h:62
double * rho
Definition: svm.h:59
int index
Definition: svm.h:14
double ** sv_coef
Definition: svm.h:58
int degree
Definition: svm.h:32
int free_sv
Definition: svm.h:70
Definition: svm.h:12
double gamma
Definition: svm.h:33
int svm_type
Definition: svm.h:30
struct svm_model * model
Definition: svmtrain.c:61
double coef0
Definition: svm.h:34
const char * model_to_matlab_structure(mxArray *plhs[], int num_of_feature, struct svm_model *model)
int kernel_type
Definition: svm.h:31
struct svm_node * x_space
Definition: svmtrain.c:62


ml_classifiers
Author(s): Scott Niekum , Joshua Whitley
autogenerated on Sun Dec 15 2019 03:53:50