narray 0.5.9.4

Sign up to get free protection for your applications and to get access to all the features.
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
+ }