GenSVM
test_gensvm_update.c
Go to the documentation of this file.
1 
27 #include "minunit.h"
28 #include "gensvm_optimize.h"
29 #include "gensvm_init.h"
30 #include "gensvm_simplex.h"
31 
33 {
34  struct GenModel *model = gensvm_init_model();
35  struct GenData *data = gensvm_init_data();
36 
37  int n = 5,
38  m = 3,
39  K = 3;
40 
41  data->n = n;
42  data->m = m;
43  data->K = K;
44 
45  data->y = Calloc(long, n);
46  data->y[0] = 2;
47  data->y[1] = 1;
48  data->y[2] = 3;
49  data->y[3] = 2;
50  data->y[4] = 3;
51 
52  model->n = n;
53  model->m = m;
54  model->K = K;
55  model->p = 1.213;
56  gensvm_allocate_model(model);
57 
58  matrix_set(model->H, model->K, 0, 0, 0.8465725800087526);
59  matrix_set(model->H, model->K, 0, 1, 1.2876921677680249);
60  matrix_set(model->H, model->K, 0, 2, 1.0338561593991831);
61  matrix_set(model->H, model->K, 1, 0, 1.1891038526621391);
62  matrix_set(model->H, model->K, 1, 1, 0.4034192031226095);
63  matrix_set(model->H, model->K, 1, 2, 1.5298894170910078);
64  matrix_set(model->H, model->K, 2, 0, 1.3505111116922732);
65  matrix_set(model->H, model->K, 2, 1, 1.4336863304586636);
66  matrix_set(model->H, model->K, 2, 2, 1.7847533480330757);
67  matrix_set(model->H, model->K, 3, 0, 1.7712504341475415);
68  matrix_set(model->H, model->K, 3, 1, 1.6905146737773038);
69  matrix_set(model->H, model->K, 3, 2, 0.8189336598535132);
70  matrix_set(model->H, model->K, 4, 0, 0.6164203008844277);
71  matrix_set(model->H, model->K, 4, 1, 0.2456444285093894);
72  matrix_set(model->H, model->K, 4, 2, 0.8184193969741095);
73 
74  // start test code //
75  mu_assert(fabs(gensvm_calculate_omega(model, data, 0) -
76  0.7394076262220608) < 1e-14,
77  "Incorrect omega at 0");
78  mu_assert(fabs(gensvm_calculate_omega(model, data, 1) -
79  0.7294526264247443) < 1e-14,
80  "Incorrect omega at 1");
81  mu_assert(fabs(gensvm_calculate_omega(model, data, 2) -
82  0.6802499471888741) < 1e-14,
83  "Incorrect omega at 2");
84  mu_assert(fabs(gensvm_calculate_omega(model, data, 3) -
85  0.6886792032441273) < 1e-14,
86  "Incorrect omega at 3");
87  mu_assert(fabs(gensvm_calculate_omega(model, data, 4) -
88  0.8695329737474283) < 1e-14,
89  "Incorrect omega at 4");
90 
91  // end test code //
92 
93  gensvm_free_model(model);
94  gensvm_free_data(data);
95 
96  return NULL;
97 }
98 
100 {
101  struct GenModel *model = gensvm_init_model();
102  struct GenData *data = gensvm_init_data();
103 
104  int n = 5,
105  m = 3,
106  K = 3;
107 
108  data->n = n;
109  data->m = m;
110  data->K = K;
111 
112  data->y = Calloc(long, n);
113  data->y[0] = 2;
114  data->y[1] = 1;
115  data->y[2] = 3;
116  data->y[3] = 2;
117  data->y[4] = 3;
118 
119  model->n = n;
120  model->m = m;
121  model->K = K;
122  model->p = 1.213;
123  gensvm_allocate_model(model);
124 
125  matrix_set(model->H, model->K, 0, 0, 0.8465725800087526);
126  matrix_set(model->H, model->K, 0, 1, 1.2876921677680249);
127  matrix_set(model->H, model->K, 0, 2, 1.0338561593991831);
128  matrix_set(model->H, model->K, 1, 0, 1.1891038526621391);
129  matrix_set(model->H, model->K, 1, 1, 0.4034192031226095);
130  matrix_set(model->H, model->K, 1, 2, 0.0);
131  matrix_set(model->H, model->K, 2, 0, 0.5);
132  matrix_set(model->H, model->K, 2, 1, 0.0);
133  matrix_set(model->H, model->K, 2, 2, 1.1);
134  matrix_set(model->H, model->K, 3, 0, 0.0);
135  matrix_set(model->H, model->K, 3, 1, 0.0);
136  matrix_set(model->H, model->K, 3, 2, 0.8189336598535132);
137  matrix_set(model->H, model->K, 4, 0, 0.6164203008844277);
138  matrix_set(model->H, model->K, 4, 1, 0.2456444285093894);
139  matrix_set(model->H, model->K, 4, 2, 0.8184193969741095);
140 
141  // start test code //
142  mu_assert(gensvm_majorize_is_simple(model, data, 0) == false,
143  "Incorrect simple at 0");
144  mu_assert(gensvm_majorize_is_simple(model, data, 1) == true,
145  "Incorrect simple at 1");
146  mu_assert(gensvm_majorize_is_simple(model, data, 2) == true,
147  "Incorrect simple at 2");
148  mu_assert(gensvm_majorize_is_simple(model, data, 3) == true,
149  "Incorrect simple at 3");
150  mu_assert(gensvm_majorize_is_simple(model, data, 4) == false,
151  "Incorrect simple at 4");
152 
153  // end test code //
154 
155  gensvm_free_model(model);
156  gensvm_free_data(data);
157  return NULL;
158 }
159 
161 {
162  struct GenModel *model = gensvm_init_model();
163  int n = 1,
164  m = 1,
165  K = 1;
166 
167  model->n = n;
168  model->m = m;
169  model->K = K;
170  model->kappa = 0.5;
171 
172  gensvm_allocate_model(model);
173 
174  // start test code //
175  double a, b_aq;
176 
177  // tests with p = 2
178  model->p = 2.0;
179  matrix_set(model->Q, K, 0, 0, -1.0);
180  gensvm_calculate_ab_non_simple(model, 0, 0, &a, &b_aq);
181  mu_assert(fabs(a - 1.5) < 1e-14, "Incorrect value for a (1)");
182  mu_assert(fabs(b_aq - 1.25) < 1e-14, "Incorrect value for b (1)");
183 
184  matrix_set(model->Q, K, 0, 0, 0.5);
185  gensvm_calculate_ab_non_simple(model, 0, 0, &a, &b_aq);
186  mu_assert(fabs(a - 1.5) < 1e-14, "Incorrect value for a (2)");
187  mu_assert(fabs(b_aq - 0.0277777777777778) < 1e-14,
188  "Incorrect value for b (2)");
189 
190  matrix_set(model->Q, K, 0, 0, 2.0);
191  gensvm_calculate_ab_non_simple(model, 0, 0, &a, &b_aq);
192  mu_assert(fabs(a - 1.5) < 1e-14, "Incorrect value for a (3)");
193  mu_assert(fabs(b_aq - 0.0) < 1e-14, "Incorrect value for b (3)");
194 
195  // tests with p != 2 (namely, 1.5)
196  // Note that here (p + kappa - 1)/(p - 2) = -2
197  //
198  // We distinguish: q <= (p + kappa - 1)/(p - 2)
199  // q in (p + kappa - 1)/(p - 2), -kappa]
200  // q in (-kappa, 1]
201  // q > 1
202  model->p = 1.5;
203  matrix_set(model->Q, K, 0, 0, -3.0);
204  gensvm_calculate_ab_non_simple(model, 0, 0, &a, &b_aq);
205  mu_assert(fabs(a - 0.312018860376691) < 1e-14,
206  "Incorrect value for a (4)");
207  mu_assert(fabs(b_aq - 1.35208172829900) < 1e-14,
208  "Incorrect value for b (4)");
209 
210  matrix_set(model->Q, K, 0, 0, -1.0);
211  gensvm_calculate_ab_non_simple(model, 0, 0, &a, &b_aq);
212  mu_assert(fabs(a - 0.866025403784439) < 1e-14,
213  "Incorrect value for a (5)");
214  mu_assert(fabs(b_aq - 0.838525491562421) < 1e-14,
215  "Incorrect value for b (5)");
216 
217  matrix_set(model->Q, K, 0, 0, 0.5);
218  gensvm_calculate_ab_non_simple(model, 0, 0, &a, &b_aq);
219  mu_assert(fabs(a - 0.866025403784439) < 1e-14,
220  "Incorrect value for a (6)");
221  mu_assert(fabs(b_aq - 0.0721687836487032) < 1e-14,
222  "Incorrect value for b (6)");
223 
224  matrix_set(model->Q, K, 0, 0, 2.0);
225  gensvm_calculate_ab_non_simple(model, 0, 0, &a, &b_aq);
226  mu_assert(fabs(a - 0.245495126515491) < 1e-14,
227  "Incorrect value for a (7)");
228  mu_assert(fabs(b_aq - 0.0) < 1e-14,
229  "Incorrect value for b (7)");
230  // end test code //
231 
232  gensvm_free_model(model);
233 
234  return NULL;
235 }
236 
238 {
239  struct GenModel *model = gensvm_init_model();
240  int n = 1,
241  m = 1,
242  K = 1;
243 
244  model->n = n;
245  model->m = m;
246  model->K = K;
247  model->kappa = 0.5;
248 
249  gensvm_allocate_model(model);
250 
251  // start test code //
252  double a, b_aq;
253 
254  matrix_set(model->Q, K, 0, 0, -1.5);
255  gensvm_calculate_ab_simple(model, 0, 0, &a, &b_aq);
256  mu_assert(fabs(a - 0.142857142857143) < 1e-14,
257  "Incorrect value for a (1)");
258  mu_assert(fabs(b_aq - 0.5) < 1e-14,
259  "Incorrect value for b (1)");
260 
261  matrix_set(model->Q, K, 0, 0, 0.75);
262  gensvm_calculate_ab_simple(model, 0, 0, &a, &b_aq);
263  mu_assert(fabs(a - 0.333333333333333) < 1e-14,
264  "Incorrect value for a (2)");
265  mu_assert(fabs(b_aq - 0.0833333333333333) < 1e-14,
266  "Incorrect value for b (2)");
267 
268  matrix_set(model->Q, K, 0, 0, 2.0);
269  gensvm_calculate_ab_simple(model, 0, 0, &a, &b_aq);
270  mu_assert(fabs(a - 0.142857142857143) < 1e-14,
271  "Incorrect value for a (3)");
272  mu_assert(fabs(b_aq - 0.0) < 1e-14,
273  "Incorrect value for b (3)");
274 
275  // end test code //
276  gensvm_free_model(model);
277 
278  return NULL;
279 }
280 
282 {
283  struct GenModel *model = gensvm_init_model();
284  struct GenData *data = gensvm_init_data();
285  int n = 8,
286  m = 3,
287  K = 3;
288 
289  model->n = n;
290  model->m = m;
291  model->K = K;
292  struct GenWork *work = gensvm_init_work(model);
293 
294  // initialize data
295  data->n = n;
296  data->m = m;
297  data->K = K;
298 
299  data->y = Calloc(long, n);
300  data->y[0] = 2;
301  data->y[1] = 1;
302  data->y[2] = 3;
303  data->y[3] = 2;
304  data->y[4] = 3;
305  data->y[5] = 3;
306  data->y[6] = 1;
307  data->y[7] = 2;
308 
309  data->Z = Calloc(double, n*(m+1));
310  matrix_set(data->Z, data->m+1, 0, 0, 1.0000000000000000);
311  matrix_set(data->Z, data->m+1, 0, 1, 0.6437306339619082);
312  matrix_set(data->Z, data->m+1, 0, 2, -0.3276778319121999);
313  matrix_set(data->Z, data->m+1, 0, 3, 0.1564053473463392);
314  matrix_set(data->Z, data->m+1, 1, 0, 1.0000000000000000);
315  matrix_set(data->Z, data->m+1, 1, 1, -0.8683091763200105);
316  matrix_set(data->Z, data->m+1, 1, 2, -0.6910830836015162);
317  matrix_set(data->Z, data->m+1, 1, 3, -0.9675430665130734);
318  matrix_set(data->Z, data->m+1, 2, 0, 1.0000000000000000);
319  matrix_set(data->Z, data->m+1, 2, 1, -0.5024888699077029);
320  matrix_set(data->Z, data->m+1, 2, 2, -0.9649738292750712);
321  matrix_set(data->Z, data->m+1, 2, 3, 0.0776560791351473);
322  matrix_set(data->Z, data->m+1, 3, 0, 1.0000000000000000);
323  matrix_set(data->Z, data->m+1, 3, 1, 0.8206429991392579);
324  matrix_set(data->Z, data->m+1, 3, 2, -0.7255681388968501);
325  matrix_set(data->Z, data->m+1, 3, 3, -0.9475952272877165);
326  matrix_set(data->Z, data->m+1, 4, 0, 1.0000000000000000);
327  matrix_set(data->Z, data->m+1, 4, 1, 0.3426050950418613);
328  matrix_set(data->Z, data->m+1, 4, 2, -0.5340602451864306);
329  matrix_set(data->Z, data->m+1, 4, 3, -0.7159704241662815);
330  matrix_set(data->Z, data->m+1, 5, 0, 1.0000000000000000);
331  matrix_set(data->Z, data->m+1, 5, 1, -0.3077314049206620);
332  matrix_set(data->Z, data->m+1, 5, 2, 0.1141288036288195);
333  matrix_set(data->Z, data->m+1, 5, 3, -0.7060114827535847);
334  matrix_set(data->Z, data->m+1, 6, 0, 1.0000000000000000);
335  matrix_set(data->Z, data->m+1, 6, 1, 0.6301294373610109);
336  matrix_set(data->Z, data->m+1, 6, 2, -0.9983027363627769);
337  matrix_set(data->Z, data->m+1, 6, 3, -0.9365684178444004);
338  matrix_set(data->Z, data->m+1, 7, 0, 1.0000000000000000);
339  matrix_set(data->Z, data->m+1, 7, 1, -0.0665379368401439);
340  matrix_set(data->Z, data->m+1, 7, 2, -0.1781385556871763);
341  matrix_set(data->Z, data->m+1, 7, 3, -0.7292593770500276);
342 
343  // initialize model
344  model->p = 1.1;
345  model->lambda = 0.123;
346  model->weight_idx = 1;
347  model->kappa = 0.5;
348 
349  // initialize matrices
350  gensvm_allocate_model(model);
351  gensvm_initialize_weights(data, model);
352  gensvm_simplex(model);
353  gensvm_simplex_diff(model);
354 
355  // initialize V
356  matrix_set(model->V, model->K-1, 0, 0, -0.7593642121025029);
357  matrix_set(model->V, model->K-1, 0, 1, -0.5497320698504756);
358  matrix_set(model->V, model->K-1, 1, 0, 0.2982680646268177);
359  matrix_set(model->V, model->K-1, 1, 1, -0.2491408622891925);
360  matrix_set(model->V, model->K-1, 2, 0, -0.3118572761092807);
361  matrix_set(model->V, model->K-1, 2, 1, 0.5461219445756100);
362  matrix_set(model->V, model->K-1, 3, 0, -0.3198994238626641);
363  matrix_set(model->V, model->K-1, 3, 1, 0.7134997072555367);
364 
365  // start test code //
366 
367  // these need to be prepared for the update call
368  gensvm_calculate_errors(model, data, work->ZV);
369  gensvm_calculate_huber(model);
370 
371  // run the actual update call
372  gensvm_get_update(model, data, work);
373 
374  // test values
375  mu_assert(fabs(matrix_get(model->V, model->K-1, 0, 0) -
376  -0.1323791019594062) < 1e-14,
377  "Incorrect value of model->V at 0, 0");
378  mu_assert(fabs(matrix_get(model->V, model->K-1, 0, 1) -
379  -0.3598407983154332) < 1e-14,
380  "Incorrect value of model->V at 0, 1");
381  mu_assert(fabs(matrix_get(model->V, model->K-1, 1, 0) -
382  0.3532993103400935) < 1e-14,
383  "Incorrect value of model->V at 1, 0");
384  mu_assert(fabs(matrix_get(model->V, model->K-1, 1, 1) -
385  -0.4094572388475382) < 1e-14,
386  "Incorrect value of model->V at 1, 1");
387  mu_assert(fabs(matrix_get(model->V, model->K-1, 2, 0) -
388  0.1313169839871234) < 1e-14,
389  "Incorrect value of model->V at 2, 0");
390  mu_assert(fabs(matrix_get(model->V, model->K-1, 2, 1) -
391  0.2423439972728328) < 1e-14,
392  "Incorrect value of model->V at 2, 1");
393  mu_assert(fabs(matrix_get(model->V, model->K-1, 3, 0) -
394  0.0458431025455224) < 1e-14,
395  "Incorrect value of model->V at 3, 0");
396  mu_assert(fabs(matrix_get(model->V, model->K-1, 3, 1) -
397  0.4390030236354089) < 1e-14,
398  "Incorrect value of model->V at 3, 1");
399  // end test code //
400 
401  gensvm_free_model(model);
402  gensvm_free_data(data);
403  gensvm_free_work(work);
404 
405  return NULL;
406 }
407 
409 {
410  struct GenModel *model = gensvm_init_model();
411  struct GenData *data = gensvm_init_data();
412  int n = 8,
413  m = 3,
414  K = 3;
415 
416  model->n = n;
417  model->m = m;
418  model->K = K;
419  struct GenWork *work = gensvm_init_work(model);
420 
421  // initialize data
422  data->n = n;
423  data->m = m;
424  data->K = K;
425 
426  data->y = Calloc(long, n);
427  data->y[0] = 2;
428  data->y[1] = 1;
429  data->y[2] = 3;
430  data->y[3] = 2;
431  data->y[4] = 3;
432  data->y[5] = 3;
433  data->y[6] = 1;
434  data->y[7] = 2;
435 
436  data->Z = Calloc(double, n*(m+1));
437  matrix_set(data->Z, data->m+1, 0, 0, 1.0000000000000000);
438  matrix_set(data->Z, data->m+1, 0, 1, 0.6437306339619082);
439  matrix_set(data->Z, data->m+1, 0, 2, -0.3276778319121999);
440  matrix_set(data->Z, data->m+1, 0, 3, 0.1564053473463392);
441  matrix_set(data->Z, data->m+1, 1, 0, 1.0000000000000000);
442  matrix_set(data->Z, data->m+1, 1, 1, -0.8683091763200105);
443  matrix_set(data->Z, data->m+1, 1, 2, -0.6910830836015162);
444  matrix_set(data->Z, data->m+1, 1, 3, -0.9675430665130734);
445  matrix_set(data->Z, data->m+1, 2, 0, 1.0000000000000000);
446  matrix_set(data->Z, data->m+1, 2, 1, -0.5024888699077029);
447  matrix_set(data->Z, data->m+1, 2, 2, -0.9649738292750712);
448  matrix_set(data->Z, data->m+1, 2, 3, 0.0776560791351473);
449  matrix_set(data->Z, data->m+1, 3, 0, 1.0000000000000000);
450  matrix_set(data->Z, data->m+1, 3, 1, 0.8206429991392579);
451  matrix_set(data->Z, data->m+1, 3, 2, -0.7255681388968501);
452  matrix_set(data->Z, data->m+1, 3, 3, -0.9475952272877165);
453  matrix_set(data->Z, data->m+1, 4, 0, 1.0000000000000000);
454  matrix_set(data->Z, data->m+1, 4, 1, 0.3426050950418613);
455  matrix_set(data->Z, data->m+1, 4, 2, -0.5340602451864306);
456  matrix_set(data->Z, data->m+1, 4, 3, -0.7159704241662815);
457  matrix_set(data->Z, data->m+1, 5, 0, 1.0000000000000000);
458  matrix_set(data->Z, data->m+1, 5, 1, -0.3077314049206620);
459  matrix_set(data->Z, data->m+1, 5, 2, 0.1141288036288195);
460  matrix_set(data->Z, data->m+1, 5, 3, -0.7060114827535847);
461  matrix_set(data->Z, data->m+1, 6, 0, 1.0000000000000000);
462  matrix_set(data->Z, data->m+1, 6, 1, 0.6301294373610109);
463  matrix_set(data->Z, data->m+1, 6, 2, -0.9983027363627769);
464  matrix_set(data->Z, data->m+1, 6, 3, -0.9365684178444004);
465  matrix_set(data->Z, data->m+1, 7, 0, 1.0000000000000000);
466  matrix_set(data->Z, data->m+1, 7, 1, -0.0665379368401439);
467  matrix_set(data->Z, data->m+1, 7, 2, -0.1781385556871763);
468  matrix_set(data->Z, data->m+1, 7, 3, -0.7292593770500276);
469 
470  // convert Z to a sparse matrix to test the sparse functions
471  data->spZ = gensvm_dense_to_sparse(data->Z, data->n, data->m+1);
472  free(data->RAW);
473  data->RAW = NULL;
474  free(data->Z);
475  data->Z = NULL;
476 
477  // initialize model
478  model->p = 1.1;
479  model->lambda = 0.123;
480  model->weight_idx = 1;
481  model->kappa = 0.5;
482 
483  // initialize matrices
484  gensvm_allocate_model(model);
485  gensvm_initialize_weights(data, model);
486  gensvm_simplex(model);
487  gensvm_simplex_diff(model);
488 
489  // initialize V
490  matrix_set(model->V, model->K-1, 0, 0, -0.7593642121025029);
491  matrix_set(model->V, model->K-1, 0, 1, -0.5497320698504756);
492  matrix_set(model->V, model->K-1, 1, 0, 0.2982680646268177);
493  matrix_set(model->V, model->K-1, 1, 1, -0.2491408622891925);
494  matrix_set(model->V, model->K-1, 2, 0, -0.3118572761092807);
495  matrix_set(model->V, model->K-1, 2, 1, 0.5461219445756100);
496  matrix_set(model->V, model->K-1, 3, 0, -0.3198994238626641);
497  matrix_set(model->V, model->K-1, 3, 1, 0.7134997072555367);
498 
499  // start test code //
500 
501  // these need to be prepared for the update call
502  gensvm_calculate_errors(model, data, work->ZV);
503  gensvm_calculate_huber(model);
504 
505  // run the actual update call
506  gensvm_get_update(model, data, work);
507 
508  // test values
509  mu_assert(fabs(matrix_get(model->V, model->K-1, 0, 0) -
510  -0.1323791019594062) < 1e-14,
511  "Incorrect value of model->V at 0, 0");
512  mu_assert(fabs(matrix_get(model->V, model->K-1, 0, 1) -
513  -0.3598407983154332) < 1e-14,
514  "Incorrect value of model->V at 0, 1");
515  mu_assert(fabs(matrix_get(model->V, model->K-1, 1, 0) -
516  0.3532993103400935) < 1e-14,
517  "Incorrect value of model->V at 1, 0");
518  mu_assert(fabs(matrix_get(model->V, model->K-1, 1, 1) -
519  -0.4094572388475382) < 1e-14,
520  "Incorrect value of model->V at 1, 1");
521  mu_assert(fabs(matrix_get(model->V, model->K-1, 2, 0) -
522  0.1313169839871234) < 1e-14,
523  "Incorrect value of model->V at 2, 0");
524  mu_assert(fabs(matrix_get(model->V, model->K-1, 2, 1) -
525  0.2423439972728328) < 1e-14,
526  "Incorrect value of model->V at 2, 1");
527  mu_assert(fabs(matrix_get(model->V, model->K-1, 3, 0) -
528  0.0458431025455224) < 1e-14,
529  "Incorrect value of model->V at 3, 0");
530  mu_assert(fabs(matrix_get(model->V, model->K-1, 3, 1) -
531  0.4390030236354089) < 1e-14,
532  "Incorrect value of model->V at 3, 1");
533  // end test code //
534 
535  gensvm_free_model(model);
536  gensvm_free_data(data);
537  gensvm_free_work(work);
538 
539  return NULL;
540 }
541 
542 
543 char *test_dposv()
544 {
545  int n = 6,
546  m = 5;
547 
548  // start test code //
549  double *A = Calloc(double, n*n);
550  double *B = Calloc(double, n*m);
551 
552  // We're only storing the upper triangular part of the symmetric
553  // matrix A.
554  matrix_set(A, n, 0, 0, 6.2522023496540386);
555  matrix_set(A, n, 0, 1, 1.2760969977888754);
556  matrix_set(A, n, 0, 2, 1.1267774552193974);
557  matrix_set(A, n, 0, 3, 0.8384267227932789);
558  matrix_set(A, n, 0, 4, 0.9588857509656767);
559  matrix_set(A, n, 0, 5, 0.7965747978871199);
560  matrix_set(A, n, 1, 1, 6.7539376310748924);
561  matrix_set(A, n, 1, 2, 0.5908599276261999);
562  matrix_set(A, n, 1, 3, 0.9987368128192129);
563  matrix_set(A, n, 1, 4, 1.1142949385131484);
564  matrix_set(A, n, 1, 5, 1.4150107613377123);
565  matrix_set(A, n, 2, 2, 7.3361678639533139);
566  matrix_set(A, n, 2, 3, 1.5596679563906113);
567  matrix_set(A, n, 2, 4, 0.8162441257417704);
568  matrix_set(A, n, 2, 5, 0.8701893160678078);
569  matrix_set(A, n, 3, 3, 6.8330423955320834);
570  matrix_set(A, n, 3, 4, 1.6081779105091201);
571  matrix_set(A, n, 3, 5, 1.0498769837396527);
572  matrix_set(A, n, 4, 4, 7.6810607313742949);
573  matrix_set(A, n, 4, 5, 1.1352511350739003);
574  matrix_set(A, n, 5, 5, 7.0573435553104567);
575 
576  // this is the matrix B (n x m), stored in COLUMN-MAJOR ORDER
577  B[0] = 0.5759809004700531;
578  B[1] = 0.4643751885289473;
579  B[2] = 0.1914807543974765;
580  B[3] = 0.2875503245961965;
581  B[4] = 0.0493123646253395;
582  B[5] = 0.4333053066976881;
583  B[6] = 0.4738306027724854;
584  B[7] = 0.2460182087225041;
585  B[8] = 0.1620492662433550;
586  B[9] = 0.9596380576403235;
587  B[10] = 0.7244837218691289;
588  B[11] = 0.9437116578537014;
589  B[12] = 0.3320986772155025;
590  B[13] = 0.4717424581951766;
591  B[14] = 0.9206089360217588;
592  B[15] = 0.7059004575000609;
593  B[16] = 0.1696670763906902;
594  B[17] = 0.4896586269167711;
595  B[18] = 0.9539497766794410;
596  B[19] = 0.2269749103273779;
597  B[20] = 0.8832156948007016;
598  B[21] = 0.4682217970327739;
599  B[22] = 0.5293439096127632;
600  B[23] = 0.8699136677253214;
601  B[24] = 0.1622687366790325;
602  B[25] = 0.4511598310105013;
603  B[26] = 0.5587302139109592;
604  B[27] = 0.7456952498557438;
605  B[28] = 0.5923112589693547;
606  B[29] = 0.2243481938151050;
607 
608  // note the 'L' here denotes the lower triangular part of A. Above we
609  // stored the upper triangular part of A in row-major order, so that's
610  // the lower triangular part in column-major order, which Lapack uses.
611  int status = dposv('L', n, m, A, n, B, n);
612  mu_assert(status == 0, "dposv didn't return status success");
613 
614  // Since B now contains the solution in Column-Major order, we have to
615  // check it in that order.
616 
617  mu_assert(fabs(B[0] - 0.0770250502756885) < 1e-14,
618  "Incorrect value of B at 0");
619  mu_assert(fabs(B[1] - 0.0449013611583528) < 1e-14,
620  "Incorrect value of B at 1");
621  mu_assert(fabs(B[2] - 0.0028421256926631) < 1e-14,
622  "Incorrect value of B at 2");
623  mu_assert(fabs(B[3] - 0.0238082780914757) < 1e-14,
624  "Incorrect value of B at 3");
625  mu_assert(fabs(B[4] - -0.0213884392480803) < 1e-14,
626  "Incorrect value of B at 4");
627  mu_assert(fabs(B[5] - 0.0432493445363141) < 1e-14,
628  "Incorrect value of B at 5");
629  mu_assert(fabs(B[6] - 0.0469188408250497) < 1e-14,
630  "Incorrect value of B at 6");
631  mu_assert(fabs(B[7] - -0.0188676544565197) < 1e-14,
632  "Incorrect value of B at 7");
633  mu_assert(fabs(B[8] - -0.0268693544126544) < 1e-14,
634  "Incorrect value of B at 8");
635  mu_assert(fabs(B[9] - 0.1139942447258460) < 1e-14,
636  "Incorrect value of B at 9");
637  mu_assert(fabs(B[10] - 0.0539483576192093) < 1e-14,
638  "Incorrect value of B at 10");
639  mu_assert(fabs(B[11] - 0.1098843745987866) < 1e-14,
640  "Incorrect value of B at 11");
641  mu_assert(fabs(B[12] - 0.0142822905211067) < 1e-14,
642  "Incorrect value of B at 12");
643  mu_assert(fabs(B[13] - 0.0425078586146396) < 1e-14,
644  "Incorrect value of B at 13");
645  mu_assert(fabs(B[14] - 0.1022650353097420) < 1e-14,
646  "Incorrect value of B at 14");
647  mu_assert(fabs(B[15] - 0.0700476338859921) < 1e-14,
648  "Incorrect value of B at 15");
649  mu_assert(fabs(B[16] - -0.0171546096353451) < 1e-14,
650  "Incorrect value of B at 16");
651  mu_assert(fabs(B[17] - 0.0389772844468578) < 1e-14,
652  "Incorrect value of B at 17");
653  mu_assert(fabs(B[18] - 0.1231757430810565) < 1e-14,
654  "Incorrect value of B at 18");
655  mu_assert(fabs(B[19] - -0.0246954324681607) < 1e-14,
656  "Incorrect value of B at 19");
657  mu_assert(fabs(B[20] - 0.0853098528328778) < 1e-14,
658  "Incorrect value of B at 20");
659  mu_assert(fabs(B[21] - 0.0155226252622933) < 1e-14,
660  "Incorrect value of B at 21");
661  mu_assert(fabs(B[22] - 0.0305321945431931) < 1e-14,
662  "Incorrect value of B at 22");
663  mu_assert(fabs(B[23] - 0.0965724559730953) < 1e-14,
664  "Incorrect value of B at 23");
665  mu_assert(fabs(B[24] - -0.0106596940426243) < 1e-14,
666  "Incorrect value of B at 24");
667  mu_assert(fabs(B[25] - 0.0446093337039209) < 1e-14,
668  "Incorrect value of B at 25");
669  mu_assert(fabs(B[26] - 0.0517721408799503) < 1e-14,
670  "Incorrect value of B at 26");
671  mu_assert(fabs(B[27] - 0.0807167333268751) < 1e-14,
672  "Incorrect value of B at 27");
673  mu_assert(fabs(B[28] - 0.0499219869343351) < 1e-14,
674  "Incorrect value of B at 28");
675  mu_assert(fabs(B[29] - -0.0023736192508975) < 1e-14,
676  "Incorrect value of B at 29");
677 
678  // end test code //
679 
680  free(A);
681  free(B);
682 
683  return NULL;
684 }
685 
686 char *test_dsysv()
687 {
688  int n = 6,
689  m = 5;
690 
691  // start test code //
692  double *A = Calloc(double, n*n);
693  double *B = Calloc(double, n*m);
694 
695  // only store the upper triangular part of A
696  matrix_set(A, n, 0, 0, 0.4543421836368821);
697  matrix_set(A, n, 0, 1, 0.8708338836669620);
698  matrix_set(A, n, 0, 2, 1.3638340495356920);
699  matrix_set(A, n, 0, 3, 0.8361050302144852);
700  matrix_set(A, n, 0, 4, 1.3203463886997013);
701  matrix_set(A, n, 0, 5, 0.3915472119381547);
702  matrix_set(A, n, 1, 1, 1.4781728513484600);
703  matrix_set(A, n, 1, 2, 1.7275151336935415);
704  matrix_set(A, n, 1, 3, 1.1817139356024176);
705  matrix_set(A, n, 1, 4, 0.7436086782250922);
706  matrix_set(A, n, 1, 5, 0.1101758222549450);
707  matrix_set(A, n, 2, 2, 1.9363682709237851);
708  matrix_set(A, n, 2, 3, 1.1255164391384127);
709  matrix_set(A, n, 2, 4, 1.0935575148560115);
710  matrix_set(A, n, 2, 5, 1.4678279983625921);
711  matrix_set(A, n, 3, 3, 1.7500757162326757);
712  matrix_set(A, n, 3, 4, 1.5490921663229316);
713  matrix_set(A, n, 3, 5, 1.0305675837706338);
714  matrix_set(A, n, 4, 4, 0.4015851628106807);
715  matrix_set(A, n, 4, 5, 1.2487496402900566);
716  matrix_set(A, n, 5, 5, 0.7245473723012897);
717 
718  // Store B in column-major order!
719  B[0] = 0.6037912122210694;
720  B[1] = 0.5464186020522516;
721  B[2] = 0.1810847918541411;
722  B[3] = 0.1418268895582175;
723  B[4] = 0.5459836535934901;
724  B[5] = 0.5890609930309275;
725  B[6] = 0.1128454279279324;
726  B[7] = 0.8930541056550655;
727  B[8] = 0.6946437745982983;
728  B[9] = 0.0955380494302154;
729  B[10] = 0.5750037200376288;
730  B[11] = 0.0326245221201559;
731  B[12] = 0.3336701777312929;
732  B[13] = 0.7648765739095678;
733  B[14] = 0.2662986413718805;
734  B[15] = 0.7850810368985298;
735  B[16] = 0.5432388739552745;
736  B[17] = 0.4387739258059151;
737  B[18] = 0.4257906469646436;
738  B[19] = 0.1272470768775465;
739  B[20] = 0.4276616397814972;
740  B[21] = 0.8137579718316245;
741  B[22] = 0.6849003723960281;
742  B[23] = 0.1768571691078990;
743  B[24] = 0.4183278358395650;
744  B[25] = 0.6517633972400351;
745  B[26] = 0.1154775550239331;
746  B[27] = 0.4217248849174023;
747  B[28] = 0.9179697263236190;
748  B[29] = 0.6532254399609347;
749 
750  // run dsysv, note that Lapack expects matrices to be in column-major
751  // order, so we can use the 'L' notation for the triangle of A, since
752  // we've stored the upper triangle in Row-Major order.
753 
754  int *IPIV = Calloc(int, n);
755  double *WORK = Calloc(double, 1);
756  int status;
757 
758  // first we determine the necessary size of the WORK array
759  status = dsysv('L', n, m, A, n, IPIV, B, n, WORK, -1);
760  mu_assert(status == 0, "dsysv workspace query failed");
761 
762  int LWORK = WORK[0];
763  WORK = Realloc(WORK, double, LWORK);
764  status = dsysv('L', n, m, A, n, IPIV, B, n, WORK, LWORK);
765  mu_assert(status == 0, "dsysv didn't return status success");
766 
767  // Since B now contains the solution in Column-Major order, we have to
768  // check it in that order
769 
770  mu_assert(fabs(B[0] - 3.0915448286548806) < 1e-14,
771  "Incorrect value of B at 0");
772  mu_assert(fabs(B[1] - -1.2114333666218096) < 1e-14,
773  "Incorrect value of B at 1");
774  mu_assert(fabs(B[2] - -0.1734297056577389) < 1e-14,
775  "Incorrect value of B at 2");
776  mu_assert(fabs(B[3] - -0.6989941801726605) < 1e-14,
777  "Incorrect value of B at 3");
778  mu_assert(fabs(B[4] - 1.2577948324106381) < 1e-14,
779  "Incorrect value of B at 4");
780  mu_assert(fabs(B[5] - -1.4956913279293909) < 1e-14,
781  "Incorrect value of B at 5");
782  mu_assert(fabs(B[6] - -0.2923881304345451) < 1e-14,
783  "Incorrect value of B at 6");
784  mu_assert(fabs(B[7] - 0.3467010144627596) < 1e-14,
785  "Incorrect value of B at 7");
786  mu_assert(fabs(B[8] - 0.4892730831569431) < 1e-14,
787  "Incorrect value of B at 8");
788  mu_assert(fabs(B[9] - 0.2811039364176572) < 1e-14,
789  "Incorrect value of B at 9");
790  mu_assert(fabs(B[10] - -0.7323586733947237) < 1e-14,
791  "Incorrect value of B at 10");
792  mu_assert(fabs(B[11] - 0.0214996365534143) < 1e-14,
793  "Incorrect value of B at 11");
794  mu_assert(fabs(B[12] - -0.9355264353773129) < 1e-14,
795  "Incorrect value of B at 12");
796  mu_assert(fabs(B[13] - 0.2709743256273919) < 1e-14,
797  "Incorrect value of B at 13");
798  mu_assert(fabs(B[14] - 0.2328234557913496) < 1e-14,
799  "Incorrect value of B at 14");
800  mu_assert(fabs(B[15] - 0.9367092697976086) < 1e-14,
801  "Incorrect value of B at 15");
802  mu_assert(fabs(B[16] - -0.4501075692310449) < 1e-14,
803  "Incorrect value of B at 16");
804  mu_assert(fabs(B[17] - 0.0416902255163366) < 1e-14,
805  "Incorrect value of B at 17");
806  mu_assert(fabs(B[18] - 2.2216982312706905) < 1e-14,
807  "Incorrect value of B at 18");
808  mu_assert(fabs(B[19] - -0.4820931673893176) < 1e-14,
809  "Incorrect value of B at 19");
810  mu_assert(fabs(B[20] - -0.8456462251088332) < 1e-14,
811  "Incorrect value of B at 20");
812  mu_assert(fabs(B[21] - -0.3761761825939751) < 1e-14,
813  "Incorrect value of B at 21");
814  mu_assert(fabs(B[22] - 1.1921920764994696) < 1e-14,
815  "Incorrect value of B at 22");
816  mu_assert(fabs(B[23] - -0.6897255145640184) < 1e-14,
817  "Incorrect value of B at 23");
818  mu_assert(fabs(B[24] - 2.0325624816957180) < 1e-14,
819  "Incorrect value of B at 24");
820  mu_assert(fabs(B[25] - -0.9900930297944344) < 1e-14,
821  "Incorrect value of B at 25");
822  mu_assert(fabs(B[26] - -0.0462533459389938) < 1e-14,
823  "Incorrect value of B at 26");
824  mu_assert(fabs(B[27] - 0.0960916931433909) < 1e-14,
825  "Incorrect value of B at 27");
826  mu_assert(fabs(B[28] - 0.5805302287627144) < 1e-14,
827  "Incorrect value of B at 28");
828  mu_assert(fabs(B[29] - -1.0897953557455400) < 1e-14,
829  "Incorrect value of B at 29");
830 
831  free(WORK);
832  free(IPIV);
833 
834  // end test code //
835 
836  free(A);
837  free(B);
838 
839  return NULL;
840 }
841 
842 char *all_tests()
843 {
844  mu_suite_start();
845 
850 
853 
856 
857  return NULL;
858 }
859 
Minimal unit testing framework for C.
#define Calloc(type, size)
Definition: gensvm_memory.h:40
char * all_tests()
long K
number of classes for the workspace
Definition: gensvm_base.h:156
double * H
Huber weighted error matrix.
Definition: gensvm_base.h:126
void gensvm_simplex(struct GenModel *model)
Generate matrix of simplex vertex coordinates.
void gensvm_get_update(struct GenModel *model, struct GenData *data, struct GenWork *work)
Perform a single step of the majorization algorithm to update V.
long m
number of features for the workspace
Definition: gensvm_base.h:154
char * test_gensvm_calculate_ab_simple()
double p
parameter for the L-p norm in the loss function
Definition: gensvm_base.h:103
bool gensvm_majorize_is_simple(struct GenModel *model, struct GenData *data, long i)
Check if we can do simple majorization for a given instance.
Definition: gensvm_update.c:89
void gensvm_calculate_ab_non_simple(struct GenModel *model, long i, long j, double *a, double *b_aq)
Compute majorization coefficients for non-simple instance.
char * test_gensvm_get_update()
#define mu_assert(test, message)
Definition: minunit.h:29
char * test_dsysv()
long K
number of classes
Definition: gensvm_base.h:58
#define matrix_get(M, cols, i, j)
double * ZV
n x (K-1) working matrix for the Z * V calculation
Definition: gensvm_base.h:169
void gensvm_calculate_ab_simple(struct GenModel *model, long i, long j, double *a, double *b_aq)
Compute majorization coefficients for simple instances.
double gensvm_calculate_omega(struct GenModel *model, struct GenData *data, long i)
Calculate the value of omega for a single instance.
Definition: gensvm_update.c:56
void gensvm_free_work(struct GenWork *work)
Free an allocated GenWork instance.
Definition: gensvm_base.c:277
double * Z
Definition: gensvm_base.h:68
A structure to hold the GenSVM workspace.
Definition: gensvm_base.h:151
void gensvm_free_model(struct GenModel *model)
Free allocated GenModel struct.
Definition: gensvm_base.c:211
int weight_idx
which weights to use (1 = unit, 2 = group)
Definition: gensvm_base.h:93
char * test_dposv()
struct GenWork * gensvm_init_work(struct GenModel *model)
Initialize the workspace structure.
Definition: gensvm_base.c:245
double * V
augmented weight matrix
Definition: gensvm_base.h:115
#define mu_run_test(test)
Definition: minunit.h:35
double * Q
error matrix
Definition: gensvm_base.h:124
long * y
array of class labels, 1..K
Definition: gensvm_base.h:66
struct GenModel * gensvm_init_model(void)
Initialize a GenModel structure.
Definition: gensvm_base.c:102
char * test_gensvm_calculate_ab_non_simple()
void gensvm_simplex_diff(struct GenModel *model)
Generate the simplex difference matrix.
A structure to represent the data.
Definition: gensvm_base.h:57
void gensvm_initialize_weights(struct GenData *data, struct GenModel *model)
Initialize instance weights.
Definition: gensvm_init.c:152
A structure to represent a single GenSVM model.
Definition: gensvm_base.h:92
RUN_TESTS(all_tests)
int dposv(char UPLO, int N, int NRHS, double *A, int LDA, double *B, int LDB)
Solve AX = B where A is symmetric positive definite.
#define Realloc(var, type, size)
Definition: gensvm_memory.h:55
long n
number of instances in the dataset
Definition: gensvm_base.h:97
void gensvm_free_data(struct GenData *data)
Free allocated GenData struct.
Definition: gensvm_base.c:73
void gensvm_calculate_errors(struct GenModel *model, struct GenData *data, double *ZV)
Calculate the scalar errors.
void gensvm_allocate_model(struct GenModel *model)
Allocate memory for a GenModel.
Definition: gensvm_base.c:144
Header file for gensvm_optimize.c.
char * test_gensvm_majorize_is_simple()
char * test_gensvm_calculate_omega()
Header file for gensvm_simplex.c.
double kappa
parameter for the Huber hinge function
Definition: gensvm_base.h:105
long K
number of classes in the dataset
Definition: gensvm_base.h:95
long m
number of predictors (width of RAW)
Definition: gensvm_base.h:62
struct GenSparse * gensvm_dense_to_sparse(double *A, long rows, long cols)
Convert a dense matrix to a GenSparse structure if advantageous.
#define matrix_set(M, cols, i, j, val)
Header file for gensvm_init.c.
long n
number of instances
Definition: gensvm_base.h:60
void gensvm_calculate_huber(struct GenModel *model)
Calculate the Huber hinge errors.
int dsysv(char UPLO, int N, int NRHS, double *A, int LDA, int *IPIV, double *B, int LDB, double *WORK, int LWORK)
Solve a system of equations AX = B where A is symmetric.
struct GenData * gensvm_init_data(void)
Initialize a GenData structure.
Definition: gensvm_base.c:45
long n
number of instances for the workspace
Definition: gensvm_base.h:152
long m
number of predictor variables in the dataset
Definition: gensvm_base.h:99
#define mu_suite_start()
Definition: minunit.h:24
double * RAW
augmented raw data matrix
Definition: gensvm_base.h:73
char * test_gensvm_get_update_sparse()
struct GenSparse * spZ
sparse representation of the augmented data matrix
Definition: gensvm_base.h:71
double lambda
regularization parameter in the loss function
Definition: gensvm_base.h:107