narray 0.5.9.4

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 (81) hide show
  1. data/src/ChangeLog +614 -0
  2. data/src/MANIFEST +82 -0
  3. data/src/README.en +54 -0
  4. data/src/README.ja +63 -0
  5. data/src/SPEC.en +300 -0
  6. data/src/SPEC.ja +284 -0
  7. data/src/depend +14 -0
  8. data/src/extconf.rb +111 -0
  9. data/src/lib/narray_ext.rb +211 -0
  10. data/src/lib/nmatrix.rb +244 -0
  11. data/src/mkmath.rb +780 -0
  12. data/src/mknafunc.rb +190 -0
  13. data/src/mkop.rb +638 -0
  14. data/src/na_array.c +644 -0
  15. data/src/na_func.c +1624 -0
  16. data/src/na_index.c +988 -0
  17. data/src/na_linalg.c +616 -0
  18. data/src/na_random.c +409 -0
  19. data/src/narray.c +1308 -0
  20. data/src/narray.def +29 -0
  21. data/src/narray.h +170 -0
  22. data/src/narray_local.h +210 -0
  23. data/src/nimage/README.en +38 -0
  24. data/src/nimage/demo/fits.rb +97 -0
  25. data/src/nimage/demo/fits_convol.rb +28 -0
  26. data/src/nimage/demo/fits_fftdemo.rb +27 -0
  27. data/src/nimage/demo/fitsdemo1.rb +13 -0
  28. data/src/nimage/demo/fitsdemo2.rb +30 -0
  29. data/src/nimage/demo/fitsdemo3.rb +26 -0
  30. data/src/nimage/demo/fitsmorph.rb +39 -0
  31. data/src/nimage/demo/life_na.rb +57 -0
  32. data/src/nimage/demo/mandel.rb +41 -0
  33. data/src/nimage/extconf.rb +12 -0
  34. data/src/nimage/lib/nimage.rb +51 -0
  35. data/src/nimage/nimage.c +328 -0
  36. data/src/speed/add.py +12 -0
  37. data/src/speed/add.rb +8 -0
  38. data/src/speed/add_int.py +12 -0
  39. data/src/speed/add_int.rb +9 -0
  40. data/src/speed/lu.m +14 -0
  41. data/src/speed/lu.rb +22 -0
  42. data/src/speed/mat.m +23 -0
  43. data/src/speed/mat.rb +28 -0
  44. data/src/speed/mul.py +12 -0
  45. data/src/speed/mul.rb +9 -0
  46. data/src/speed/mul2.py +15 -0
  47. data/src/speed/mul2.rb +13 -0
  48. data/src/speed/mul_comp.py +12 -0
  49. data/src/speed/mul_comp.rb +9 -0
  50. data/src/speed/mul_int.py +12 -0
  51. data/src/speed/mul_int.rb +9 -0
  52. data/src/speed/mybench.py +15 -0
  53. data/src/speed/mybench.rb +31 -0
  54. data/src/speed/solve.m +18 -0
  55. data/src/speed/solve.py +16 -0
  56. data/src/speed/solve.rb +21 -0
  57. data/src/test/statistics.rb +22 -0
  58. data/src/test/testarray.rb +20 -0
  59. data/src/test/testbit.rb +27 -0
  60. data/src/test/testcast.rb +14 -0
  61. data/src/test/testcomplex.rb +35 -0
  62. data/src/test/testfftw.rb +16 -0
  63. data/src/test/testindex.rb +11 -0
  64. data/src/test/testindexary.rb +26 -0
  65. data/src/test/testindexset.rb +55 -0
  66. data/src/test/testmask.rb +40 -0
  67. data/src/test/testmath.rb +48 -0
  68. data/src/test/testmath2.rb +46 -0
  69. data/src/test/testmatrix.rb +13 -0
  70. data/src/test/testmatrix2.rb +33 -0
  71. data/src/test/testmatrix3.rb +19 -0
  72. data/src/test/testminmax.rb +46 -0
  73. data/src/test/testobject.rb +29 -0
  74. data/src/test/testpow.rb +19 -0
  75. data/src/test/testrandom.rb +23 -0
  76. data/src/test/testround.rb +11 -0
  77. data/src/test/testsort.rb +37 -0
  78. data/src/test/teststr.rb +13 -0
  79. data/src/test/testtrans.rb +18 -0
  80. data/src/test/testwhere.rb +27 -0
  81. metadata +127 -0
data/src/na_linalg.c ADDED
@@ -0,0 +1,616 @@
1
+ /*
2
+ * na_linalg.c
3
+ * Numerical Array Extention for Ruby
4
+ * (C) Copyright 2000-2002 by Masahiro TANAKA
5
+ */
6
+ #include <ruby.h>
7
+ #include "narray.h"
8
+ #include "narray_local.h"
9
+ #define ARRAY_BUF
10
+
11
+ /*
12
+ a_ij == a[j,i]
13
+ j - >
14
+ i 11 21 31
15
+ | 12 22 32
16
+ v 13 23 33
17
+ */
18
+
19
+ #define SWAPMEM(a,b,tmp,sz) \
20
+ { memcpy(tmp,a,sz); memcpy(a,b,sz); memcpy(b,tmp,sz); }
21
+
22
+ typedef struct NARRAY_FUNCSET {
23
+ int elmsz;
24
+ char *zero;
25
+ char *one;
26
+ char *tiny;
27
+ void (*set)();
28
+ void (*neg)();
29
+ void (*rcp)();
30
+ void (*abs)();
31
+ void (*add)();
32
+ void (*sbt)();
33
+ void (*mul)();
34
+ void (*div)();
35
+ void (*muladd)();
36
+ void (*mulsbt)();
37
+ void (*cmp)();
38
+ int (*sort)();
39
+ void (*min)();
40
+ void (*max)();
41
+ } na_funcset_t;
42
+
43
+ VALUE cNMatrix, cNVector, cNMatrixLU;
44
+ static na_funcset_t na_funcset[NA_NTYPES];
45
+ static ID id_lu, id_pivot;
46
+
47
+
48
+ static void
49
+ na_loop_linalg( int nd, char *p1, char *p2, char *p3,
50
+ struct slice *s1, struct slice *s2, struct slice *s3,
51
+ void (*func)(), int *shape, int type )
52
+ {
53
+ int i;
54
+ int ps1 = s1[0].pstep;
55
+ int ps2 = s2[0].pstep;
56
+ int ps3 = s3[0].pstep;
57
+ int *si;
58
+
59
+ if (nd==0) {
60
+ (*func)(1, p1, 0, p2, 0, p3, 0, shape, type);
61
+ return;
62
+ }
63
+
64
+ si = ALLOCA_N(int,nd);
65
+ i = nd;
66
+ s1[i].p = p1;
67
+ s2[i].p = p2;
68
+ s3[i].p = p3;
69
+
70
+ for(;;) {
71
+ /* set pointers */
72
+ while (i > 0) {
73
+ i--;
74
+ s3[i].p = s3[i].pbeg + s3[i+1].p;
75
+ s2[i].p = s2[i].pbeg + s2[i+1].p;
76
+ s1[i].p = s1[i].pbeg + s1[i+1].p;
77
+ si[i] = s1[i].n;
78
+ }
79
+ /* rank 0 loop */
80
+ (*func)(s2[0].n, s1[0].p, ps1, s2[0].p, ps2, s3[0].p, ps3, shape, type);
81
+ /* rank up */
82
+ do {
83
+ if ( ++i >= nd ) return;
84
+ } while ( --si[i] == 0 );
85
+ /* next point */
86
+ s1[i].p += s1[i].pstep;
87
+ s2[i].p += s2[i].pstep;
88
+ s3[i].p += s3[i].pstep;
89
+ }
90
+ }
91
+
92
+ static int
93
+ na_shape_total( int n, int *shape )
94
+ {
95
+ int total=1;
96
+
97
+ for (; n>0; n--)
98
+ total *= *(shape++);
99
+
100
+ return total;
101
+ }
102
+
103
+ static void
104
+ na_exec_linalg( struct NARRAY *a1, struct NARRAY *a2, struct NARRAY *a3,
105
+ int ncd1, int ncd2, int ncd3, void (*func)() )
106
+ {
107
+ int ndim, ncd, nsz1, nsz2, nsz3;
108
+ int *itr, *shp1, *shp2, *shp3;
109
+ struct slice *s1, *s2, *s3;
110
+
111
+ ncd = na_max3(ncd1,ncd2,ncd3); /* class dim */
112
+ ndim = na_max3(a1->rank-ncd1, a2->rank-ncd2, a3->rank-ncd3) + ncd;
113
+
114
+ NA_ALLOC_SLICE(s1,(ndim+1)*3,shp1,ndim*4);
115
+ shp2 = &shp1[ndim];
116
+ shp3 = &shp2[ndim];
117
+ itr = &shp3[ndim];
118
+ s2 = &s1[ndim+1];
119
+ s3 = &s2[ndim+1];
120
+
121
+ na_shape_copy( ndim, shp1, a1 );
122
+ na_shape_copy( ndim, shp2, a2 );
123
+ na_shape_copy( ndim, shp3, a3 );
124
+ ndim -= ncd;
125
+ shp1 += ncd1;
126
+ shp2 += ncd2;
127
+ shp3 += ncd3;
128
+ na_shape_max3( ndim, itr, shp1, shp2, shp3 );
129
+
130
+ ndim = na_set_slice_3obj( ndim, s1, s2, s3, shp1, shp2, shp3, itr );
131
+
132
+ nsz1 = na_shape_total(a1->rank-ncd1,a1->shape+ncd1);
133
+ nsz2 = na_shape_total(a2->rank-ncd2,a2->shape+ncd2);
134
+ nsz3 = na_shape_total(a3->rank-ncd3,a3->shape+ncd3);
135
+
136
+ na_init_slice(s1, ndim, shp1, na_sizeof[a1->type]*nsz1 );
137
+ na_init_slice(s2, ndim, shp2, na_sizeof[a2->type]*nsz2 );
138
+ na_init_slice(s3, ndim, shp3, na_sizeof[a3->type]*nsz3 );
139
+
140
+ na_loop_linalg( ndim, a1->ptr, a2->ptr, a3->ptr,
141
+ s1, s2, s3, func, a2->shape, a2->type );
142
+ xfree(s1);
143
+ }
144
+
145
+
146
+ static int
147
+ na_lu_fact_func_body(int ni, char *a, char *idx, int *shape, int type, char *buf)
148
+ {
149
+ int i, j, k;
150
+ int imax;
151
+
152
+ char *amax, *rtmp;
153
+ char *aa, *aii, *aij, *ai0, *a0i, *a0j;
154
+ char *v, *vi;
155
+
156
+ na_funcset_t *f = &na_funcset[type];
157
+ na_funcset_t *r = &na_funcset[na_cast_real[type]];
158
+
159
+ int status = 0;
160
+ int n = shape[0];
161
+ int relmsz = r->elmsz;
162
+ int felmsz = f->elmsz;
163
+ int rowsz = felmsz*n;
164
+ int matsz = rowsz*n;
165
+ int diagsz = rowsz + felmsz;
166
+
167
+ v = buf + rowsz;
168
+ amax = v + relmsz*n;
169
+
170
+ while (ni-->0) {
171
+
172
+ aa = a;
173
+ vi = v;
174
+
175
+ /* v[j] = 1/max( abs( a[i,j] ) ) */
176
+ for (j=0;j<n;j++) {
177
+ f->abs(n, buf, relmsz, aa, felmsz);
178
+
179
+ r->set(1, amax,0, r->zero,0);
180
+ rtmp = buf;
181
+ for (i=0;i<n;i++) {
182
+ if (r->sort(rtmp, amax) == 1)
183
+ r->set(1, amax,0, rtmp,0);
184
+ rtmp += relmsz;
185
+ }
186
+
187
+ if (r->sort(amax,r->tiny) != 1)
188
+ status = 2; /* Singular Matrix */
189
+
190
+ r->rcp(1, vi,0, amax,0);
191
+ vi += relmsz;
192
+ }
193
+
194
+ ai0 = a0i = aii = a;
195
+ vi = v;
196
+
197
+ for (i=0;i<n;i++) {
198
+
199
+ f->set(n, buf, felmsz, ai0, rowsz);
200
+
201
+ aij = buf;
202
+ a0j = a;
203
+ /* a[i,j(<i)] -= sum(k<j){ a[i,k]*a[k,j] } */
204
+ for (j=1;j<i;j++) {
205
+ aij += felmsz;
206
+ a0j += rowsz;
207
+ f->mulsbt(j, aij, 0, buf, felmsz, a0j, felmsz);
208
+ }
209
+ /* a[i,j(>=i)] -= sum(k<i){ a[i,k]*a[k,j] } */
210
+ for ( ;j<n;j++) {
211
+ aij += felmsz;
212
+ a0j += rowsz;
213
+ f->mulsbt(i, aij, 0, buf, felmsz, a0j, felmsz);
214
+ }
215
+ f->set(n, ai0, rowsz, buf, felmsz);
216
+
217
+ /* pivoting
218
+ imax = max_idx( abs( a[i,j(>=i)] ) * v[j(>=i)] ) */
219
+ f->abs(n-i, buf, relmsz, aii, rowsz);
220
+ r->mul(n-i, buf, relmsz, vi, relmsz);
221
+
222
+ r->set(1, amax,0, r->zero,0);
223
+ rtmp = buf;
224
+ imax = 0;
225
+ for (j=i;j<n;j++) {
226
+ if (r->sort(rtmp,amax) == 1) {
227
+ r->set(1, amax,0, rtmp,0);
228
+ imax = j;
229
+ }
230
+ rtmp += relmsz;
231
+ }
232
+
233
+ if (r->sort(amax,r->tiny)!=1)
234
+ status = 1; /* Singular Matrix */
235
+
236
+ if (i != imax) {
237
+ /* a[*,i] <=> a[*,imax] */
238
+ SWAPMEM(a+i*rowsz, a+imax*rowsz, buf, rowsz);
239
+ /* v[i] <=> v[imax] */
240
+ SWAPMEM(vi, v+imax*relmsz, buf, relmsz);
241
+ NA_SWAP(((int32_t*)idx)[i],((int32_t*)idx)[imax],k);
242
+ }
243
+
244
+ /* a[i,j(>i)] = a[i,j]/a[i,i] */
245
+ f->div(n-i-1, aii+rowsz, rowsz, aii, 0);
246
+
247
+ ai0 += felmsz;
248
+ a0i += rowsz;
249
+ aii += diagsz;
250
+ vi += relmsz;
251
+ }
252
+
253
+ a += matsz;
254
+ idx += sizeof(int32_t)*n;
255
+ }
256
+ return status;
257
+ }
258
+
259
+
260
+
261
+ static int
262
+ na_lu_fact_func(int ni, char *a, char *idx, int *shape, int type)
263
+ {
264
+ volatile VALUE val;
265
+ char *buf;
266
+ int status, size, n=shape[0];
267
+
268
+ if (type==NA_ROBJ) {
269
+ size = n*2+1;
270
+ val = rb_ary_new2(size);
271
+ rb_mem_clear(RARRAY(val)->ptr,size);
272
+ RARRAY(val)->len = size;
273
+ buf = (char*)((RARRAY(val))->ptr);
274
+ status = na_lu_fact_func_body( ni, a, idx, shape, type, buf );
275
+ //na_touch_object(val);
276
+ } else {
277
+ size = na_sizeof[type]*n + na_sizeof[na_cast_real[type]]*(n+1);
278
+ buf = ALLOC_N(char, size);
279
+ status = na_lu_fact_func_body( ni, a, idx, shape, type, buf );
280
+ xfree(buf);
281
+ }
282
+ return status;
283
+ }
284
+
285
+
286
+ static VALUE
287
+ na_lu_fact_bang(VALUE self)
288
+ {
289
+ int i, total, n, sz, stat;
290
+ struct NARRAY *ary;
291
+ VALUE piv;
292
+ char *ptr, *idx;
293
+ void (*func)();
294
+
295
+ GetNArray(self,ary);
296
+
297
+ /* shape & dimension check */
298
+ if (ary->rank<2)
299
+ rb_raise(rb_eTypeError,"dim(=%i) < 2", ary->rank);
300
+
301
+ n = ary->shape[0];
302
+ if (n != ary->shape[1])
303
+ rb_raise(rb_eTypeError,"not square matrix");
304
+
305
+ total=1;
306
+ for (i=2; i<ary->rank; i++)
307
+ total *= ary->shape[i];
308
+
309
+ piv = na_make_object(NA_LINT, ary->rank-1, ary->shape+1, cNVector);
310
+
311
+ /* prepare pivot index */
312
+ func = IndGenFuncs[NA_LINT];
313
+ sz = na_sizeof[NA_LINT];
314
+ ptr = idx = ((struct NARRAY *)DATA_PTR(piv))->ptr;
315
+ for (i=0; i<total; i++) {
316
+ func(n,ptr,sz,0,1);
317
+ ptr += n*sz;
318
+ }
319
+
320
+ stat = na_lu_fact_func(total, ary->ptr, idx, ary->shape, ary->type);
321
+
322
+ if (stat!=0)
323
+ rb_raise(rb_eZeroDivError,"singular matrix, status=%i",stat);
324
+
325
+ return rb_funcall(cNMatrixLU,na_id_new,2,self,piv);
326
+ }
327
+
328
+
329
+ static VALUE
330
+ na_lu_fact(VALUE self)
331
+ {
332
+ return na_lu_fact_bang( na_clone(self) );
333
+ }
334
+
335
+
336
+ static void
337
+ na_lu_pivot_func( int ni,
338
+ char *x, int ps1, char *y, int ps2, char *idx, int ps3,
339
+ int *shape, int type )
340
+ {
341
+ int i, n, sz;
342
+ char *xi;
343
+ na_funcset_t *f = &na_funcset[type];
344
+
345
+ n = shape[1];
346
+ sz = f->elmsz * shape[0];
347
+
348
+ for (; ni>0; ni--) {
349
+ xi = x;
350
+ for (i=0; i<n; i++) {
351
+ memcpy(xi, y+((int32_t*)idx)[i]*sz, sz);
352
+ xi += sz;
353
+ }
354
+ x += ps1;
355
+ y += ps2;
356
+ idx += ps3;
357
+ }
358
+ }
359
+
360
+
361
+
362
+ static void
363
+ na_lu_solve_func_body( int ni,
364
+ char *x, int ps1, char *a, int ps2,
365
+ int *shape, int type, char *buf )
366
+ {
367
+ char *aii, *a0i, *xx, *xi;
368
+ int i,k;
369
+ na_funcset_t *f = &na_funcset[type];
370
+ int n = shape[1];
371
+ int sz = na_sizeof[type];
372
+ int xsz = shape[0] * sz;
373
+ int rowsz = sz * n;
374
+ int matsz = rowsz * n;
375
+ int diagsz = rowsz + sz;
376
+
377
+ for (; ni>0; ni--) {
378
+
379
+ xx = x;
380
+
381
+ for (k=shape[0]; k>0; k--) { /* once if x is vector */
382
+
383
+ f->set(n, buf,sz, xx,xsz);
384
+
385
+ xi = buf;
386
+ a0i = a;
387
+
388
+ /* solve Lx' = y' */
389
+ for (i=1; i<n; i++) {
390
+ /* x[i] -= a[j(<i),i] * x[j(<i)] */
391
+ xi += sz;
392
+ a0i += rowsz;
393
+ f->mulsbt(i, xi, 0, a0i, sz, buf, sz);
394
+ }
395
+
396
+ xi = buf + sz*(n-1);
397
+ aii = a + (matsz-sz);
398
+
399
+ /* solve Ux = x' */
400
+ f->div(1, xi,0, aii,0);
401
+ for (i=n-1; i>0; i--) {
402
+ xi -= sz;
403
+ aii -= diagsz;
404
+ /* x[i] -= a[j(>i),i] * x[j(>i)] */
405
+ f->mulsbt(n-i, xi,0, aii+sz, sz, xi+sz, sz);
406
+ /* x[i] /= a[i,i] */
407
+ f->div(1, xi,0, aii,0);
408
+ }
409
+
410
+ f->set(n, xx,xsz, buf,sz);
411
+
412
+ xx += sz;
413
+ }
414
+
415
+ x += ps1;
416
+ a += ps2;
417
+ }
418
+ }
419
+
420
+
421
+ static void
422
+ na_lu_solve_func( int ni,
423
+ char *z, int ps, char *x, int ps1, char *a, int ps2,
424
+ int *shape, int type )
425
+ {
426
+ volatile VALUE val;
427
+ char *buf;
428
+ int size;
429
+
430
+ if (type==NA_ROBJ) {
431
+ size = shape[1];
432
+ val = rb_ary_new2(size);
433
+ rb_mem_clear(RARRAY(val)->ptr,size);
434
+ RARRAY(val)->len = size;
435
+ buf = (char*)((RARRAY(val))->ptr);
436
+ na_lu_solve_func_body( ni, x, ps1, a, ps2, shape, type, buf );
437
+ //na_touch_object(val);
438
+ } else {
439
+ size = shape[1] * na_sizeof[type];
440
+ buf = ALLOC_N(char, size);
441
+ na_lu_solve_func_body( ni, x, ps1, a, ps2, shape, type, buf );
442
+ xfree(buf);
443
+ }
444
+ }
445
+
446
+
447
+ static void
448
+ na_shape_max2(int ndim, int *shape, int n1, int *shape1, int n2, int *shape2)
449
+ {
450
+ int *tmp;
451
+ int i;
452
+
453
+ if (n1 < n2) {
454
+ NA_SWAP(shape1,shape2,tmp);
455
+ }
456
+
457
+ for (i=0; i<n2; i++) {
458
+ shape[i] = NA_MAX(shape1[i],shape2[i]);
459
+ }
460
+ for ( ; i<n1; i++) {
461
+ shape[i] = shape1[i];
462
+ }
463
+ for ( ; i<ndim; i++) {
464
+ shape[i] = 1;
465
+ }
466
+ }
467
+
468
+
469
+ static VALUE
470
+ na_lu_solve(VALUE self, volatile VALUE other)
471
+ {
472
+ int n, ndim;
473
+ int *shape;
474
+ struct NARRAY *a1, *a2, *l, *p;
475
+ VALUE pv, obj, klass;
476
+ volatile VALUE lu;
477
+
478
+ klass = CLASS_OF(other);
479
+ if (klass==cNVector)
480
+ other = na_newdim_ref(1,(VALUE*)na_funcset[NA_ROBJ].zero,other);
481
+ else if (klass!=cNMatrix)
482
+ rb_raise(rb_eTypeError,"neither NMatrix or NVector");
483
+
484
+ lu = rb_ivar_get(self, id_lu);
485
+ pv = rb_ivar_get(self, id_pivot);
486
+
487
+ GetNArray(lu,l);
488
+
489
+ other = na_upcast_object(other,l->type);
490
+ GetNArray(other,a1);
491
+
492
+ lu = na_upcast_type(lu,a1->type);
493
+ GetNArray(lu,l);
494
+ GetNArray(pv,p);
495
+
496
+ n = l->shape[0];
497
+ if (n != a1->shape[1])
498
+ rb_raise(rb_eTypeError,"size mismatch (%i!=%i)",n,a1->shape[1]);
499
+
500
+ ndim = NA_MAX(l->rank, a1->rank);
501
+ shape = ALLOCA_N(int, ndim);
502
+
503
+ shape[0] = a1->shape[0];
504
+ na_shape_max2( ndim-1, shape+1, a1->rank-1, a1->shape+1,
505
+ l->rank-1, l->shape+1 );
506
+ obj = na_make_object( a1->type, ndim, shape, klass );
507
+
508
+ GetNArray(obj,a2);
509
+
510
+ na_exec_linalg( a2, a1, p, 2, 2, 1, na_lu_pivot_func );
511
+ na_exec_linalg( a2, a2, l, 2, 2, 2, na_lu_solve_func );
512
+
513
+ if (klass==cNVector) {
514
+ shape = ALLOC_N(int, ndim-1);
515
+ memcpy(shape,a2->shape+1,sizeof(int)*(ndim-1));
516
+ xfree(a2->shape);
517
+ a2->shape = shape;
518
+ a2->rank--;
519
+ }
520
+ //na_touch_object(other,lu);
521
+ return obj;
522
+ }
523
+
524
+
525
+ static VALUE
526
+ na_lu_init(VALUE self, VALUE lu, VALUE piv)
527
+ {
528
+ int i;
529
+ struct NARRAY *l, *p;
530
+
531
+ if (CLASS_OF(lu)!=cNMatrix)
532
+ rb_raise(rb_eTypeError,"LU should be NMatrix");
533
+ if (CLASS_OF(piv)!=cNVector)
534
+ rb_raise(rb_eTypeError,"pivot should be NVector");
535
+
536
+ GetNArray(lu,l);
537
+ GetNArray(piv,p);
538
+
539
+ if (p->type != NA_LINT)
540
+ rb_raise(rb_eRuntimeError,"pivot type must be Integer");
541
+
542
+ if (l->rank != p->rank+1)
543
+ rb_raise(rb_eRuntimeError,"array dimension mismatch %i!=%i+1",
544
+ l->rank, p->rank);
545
+
546
+ if (l->shape[0] != l->shape[1])
547
+ rb_raise(rb_eRuntimeError,"LU matrix (%i,%i) is not square",
548
+ l->shape[0], l->shape[1]);
549
+
550
+ for (i=1; i<l->rank; i++)
551
+ if (l->shape[i] != p->shape[i-1])
552
+ rb_raise(rb_eRuntimeError,"array size mismatch %i!=%i at %i",
553
+ l->shape[i], p->shape[i-1], i);
554
+
555
+ rb_ivar_set(self, id_lu, lu);
556
+ rb_ivar_set(self, id_pivot, piv);
557
+ return Qnil;
558
+ }
559
+
560
+
561
+
562
+ void Init_na_linalg()
563
+ {
564
+ static double tiny_d=1e-15;
565
+ static float tiny_f=1e-7;
566
+ int i, sz;
567
+ int32_t one=1, zero=0;
568
+ static VALUE zerov = INT2FIX(0);
569
+ static VALUE onev = INT2FIX(1);
570
+ char *a = malloc(NA_NTYPES*sizeof(dcomplex)*2);
571
+
572
+ for (i=1;i<NA_NTYPES;i++) {
573
+ sz = na_funcset[i].elmsz = na_sizeof[i];
574
+ sz = (sz>sizeof(int)) ? sz : sizeof(int);
575
+ SetFuncs[i][NA_LINT](1, a,0, &one, 0);
576
+ na_funcset[i].one = a;
577
+ a += sz;
578
+ SetFuncs[i][NA_LINT](1, a,0, &zero,0);
579
+ na_funcset[i].zero = a;
580
+ na_funcset[i].tiny = a;
581
+ a += sz;
582
+ na_funcset[i].set = SetFuncs[i][i];
583
+ na_funcset[i].neg = NegFuncs[i];
584
+ na_funcset[i].rcp = RcpFuncs[i];
585
+ na_funcset[i].abs = AbsFuncs[i];
586
+ na_funcset[i].add = AddUFuncs[i];
587
+ na_funcset[i].sbt = SbtUFuncs[i];
588
+ na_funcset[i].mul = MulUFuncs[i];
589
+ na_funcset[i].div = DivUFuncs[i];
590
+ na_funcset[i].muladd = MulAddFuncs[i];
591
+ na_funcset[i].mulsbt = MulSbtFuncs[i];
592
+ na_funcset[i].cmp = CmpFuncs[i];
593
+ na_funcset[i].min = MinFuncs[i];
594
+ na_funcset[i].max = MaxFuncs[i];
595
+ na_funcset[i].sort = SortFuncs[i];
596
+ }
597
+ na_funcset[NA_SFLOAT].tiny = (char*)&tiny_f;
598
+ na_funcset[NA_DFLOAT].tiny = (char*)&tiny_d;
599
+ na_funcset[NA_ROBJ].zero = (char*)&zerov;
600
+ na_funcset[NA_ROBJ].one = (char*)&onev;
601
+
602
+ cNVector = rb_define_class("NVector",cNArray);
603
+ cNMatrix = rb_define_class("NMatrix",cNArray);
604
+ cNMatrixLU = rb_define_class("NMatrixLU",rb_cObject);
605
+
606
+ rb_define_method(cNMatrix, "lu_fact!", na_lu_fact_bang, 0);
607
+ rb_define_alias(cNMatrix, "lu!","lu_fact!");
608
+ rb_define_method(cNMatrix, "lu_fact", na_lu_fact, 0);
609
+ rb_define_alias(cNMatrix, "lu","lu_fact");
610
+
611
+ rb_define_method(cNMatrixLU, "initialize", na_lu_init, 2);
612
+ rb_define_method(cNMatrixLU, "solve", na_lu_solve, 1);
613
+
614
+ id_lu = rb_intern("@lu");
615
+ id_pivot = rb_intern("@pivot");
616
+ }