Line data Source code
1 : /**
2 : * @file gensvm_base.c
3 : * @author G.J.J. van den Burg
4 : * @date 2016-05-01
5 : * @brief Functions for initializing GenModel, GenData, and GenWork structures
6 : *
7 : * @details
8 : * This file contains functions for initializing, freeing, allocating, and
9 : * reallocating a GenModel instance. It also contains functions for
10 : * initializing and freeing a GenData structure. In addition, default values
11 : * for these structures are defined here (and only here).
12 : *
13 : * @copyright
14 : Copyright 2016, G.J.J. van den Burg.
15 :
16 : This file is part of GenSVM.
17 :
18 : GenSVM is free software: you can redistribute it and/or modify
19 : it under the terms of the GNU General Public License as published by
20 : the Free Software Foundation, either version 3 of the License, or
21 : (at your option) any later version.
22 :
23 : GenSVM is distributed in the hope that it will be useful,
24 : but WITHOUT ANY WARRANTY; without even the implied warranty of
25 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 : GNU General Public License for more details.
27 :
28 : You should have received a copy of the GNU General Public License
29 : along with GenSVM. If not, see <http://www.gnu.org/licenses/>.
30 :
31 : */
32 :
33 : #include "gensvm_base.h"
34 :
35 : /**
36 : * @brief Initialize a GenData structure
37 : *
38 : * @details
39 : * A GenData structure is initialized and default values are set.
40 : * A pointer to the initialized data is returned.
41 : *
42 : * @returns initialized GenData
43 : *
44 : */
45 76 : struct GenData *gensvm_init_data(void)
46 : {
47 76 : struct GenData *data = Malloc(struct GenData, 1);
48 76 : data->Sigma = NULL;
49 76 : data->y = NULL;
50 76 : data->Z = NULL;
51 76 : data->spZ = NULL;
52 76 : data->RAW = NULL;
53 :
54 : // set default values
55 76 : data->kerneltype = K_LINEAR;
56 76 : data->gamma = -1;
57 76 : data->coef = -1;
58 76 : data->degree = -1;
59 :
60 76 : return data;
61 : }
62 :
63 : /**
64 : * @brief Free allocated GenData struct
65 : *
66 : * @details
67 : * Simply free a previously allocated GenData struct by freeing all its
68 : * components. Note that the data struct itself is also freed here.
69 : *
70 : * @param[in] data GenData struct to free
71 : *
72 : */
73 78 : void gensvm_free_data(struct GenData *data)
74 : {
75 78 : if (data == NULL)
76 2 : return;
77 :
78 76 : if (data->spZ != NULL)
79 10 : gensvm_free_sparse(data->spZ);
80 :
81 76 : if (data->Z == data->RAW) {
82 51 : free(data->Z);
83 : } else {
84 25 : free(data->Z);
85 25 : free(data->RAW);
86 : }
87 76 : free(data->y);
88 76 : free(data->Sigma);
89 76 : free(data);
90 76 : data = NULL;
91 : }
92 :
93 : /**
94 : * @brief Initialize a GenModel structure
95 : *
96 : * @details
97 : * A GenModel structure is initialized and the default value for the
98 : * parameters are set. A pointer to the initialized model is returned.
99 : *
100 : * @returns initialized GenModel
101 : */
102 72 : struct GenModel *gensvm_init_model(void)
103 : {
104 72 : struct GenModel *model = Malloc(struct GenModel, 1);
105 :
106 : // set default values
107 72 : model->p = 1.0;
108 72 : model->lambda = pow(2, -8.0);
109 72 : model->epsilon = 1e-6;
110 72 : model->kappa = 0.0;
111 72 : model->weight_idx = 1;
112 72 : model->gamma = 1.0;
113 72 : model->coef = 0.0;
114 72 : model->degree = 2.0;
115 72 : model->kerneltype = K_LINEAR;
116 72 : model->kernel_eigen_cutoff = 1e-8;
117 72 : model->max_iter = 1000000000;
118 72 : model->training_error = -1;
119 72 : model->elapsed_iter = -1;
120 72 : model->status = -1;
121 :
122 72 : model->V = NULL;
123 72 : model->Vbar = NULL;
124 72 : model->U = NULL;
125 72 : model->UU = NULL;
126 72 : model->Q = NULL;
127 72 : model->H = NULL;
128 72 : model->rho = NULL;
129 72 : model->data_file = NULL;
130 :
131 72 : return model;
132 : }
133 :
134 : /**
135 : * @brief Allocate memory for a GenModel
136 : *
137 : * @details
138 : * This function can be used to allocate the memory needed for a GenModel. All
139 : * arrays in the model are specified and initialized to 0.
140 : *
141 : * @param[in] model GenModel to allocate
142 : *
143 : */
144 27 : void gensvm_allocate_model(struct GenModel *model)
145 : {
146 27 : long n = model->n;
147 27 : long m = model->m;
148 27 : long K = model->K;
149 :
150 27 : model->V = Calloc(double, (m+1)*(K-1));
151 27 : model->Vbar = Calloc(double, (m+1)*(K-1));
152 27 : model->U = Calloc(double, K*(K-1));
153 27 : model->UU = Calloc(double, K*K*(K-1));
154 27 : model->Q = Calloc(double, n*K);
155 27 : model->H = Calloc(double, n*K);
156 27 : model->rho = Calloc(double, n);
157 27 : }
158 :
159 : /**
160 : * @brief Reallocate memory for GenModel
161 : *
162 : * @details
163 : * This function can be used to reallocate existing memory for a GenModel,
164 : * upon a change in the model dimensions. This is used in combination with
165 : * kernels.
166 : *
167 : * @param[in] model GenModel to reallocate
168 : * @param[in] n new value of GenModel->n
169 : * @param[in] m new value of GenModel->m
170 : *
171 : */
172 6 : void gensvm_reallocate_model(struct GenModel *model, long n, long m)
173 : {
174 6 : long K = model->K;
175 :
176 6 : if (model->n == n && model->m == m)
177 3 : return;
178 3 : if (model->n != n) {
179 1 : model->Q = Realloc(model->Q, double, n*K);
180 1 : Memset(model->Q, double, n*K);
181 :
182 1 : model->H = Realloc(model->H, double, n*K);
183 1 : Memset(model->H, double, n*K);
184 :
185 1 : model->rho = Realloc(model->rho, double, n);
186 1 : Memset(model->rho, double, n);
187 :
188 1 : model->n = n;
189 : }
190 3 : if (model->m != m) {
191 3 : model->V = Realloc(model->V, double, (m+1)*(K-1));
192 3 : Memset(model->V, double, (m+1)*(K-1));
193 :
194 3 : model->Vbar = Realloc(model->Vbar, double, (m+1)*(K-1));
195 3 : Memset(model->Vbar, double, (m+1)*(K-1));
196 :
197 3 : model->m = m;
198 : }
199 : }
200 :
201 : /**
202 : * @brief Free allocated GenModel struct
203 : *
204 : * @details
205 : * Simply free a previously allocated GenModel by freeing all its component
206 : * arrays. Note that the model struct itself is also freed here.
207 : *
208 : * @param[in] model GenModel to free
209 : *
210 : */
211 73 : void gensvm_free_model(struct GenModel *model)
212 : {
213 73 : if (model == NULL)
214 1 : return;
215 :
216 72 : free(model->V);
217 72 : free(model->Vbar);
218 72 : free(model->U);
219 72 : free(model->UU);
220 72 : free(model->Q);
221 72 : free(model->H);
222 72 : free(model->rho);
223 72 : free(model->data_file);
224 :
225 72 : free(model);
226 72 : model = NULL;
227 : }
228 :
229 : /**
230 : * @brief Initialize the workspace structure
231 : *
232 : * @details
233 : * During the computations in gensvm_get_update(), a number of matrices need
234 : * to be allocated which are used to store intermediate results. To avoid
235 : * reallocating these matrices at every call to gensvm_get_update(), we create
236 : * here a workspace with these matrices. This workspace is created once by
237 : * gensvm_optimize(), and is passed to gensvm_get_update() and
238 : * gensvm_get_loss(). See the documentation of the GenWork structure for
239 : * information on each allocated field.
240 : *
241 : * @param[in] model a GenModel with the dimensionality of the problem
242 : * @returns an allocated GenWork instance
243 : *
244 : */
245 9 : struct GenWork *gensvm_init_work(struct GenModel *model)
246 : {
247 9 : long n = model->n;
248 9 : long m = model->m;
249 9 : long K = model->K;
250 :
251 9 : struct GenWork *work = Malloc(struct GenWork, 1);
252 9 : work->n = n;
253 9 : work->m = m;
254 9 : work->K = K;
255 :
256 9 : work->LZ = Calloc(double, n*(m+1));
257 9 : work->ZB = Calloc(double, (m+1)*(K-1)),
258 9 : work->ZBc = Calloc(double, (m+1)*(K-1)),
259 9 : work->ZAZ = Calloc(double, (m+1)*(m+1)),
260 9 : work->tmpZAZ = Calloc(double, (m+1)*(m+1)),
261 9 : work->ZV = Calloc(double, n*(K-1));
262 9 : work->beta = Calloc(double, K-1);
263 :
264 9 : return work;
265 : }
266 :
267 : /**
268 : * @brief Free an allocated GenWork instance
269 : *
270 : * @details
271 : * This function simply frees every matrix allocated for in the GenWork
272 : * workspace.
273 : *
274 : * @param[in] work a pointer to an allocated GenWork instance
275 : *
276 : */
277 9 : void gensvm_free_work(struct GenWork *work)
278 : {
279 9 : free(work->LZ);
280 9 : free(work->ZB);
281 9 : free(work->ZBc);
282 9 : free(work->ZAZ);
283 9 : free(work->tmpZAZ);
284 9 : free(work->ZV);
285 9 : free(work->beta);
286 9 : free(work);
287 9 : work = NULL;
288 9 : }
289 :
290 : /**
291 : * @brief Reset all matrices of a GenWork instance
292 : *
293 : * @details
294 : * In the gensvm_get_update() function, it is expected for some matrices that
295 : * all their entries are initialized to 0. This function sets the memory for
296 : * each of the matrices in the GenWork workspace to 0 to facilitate this.
297 : *
298 : * @param[in,out] work an initialized GenWork instance. On exit, the
299 : * matrices of the GenWork instance are all
300 : * initialized to 0.
301 : */
302 467 : void gensvm_reset_work(struct GenWork *work)
303 : {
304 467 : long n = work->n;
305 467 : long m = work->m;
306 467 : long K = work->K;
307 :
308 467 : Memset(work->LZ, double, n*(m+1));
309 467 : Memset(work->ZB, double, (m+1)*(K-1)),
310 467 : Memset(work->ZBc, double, (m+1)*(K-1)),
311 467 : Memset(work->ZAZ, double, (m+1)*(m+1)),
312 467 : Memset(work->tmpZAZ, double, (m+1)*(m+1)),
313 467 : Memset(work->ZV, double, n*(K-1));
314 467 : Memset(work->beta, double, K-1);
315 467 : }
|