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.
- data/README.rdoc +29 -0
- data/Rakefile +54 -0
- data/VERSION +2 -0
- data/ext/MANIFEST +119 -0
- data/ext/alf.c +206 -0
- data/ext/array.c +666 -0
- data/ext/array_complex.c +247 -0
- data/ext/blas.c +29 -0
- data/ext/blas1.c +731 -0
- data/ext/blas2.c +1093 -0
- data/ext/blas3.c +881 -0
- data/ext/block.c +44 -0
- data/ext/block_source.c +886 -0
- data/ext/bspline.c +130 -0
- data/ext/bundle.c +3 -0
- data/ext/cdf.c +754 -0
- data/ext/cheb.c +542 -0
- data/ext/combination.c +283 -0
- data/ext/common.c +325 -0
- data/ext/complex.c +1004 -0
- data/ext/const.c +673 -0
- data/ext/const_additional.c +120 -0
- data/ext/cqp.c +283 -0
- data/ext/deriv.c +195 -0
- data/ext/dht.c +361 -0
- data/ext/diff.c +166 -0
- data/ext/dirac.c +395 -0
- data/ext/eigen.c +2373 -0
- data/ext/error.c +194 -0
- data/ext/extconf.rb +281 -0
- data/ext/fcmp.c +66 -0
- data/ext/fft.c +1092 -0
- data/ext/fit.c +205 -0
- data/ext/fresnel.c +312 -0
- data/ext/function.c +524 -0
- data/ext/geometry.c +139 -0
- data/ext/graph.c +1638 -0
- data/ext/gsl.c +271 -0
- data/ext/gsl_narray.c +653 -0
- data/ext/histogram.c +1995 -0
- data/ext/histogram2d.c +1068 -0
- data/ext/histogram3d.c +884 -0
- data/ext/histogram3d_source.c +750 -0
- data/ext/histogram_find.c +101 -0
- data/ext/histogram_oper.c +159 -0
- data/ext/ieee.c +98 -0
- data/ext/integration.c +1138 -0
- data/ext/interp.c +512 -0
- data/ext/jacobi.c +739 -0
- data/ext/linalg.c +4047 -0
- data/ext/linalg_complex.c +741 -0
- data/ext/math.c +725 -0
- data/ext/matrix.c +39 -0
- data/ext/matrix_complex.c +1732 -0
- data/ext/matrix_double.c +560 -0
- data/ext/matrix_int.c +256 -0
- data/ext/matrix_source.c +2733 -0
- data/ext/min.c +250 -0
- data/ext/monte.c +992 -0
- data/ext/multifit.c +1879 -0
- data/ext/multimin.c +808 -0
- data/ext/multimin_fsdf.c +156 -0
- data/ext/multiroots.c +955 -0
- data/ext/ndlinear.c +321 -0
- data/ext/nmf.c +167 -0
- data/ext/nmf_wrap.c +72 -0
- data/ext/ntuple.c +469 -0
- data/ext/odeiv.c +959 -0
- data/ext/ool.c +879 -0
- data/ext/oper_complex_source.c +253 -0
- data/ext/permutation.c +596 -0
- data/ext/poly.c +42 -0
- data/ext/poly2.c +265 -0
- data/ext/poly_source.c +1885 -0
- data/ext/qrng.c +171 -0
- data/ext/randist.c +1873 -0
- data/ext/rational.c +480 -0
- data/ext/rng.c +612 -0
- data/ext/root.c +408 -0
- data/ext/sf.c +1494 -0
- data/ext/sf_airy.c +200 -0
- data/ext/sf_bessel.c +867 -0
- data/ext/sf_clausen.c +28 -0
- data/ext/sf_coulomb.c +206 -0
- data/ext/sf_coupling.c +118 -0
- data/ext/sf_dawson.c +29 -0
- data/ext/sf_debye.c +157 -0
- data/ext/sf_dilog.c +42 -0
- data/ext/sf_elementary.c +44 -0
- data/ext/sf_ellint.c +206 -0
- data/ext/sf_elljac.c +29 -0
- data/ext/sf_erfc.c +93 -0
- data/ext/sf_exp.c +164 -0
- data/ext/sf_expint.c +211 -0
- data/ext/sf_fermi_dirac.c +148 -0
- data/ext/sf_gamma.c +344 -0
- data/ext/sf_gegenbauer.c +96 -0
- data/ext/sf_hyperg.c +197 -0
- data/ext/sf_laguerre.c +112 -0
- data/ext/sf_lambert.c +47 -0
- data/ext/sf_legendre.c +367 -0
- data/ext/sf_log.c +104 -0
- data/ext/sf_mathieu.c +238 -0
- data/ext/sf_power.c +46 -0
- data/ext/sf_psi.c +98 -0
- data/ext/sf_synchrotron.c +48 -0
- data/ext/sf_transport.c +76 -0
- data/ext/sf_trigonometric.c +207 -0
- data/ext/sf_zeta.c +119 -0
- data/ext/signal.c +310 -0
- data/ext/siman.c +718 -0
- data/ext/sort.c +208 -0
- data/ext/spline.c +395 -0
- data/ext/stats.c +799 -0
- data/ext/sum.c +168 -0
- data/ext/tamu_anova.c +56 -0
- data/ext/tensor.c +38 -0
- data/ext/tensor_source.c +1123 -0
- data/ext/vector.c +38 -0
- data/ext/vector_complex.c +2236 -0
- data/ext/vector_double.c +1433 -0
- data/ext/vector_int.c +204 -0
- data/ext/vector_source.c +3329 -0
- data/ext/wavelet.c +937 -0
- data/include/rb_gsl.h +151 -0
- data/include/rb_gsl_array.h +238 -0
- data/include/rb_gsl_cheb.h +21 -0
- data/include/rb_gsl_common.h +343 -0
- data/include/rb_gsl_complex.h +25 -0
- data/include/rb_gsl_const.h +29 -0
- data/include/rb_gsl_dirac.h +13 -0
- data/include/rb_gsl_eigen.h +17 -0
- data/include/rb_gsl_fft.h +62 -0
- data/include/rb_gsl_fit.h +25 -0
- data/include/rb_gsl_function.h +27 -0
- data/include/rb_gsl_graph.h +70 -0
- data/include/rb_gsl_histogram.h +63 -0
- data/include/rb_gsl_histogram3d.h +97 -0
- data/include/rb_gsl_integration.h +17 -0
- data/include/rb_gsl_interp.h +46 -0
- data/include/rb_gsl_linalg.h +25 -0
- data/include/rb_gsl_math.h +26 -0
- data/include/rb_gsl_odeiv.h +21 -0
- data/include/rb_gsl_poly.h +71 -0
- data/include/rb_gsl_rational.h +37 -0
- data/include/rb_gsl_rng.h +21 -0
- data/include/rb_gsl_root.h +22 -0
- data/include/rb_gsl_sf.h +119 -0
- data/include/rb_gsl_statistics.h +17 -0
- data/include/rb_gsl_tensor.h +45 -0
- data/include/rb_gsl_with_narray.h +22 -0
- data/include/templates_off.h +87 -0
- data/include/templates_on.h +241 -0
- data/lib/gsl/gnuplot.rb +41 -0
- data/lib/gsl/oper.rb +68 -0
- data/lib/ool.rb +22 -0
- data/lib/ool/conmin.rb +30 -0
- metadata +224 -0
data/ext/ndlinear.c
ADDED
|
@@ -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
|
+
|
data/ext/nmf.c
ADDED
|
@@ -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
|
+
}
|