1 /*
2 This code was extracted from liblinear-2.2.1 in Feb 2019 and
3 modified for the use with Octave and Matlab
4
5 Copyright (c) 2007-2019 The LIBLINEAR Project.
6 All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions
10 are met:
11
12 1. Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 2. Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in the
17 documentation and/or other materials provided with the distribution.
18
19 3. Neither name of copyright holders nor the names of its contributors
20 may be used to endorse or promote products derived from this software
21 without specific prior written permission.
22
23
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
28 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
30 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35
36 */
37
38 #include <stdlib.h>
39 #include <string.h>
40 #include "linear.h"
41 #include "linear_model_matlab.h"
42
43 #ifdef MX_API_VER
44 #if MX_API_VER < 0x07030000
45 typedef int mwIndex;
46 #endif
47 #endif
48
49 #define Malloc(type,n) (type *)malloc((n)*sizeof(type))
50
51 #define NUM_OF_RETURN_FIELD 6
52
53 static const char *field_names[] = {
54 "Parameters",
55 "nr_class",
56 "nr_feature",
57 "bias",
58 "Label",
59 "w",
60 };
61
model_to_matlab_structure(mxArray * plhs[],struct model * model_)62 const char *model_to_matlab_structure(mxArray *plhs[], struct model *model_)
63 {
64 int i;
65 int nr_w;
66 double *ptr;
67 mxArray *return_model, **rhs;
68 int out_id = 0;
69 int n, w_size;
70
71 rhs = (mxArray **)mxMalloc(sizeof(mxArray *)*NUM_OF_RETURN_FIELD);
72
73 // Parameters
74 // for now, only solver_type is needed
75 rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
76 ptr = mxGetPr(rhs[out_id]);
77 ptr[0] = model_->param.solver_type;
78 out_id++;
79
80 // nr_class
81 rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
82 ptr = mxGetPr(rhs[out_id]);
83 ptr[0] = model_->nr_class;
84 out_id++;
85
86 if(model_->nr_class==2 && model_->param.solver_type != MCSVM_CS)
87 nr_w=1;
88 else
89 nr_w=model_->nr_class;
90
91 // nr_feature
92 rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
93 ptr = mxGetPr(rhs[out_id]);
94 ptr[0] = model_->nr_feature;
95 out_id++;
96
97 // bias
98 rhs[out_id] = mxCreateDoubleMatrix(1, 1, mxREAL);
99 ptr = mxGetPr(rhs[out_id]);
100 ptr[0] = model_->bias;
101 out_id++;
102
103 if(model_->bias>=0)
104 n=model_->nr_feature+1;
105 else
106 n=model_->nr_feature;
107
108 w_size = n;
109 // Label
110 if(model_->label)
111 {
112 rhs[out_id] = mxCreateDoubleMatrix(model_->nr_class, 1, mxREAL);
113 ptr = mxGetPr(rhs[out_id]);
114 for(i = 0; i < model_->nr_class; i++)
115 ptr[i] = model_->label[i];
116 }
117 else
118 rhs[out_id] = mxCreateDoubleMatrix(0, 0, mxREAL);
119 out_id++;
120
121 // w
122 rhs[out_id] = mxCreateDoubleMatrix(nr_w, w_size, mxREAL);
123 ptr = mxGetPr(rhs[out_id]);
124 for(i = 0; i < w_size*nr_w; i++)
125 ptr[i]=model_->w[i];
126 out_id++;
127
128 /* Create a struct matrix contains NUM_OF_RETURN_FIELD fields */
129 return_model = mxCreateStructMatrix(1, 1, NUM_OF_RETURN_FIELD, field_names);
130
131 /* Fill struct matrix with input arguments */
132 for(i = 0; i < NUM_OF_RETURN_FIELD; i++)
133 mxSetField(return_model,0,field_names[i],mxDuplicateArray(rhs[i]));
134 /* return */
135 plhs[0] = return_model;
136 mxFree(rhs);
137
138 return NULL;
139 }
140
matlab_matrix_to_model(struct model * model_,const mxArray * matlab_struct)141 const char *matlab_matrix_to_model(struct model *model_, const mxArray *matlab_struct)
142 {
143 int i, num_of_fields;
144 int nr_w;
145 double *ptr;
146 int id = 0;
147 int n, w_size;
148 mxArray **rhs;
149
150 num_of_fields = mxGetNumberOfFields(matlab_struct);
151 rhs = (mxArray **) mxMalloc(sizeof(mxArray *)*num_of_fields);
152
153 for(i=0;i<num_of_fields;i++)
154 rhs[i] = mxGetFieldByNumber(matlab_struct, 0, i);
155
156 model_->nr_class=0;
157 nr_w=0;
158 model_->nr_feature=0;
159 model_->w=NULL;
160 model_->label=NULL;
161
162 // Parameters
163 ptr = mxGetPr(rhs[id]);
164 model_->param.solver_type = (int)ptr[0];
165 id++;
166
167 // nr_class
168 ptr = mxGetPr(rhs[id]);
169 model_->nr_class = (int)ptr[0];
170 id++;
171
172 if(model_->nr_class==2 && model_->param.solver_type != MCSVM_CS)
173 nr_w=1;
174 else
175 nr_w=model_->nr_class;
176
177 // nr_feature
178 ptr = mxGetPr(rhs[id]);
179 model_->nr_feature = (int)ptr[0];
180 id++;
181
182 // bias
183 ptr = mxGetPr(rhs[id]);
184 model_->bias = ptr[0];
185 id++;
186
187 if(model_->bias>=0)
188 n=model_->nr_feature+1;
189 else
190 n=model_->nr_feature;
191 w_size = n;
192
193 // Label
194 if(mxIsEmpty(rhs[id]) == 0)
195 {
196 model_->label = Malloc(int, model_->nr_class);
197 ptr = mxGetPr(rhs[id]);
198 for(i=0;i<model_->nr_class;i++)
199 model_->label[i] = (int)ptr[i];
200 }
201 id++;
202
203 ptr = mxGetPr(rhs[id]);
204 model_->w=Malloc(double, w_size*nr_w);
205 for(i = 0; i < w_size*nr_w; i++)
206 model_->w[i]=ptr[i];
207 id++;
208 mxFree(rhs);
209
210 return NULL;
211 }
212
213