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/mkop.rb ADDED
@@ -0,0 +1,638 @@
1
+ require "mknafunc"
2
+
3
+ fname = "na_op.c"
4
+ $> = open(fname,"w")
5
+
6
+ upcast_ary = $upcast.collect{|i| ' {'+i.join(", ")+'}'}.join(",\n")
7
+
8
+ print <<EOM
9
+ /*
10
+ #{fname}
11
+ Automatically generated code
12
+ Numerical Array Extention for Ruby
13
+ (C) Copyright 1999-2003 by Masahiro TANAKA
14
+
15
+ This program is free software.
16
+ You can distribute/modify this program
17
+ under the same terms as Ruby itself.
18
+ NO WARRANTY.
19
+ */
20
+ #include <ruby.h>
21
+ #include "narray.h"
22
+ #include "narray_local.h"
23
+ /* isalpha(3) etc. */
24
+ #include <ctype.h>
25
+
26
+ const int na_upcast[NA_NTYPES][NA_NTYPES] = {
27
+ #{upcast_ary} };
28
+
29
+ const int na_no_cast[NA_NTYPES] =
30
+ { 0, 1, 2, 3, 4, 5, 6, 7, 8 };
31
+ const int na_cast_real[NA_NTYPES] =
32
+ { 0, 1, 2, 3, 4, 5, 4, 5, 8 };
33
+ const int na_cast_comp[NA_NTYPES] =
34
+ { 0, 6, 6, 6, 6, 7, 6, 7, 8 };
35
+ const int na_cast_round[NA_NTYPES] =
36
+ { 0, 1, 2, 3, 3, 3, 6, 7, 8 };
37
+ const int na_cast_byte[NA_NTYPES] =
38
+ { 0, 1, 1, 1, 1, 1, 1, 1, 1 };
39
+
40
+
41
+ static void TpErr(void) {
42
+ rb_raise(rb_eTypeError,"illegal operation with this type");
43
+ }
44
+ static int TpErrI(void) {
45
+ rb_raise(rb_eTypeError,"illegal operation with this type");
46
+ return 0;
47
+ }
48
+ static void na_zerodiv() {
49
+ rb_raise(rb_eZeroDivError, "divided by 0");
50
+ }
51
+
52
+ static int notnanF(float *n)
53
+ {
54
+ return *n == *n;
55
+ }
56
+ static int notnanD(double *n)
57
+ {
58
+ return *n == *n;
59
+ }
60
+ EOM
61
+
62
+
63
+ #
64
+ # Set Fucs
65
+ #
66
+ data = [
67
+ [/[O]/,/[O]/, "*p1 = *p2;"],
68
+ [/[O]/,/[BI]/, "*p1 = INT2FIX(*p2);"],
69
+ [/[O]/,/[L]/, "*p1 = INT2NUM(*p2);"],
70
+ [/[O]/,/[FD]/, "*p1 = rb_float_new(*p2);"],
71
+ [/[O]/,/[XC]/, "*p1 = rb_complex_new(p2->r,p2->i);"],
72
+ [/[BIL]/,/[O]/, "*p1 = NUM2INT(*p2);"],
73
+ [/[FD]/,/[O]/, "*p1 = NUM2DBL(*p2);"],
74
+ [/[XC]/,/[O]/, "p1->r = NUM2REAL(*p2); p1->i = NUM2IMAG(*p2);"],
75
+ [/[BILFD]/,/[BILFD]/,"*p1 = *p2;"],
76
+ [/[BILFD]/,/[XC]/, "*p1 = p2->r;"],
77
+ [/[XC]/,/[BILFD]/, "p1->r = *p2; p1->i = 0;"],
78
+ [/[XC]/,/[XC]/, "p1->r = p2->r; p1->i = p2->i;"] ]
79
+
80
+ $func_body =
81
+ "static void #name#CC(int n, char *p1, int i1, char *p2, int i2)
82
+ {
83
+ for (; n; n--) {
84
+ OPERATION
85
+ p1+=i1; p2+=i2;
86
+ }
87
+ }
88
+ "
89
+ mksetfuncs('Set','','',data)
90
+
91
+
92
+
93
+ #
94
+ # Unary Funcs
95
+ #
96
+ $func_body =
97
+ "static void #name#C(int n, char *p1, int i1, char *p2, int i2)
98
+ {
99
+ for (; n; n--) {
100
+ OPERATION
101
+ p1+=i1; p2+=i2;
102
+ }
103
+ }
104
+ "
105
+
106
+
107
+ mkfuncs('Swp', $swap_types, $swap_types,
108
+ [nil] +
109
+ ["*p1 = *p2;"] +
110
+ ["na_size16_t x; swap16(x,*p2); *p1 = x;"] +
111
+ ["na_size32_t x; swap32(x,*p2); *p1 = x;"] +
112
+ ["na_size32_t x; swap32(x,*p2); *p1 = x;"] +
113
+ ["na_size64_t x; swap64(x,*p2); *p1 = x;"] +
114
+ ["na_size64_t x; swap64c(x,*p2); *p1 = x;"] +
115
+ ["na_size128_t x; swap128c(x,*p2); *p1 = x;"] +
116
+ ["*p1 = *p2;"]
117
+ )
118
+
119
+ print <<EOM
120
+
121
+ /* ------------------------- H2N --------------------------- */
122
+ #ifdef WORDS_BIGENDIAN
123
+
124
+ na_func_t H2NFuncs =
125
+ { TpErr, SetBB, SetII, SetLL, SetFF, SetDD, SetXX, SetCC, SetOO };
126
+
127
+ na_func_t H2VFuncs =
128
+ { TpErr, SetBB, SwpI, SwpL, SwpF, SwpD, SwpX, SwpC, SetOO };
129
+
130
+ #else
131
+ #ifdef DYNAMIC_ENDIAN /* not supported yet */
132
+ #else /* LITTLE ENDIAN */
133
+
134
+ na_func_t H2NFuncs =
135
+ { TpErr, SetBB, SwpI, SwpL, SwpF, SwpD, SwpX, SwpC, SetOO };
136
+
137
+ na_func_t H2VFuncs =
138
+ { TpErr, SetBB, SetII, SetLL, SetFF, SetDD, SetXX, SetCC, SetOO };
139
+
140
+ #endif
141
+ #endif
142
+ EOM
143
+
144
+ mkfuncs('Neg', $data_types, $data_types,
145
+ [nil] +
146
+ ["*p1 = -*p2;"]*5 +
147
+ ["p1->r = -p2->r;
148
+ p1->i = -p2->i;"]*2 +
149
+ ["*p1 = rb_funcall(*p2,na_id_minus,0);"]
150
+ )
151
+
152
+ mkfuncs('AddU', $data_types, $data_types,
153
+ [nil] +
154
+ ["*p1 += *p2;"]*5 +
155
+ ["p1->r += p2->r;
156
+ p1->i += p2->i;"]*2 +
157
+ ["*p1 = rb_funcall(*p1,'+',1,*p2);"]
158
+ )
159
+
160
+ mkfuncs('SbtU', $data_types, $data_types,
161
+ [nil] +
162
+ ["*p1 -= *p2;"]*5 +
163
+ ["p1->r -= p2->r;
164
+ p1->i -= p2->i;"]*2 +
165
+ ["*p1 = rb_funcall(*p1,'-',1,*p2);"]
166
+ )
167
+
168
+ mkfuncs('MulU', $data_types, $data_types,
169
+ [nil] +
170
+ ["*p1 *= *p2;"]*5 +
171
+ ["type1 x = *p1;
172
+ p1->r = x.r*p2->r - x.i*p2->i;
173
+ p1->i = x.r*p2->i + x.i*p2->r;"]*2 +
174
+ ["*p1 = rb_funcall(*p1,'*',1,*p2);"]
175
+ )
176
+
177
+ mkfuncs('DivU', $data_types, $data_types,
178
+ [nil] +
179
+ ["if (*p2==0) {na_zerodiv();}
180
+ *p1 /= *p2;"]*3 +
181
+ ["*p1 /= *p2;"]*2 +
182
+ ["type1 x = *p1;
183
+ typef a = p2->r*p2->r + p2->i*p2->i;
184
+ p1->r = (x.r*p2->r + x.i*p2->i)/a;
185
+ p1->i = (x.i*p2->r - x.r*p2->i)/a;"]*2 +
186
+ ["*p1 = rb_funcall(*p1,'/',1,*p2);"]
187
+ )
188
+
189
+
190
+ # method: imag=
191
+ mkfuncs('ImgSet',$data_types,$real_types,
192
+ [nil]*6 +
193
+ ["p1->i = *p2;"]*2 +
194
+ [nil]
195
+ )
196
+
197
+
198
+ mkfuncs('Floor',$int_types,$data_types,[nil] +
199
+ ['copy']*3 +
200
+ ["*p1 = floor(*p2);"]*2 +
201
+ [nil]*3
202
+ )
203
+
204
+ mkfuncs('Ceil',$int_types,$data_types,[nil] +
205
+ ['copy']*3 +
206
+ ["*p1 = ceil(*p2);"]*2 +
207
+ [nil]*3
208
+ )
209
+
210
+ mkfuncs('Round',$int_types,$data_types,[nil] +
211
+ ['copy']*3 +
212
+ # ["*p1 = floor(*p2+0.5);"]*2 +
213
+ ["if (*p2 >= 0) *p1 = floor(*p2+0.5);
214
+ else *p1 = ceil(*p2-0.5);"]*2 +
215
+ [nil]*3
216
+ )
217
+
218
+ mkfuncs('Abs',$real_types,$data_types,[nil] +
219
+ ["*p1 = *p2;"] +
220
+ ["*p1 = (*p2<0) ? -*p2 : *p2;"]*4 +
221
+ ["*p1 = hypot(p2->r, p2->i);"]*2 +
222
+ ["*p1 = rb_funcall(*p2,na_id_abs,0);"]
223
+ )
224
+
225
+
226
+ mkfuncs('Real',$real_types,$data_types,[nil] +
227
+ ['copy']*7 +
228
+ [nil]
229
+ )
230
+
231
+ mkfuncs('Imag',$real_types,$data_types,[nil] +
232
+ ["*p1 = 0;"]*5 +
233
+ ["*p1 = p2->i;"]*2 +
234
+ [nil]
235
+ )
236
+
237
+ mkfuncs('Angl',$real_types,$data_types,[nil] +
238
+ [nil]*5 +
239
+ ["*p1 = atan2(p2->i,p2->r);"]*2 +
240
+ [nil]
241
+ )
242
+
243
+ mkfuncs('ImagMul',$comp_types,$data_types,[nil] +
244
+ [nil]*3 +
245
+ ["p1->r = 0; p1->i = *p2;"]*2 +
246
+ ["p1->r = -p2->i; p1->i = p2->r;"]*2 +
247
+ [nil]
248
+ )
249
+
250
+ mkfuncs('Conj',$data_types,$data_types,[nil] +
251
+ ['copy']*5 +
252
+ ["p1->r = p2->r; p1->i = -p2->i;"]*2 +
253
+ [nil]
254
+ )
255
+
256
+ mkfuncs('Not', [$data_types[1]]*9, $data_types,
257
+ [nil] +
258
+ ["*p1 = (*p2==0) ? 1:0;"]*5 +
259
+ ["*p1 = (p2->r==0 && p2->i==0) ? 1:0;"]*2 +
260
+ ["*p1 = RTEST(*p2) ? 0:1;"]
261
+ )
262
+
263
+ mkfuncs('BRv', $data_types, $data_types, [nil] +
264
+ ["*p1 = ~(*p2);"]*3 +
265
+ [nil]*4 +
266
+ ["*p1 = rb_funcall(*p2,'~',0);"]
267
+ )
268
+
269
+ mkfuncs('Min', $data_types, $data_types, [nil] +
270
+ ["if (*p1>*p2) *p1=*p2;"]*3 +
271
+ ["if (notnan#C((type1*)p2) && *p1>*p2) *p1=*p2;"]*2 +
272
+ [nil]*2 +
273
+ ["if (FIX2INT(rb_funcall(*p1,na_id_compare,1,*p2))>0) *p1=*p2;"]
274
+ )
275
+
276
+ mkfuncs('Max', $data_types, $data_types, [nil] +
277
+ ["if (*p1<*p2) *p1=*p2;"]*3 +
278
+ ["if (notnan#C((type1*)p2) && *p1<*p2) *p1=*p2;"]*2 +
279
+ [nil]*2 +
280
+ ["if (FIX2INT(rb_funcall(*p1,na_id_compare,1,*p2))<0) *p1=*p2;"]
281
+ )
282
+
283
+
284
+ mksortfuncs('Sort', $data_types, $data_types, [nil] +
285
+ ["
286
+ { if (*p1 > *p2) return 1;
287
+ if (*p1 < *p2) return -1;
288
+ return 0; }"]*5 +
289
+ [nil]*2 +
290
+ ["
291
+ { VALUE r = rb_funcall(*p1, na_id_compare, 1, *p2);
292
+ return NUM2INT(r); }"]
293
+ )
294
+
295
+ mksortfuncs('SortIdx', $data_types, $data_types, [nil] +
296
+ ["
297
+ { if (**p1 > **p2) return 1;
298
+ if (**p1 < **p2) return -1;
299
+ return 0; }"]*5 +
300
+ [nil]*2 +
301
+ ["
302
+ { VALUE r = rb_funcall(**p1, na_id_compare, 1, **p2);
303
+ return NUM2INT(r); }"]
304
+ )
305
+
306
+ # indgen
307
+ $func_body =
308
+ "static void #name#C(int n, char *p1, int i1, int p2, int i2)
309
+ {
310
+ for (; n; n--) {
311
+ OPERATION
312
+ p1+=i1; p2+=i2;
313
+ }
314
+ }
315
+ "
316
+ mkfuncs('IndGen',$data_types,[$data_types[3]]*8,
317
+ [nil] +
318
+ ["*p1 = p2;"]*5 +
319
+ ["p1->r = p2;
320
+ p1->i = 0;"]*2 +
321
+ ["*p1 = INT2FIX(p2);"]
322
+ )
323
+
324
+
325
+
326
+ $func_body =
327
+ "static void #name#C(int n, char *p1, int i1, char *p2, int i2)
328
+ {
329
+ OPERATION
330
+ }
331
+ "
332
+ mkfuncs('ToStr',['']+[$data_types[8]]*8,$data_types,
333
+ [nil] +
334
+ ["char buf[22];
335
+ for (; n; n--) {
336
+ sprintf(buf,\"%i\",(int)*p2);
337
+ *p1 = rb_str_new2(buf);
338
+ p1+=i1; p2+=i2;
339
+ }"]*3 +
340
+ ["char buf[24];
341
+ for (; n; n--) {
342
+ sprintf(buf,\"%.5g\",(double)*p2);
343
+ *p1 = rb_str_new2(buf);
344
+ p1+=i1; p2+=i2;
345
+ }"] +
346
+ ["char buf[24];
347
+ for (; n; n--) {
348
+ sprintf(buf,\"%.8g\",(double)*p2);
349
+ *p1 = rb_str_new2(buf);
350
+ p1+=i1; p2+=i2;
351
+ }"] +
352
+ ["char buf[50];
353
+ for (; n; n--) {
354
+ sprintf(buf,\"%.5g%+.5gi\",(double)p2->r,(double)p2->i);
355
+ *p1 = rb_str_new2(buf);
356
+ p1+=i1; p2+=i2;
357
+ }"] +
358
+ ["char buf[50];
359
+ for (; n; n--) {
360
+ sprintf(buf,\"%.8g%+.8gi\",(double)p2->r,(double)p2->i);
361
+ *p1 = rb_str_new2(buf);
362
+ p1+=i1; p2+=i2;
363
+ }"] +
364
+ ["for (; n; n--) {
365
+ *p1 = rb_obj_as_string(*p2);
366
+ p1+=i1; p2+=i2;
367
+ }"]
368
+ )
369
+
370
+
371
+ print <<EOM
372
+
373
+ /* from numeric.c */
374
+ static void na_str_append_fp(char *buf)
375
+ {
376
+ if (buf[0]=='-' || buf[0]=='+') buf++;
377
+ if (ISALPHA(buf[0])) return; /* NaN or Inf */
378
+ if (strchr(buf, '.') == 0) {
379
+ int len = strlen(buf);
380
+ char *ind = strchr(buf, 'e');
381
+ if (ind) {
382
+ memmove(ind+2, ind, len-(ind-buf)+1);
383
+ ind[0] = '.';
384
+ ind[1] = '0';
385
+ } else {
386
+ strcat(buf, ".0");
387
+ }
388
+ }
389
+ }
390
+ EOM
391
+
392
+ $func_body =
393
+ "static void #name#C(char *p1, char *p2)
394
+ {
395
+ OPERATION
396
+ }
397
+ "
398
+ mkfuncs('Insp',['']+[$data_types[8]]*8,$data_types,
399
+ [nil] +
400
+ ["char buf[22];
401
+ sprintf(buf,\"%i\",(int)*p2);
402
+ *p1 = rb_str_new2(buf);"]*3 +
403
+ ["char buf[24];
404
+ sprintf(buf,\"%g\",(double)*p2);
405
+ na_str_append_fp(buf);
406
+ *p1 = rb_str_new2(buf);"] +
407
+ ["char buf[24];
408
+ sprintf(buf,\"%g\",(double)*p2);
409
+ na_str_append_fp(buf);
410
+ *p1 = rb_str_new2(buf);"] +
411
+ ["char buf[50], *b;
412
+ sprintf(buf,\"%g\",(double)p2->r);
413
+ na_str_append_fp(buf);
414
+ b = buf+strlen(buf);
415
+ sprintf(b,\"%+g\",(double)p2->i);
416
+ na_str_append_fp(b);
417
+ strcat(buf,\"i\");
418
+ *p1 = rb_str_new2(buf);"] +
419
+ ["char buf[50], *b;
420
+ sprintf(buf,\"%g\",(double)p2->r);
421
+ na_str_append_fp(buf);
422
+ b = buf+strlen(buf);
423
+ sprintf(b,\"%+g\",(double)p2->i);
424
+ na_str_append_fp(b);
425
+ strcat(buf,\"i\");
426
+ *p1 = rb_str_new2(buf);"] +
427
+ ["*p1 = rb_inspect(*p2);"]
428
+ )
429
+
430
+
431
+
432
+ #
433
+ # Binary Funcs
434
+ #
435
+
436
+ =begin
437
+ # Optimize experiment
438
+ $func_body =
439
+ "static void #name#C(int n, char *p1, int i1, char *p2, int i2, char *p3, int i3)
440
+ {
441
+ int i;
442
+ if (i1==sizeof(type1) && i2==sizeof(type1) && i3==sizeof(type1)) {
443
+ type1 *a1=p1, *a2=p2, *a3=p3;
444
+ for (i=0; n; n--,i++) {
445
+ *a1 = *a2 * *a3; a1++;a2++;a3++;
446
+ }
447
+ } else
448
+ for (; n; n--) {
449
+ OPERATION
450
+ p1+=i1; p2+=i2; p3+=i3;
451
+ }
452
+ }
453
+ "
454
+ mkfuncs('MulB', $data_types, $data_types,
455
+ [nil] +
456
+ ["*p1 = *p2 * *p3;"]*5 + [nil]*3
457
+ )
458
+ =end
459
+
460
+ $func_body =
461
+ "static void #name#C(int n, char *p1, int i1, char *p2, int i2, char *p3, int i3)
462
+ {
463
+ for (; n; n--) {
464
+ OPERATION
465
+ p1+=i1; p2+=i2; p3+=i3;
466
+ }
467
+ }
468
+ "
469
+
470
+ mkfuncs('AddB', $data_types, $data_types,
471
+ [nil] +
472
+ ["*p1 = *p2 + *p3;"]*5 +
473
+ ["p1->r = p2->r + p3->r;
474
+ p1->i = p2->i + p3->i;"]*2 +
475
+ ["*p1 = rb_funcall(*p2,'+',1,*p3);"]
476
+ )
477
+
478
+ mkfuncs('SbtB', $data_types, $data_types,
479
+ [nil] +
480
+ ["*p1 = *p2 - *p3;"]*5 +
481
+ ["p1->r = p2->r - p3->r;
482
+ p1->i = p2->i - p3->i;"]*2 +
483
+ ["*p1 = rb_funcall(*p2,'-',1,*p3);"]
484
+ )
485
+
486
+ mkfuncs('MulB', $data_types, $data_types,
487
+ [nil] +
488
+ ["*p1 = *p2 * *p3;"]*5 +
489
+ ["type1 x = *p2;
490
+ p1->r = x.r*p3->r - x.i*p3->i;
491
+ p1->i = x.r*p3->i + x.i*p3->r;"]*2 +
492
+ ["*p1 = rb_funcall(*p2,'*',1,*p3);"]
493
+ )
494
+
495
+ mkfuncs('DivB', $data_types, $data_types,
496
+ [nil] +
497
+ ["if (*p3==0) {na_zerodiv();};
498
+ *p1 = *p2 / *p3;"]*3 +
499
+ ["*p1 = *p2 / *p3;"]*2 +
500
+ ["type1 x = *p2;
501
+ typef a = p3->r*p3->r + p3->i*p3->i;
502
+ p1->r = (x.r*p3->r + x.i*p3->i)/a;
503
+ p1->i = (x.i*p3->r - x.r*p3->i)/a;"]*2 +
504
+ ["*p1 = rb_funcall(*p2,'/',1,*p3);"]
505
+ )
506
+
507
+ mkfuncs('ModB', $data_types, $data_types,
508
+ [nil] +
509
+ ["*p1 = *p2 % *p3;"]*3 +
510
+ ["*p1 = fmod(*p2, *p3);"]*2 +
511
+ [nil]*2 +
512
+ ["*p1 = rb_funcall(*p2,'%',1,*p3);"]
513
+ )
514
+
515
+
516
+ mkfuncs('MulAdd', $data_types, $data_types,
517
+ [nil] +
518
+ ["*p1 += *p2 * *p3;"]*5 +
519
+ ["type1 x = *p2;
520
+ p1->r += x.r*p3->r - x.i*p3->i;
521
+ p1->i += x.r*p3->i + x.i*p3->r;"]*2 +
522
+ ["*p1 = rb_funcall(*p1,'+',1,
523
+ rb_funcall(*p2,'*',1,*p3));"]
524
+ )
525
+
526
+ mkfuncs('MulSbt', $data_types, $data_types,
527
+ [nil] +
528
+ ["*p1 -= *p2 * *p3;"]*5 +
529
+ ["type1 x = *p2;
530
+ p1->r -= x.r*p3->r - x.i*p3->i;
531
+ p1->i -= x.r*p3->i + x.i*p3->r;"]*2 +
532
+ ["*p1 = rb_funcall(*p1,'-',1,
533
+ rb_funcall(*p2,'*',1,*p3));"]
534
+ )
535
+
536
+
537
+ #
538
+ # Bit operator
539
+ #
540
+
541
+ mkfuncs('BAn', $data_types, $data_types,
542
+ [nil] +
543
+ ["*p1 = *p2 & *p3;"]*3 +
544
+ [nil]*4 +
545
+ ["*p1 = rb_funcall(*p2,'&',1,*p3);"]
546
+ )
547
+
548
+ mkfuncs('BOr', $data_types, $data_types,
549
+ [nil] +
550
+ ["*p1 = *p2 | *p3;"]*3 +
551
+ [nil]*4 +
552
+ ["*p1 = rb_funcall(*p2,'|',1,*p3);"]
553
+ )
554
+
555
+ mkfuncs('BXo', $data_types, $data_types,
556
+ [nil] +
557
+ ["*p1 = *p2 ^ *p3;"]*3 +
558
+ [nil]*4 +
559
+ ["*p1 = rb_funcall(*p2,'^',1,*p3);"]
560
+ )
561
+
562
+
563
+ #
564
+ # Comparison
565
+ #
566
+
567
+ mkfuncs('Eql', [$data_types[1]]*9, $data_types,
568
+ [nil] +
569
+ ["*p1 = (*p2==*p3) ? 1:0;"]*5 +
570
+ ["*p1 = (p2->r==p3->r) && (p2->i==p3->i) ? 1:0;"]*2 +
571
+ ["*p1 = RTEST(rb_equal(*p2, *p3)) ? 1:0;"]
572
+ )
573
+
574
+ mkfuncs('Cmp', [$data_types[1]]*9, $data_types,
575
+ [nil] +
576
+ ["if (*p2>*p3) *p1=1;
577
+ else if (*p2<*p3) *p1=2;
578
+ else *p1=0;"]*5 +
579
+ [nil]*2 +
580
+ ["int v = NUM2INT(rb_funcall(*p2,na_id_compare,1,*p3));
581
+ if (v>0) *p1=1; else if (v<0) *p1=2; else *p1=0;"]
582
+ )
583
+
584
+ mkfuncs('And', [$data_types[1]]*9, $data_types,
585
+ [nil] +
586
+ ["*p1 = (*p2!=0 && *p3!=0) ? 1:0;"]*5 +
587
+ ["*p1 = ((p2->r!=0||p2->i!=0) && (p3->r!=0||p3->i!=0)) ? 1:0;"]*2 +
588
+ ["*p1 = (RTEST(*p2) && RTEST(*p3)) ? 1:0;"]
589
+ )
590
+
591
+ mkfuncs('Or_', [$data_types[1]]*9, $data_types,
592
+ [nil] +
593
+ ["*p1 = (*p2!=0 || *p3!=0) ? 1:0;"]*5 +
594
+ ["*p1 = ((p2->r!=0||p2->i!=0) || (p3->r!=0||p3->i!=0)) ? 1:0;"]*2 +
595
+ ["*p1 = (RTEST(*p2) || RTEST(*p3)) ? 1:0;"]
596
+ )
597
+
598
+ mkfuncs('Xor', [$data_types[1]]*9, $data_types,
599
+ [nil] +
600
+ ["*p1 = ((*p2!=0) == (*p3!=0)) ? 0:1;"]*5 +
601
+ ["*p1 = ((p2->r!=0||p2->i!=0) == (p3->r!=0||p3->i!=0)) ? 0:1;"]*2 +
602
+ ["*p1 = (RTEST(*p2) == RTEST(*p3)) ? 0:1;"]
603
+ )
604
+
605
+
606
+ #
607
+ # Atan2
608
+ #
609
+
610
+ mkfuncs('atan2', $data_types, $data_types,
611
+ [nil]*4 +
612
+ ["*p1 = atan2(*p2, *p3);"]*2 +
613
+ [nil]*3
614
+ )
615
+
616
+
617
+ #
618
+ # Mask
619
+ #
620
+ $func_body =
621
+ "static void #name#C(int n, char *p1, int i1, char *p2, int i2, char *p3, int i3)
622
+ {
623
+ for (; n; n--) {
624
+ OPERATION
625
+ }
626
+ }
627
+ "
628
+ mkfuncs('RefMask',$data_types,$data_types,
629
+ [nil] +
630
+ ["if (*(u_int8_t*)p3) { *p1=*p2; p1+=i1; }
631
+ p3+=i3; p2+=i2;"]*8
632
+ )
633
+
634
+ mkfuncs('SetMask',$data_types,$data_types,
635
+ [nil] +
636
+ ["if (*(u_int8_t*)p3) { *p1=*p2; p2+=i2; }
637
+ p3+=i3; p1+=i1;"]*8
638
+ )