narray-nmatrix 0.6.1.0.pre

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