gsl 1.12.108

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. data/README.rdoc +29 -0
  2. data/Rakefile +54 -0
  3. data/VERSION +2 -0
  4. data/ext/MANIFEST +119 -0
  5. data/ext/alf.c +206 -0
  6. data/ext/array.c +666 -0
  7. data/ext/array_complex.c +247 -0
  8. data/ext/blas.c +29 -0
  9. data/ext/blas1.c +731 -0
  10. data/ext/blas2.c +1093 -0
  11. data/ext/blas3.c +881 -0
  12. data/ext/block.c +44 -0
  13. data/ext/block_source.c +886 -0
  14. data/ext/bspline.c +130 -0
  15. data/ext/bundle.c +3 -0
  16. data/ext/cdf.c +754 -0
  17. data/ext/cheb.c +542 -0
  18. data/ext/combination.c +283 -0
  19. data/ext/common.c +325 -0
  20. data/ext/complex.c +1004 -0
  21. data/ext/const.c +673 -0
  22. data/ext/const_additional.c +120 -0
  23. data/ext/cqp.c +283 -0
  24. data/ext/deriv.c +195 -0
  25. data/ext/dht.c +361 -0
  26. data/ext/diff.c +166 -0
  27. data/ext/dirac.c +395 -0
  28. data/ext/eigen.c +2373 -0
  29. data/ext/error.c +194 -0
  30. data/ext/extconf.rb +281 -0
  31. data/ext/fcmp.c +66 -0
  32. data/ext/fft.c +1092 -0
  33. data/ext/fit.c +205 -0
  34. data/ext/fresnel.c +312 -0
  35. data/ext/function.c +524 -0
  36. data/ext/geometry.c +139 -0
  37. data/ext/graph.c +1638 -0
  38. data/ext/gsl.c +271 -0
  39. data/ext/gsl_narray.c +653 -0
  40. data/ext/histogram.c +1995 -0
  41. data/ext/histogram2d.c +1068 -0
  42. data/ext/histogram3d.c +884 -0
  43. data/ext/histogram3d_source.c +750 -0
  44. data/ext/histogram_find.c +101 -0
  45. data/ext/histogram_oper.c +159 -0
  46. data/ext/ieee.c +98 -0
  47. data/ext/integration.c +1138 -0
  48. data/ext/interp.c +512 -0
  49. data/ext/jacobi.c +739 -0
  50. data/ext/linalg.c +4047 -0
  51. data/ext/linalg_complex.c +741 -0
  52. data/ext/math.c +725 -0
  53. data/ext/matrix.c +39 -0
  54. data/ext/matrix_complex.c +1732 -0
  55. data/ext/matrix_double.c +560 -0
  56. data/ext/matrix_int.c +256 -0
  57. data/ext/matrix_source.c +2733 -0
  58. data/ext/min.c +250 -0
  59. data/ext/monte.c +992 -0
  60. data/ext/multifit.c +1879 -0
  61. data/ext/multimin.c +808 -0
  62. data/ext/multimin_fsdf.c +156 -0
  63. data/ext/multiroots.c +955 -0
  64. data/ext/ndlinear.c +321 -0
  65. data/ext/nmf.c +167 -0
  66. data/ext/nmf_wrap.c +72 -0
  67. data/ext/ntuple.c +469 -0
  68. data/ext/odeiv.c +959 -0
  69. data/ext/ool.c +879 -0
  70. data/ext/oper_complex_source.c +253 -0
  71. data/ext/permutation.c +596 -0
  72. data/ext/poly.c +42 -0
  73. data/ext/poly2.c +265 -0
  74. data/ext/poly_source.c +1885 -0
  75. data/ext/qrng.c +171 -0
  76. data/ext/randist.c +1873 -0
  77. data/ext/rational.c +480 -0
  78. data/ext/rng.c +612 -0
  79. data/ext/root.c +408 -0
  80. data/ext/sf.c +1494 -0
  81. data/ext/sf_airy.c +200 -0
  82. data/ext/sf_bessel.c +867 -0
  83. data/ext/sf_clausen.c +28 -0
  84. data/ext/sf_coulomb.c +206 -0
  85. data/ext/sf_coupling.c +118 -0
  86. data/ext/sf_dawson.c +29 -0
  87. data/ext/sf_debye.c +157 -0
  88. data/ext/sf_dilog.c +42 -0
  89. data/ext/sf_elementary.c +44 -0
  90. data/ext/sf_ellint.c +206 -0
  91. data/ext/sf_elljac.c +29 -0
  92. data/ext/sf_erfc.c +93 -0
  93. data/ext/sf_exp.c +164 -0
  94. data/ext/sf_expint.c +211 -0
  95. data/ext/sf_fermi_dirac.c +148 -0
  96. data/ext/sf_gamma.c +344 -0
  97. data/ext/sf_gegenbauer.c +96 -0
  98. data/ext/sf_hyperg.c +197 -0
  99. data/ext/sf_laguerre.c +112 -0
  100. data/ext/sf_lambert.c +47 -0
  101. data/ext/sf_legendre.c +367 -0
  102. data/ext/sf_log.c +104 -0
  103. data/ext/sf_mathieu.c +238 -0
  104. data/ext/sf_power.c +46 -0
  105. data/ext/sf_psi.c +98 -0
  106. data/ext/sf_synchrotron.c +48 -0
  107. data/ext/sf_transport.c +76 -0
  108. data/ext/sf_trigonometric.c +207 -0
  109. data/ext/sf_zeta.c +119 -0
  110. data/ext/signal.c +310 -0
  111. data/ext/siman.c +718 -0
  112. data/ext/sort.c +208 -0
  113. data/ext/spline.c +395 -0
  114. data/ext/stats.c +799 -0
  115. data/ext/sum.c +168 -0
  116. data/ext/tamu_anova.c +56 -0
  117. data/ext/tensor.c +38 -0
  118. data/ext/tensor_source.c +1123 -0
  119. data/ext/vector.c +38 -0
  120. data/ext/vector_complex.c +2236 -0
  121. data/ext/vector_double.c +1433 -0
  122. data/ext/vector_int.c +204 -0
  123. data/ext/vector_source.c +3329 -0
  124. data/ext/wavelet.c +937 -0
  125. data/include/rb_gsl.h +151 -0
  126. data/include/rb_gsl_array.h +238 -0
  127. data/include/rb_gsl_cheb.h +21 -0
  128. data/include/rb_gsl_common.h +343 -0
  129. data/include/rb_gsl_complex.h +25 -0
  130. data/include/rb_gsl_const.h +29 -0
  131. data/include/rb_gsl_dirac.h +13 -0
  132. data/include/rb_gsl_eigen.h +17 -0
  133. data/include/rb_gsl_fft.h +62 -0
  134. data/include/rb_gsl_fit.h +25 -0
  135. data/include/rb_gsl_function.h +27 -0
  136. data/include/rb_gsl_graph.h +70 -0
  137. data/include/rb_gsl_histogram.h +63 -0
  138. data/include/rb_gsl_histogram3d.h +97 -0
  139. data/include/rb_gsl_integration.h +17 -0
  140. data/include/rb_gsl_interp.h +46 -0
  141. data/include/rb_gsl_linalg.h +25 -0
  142. data/include/rb_gsl_math.h +26 -0
  143. data/include/rb_gsl_odeiv.h +21 -0
  144. data/include/rb_gsl_poly.h +71 -0
  145. data/include/rb_gsl_rational.h +37 -0
  146. data/include/rb_gsl_rng.h +21 -0
  147. data/include/rb_gsl_root.h +22 -0
  148. data/include/rb_gsl_sf.h +119 -0
  149. data/include/rb_gsl_statistics.h +17 -0
  150. data/include/rb_gsl_tensor.h +45 -0
  151. data/include/rb_gsl_with_narray.h +22 -0
  152. data/include/templates_off.h +87 -0
  153. data/include/templates_on.h +241 -0
  154. data/lib/gsl/gnuplot.rb +41 -0
  155. data/lib/gsl/oper.rb +68 -0
  156. data/lib/ool.rb +22 -0
  157. data/lib/ool/conmin.rb +30 -0
  158. metadata +224 -0
@@ -0,0 +1,321 @@
1
+ #include "rb_gsl.h"
2
+
3
+ #ifdef HAVE_NDLINEAR_GSL_MULTIFIT_NDLINEAR_H
4
+ #include <gsl/gsl_math.h>
5
+ #include <gsl/gsl_matrix.h>
6
+ #include <gsl/gsl_vector.h>
7
+ #include <gsl/gsl_multifit.h>
8
+ #include <ndlinear/gsl_multifit_ndlinear.h>
9
+
10
+ static VALUE cWorkspace;
11
+
12
+ enum Index_Ndlinear {
13
+ INDEX_NDIM = 0,
14
+ INDEX_N = 1,
15
+ INDEX_PROCS = 2,
16
+ INDEX_PARAMS = 3,
17
+ INDEX_FUNCS = 4,
18
+ INDEX_NDIM_I = 5,
19
+
20
+ NDLINEAR_ARY_SIZE = 6,
21
+ };
22
+
23
+ static void multifit_ndlinear_mark(gsl_multifit_ndlinear_workspace *w)
24
+ {
25
+ rb_gc_mark((VALUE) w->params);
26
+ }
27
+
28
+ typedef int (*UFUNC)(double, double[], void*);
29
+ typedef struct ufunc_struct
30
+ {
31
+ UFUNC *fptr;
32
+ } ufunc_struct;
33
+
34
+ static VALUE cUFunc;
35
+ static ufunc_struct* ufunc_struct_alloc(size_t n_dim) {
36
+ ufunc_struct *p;
37
+ p = (ufunc_struct*) malloc(sizeof(ufunc_struct));
38
+ p->fptr = malloc(sizeof(UFUNC)*n_dim);
39
+ return p;
40
+ }
41
+ static void ufunc_struct_free(ufunc_struct *p)
42
+ {
43
+ free(p->fptr);
44
+ free(p);
45
+ }
46
+
47
+ static int func_u(double x, double y[], void *data);
48
+ static VALUE rb_gsl_multifit_ndlinear_alloc(int argc, VALUE *argv, VALUE klass)
49
+ {
50
+ gsl_multifit_ndlinear_workspace *w;
51
+ int istart = 0;
52
+ size_t n_dim = 0, *N, i;
53
+ struct ufunc_struct *p;
54
+ VALUE params, wspace, pp;
55
+ switch (argc) {
56
+ case 4:
57
+ istart = 1;
58
+ CHECK_FIXNUM(argv[0]);
59
+ n_dim = FIX2INT(argv[0]);
60
+ /* no break */
61
+ case 3:
62
+ if (TYPE(argv[istart]) != T_ARRAY) {
63
+ rb_raise(rb_eTypeError, "Wrong argument type %s (Array expected)",
64
+ rb_class2name(CLASS_OF(argv[istart])));
65
+ }
66
+ if (TYPE(argv[istart+1]) != T_ARRAY) {
67
+ rb_raise(rb_eTypeError, "Wrong argument type %s (Array expected)",
68
+ rb_class2name(CLASS_OF(argv[istart+1])));
69
+ }
70
+ // n_dim = RARRAY(argv[istart])->len;
71
+ n_dim = RARRAY_LEN(argv[istart]);
72
+ N = (size_t*) malloc(sizeof(size_t)*n_dim);
73
+ break;
74
+ default:
75
+ rb_raise(rb_eArgError, "Wrong number of arguments (%d for 3 or 4)", argc);
76
+ }
77
+ for (i = 0; i < n_dim; i++) {
78
+ N[i] = FIX2INT(rb_ary_entry(argv[istart], i));
79
+ }
80
+
81
+ params = rb_ary_new2(NDLINEAR_ARY_SIZE);
82
+ rb_ary_store(params, INDEX_NDIM, INT2FIX((int) n_dim));
83
+ rb_ary_store(params, INDEX_N, argv[istart]); /* N */
84
+ rb_ary_store(params, INDEX_PROCS, argv[istart+1]); /* procs */
85
+ rb_ary_store(params, INDEX_PARAMS, argv[istart+2]); /* params */
86
+ rb_ary_store(params, INDEX_NDIM_I, INT2FIX(0)); /* for the first parameter */
87
+
88
+ p = ufunc_struct_alloc(n_dim);
89
+ for (i = 0; i < n_dim; i++) p->fptr[i] = func_u;
90
+ pp = Data_Wrap_Struct(cUFunc, 0, ufunc_struct_free, p);
91
+ rb_ary_store(params, INDEX_FUNCS, pp);
92
+
93
+ w = gsl_multifit_ndlinear_alloc(n_dim, N, p->fptr, (void*) params);
94
+
95
+ free((size_t*) N);
96
+
97
+ wspace = Data_Wrap_Struct(cWorkspace, multifit_ndlinear_mark, gsl_multifit_ndlinear_free, w);
98
+
99
+ return wspace;
100
+ }
101
+
102
+ static int func_u(double x, double y[], void *data)
103
+ {
104
+ VALUE ary, vN, procs, proc, vy, params;
105
+ gsl_vector_view ytmp;
106
+ size_t i, n_dim;
107
+ int rslt;
108
+ ary = (VALUE) data;
109
+ n_dim = FIX2INT(rb_ary_entry(ary, INDEX_NDIM));
110
+ vN = rb_ary_entry(ary, INDEX_N);
111
+ procs = rb_ary_entry(ary, INDEX_PROCS);
112
+ params = rb_ary_entry(ary, INDEX_PARAMS);
113
+ i = FIX2INT(rb_ary_entry(ary, INDEX_NDIM_I));
114
+ proc = rb_ary_entry(procs, i);
115
+
116
+ ytmp.vector.data = (double*) y;
117
+ ytmp.vector.stride = 1;
118
+ ytmp.vector.size = FIX2INT(rb_ary_entry(vN, i));
119
+ vy = Data_Wrap_Struct(cgsl_vector_view, 0, NULL, &ytmp);
120
+
121
+ rslt = rb_funcall((VALUE) proc, RBGSL_ID_call, 3, rb_float_new(x), vy, params);
122
+
123
+ /* for the next parameter */
124
+ i += 1;
125
+ if (i == n_dim) i = 0;
126
+ rb_ary_store(ary, INDEX_NDIM_I, INT2FIX(i));
127
+
128
+ return GSL_SUCCESS;
129
+ }
130
+
131
+ static VALUE rb_gsl_multifit_ndlinear_design(int argc, VALUE *argv, VALUE obj)
132
+ {
133
+ gsl_multifit_ndlinear_workspace *w;
134
+ gsl_matrix *vars = NULL, *X = NULL;
135
+ int argc2, flag = 0, ret;
136
+ switch (TYPE(obj)) {
137
+ case T_MODULE:
138
+ case T_CLASS:
139
+ case T_OBJECT:
140
+ if (!rb_obj_is_kind_of(argv[argc-1], cWorkspace)) {
141
+ rb_raise(rb_eTypeError, "Wrong argument type %s (GSL::MultiFit::Ndlinear::Workspace expected)",
142
+ rb_class2name(CLASS_OF(argv[argc-1])));
143
+ }
144
+ Data_Get_Struct(argv[argc-1], gsl_multifit_ndlinear_workspace, w);
145
+ argc2 = argc-1;
146
+ break;
147
+ default:
148
+ Data_Get_Struct(obj, gsl_multifit_ndlinear_workspace, w);
149
+ argc2 = argc;
150
+ }
151
+ switch (argc2) {
152
+ case 1:
153
+ CHECK_MATRIX(argv[0]);
154
+ Data_Get_Struct(argv[0], gsl_matrix, vars);
155
+ X = gsl_matrix_alloc(vars->size1, w->n_coeffs);
156
+ flag = 1;
157
+ break;
158
+ case 2:
159
+ CHECK_MATRIX(argv[0]);
160
+ CHECK_MATRIX(argv[1]);
161
+ Data_Get_Struct(argv[0], gsl_matrix, vars);
162
+ Data_Get_Struct(argv[1], gsl_matrix, X);
163
+ break;
164
+ default:
165
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
166
+ }
167
+ ret = gsl_multifit_ndlinear_design(vars, X, w);
168
+
169
+ if (flag == 1) {
170
+ return Data_Wrap_Struct(cgsl_matrix, 0, gsl_matrix_free, X);
171
+ } else {
172
+ return INT2FIX(ret);
173
+ }
174
+ }
175
+
176
+ static VALUE rb_gsl_multifit_ndlinear_est(int argc, VALUE *argv, VALUE obj)
177
+ {
178
+ gsl_multifit_ndlinear_workspace *w;
179
+ gsl_vector *x = NULL, *c = NULL;
180
+ gsl_matrix *cov = NULL;
181
+ double y, yerr;
182
+ int argc2;
183
+ switch (TYPE(obj)) {
184
+ case T_MODULE:
185
+ case T_CLASS:
186
+ case T_OBJECT:
187
+ if (!rb_obj_is_kind_of(argv[argc-1], cWorkspace)) {
188
+ rb_raise(rb_eTypeError, "Wrong argument type %s (GSL::MultiFit::Ndlinear::Workspace expected)",
189
+ rb_class2name(CLASS_OF(argv[argc-1])));
190
+ }
191
+ Data_Get_Struct(argv[argc-1], gsl_multifit_ndlinear_workspace, w);
192
+ argc2 = argc-1;
193
+ break;
194
+ default:
195
+ Data_Get_Struct(obj, gsl_multifit_ndlinear_workspace, w);
196
+ argc2 = argc;
197
+ }
198
+ switch (argc2) {
199
+ case 3:
200
+ CHECK_VECTOR(argv[0]);
201
+ CHECK_VECTOR(argv[1]);
202
+ CHECK_MATRIX(argv[2]);
203
+ Data_Get_Struct(argv[0], gsl_vector, x);
204
+ Data_Get_Struct(argv[1], gsl_vector, c);
205
+ Data_Get_Struct(argv[2], gsl_matrix, cov);
206
+ break;
207
+ default:
208
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
209
+ }
210
+ gsl_multifit_ndlinear_est(x, c, cov, &y, &yerr, w);
211
+ return rb_ary_new3(2, rb_float_new(y), rb_float_new(yerr));
212
+ }
213
+
214
+ static VALUE rb_gsl_multifit_ndlinear_calc(int argc, VALUE *argv, VALUE obj)
215
+ {
216
+ gsl_multifit_ndlinear_workspace *w;
217
+ gsl_vector *x = NULL, *c = NULL;
218
+ double val;
219
+ int argc2;
220
+ switch (TYPE(obj)) {
221
+ case T_MODULE:
222
+ case T_CLASS:
223
+ case T_OBJECT:
224
+ if (!rb_obj_is_kind_of(argv[argc-1], cWorkspace)) {
225
+ rb_raise(rb_eTypeError,
226
+ "Wrong argument type %s (GSL::MultiFit::Ndlinear::Workspace expected)",
227
+ rb_class2name(CLASS_OF(argv[argc-1])));
228
+ }
229
+ Data_Get_Struct(argv[argc-1], gsl_multifit_ndlinear_workspace, w);
230
+ argc2 = argc-1;
231
+ break;
232
+ default:
233
+ Data_Get_Struct(obj, gsl_multifit_ndlinear_workspace, w);
234
+ argc2 = argc;
235
+ }
236
+ switch (argc2) {
237
+ case 2:
238
+ CHECK_VECTOR(argv[0]);
239
+ CHECK_VECTOR(argv[1]);
240
+ Data_Get_Struct(argv[0], gsl_vector, x);
241
+ Data_Get_Struct(argv[1], gsl_vector, c);
242
+ break;
243
+ default:
244
+ rb_raise(rb_eArgError, "Wrong number of arguments.");
245
+ }
246
+ val = gsl_multifit_ndlinear_calc(x, c, w);
247
+ return rb_float_new(val);
248
+ }
249
+
250
+ static VALUE rb_gsl_multifit_ndlinear_n_coeffs(VALUE obj)
251
+ {
252
+ gsl_multifit_ndlinear_workspace *w;
253
+ Data_Get_Struct(obj, gsl_multifit_ndlinear_workspace, w);
254
+ return INT2FIX(w->n_coeffs);
255
+ }
256
+
257
+ static VALUE rb_gsl_multifit_ndlinear_n_dim(VALUE obj)
258
+ {
259
+ gsl_multifit_ndlinear_workspace *w;
260
+ Data_Get_Struct(obj, gsl_multifit_ndlinear_workspace, w);
261
+ return INT2FIX(w->n_dim);
262
+ }
263
+
264
+ static VALUE rb_gsl_multifit_ndlinear_N(VALUE obj)
265
+ {
266
+ gsl_multifit_ndlinear_workspace *w;
267
+ VALUE ary;
268
+ Data_Get_Struct(obj, gsl_multifit_ndlinear_workspace, w);
269
+ ary = (VALUE) w->params;
270
+ return rb_ary_entry(ary, INDEX_N);
271
+ }
272
+ /*
273
+ static VALUE rb_gsl_multifit_linear_Rsq(VALUE module, VALUE vy, VALUE vchisq)
274
+ {
275
+ gsl_vector *y;
276
+ double chisq, Rsq;
277
+ CHECK_VECTOR(vy);
278
+ Data_Get_Struct(vy, gsl_vector, y);
279
+ chisq = NUM2DBL(vchisq);
280
+ gsl_multifit_linear_Rsq(y, chisq, &Rsq);
281
+ return rb_float_new(Rsq);
282
+ }
283
+ */
284
+ void Init_ndlinear(VALUE module)
285
+ {
286
+ VALUE mNdlinear;
287
+ mNdlinear = rb_define_module_under(module, "Ndlinear");
288
+ cUFunc = rb_define_class_under(mNdlinear, "UFunc", rb_cObject);
289
+ cWorkspace = rb_define_class_under(mNdlinear, "Workspace", cGSL_Object);
290
+
291
+ rb_define_singleton_method(mNdlinear, "alloc",
292
+ rb_gsl_multifit_ndlinear_alloc, -1);
293
+ rb_define_singleton_method(cWorkspace, "alloc",
294
+ rb_gsl_multifit_ndlinear_alloc, -1);
295
+
296
+ rb_define_singleton_method(mNdlinear, "design",
297
+ rb_gsl_multifit_ndlinear_design, -1);
298
+ rb_define_singleton_method(cWorkspace, "design",
299
+ rb_gsl_multifit_ndlinear_design, -1);
300
+ rb_define_method(cWorkspace, "design",rb_gsl_multifit_ndlinear_est, -1);
301
+ rb_define_singleton_method(mNdlinear, "est",
302
+ rb_gsl_multifit_ndlinear_est, -1);
303
+ rb_define_singleton_method(cWorkspace, "est",
304
+ rb_gsl_multifit_ndlinear_est, -1);
305
+ rb_define_method(cWorkspace, "est",rb_gsl_multifit_ndlinear_est, -1);
306
+
307
+ rb_define_singleton_method(mNdlinear, "calc",
308
+ rb_gsl_multifit_ndlinear_calc, -1);
309
+ rb_define_singleton_method(cWorkspace, "calc",
310
+ rb_gsl_multifit_ndlinear_calc, -1);
311
+ rb_define_method(cWorkspace, "calc",rb_gsl_multifit_ndlinear_calc, -1);
312
+
313
+ rb_define_method(cWorkspace, "n_coeffs",rb_gsl_multifit_ndlinear_n_coeffs, 0);
314
+ rb_define_method(cWorkspace, "n_dim",rb_gsl_multifit_ndlinear_n_dim, 0);
315
+ rb_define_method(cWorkspace, "N",rb_gsl_multifit_ndlinear_N, 0);
316
+
317
+ // rb_define_module_function(module, "linear_Rsq", rb_gsl_multifit_linear_Rsq, 2);
318
+ }
319
+
320
+ #endif
321
+
@@ -0,0 +1,167 @@
1
+ /**
2
+ * NMF: Non-Negative Matrix Factorization
3
+ *
4
+ * Written by Roman Shterenzon
5
+ * (Slightly modified by Y.Tsunesada: just added "const" qualifiers etc.)
6
+ */
7
+
8
+ #include <math.h>
9
+ #include <time.h>
10
+ #include <gsl/gsl_matrix.h>
11
+ #include <gsl/gsl_blas.h> /* for multiplication */
12
+
13
+ #define THRESH 0.000001
14
+ #define MAXITER 1000
15
+
16
+ #undef DEBUG
17
+
18
+ #define mm(a, b) gsl_matrix_mult(a, b)
19
+ gsl_matrix * gsl_matrix_mult(const gsl_matrix *a, const gsl_matrix *b)
20
+ {
21
+ gsl_matrix *c;
22
+ c = gsl_matrix_alloc(a->size1, b->size2);
23
+
24
+ gsl_blas_dgemm(CblasNoTrans, CblasNoTrans, 1.0, a, b, 0.0, c);
25
+ return c;
26
+ }
27
+
28
+ // pretty print
29
+ void pp(const gsl_matrix *m)
30
+ {
31
+ int r, c;
32
+
33
+ for(r=0; r<m->size1; r++) {
34
+ for(c=0; c<m->size2; c++) {
35
+ printf(" %.2f", gsl_matrix_get(m, r, c));
36
+ }
37
+ printf("\n");
38
+ }
39
+ }
40
+
41
+ /* Returns a distance cost */
42
+ double difcost(const gsl_matrix *a, const gsl_matrix *b)
43
+ {
44
+ int i, j;
45
+ double dif=0, d;
46
+
47
+ for (i=0; i < a->size1; i++)
48
+ {
49
+ for (j=0; j < a->size2; j++)
50
+ {
51
+ d = gsl_matrix_get(a, i, j) - gsl_matrix_get(b, i, j);
52
+ dif += d*d;
53
+ }
54
+ }
55
+ return dif;
56
+ }
57
+
58
+ static void initmatrix(gsl_matrix *m, double min, double max)
59
+ {
60
+ int i,j;
61
+ double val;
62
+
63
+ srand(time(NULL));
64
+
65
+ for(i=0; i < m->size1; i++)
66
+ {
67
+ for(j=0; j < m->size2; j++)
68
+ {
69
+ val = min + (int) (max * (rand() / (RAND_MAX + min)));
70
+ gsl_matrix_set(m, i, j, val);
71
+ }
72
+ }
73
+ }
74
+
75
+ static double update(gsl_matrix *v, gsl_matrix *w, gsl_matrix *h)
76
+ {
77
+ double dist = 0;
78
+ gsl_matrix *wt=NULL, *ht=NULL, *wh=NULL;
79
+ gsl_matrix *w_h=NULL, *wt_w=NULL;
80
+ gsl_matrix *wt_v = NULL;
81
+ gsl_matrix *v_ht=NULL, *wt_w_h=NULL, *w_h_ht=NULL;
82
+
83
+ wt = gsl_matrix_alloc(w->size2, w->size1);
84
+ gsl_matrix_transpose_memcpy(wt, w);
85
+ ht = gsl_matrix_alloc(h->size2, h->size1);
86
+ gsl_matrix_transpose_memcpy(ht, h);
87
+
88
+ // wt * v
89
+ wt_v = mm(wt, v);
90
+
91
+ // wt * w * h
92
+ wt_w = mm(wt, w);
93
+ wt_w_h = mm(wt_w, h);
94
+ gsl_matrix_free(wt_w);
95
+
96
+ // h = h.mul_elements(wt * v).div_elements(wt * w * h)
97
+ gsl_matrix_mul_elements(h, wt_v);
98
+ gsl_matrix_div_elements(h, wt_w_h);
99
+ gsl_matrix_free(wt_v);
100
+ gsl_matrix_free(wt_w_h);
101
+
102
+ // v * ht
103
+ v_ht = mm(v, ht);
104
+
105
+ // w * h * ht
106
+ w_h = mm(w, h);
107
+ w_h_ht = mm(w_h, ht);
108
+ gsl_matrix_free(w_h);
109
+
110
+ // w = w.mul_elements(v * ht).div_elements(w * h * ht)
111
+ gsl_matrix_mul_elements(w, v_ht);
112
+ gsl_matrix_div_elements(w, w_h_ht);
113
+ gsl_matrix_free(v_ht);
114
+ gsl_matrix_free(w_h_ht);
115
+
116
+ gsl_matrix_free(wt);
117
+ gsl_matrix_free(ht);
118
+
119
+ wh = mm(w, h);
120
+ dist = difcost(v, wh);
121
+ gsl_matrix_free(wh);
122
+
123
+ // w and h were modified in place
124
+ return dist;
125
+ }
126
+
127
+ /* The main thing - compute the nmf */
128
+ int gsl_matrix_nmf(gsl_matrix *v, int cols, gsl_matrix **w, gsl_matrix **h)
129
+ {
130
+ double dist = 1;
131
+ int iter = 1;
132
+ double min, max;
133
+
134
+ #ifdef DEBUG
135
+ printf("\nCols: %d\nv:\n", cols);
136
+ pp(v);
137
+ #endif
138
+
139
+ gsl_matrix_minmax(v, &min, &max);
140
+
141
+ #ifdef DEBUG
142
+ printf("Min: %f, Max: %f\n", min, max);
143
+ #endif
144
+ *w = gsl_matrix_alloc(v->size1, cols);
145
+ initmatrix(*w, min, max/2); // the multiplicative rules tend to increase w
146
+
147
+ *h = gsl_matrix_alloc(cols, v->size2);
148
+ initmatrix(*h, min, max);
149
+
150
+ while(dist >= THRESH && iter < MAXITER)
151
+ {
152
+ dist = update(v, *w, *h);
153
+ #ifdef DEBUG
154
+ printf("Iteration: %d, distance: %f\n", iter, dist);
155
+ printf("\nw:\n");
156
+ pp(*w);
157
+ printf("\nh:\n");
158
+ pp(*h);
159
+ printf("\n");
160
+ #endif
161
+ iter++;
162
+ }
163
+ #ifdef DEBUG
164
+ printf("Ended\n");
165
+ #endif
166
+ return GSL_SUCCESS;
167
+ }