diff options
author | Alberto Ruiz <aruiz@um.es> | 2015-06-04 12:39:33 +0200 |
---|---|---|
committer | Alberto Ruiz <aruiz@um.es> | 2015-06-04 12:39:33 +0200 |
commit | b7e57952112eae61054fc9171ddb311fbaca0841 (patch) | |
tree | ef72da1ad7d661a3bc0a2f72fd65a2074ccf1a73 /packages/base/src/Internal/C/vector-aux.c | |
parent | 27334e233edd3d891d2837330289a26e54d05fd1 (diff) |
move c sources
Diffstat (limited to 'packages/base/src/Internal/C/vector-aux.c')
-rw-r--r-- | packages/base/src/Internal/C/vector-aux.c | 1134 |
1 files changed, 1134 insertions, 0 deletions
diff --git a/packages/base/src/Internal/C/vector-aux.c b/packages/base/src/Internal/C/vector-aux.c new file mode 100644 index 0000000..5662697 --- /dev/null +++ b/packages/base/src/Internal/C/vector-aux.c | |||
@@ -0,0 +1,1134 @@ | |||
1 | #include <complex.h> | ||
2 | |||
3 | typedef double complex TCD; | ||
4 | typedef float complex TCF; | ||
5 | |||
6 | #undef complex | ||
7 | |||
8 | #include "lapack-aux.h" | ||
9 | |||
10 | #define V(x) x##n,x##p | ||
11 | |||
12 | #include <string.h> | ||
13 | #include <math.h> | ||
14 | #include <stdio.h> | ||
15 | #include <stdlib.h> | ||
16 | #include <stdint.h> | ||
17 | |||
18 | #define MACRO(B) do {B} while (0) | ||
19 | #define ERROR(CODE) MACRO(return CODE;) | ||
20 | #define REQUIRES(COND, CODE) MACRO(if(!(COND)) {ERROR(CODE);}) | ||
21 | #define OK return 0; | ||
22 | |||
23 | #define MIN(A,B) ((A)<(B)?(A):(B)) | ||
24 | #define MAX(A,B) ((A)>(B)?(A):(B)) | ||
25 | |||
26 | #ifdef DBG | ||
27 | #define DEBUGMSG(M) printf("*** calling aux C function: %s\n",M); | ||
28 | #else | ||
29 | #define DEBUGMSG(M) | ||
30 | #endif | ||
31 | |||
32 | #define CHECK(RES,CODE) MACRO(if(RES) return CODE;) | ||
33 | |||
34 | #define BAD_SIZE 2000 | ||
35 | #define BAD_CODE 2001 | ||
36 | #define MEM 2002 | ||
37 | #define BAD_FILE 2003 | ||
38 | |||
39 | |||
40 | int sumF(KFVEC(x),FVEC(r)) { | ||
41 | DEBUGMSG("sumF"); | ||
42 | REQUIRES(rn==1,BAD_SIZE); | ||
43 | int i; | ||
44 | float res = 0; | ||
45 | for (i = 0; i < xn; i++) res += xp[i]; | ||
46 | rp[0] = res; | ||
47 | OK | ||
48 | } | ||
49 | |||
50 | int sumR(KDVEC(x),DVEC(r)) { | ||
51 | DEBUGMSG("sumR"); | ||
52 | REQUIRES(rn==1,BAD_SIZE); | ||
53 | int i; | ||
54 | double res = 0; | ||
55 | for (i = 0; i < xn; i++) res += xp[i]; | ||
56 | rp[0] = res; | ||
57 | OK | ||
58 | } | ||
59 | |||
60 | int sumI(KIVEC(x),IVEC(r)) { | ||
61 | REQUIRES(rn==1,BAD_SIZE); | ||
62 | int i; | ||
63 | int res = 0; | ||
64 | for (i = 0; i < xn; i++) res += xp[i]; | ||
65 | rp[0] = res; | ||
66 | OK | ||
67 | } | ||
68 | |||
69 | |||
70 | int sumQ(KQVEC(x),QVEC(r)) { | ||
71 | DEBUGMSG("sumQ"); | ||
72 | REQUIRES(rn==1,BAD_SIZE); | ||
73 | int i; | ||
74 | complex res; | ||
75 | res.r = 0; | ||
76 | res.i = 0; | ||
77 | for (i = 0; i < xn; i++) { | ||
78 | res.r += xp[i].r; | ||
79 | res.i += xp[i].i; | ||
80 | } | ||
81 | rp[0] = res; | ||
82 | OK | ||
83 | } | ||
84 | |||
85 | int sumC(KCVEC(x),CVEC(r)) { | ||
86 | DEBUGMSG("sumC"); | ||
87 | REQUIRES(rn==1,BAD_SIZE); | ||
88 | int i; | ||
89 | doublecomplex res; | ||
90 | res.r = 0; | ||
91 | res.i = 0; | ||
92 | for (i = 0; i < xn; i++) { | ||
93 | res.r += xp[i].r; | ||
94 | res.i += xp[i].i; | ||
95 | } | ||
96 | rp[0] = res; | ||
97 | OK | ||
98 | } | ||
99 | |||
100 | |||
101 | int prodF(KFVEC(x),FVEC(r)) { | ||
102 | DEBUGMSG("prodF"); | ||
103 | REQUIRES(rn==1,BAD_SIZE); | ||
104 | int i; | ||
105 | float res = 1; | ||
106 | for (i = 0; i < xn; i++) res *= xp[i]; | ||
107 | rp[0] = res; | ||
108 | OK | ||
109 | } | ||
110 | |||
111 | int prodR(KDVEC(x),DVEC(r)) { | ||
112 | DEBUGMSG("prodR"); | ||
113 | REQUIRES(rn==1,BAD_SIZE); | ||
114 | int i; | ||
115 | double res = 1; | ||
116 | for (i = 0; i < xn; i++) res *= xp[i]; | ||
117 | rp[0] = res; | ||
118 | OK | ||
119 | } | ||
120 | |||
121 | int prodI(KIVEC(x),IVEC(r)) { | ||
122 | REQUIRES(rn==1,BAD_SIZE); | ||
123 | int i; | ||
124 | int res = 1; | ||
125 | for (i = 0; i < xn; i++) res *= xp[i]; | ||
126 | rp[0] = res; | ||
127 | OK | ||
128 | } | ||
129 | |||
130 | |||
131 | |||
132 | int prodQ(KQVEC(x),QVEC(r)) { | ||
133 | DEBUGMSG("prodQ"); | ||
134 | REQUIRES(rn==1,BAD_SIZE); | ||
135 | int i; | ||
136 | complex res; | ||
137 | float temp; | ||
138 | res.r = 1; | ||
139 | res.i = 0; | ||
140 | for (i = 0; i < xn; i++) { | ||
141 | temp = res.r * xp[i].r - res.i * xp[i].i; | ||
142 | res.i = res.r * xp[i].i + res.i * xp[i].r; | ||
143 | res.r = temp; | ||
144 | } | ||
145 | rp[0] = res; | ||
146 | OK | ||
147 | } | ||
148 | |||
149 | int prodC(KCVEC(x),CVEC(r)) { | ||
150 | DEBUGMSG("prodC"); | ||
151 | REQUIRES(rn==1,BAD_SIZE); | ||
152 | int i; | ||
153 | doublecomplex res; | ||
154 | double temp; | ||
155 | res.r = 1; | ||
156 | res.i = 0; | ||
157 | for (i = 0; i < xn; i++) { | ||
158 | temp = res.r * xp[i].r - res.i * xp[i].i; | ||
159 | res.i = res.r * xp[i].i + res.i * xp[i].r; | ||
160 | res.r = temp; | ||
161 | } | ||
162 | rp[0] = res; | ||
163 | OK | ||
164 | } | ||
165 | |||
166 | |||
167 | double dnrm2_(integer*, const double*, integer*); | ||
168 | double dasum_(integer*, const double*, integer*); | ||
169 | |||
170 | double vector_max(KDVEC(x)) { | ||
171 | double r = xp[0]; | ||
172 | int k; | ||
173 | for (k = 1; k<xn; k++) { | ||
174 | if(xp[k]>r) { | ||
175 | r = xp[k]; | ||
176 | } | ||
177 | } | ||
178 | return r; | ||
179 | } | ||
180 | |||
181 | double vector_min(KDVEC(x)) { | ||
182 | double r = xp[0]; | ||
183 | int k; | ||
184 | for (k = 1; k<xn; k++) { | ||
185 | if(xp[k]<r) { | ||
186 | r = xp[k]; | ||
187 | } | ||
188 | } | ||
189 | return r; | ||
190 | } | ||
191 | |||
192 | double vector_max_index(KDVEC(x)) { | ||
193 | int k, r = 0; | ||
194 | for (k = 1; k<xn; k++) { | ||
195 | if(xp[k]>xp[r]) { | ||
196 | r = k; | ||
197 | } | ||
198 | } | ||
199 | return r; | ||
200 | } | ||
201 | |||
202 | double vector_min_index(KDVEC(x)) { | ||
203 | int k, r = 0; | ||
204 | for (k = 1; k<xn; k++) { | ||
205 | if(xp[k]<xp[r]) { | ||
206 | r = k; | ||
207 | } | ||
208 | } | ||
209 | return r; | ||
210 | } | ||
211 | |||
212 | int toScalarR(int code, KDVEC(x), DVEC(r)) { | ||
213 | REQUIRES(rn==1,BAD_SIZE); | ||
214 | DEBUGMSG("toScalarR"); | ||
215 | double res; | ||
216 | integer one = 1; | ||
217 | integer n = xn; | ||
218 | switch(code) { | ||
219 | case 0: { res = dnrm2_(&n,xp,&one); break; } | ||
220 | case 1: { res = dasum_(&n,xp,&one); break; } | ||
221 | case 2: { res = vector_max_index(V(x)); break; } | ||
222 | case 3: { res = vector_max(V(x)); break; } | ||
223 | case 4: { res = vector_min_index(V(x)); break; } | ||
224 | case 5: { res = vector_min(V(x)); break; } | ||
225 | default: ERROR(BAD_CODE); | ||
226 | } | ||
227 | rp[0] = res; | ||
228 | OK | ||
229 | } | ||
230 | |||
231 | |||
232 | float snrm2_(integer*, const float*, integer*); | ||
233 | float sasum_(integer*, const float*, integer*); | ||
234 | |||
235 | float vector_max_f(KFVEC(x)) { | ||
236 | float r = xp[0]; | ||
237 | int k; | ||
238 | for (k = 1; k<xn; k++) { | ||
239 | if(xp[k]>r) { | ||
240 | r = xp[k]; | ||
241 | } | ||
242 | } | ||
243 | return r; | ||
244 | } | ||
245 | |||
246 | float vector_min_f(KFVEC(x)) { | ||
247 | float r = xp[0]; | ||
248 | int k; | ||
249 | for (k = 1; k<xn; k++) { | ||
250 | if(xp[k]<r) { | ||
251 | r = xp[k]; | ||
252 | } | ||
253 | } | ||
254 | return r; | ||
255 | } | ||
256 | |||
257 | float vector_max_index_f(KFVEC(x)) { | ||
258 | int k, r = 0; | ||
259 | for (k = 1; k<xn; k++) { | ||
260 | if(xp[k]>xp[r]) { | ||
261 | r = k; | ||
262 | } | ||
263 | } | ||
264 | return r; | ||
265 | } | ||
266 | |||
267 | float vector_min_index_f(KFVEC(x)) { | ||
268 | int k, r = 0; | ||
269 | for (k = 1; k<xn; k++) { | ||
270 | if(xp[k]<xp[r]) { | ||
271 | r = k; | ||
272 | } | ||
273 | } | ||
274 | return r; | ||
275 | } | ||
276 | |||
277 | |||
278 | int toScalarF(int code, KFVEC(x), FVEC(r)) { | ||
279 | REQUIRES(rn==1,BAD_SIZE); | ||
280 | DEBUGMSG("toScalarF"); | ||
281 | float res; | ||
282 | integer one = 1; | ||
283 | integer n = xn; | ||
284 | switch(code) { | ||
285 | case 0: { res = snrm2_(&n,xp,&one); break; } | ||
286 | case 1: { res = sasum_(&n,xp,&one); break; } | ||
287 | case 2: { res = vector_max_index_f(V(x)); break; } | ||
288 | case 3: { res = vector_max_f(V(x)); break; } | ||
289 | case 4: { res = vector_min_index_f(V(x)); break; } | ||
290 | case 5: { res = vector_min_f(V(x)); break; } | ||
291 | default: ERROR(BAD_CODE); | ||
292 | } | ||
293 | rp[0] = res; | ||
294 | OK | ||
295 | } | ||
296 | |||
297 | int vector_max_i(KIVEC(x)) { | ||
298 | int r = xp[0]; | ||
299 | int k; | ||
300 | for (k = 1; k<xn; k++) { | ||
301 | if(xp[k]>r) { | ||
302 | r = xp[k]; | ||
303 | } | ||
304 | } | ||
305 | return r; | ||
306 | } | ||
307 | |||
308 | int vector_min_i(KIVEC(x)) { | ||
309 | float r = xp[0]; | ||
310 | int k; | ||
311 | for (k = 1; k<xn; k++) { | ||
312 | if(xp[k]<r) { | ||
313 | r = xp[k]; | ||
314 | } | ||
315 | } | ||
316 | return r; | ||
317 | } | ||
318 | |||
319 | int vector_max_index_i(KIVEC(x)) { | ||
320 | int k, r = 0; | ||
321 | for (k = 1; k<xn; k++) { | ||
322 | if(xp[k]>xp[r]) { | ||
323 | r = k; | ||
324 | } | ||
325 | } | ||
326 | return r; | ||
327 | } | ||
328 | |||
329 | int vector_min_index_i(KIVEC(x)) { | ||
330 | int k, r = 0; | ||
331 | for (k = 1; k<xn; k++) { | ||
332 | if(xp[k]<xp[r]) { | ||
333 | r = k; | ||
334 | } | ||
335 | } | ||
336 | return r; | ||
337 | } | ||
338 | |||
339 | |||
340 | int toScalarI(int code, KIVEC(x), IVEC(r)) { | ||
341 | REQUIRES(rn==1,BAD_SIZE); | ||
342 | int res; | ||
343 | switch(code) { | ||
344 | case 2: { res = vector_max_index_i(V(x)); break; } | ||
345 | case 3: { res = vector_max_i(V(x)); break; } | ||
346 | case 4: { res = vector_min_index_i(V(x)); break; } | ||
347 | case 5: { res = vector_min_i(V(x)); break; } | ||
348 | default: ERROR(BAD_CODE); | ||
349 | } | ||
350 | rp[0] = res; | ||
351 | OK | ||
352 | } | ||
353 | |||
354 | |||
355 | double dznrm2_(integer*, const doublecomplex*, integer*); | ||
356 | double dzasum_(integer*, const doublecomplex*, integer*); | ||
357 | |||
358 | int toScalarC(int code, KCVEC(x), DVEC(r)) { | ||
359 | REQUIRES(rn==1,BAD_SIZE); | ||
360 | DEBUGMSG("toScalarC"); | ||
361 | double res; | ||
362 | integer one = 1; | ||
363 | integer n = xn; | ||
364 | switch(code) { | ||
365 | case 0: { res = dznrm2_(&n,xp,&one); break; } | ||
366 | case 1: { res = dzasum_(&n,xp,&one); break; } | ||
367 | default: ERROR(BAD_CODE); | ||
368 | } | ||
369 | rp[0] = res; | ||
370 | OK | ||
371 | } | ||
372 | |||
373 | |||
374 | double scnrm2_(integer*, const complex*, integer*); | ||
375 | double scasum_(integer*, const complex*, integer*); | ||
376 | |||
377 | int toScalarQ(int code, KQVEC(x), FVEC(r)) { | ||
378 | REQUIRES(rn==1,BAD_SIZE); | ||
379 | DEBUGMSG("toScalarQ"); | ||
380 | float res; | ||
381 | integer one = 1; | ||
382 | integer n = xn; | ||
383 | switch(code) { | ||
384 | case 0: { res = scnrm2_(&n,xp,&one); break; } | ||
385 | case 1: { res = scasum_(&n,xp,&one); break; } | ||
386 | default: ERROR(BAD_CODE); | ||
387 | } | ||
388 | rp[0] = res; | ||
389 | OK | ||
390 | } | ||
391 | |||
392 | |||
393 | inline double sign(double x) { | ||
394 | if(x>0) { | ||
395 | return +1.0; | ||
396 | } else if (x<0) { | ||
397 | return -1.0; | ||
398 | } else { | ||
399 | return 0.0; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | inline float float_sign(float x) { | ||
404 | if(x>0) { | ||
405 | return +1.0; | ||
406 | } else if (x<0) { | ||
407 | return -1.0; | ||
408 | } else { | ||
409 | return 0.0; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | |||
414 | #define OP(C,F) case C: { for(k=0;k<xn;k++) rp[k] = F(xp[k]); OK } | ||
415 | #define OPV(C,E) case C: { for(k=0;k<xn;k++) rp[k] = E; OK } | ||
416 | int mapR(int code, KDVEC(x), DVEC(r)) { | ||
417 | int k; | ||
418 | REQUIRES(xn == rn,BAD_SIZE); | ||
419 | DEBUGMSG("mapR"); | ||
420 | switch (code) { | ||
421 | OP(0,sin) | ||
422 | OP(1,cos) | ||
423 | OP(2,tan) | ||
424 | OP(3,fabs) | ||
425 | OP(4,asin) | ||
426 | OP(5,acos) | ||
427 | OP(6,atan) | ||
428 | OP(7,sinh) | ||
429 | OP(8,cosh) | ||
430 | OP(9,tanh) | ||
431 | OP(10,asinh) | ||
432 | OP(11,acosh) | ||
433 | OP(12,atanh) | ||
434 | OP(13,exp) | ||
435 | OP(14,log) | ||
436 | OP(15,sign) | ||
437 | OP(16,sqrt) | ||
438 | default: ERROR(BAD_CODE); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | int mapF(int code, KFVEC(x), FVEC(r)) { | ||
443 | int k; | ||
444 | REQUIRES(xn == rn,BAD_SIZE); | ||
445 | DEBUGMSG("mapF"); | ||
446 | switch (code) { | ||
447 | OP(0,sin) | ||
448 | OP(1,cos) | ||
449 | OP(2,tan) | ||
450 | OP(3,fabs) | ||
451 | OP(4,asin) | ||
452 | OP(5,acos) | ||
453 | OP(6,atan) | ||
454 | OP(7,sinh) | ||
455 | OP(8,cosh) | ||
456 | OP(9,tanh) | ||
457 | OP(10,asinh) | ||
458 | OP(11,acosh) | ||
459 | OP(12,atanh) | ||
460 | OP(13,exp) | ||
461 | OP(14,log) | ||
462 | OP(15,sign) | ||
463 | OP(16,sqrt) | ||
464 | default: ERROR(BAD_CODE); | ||
465 | } | ||
466 | } | ||
467 | |||
468 | |||
469 | int mapI(int code, KIVEC(x), IVEC(r)) { | ||
470 | int k; | ||
471 | REQUIRES(xn == rn,BAD_SIZE); | ||
472 | switch (code) { | ||
473 | OP(3,abs) | ||
474 | OP(15,sign) | ||
475 | default: ERROR(BAD_CODE); | ||
476 | } | ||
477 | } | ||
478 | |||
479 | |||
480 | |||
481 | inline double abs_complex(doublecomplex z) { | ||
482 | return sqrt(z.r*z.r + z.i*z.i); | ||
483 | } | ||
484 | |||
485 | inline doublecomplex complex_abs_complex(doublecomplex z) { | ||
486 | doublecomplex r; | ||
487 | r.r = abs_complex(z); | ||
488 | r.i = 0; | ||
489 | return r; | ||
490 | } | ||
491 | |||
492 | inline doublecomplex complex_signum_complex(doublecomplex z) { | ||
493 | doublecomplex r; | ||
494 | double mag; | ||
495 | if (z.r == 0 && z.i == 0) { | ||
496 | r.r = 0; | ||
497 | r.i = 0; | ||
498 | } else { | ||
499 | mag = abs_complex(z); | ||
500 | r.r = z.r/mag; | ||
501 | r.i = z.i/mag; | ||
502 | } | ||
503 | return r; | ||
504 | } | ||
505 | |||
506 | #define OPb(C,F) case C: { for(k=0;k<xn;k++) r2p[k] = F(x2p[k]); OK } | ||
507 | int mapC(int code, KCVEC(x), CVEC(r)) { | ||
508 | TCD* x2p = (TCD*)xp; | ||
509 | TCD* r2p = (TCD*)rp; | ||
510 | int k; | ||
511 | REQUIRES(xn == rn,BAD_SIZE); | ||
512 | DEBUGMSG("mapC"); | ||
513 | switch (code) { | ||
514 | OPb(0,csin) | ||
515 | OPb(1,ccos) | ||
516 | OPb(2,ctan) | ||
517 | OP(3,complex_abs_complex) | ||
518 | OPb(4,casin) | ||
519 | OPb(5,cacos) | ||
520 | OPb(6,catan) | ||
521 | OPb(7,csinh) | ||
522 | OPb(8,ccosh) | ||
523 | OPb(9,ctanh) | ||
524 | OPb(10,casinh) | ||
525 | OPb(11,cacosh) | ||
526 | OPb(12,catanh) | ||
527 | OPb(13,cexp) | ||
528 | OPb(14,clog) | ||
529 | OP(15,complex_signum_complex) | ||
530 | OPb(16,csqrt) | ||
531 | default: ERROR(BAD_CODE); | ||
532 | } | ||
533 | } | ||
534 | |||
535 | |||
536 | |||
537 | inline complex complex_f_math_fun(doublecomplex (*cf)(doublecomplex), complex a) | ||
538 | { | ||
539 | doublecomplex c; | ||
540 | doublecomplex r; | ||
541 | |||
542 | complex float_r; | ||
543 | |||
544 | c.r = a.r; | ||
545 | c.i = a.i; | ||
546 | |||
547 | r = (*cf)(c); | ||
548 | |||
549 | float_r.r = r.r; | ||
550 | float_r.i = r.i; | ||
551 | |||
552 | return float_r; | ||
553 | } | ||
554 | |||
555 | |||
556 | #define OPC(C,F) case C: { for(k=0;k<xn;k++) rp[k] = complex_f_math_fun(&F,xp[k]); OK } | ||
557 | int mapQ(int code, KQVEC(x), QVEC(r)) { | ||
558 | TCF* x2p = (TCF*)xp; | ||
559 | TCF* r2p = (TCF*)rp; | ||
560 | int k; | ||
561 | REQUIRES(xn == rn,BAD_SIZE); | ||
562 | DEBUGMSG("mapQ"); | ||
563 | switch (code) { | ||
564 | OPb(0,csinf) | ||
565 | OPb(1,ccosf) | ||
566 | OPb(2,ctanf) | ||
567 | OPC(3,complex_abs_complex) | ||
568 | OPb(4,casinf) | ||
569 | OPb(5,cacosf) | ||
570 | OPb(6,catanf) | ||
571 | OPb(7,csinhf) | ||
572 | OPb(8,ccoshf) | ||
573 | OPb(9,ctanhf) | ||
574 | OPb(10,casinhf) | ||
575 | OPb(11,cacoshf) | ||
576 | OPb(12,catanhf) | ||
577 | OPb(13,cexpf) | ||
578 | OPb(14,clogf) | ||
579 | OPC(15,complex_signum_complex) | ||
580 | OPb(16,csqrtf) | ||
581 | default: ERROR(BAD_CODE); | ||
582 | } | ||
583 | } | ||
584 | |||
585 | |||
586 | int mapValR(int code, double* pval, KDVEC(x), DVEC(r)) { | ||
587 | int k; | ||
588 | double val = *pval; | ||
589 | REQUIRES(xn == rn,BAD_SIZE); | ||
590 | DEBUGMSG("mapValR"); | ||
591 | switch (code) { | ||
592 | OPV(0,val*xp[k]) | ||
593 | OPV(1,val/xp[k]) | ||
594 | OPV(2,val+xp[k]) | ||
595 | OPV(3,val-xp[k]) | ||
596 | OPV(4,pow(val,xp[k])) | ||
597 | OPV(5,pow(xp[k],val)) | ||
598 | default: ERROR(BAD_CODE); | ||
599 | } | ||
600 | } | ||
601 | |||
602 | int mapValF(int code, float* pval, KFVEC(x), FVEC(r)) { | ||
603 | int k; | ||
604 | float val = *pval; | ||
605 | REQUIRES(xn == rn,BAD_SIZE); | ||
606 | DEBUGMSG("mapValF"); | ||
607 | switch (code) { | ||
608 | OPV(0,val*xp[k]) | ||
609 | OPV(1,val/xp[k]) | ||
610 | OPV(2,val+xp[k]) | ||
611 | OPV(3,val-xp[k]) | ||
612 | OPV(4,pow(val,xp[k])) | ||
613 | OPV(5,pow(xp[k],val)) | ||
614 | default: ERROR(BAD_CODE); | ||
615 | } | ||
616 | } | ||
617 | |||
618 | int mod (int a, int b) { | ||
619 | int m = a % b; | ||
620 | if (b>0) { | ||
621 | return m >=0 ? m : m+b; | ||
622 | } else { | ||
623 | return m <=0 ? m : m+b; | ||
624 | } | ||
625 | } | ||
626 | |||
627 | int mapValI(int code, int* pval, KIVEC(x), IVEC(r)) { | ||
628 | int k; | ||
629 | int val = *pval; | ||
630 | REQUIRES(xn == rn,BAD_SIZE); | ||
631 | DEBUGMSG("mapValI"); | ||
632 | switch (code) { | ||
633 | OPV(0,val*xp[k]) | ||
634 | OPV(1,val/xp[k]) | ||
635 | OPV(2,val+xp[k]) | ||
636 | OPV(3,val-xp[k]) | ||
637 | OPV(6,mod(val,xp[k])) | ||
638 | OPV(7,mod(xp[k],val)) | ||
639 | default: ERROR(BAD_CODE); | ||
640 | } | ||
641 | } | ||
642 | |||
643 | |||
644 | |||
645 | inline doublecomplex complex_add(doublecomplex a, doublecomplex b) { | ||
646 | doublecomplex r; | ||
647 | r.r = a.r+b.r; | ||
648 | r.i = a.i+b.i; | ||
649 | return r; | ||
650 | } | ||
651 | |||
652 | #define OPVb(C,E) case C: { for(k=0;k<xn;k++) r2p[k] = E; OK } | ||
653 | int mapValC(int code, doublecomplex* pval, KCVEC(x), CVEC(r)) { | ||
654 | TCD* x2p = (TCD*)xp; | ||
655 | TCD* r2p = (TCD*)rp; | ||
656 | int k; | ||
657 | TCD val = * (TCD*)pval; | ||
658 | REQUIRES(xn == rn,BAD_SIZE); | ||
659 | DEBUGMSG("mapValC"); | ||
660 | switch (code) { | ||
661 | OPVb(0,val*x2p[k]) | ||
662 | OPVb(1,val/x2p[k]) | ||
663 | OPVb(2,val+x2p[k]) | ||
664 | OPVb(3,val-x2p[k]) | ||
665 | OPVb(4,cpow(val,x2p[k])) | ||
666 | OPVb(5,cpow(x2p[k],val)) | ||
667 | default: ERROR(BAD_CODE); | ||
668 | } | ||
669 | } | ||
670 | |||
671 | |||
672 | int mapValQ(int code, complex* pval, KQVEC(x), QVEC(r)) { | ||
673 | TCF* x2p = (TCF*)xp; | ||
674 | TCF* r2p = (TCF*)rp; | ||
675 | int k; | ||
676 | TCF val = *(TCF*)pval; | ||
677 | REQUIRES(xn == rn,BAD_SIZE); | ||
678 | DEBUGMSG("mapValQ"); | ||
679 | switch (code) { | ||
680 | OPVb(0,val*x2p[k]) | ||
681 | OPVb(1,val/x2p[k]) | ||
682 | OPVb(2,val+x2p[k]) | ||
683 | OPVb(3,val-x2p[k]) | ||
684 | OPVb(4,cpow(val,x2p[k])) | ||
685 | OPVb(5,cpow(x2p[k],val)) | ||
686 | default: ERROR(BAD_CODE); | ||
687 | } | ||
688 | } | ||
689 | |||
690 | |||
691 | |||
692 | #define OPZE(C,msg,E) case C: {DEBUGMSG(msg) for(k=0;k<an;k++) rp[k] = E(ap[k],bp[k]); OK } | ||
693 | #define OPZV(C,msg,E) case C: {DEBUGMSG(msg) res = E(V(r),V(b)); CHECK(res,res); OK } | ||
694 | #define OPZO(C,msg,O) case C: {DEBUGMSG(msg) for(k=0;k<an;k++) rp[k] = ap[k] O bp[k]; OK } | ||
695 | |||
696 | int zipR(int code, KDVEC(a), KDVEC(b), DVEC(r)) { | ||
697 | REQUIRES(an == bn && an == rn, BAD_SIZE); | ||
698 | int k; | ||
699 | switch(code) { | ||
700 | OPZO(0,"zipR Add",+) | ||
701 | OPZO(1,"zipR Sub",-) | ||
702 | OPZO(2,"zipR Mul",*) | ||
703 | OPZO(3,"zipR Div",/) | ||
704 | OPZE(4,"zipR Pow", pow) | ||
705 | OPZE(5,"zipR ATan2",atan2) | ||
706 | default: ERROR(BAD_CODE); | ||
707 | } | ||
708 | } | ||
709 | |||
710 | int zipF(int code, KFVEC(a), KFVEC(b), FVEC(r)) { | ||
711 | REQUIRES(an == bn && an == rn, BAD_SIZE); | ||
712 | int k; | ||
713 | switch(code) { | ||
714 | OPZO(0,"zipR Add",+) | ||
715 | OPZO(1,"zipR Sub",-) | ||
716 | OPZO(2,"zipR Mul",*) | ||
717 | OPZO(3,"zipR Div",/) | ||
718 | OPZE(4,"zipR Pow", pow) | ||
719 | OPZE(5,"zipR ATan2",atan2) | ||
720 | default: ERROR(BAD_CODE); | ||
721 | } | ||
722 | } | ||
723 | |||
724 | |||
725 | int zipI(int code, KIVEC(a), KIVEC(b), IVEC(r)) { | ||
726 | REQUIRES(an == bn && an == rn, BAD_SIZE); | ||
727 | int k; | ||
728 | switch(code) { | ||
729 | OPZO(0,"zipI Add",+) | ||
730 | OPZO(1,"zipI Sub",-) | ||
731 | OPZO(2,"zipI Mul",*) | ||
732 | OPZO(3,"zipI Div",/) | ||
733 | OPZO(6,"zipI Mod",%) | ||
734 | default: ERROR(BAD_CODE); | ||
735 | } | ||
736 | } | ||
737 | |||
738 | |||
739 | |||
740 | #define OPZOb(C,msg,O) case C: {DEBUGMSG(msg) for(k=0;k<an;k++) r2p[k] = a2p[k] O b2p[k]; OK } | ||
741 | #define OPZEb(C,msg,E) case C: {DEBUGMSG(msg) for(k=0;k<an;k++) r2p[k] = E(a2p[k],b2p[k]); OK } | ||
742 | int zipC(int code, KCVEC(a), KCVEC(b), CVEC(r)) { | ||
743 | REQUIRES(an == bn && an == rn, BAD_SIZE); | ||
744 | TCD* a2p = (TCD*)ap; | ||
745 | TCD* b2p = (TCD*)bp; | ||
746 | TCD* r2p = (TCD*)rp; | ||
747 | int k; | ||
748 | switch(code) { | ||
749 | OPZOb(0,"zipC Add",+) | ||
750 | OPZOb(1,"zipC Sub",-) | ||
751 | OPZOb(2,"zipC Mul",*) | ||
752 | OPZOb(3,"zipC Div",/) | ||
753 | OPZEb(4,"zipC Pow",cpow) | ||
754 | default: ERROR(BAD_CODE); | ||
755 | } | ||
756 | } | ||
757 | |||
758 | |||
759 | |||
760 | |||
761 | |||
762 | #define OPCZE(C,msg,E) case C: {DEBUGMSG(msg) for(k=0;k<an;k++) rp[k] = complex_f_math_op(&E,ap[k],bp[k]); OK } | ||
763 | |||
764 | int zipQ(int code, KQVEC(a), KQVEC(b), QVEC(r)) { | ||
765 | REQUIRES(an == bn && an == rn, BAD_SIZE); | ||
766 | TCF* a2p = (TCF*)ap; | ||
767 | TCF* b2p = (TCF*)bp; | ||
768 | TCF* r2p = (TCF*)rp; | ||
769 | |||
770 | int k; | ||
771 | switch(code) { | ||
772 | OPZOb(0,"zipC Add",+) | ||
773 | OPZOb(1,"zipC Sub",-) | ||
774 | OPZOb(2,"zipC Mul",*) | ||
775 | OPZOb(3,"zipC Div",/) | ||
776 | OPZEb(4,"zipC Pow",cpowf) | ||
777 | default: ERROR(BAD_CODE); | ||
778 | } | ||
779 | } | ||
780 | |||
781 | //////////////////////////////////////////////////////////////////////////////// | ||
782 | |||
783 | int vectorScan(char * file, int* n, double**pp){ | ||
784 | FILE * fp; | ||
785 | fp = fopen (file, "r"); | ||
786 | if(!fp) { | ||
787 | ERROR(BAD_FILE); | ||
788 | } | ||
789 | int nbuf = 100*100; | ||
790 | double * p = (double*)malloc(nbuf*sizeof(double)); | ||
791 | int k=0; | ||
792 | double d; | ||
793 | int ok; | ||
794 | for (;;) { | ||
795 | ok = fscanf(fp,"%lf",&d); | ||
796 | if (ok<1) { | ||
797 | break; | ||
798 | } | ||
799 | if (k==nbuf) { | ||
800 | nbuf = nbuf * 2; | ||
801 | p = (double*)realloc(p,nbuf*sizeof(double)); | ||
802 | // printf("R\n"); | ||
803 | } | ||
804 | p[k++] = d; | ||
805 | } | ||
806 | *n = k; | ||
807 | *pp = p; | ||
808 | fclose(fp); | ||
809 | OK | ||
810 | } | ||
811 | |||
812 | int saveMatrix(char * file, char * format, KDMAT(a)){ | ||
813 | FILE * fp; | ||
814 | fp = fopen (file, "w"); | ||
815 | int r, c; | ||
816 | for (r=0;r<ar; r++) { | ||
817 | for (c=0; c<ac; c++) { | ||
818 | fprintf(fp,format,ap[r*ac+c]); | ||
819 | if (c<ac-1) { | ||
820 | fprintf(fp," "); | ||
821 | } else { | ||
822 | fprintf(fp,"\n"); | ||
823 | } | ||
824 | } | ||
825 | } | ||
826 | fclose(fp); | ||
827 | OK | ||
828 | } | ||
829 | |||
830 | //////////////////////////////////////////////////////////////////////////////// | ||
831 | |||
832 | #if defined (__APPLE__) || (__FreeBSD__) | ||
833 | /* FreeBSD and Mac OS X do not provide random_r(), thread safety cannot be | ||
834 | guaranteed. | ||
835 | For FreeBSD and Mac OS X, nrand48() is much better than random(). | ||
836 | See: http://www.evanjones.ca/random-thread-safe.html | ||
837 | */ | ||
838 | #pragma message "randomVector is not thread-safe in OSX and FreeBSD" | ||
839 | |||
840 | inline double urandom() { | ||
841 | /* the probalility of matching will be theoretically p^3(in fact, it is not) | ||
842 | p is matching probalility of random(). | ||
843 | using the test there, only 3 matches, using random(), 13783 matches | ||
844 | */ | ||
845 | unsigned short state[3]; | ||
846 | state[0] = random(); | ||
847 | state[1] = random(); | ||
848 | state[2] = random(); | ||
849 | |||
850 | const long max_random = 2147483647; // 2**31 - 1 | ||
851 | return (double)nrand48(state) / (double)max_random; | ||
852 | } | ||
853 | |||
854 | double gaussrand(int *phase, double *pV1, double *pV2, double *pS) | ||
855 | { | ||
856 | double V1=*pV1, V2=*pV2, S=*pS; | ||
857 | double X; | ||
858 | |||
859 | if(*phase == 0) { | ||
860 | do { | ||
861 | double U1 = urandom(); | ||
862 | double U2 = urandom(); | ||
863 | |||
864 | V1 = 2 * U1 - 1; | ||
865 | V2 = 2 * U2 - 1; | ||
866 | S = V1 * V1 + V2 * V2; | ||
867 | } while(S >= 1 || S == 0); | ||
868 | |||
869 | X = V1 * sqrt(-2 * log(S) / S); | ||
870 | } else | ||
871 | X = V2 * sqrt(-2 * log(S) / S); | ||
872 | |||
873 | *phase = 1 - *phase; | ||
874 | *pV1=V1; *pV2=V2; *pS=S; | ||
875 | |||
876 | return X; | ||
877 | |||
878 | } | ||
879 | |||
880 | int random_vector(unsigned int seed, int code, DVEC(r)) { | ||
881 | int phase = 0; | ||
882 | double V1,V2,S; | ||
883 | |||
884 | srandom(seed); | ||
885 | |||
886 | int k; | ||
887 | switch (code) { | ||
888 | case 0: { // uniform | ||
889 | for (k=0; k<rn; k++) { | ||
890 | rp[k] = urandom(); | ||
891 | } | ||
892 | OK | ||
893 | } | ||
894 | case 1: { // gaussian | ||
895 | for (k=0; k<rn; k++) { | ||
896 | rp[k] = gaussrand(&phase,&V1,&V2,&S); | ||
897 | } | ||
898 | OK | ||
899 | } | ||
900 | |||
901 | default: ERROR(BAD_CODE); | ||
902 | } | ||
903 | } | ||
904 | |||
905 | #else | ||
906 | |||
907 | inline double urandom(struct random_data * buffer) { | ||
908 | int32_t res; | ||
909 | random_r(buffer,&res); | ||
910 | return (double)res/RAND_MAX; | ||
911 | } | ||
912 | |||
913 | |||
914 | // http://c-faq.com/lib/gaussian.html | ||
915 | double gaussrand(struct random_data *buffer, | ||
916 | int *phase, double *pV1, double *pV2, double *pS) | ||
917 | { | ||
918 | double V1=*pV1, V2=*pV2, S=*pS; | ||
919 | double X; | ||
920 | |||
921 | if(*phase == 0) { | ||
922 | do { | ||
923 | double U1 = urandom(buffer); | ||
924 | double U2 = urandom(buffer); | ||
925 | |||
926 | V1 = 2 * U1 - 1; | ||
927 | V2 = 2 * U2 - 1; | ||
928 | S = V1 * V1 + V2 * V2; | ||
929 | } while(S >= 1 || S == 0); | ||
930 | |||
931 | X = V1 * sqrt(-2 * log(S) / S); | ||
932 | } else | ||
933 | X = V2 * sqrt(-2 * log(S) / S); | ||
934 | |||
935 | *phase = 1 - *phase; | ||
936 | *pV1=V1; *pV2=V2; *pS=S; | ||
937 | |||
938 | return X; | ||
939 | |||
940 | } | ||
941 | |||
942 | int random_vector(unsigned int seed, int code, DVEC(r)) { | ||
943 | struct random_data buffer; | ||
944 | char random_state[128]; | ||
945 | memset(&buffer, 0, sizeof(struct random_data)); | ||
946 | memset(random_state, 0, sizeof(random_state)); | ||
947 | |||
948 | initstate_r(seed,random_state,sizeof(random_state),&buffer); | ||
949 | // setstate_r(random_state,&buffer); | ||
950 | // srandom_r(seed,&buffer); | ||
951 | |||
952 | int phase = 0; | ||
953 | double V1,V2,S; | ||
954 | |||
955 | int k; | ||
956 | switch (code) { | ||
957 | case 0: { // uniform | ||
958 | for (k=0; k<rn; k++) { | ||
959 | rp[k] = urandom(&buffer); | ||
960 | } | ||
961 | OK | ||
962 | } | ||
963 | case 1: { // gaussian | ||
964 | for (k=0; k<rn; k++) { | ||
965 | rp[k] = gaussrand(&buffer,&phase,&V1,&V2,&S); | ||
966 | } | ||
967 | OK | ||
968 | } | ||
969 | |||
970 | default: ERROR(BAD_CODE); | ||
971 | } | ||
972 | } | ||
973 | |||
974 | #endif | ||
975 | |||
976 | //////////////////////////////////////////////////////////////////////////////// | ||
977 | |||
978 | int smXv(KDVEC(vals),KIVEC(cols),KIVEC(rows),KDVEC(x),DVEC(r)) { | ||
979 | int r, c; | ||
980 | for (r = 0; r < rowsn - 1; r++) { | ||
981 | rp[r] = 0; | ||
982 | for (c = rowsp[r]; c < rowsp[r+1]; c++) { | ||
983 | rp[r] += valsp[c-1] * xp[colsp[c-1]-1]; | ||
984 | } | ||
985 | } | ||
986 | OK | ||
987 | } | ||
988 | |||
989 | int smTXv(KDVEC(vals),KIVEC(cols),KIVEC(rows),KDVEC(x),DVEC(r)) { | ||
990 | int r,c; | ||
991 | for (c = 0; c < rn; c++) { | ||
992 | rp[c] = 0; | ||
993 | } | ||
994 | for (r = 0; r < rowsn - 1; r++) { | ||
995 | for (c = rowsp[r]; c < rowsp[r+1]; c++) { | ||
996 | rp[colsp[c-1]-1] += valsp[c-1] * xp[r]; | ||
997 | } | ||
998 | } | ||
999 | OK | ||
1000 | } | ||
1001 | |||
1002 | //////////////////////////////////////////////////////////////////////////////// | ||
1003 | |||
1004 | int | ||
1005 | compare_doubles (const void *a, const void *b) { | ||
1006 | return *(double*)a > *(double*)b; | ||
1007 | } | ||
1008 | |||
1009 | int sort_valuesD(KDVEC(v),DVEC(r)) { | ||
1010 | memcpy(rp,vp,vn*sizeof(double)); | ||
1011 | qsort(rp,rn,sizeof(double),compare_doubles); | ||
1012 | OK | ||
1013 | } | ||
1014 | |||
1015 | int | ||
1016 | compare_floats (const void *a, const void *b) { | ||
1017 | return *(float*)a > *(float*)b; | ||
1018 | } | ||
1019 | |||
1020 | int sort_valuesF(KFVEC(v),FVEC(r)) { | ||
1021 | memcpy(rp,vp,vn*sizeof(float)); | ||
1022 | qsort(rp,rn,sizeof(float),compare_floats); | ||
1023 | OK | ||
1024 | } | ||
1025 | |||
1026 | int | ||
1027 | compare_ints(const void *a, const void *b) { | ||
1028 | return *(int*)a > *(int*)b; | ||
1029 | } | ||
1030 | |||
1031 | int sort_valuesI(KIVEC(v),IVEC(r)) { | ||
1032 | memcpy(rp,vp,vn*sizeof(int)); | ||
1033 | qsort(rp,rn,sizeof(int),compare_ints); | ||
1034 | OK | ||
1035 | } | ||
1036 | |||
1037 | //////////////////////////////////////// | ||
1038 | |||
1039 | |||
1040 | #define SORTIDX_IMP(T,C) \ | ||
1041 | T* x = (T*)malloc(sizeof(T)*vn); \ | ||
1042 | int k; \ | ||
1043 | for (k=0;k<vn;k++) { \ | ||
1044 | x[k].pos = k; \ | ||
1045 | x[k].val = vp[k]; \ | ||
1046 | } \ | ||
1047 | \ | ||
1048 | qsort(x,vn,sizeof(T),C); \ | ||
1049 | \ | ||
1050 | for (k=0;k<vn;k++) { \ | ||
1051 | rp[k] = x[k].pos; \ | ||
1052 | } \ | ||
1053 | free(x); \ | ||
1054 | OK | ||
1055 | |||
1056 | |||
1057 | typedef struct SDI { int pos; double val;} DI; | ||
1058 | |||
1059 | int compare_doubles_i (const void *a, const void *b) { | ||
1060 | return ((DI*)a)->val > ((DI*)b)->val; | ||
1061 | } | ||
1062 | |||
1063 | int sort_indexD(KDVEC(v),IVEC(r)) { | ||
1064 | SORTIDX_IMP(DI,compare_doubles_i) | ||
1065 | } | ||
1066 | |||
1067 | |||
1068 | typedef struct FI { int pos; float val;} FI; | ||
1069 | |||
1070 | int compare_floats_i (const void *a, const void *b) { | ||
1071 | return ((FI*)a)->val > ((FI*)b)->val; | ||
1072 | } | ||
1073 | |||
1074 | int sort_indexF(KFVEC(v),IVEC(r)) { | ||
1075 | SORTIDX_IMP(FI,compare_floats_i) | ||
1076 | } | ||
1077 | |||
1078 | |||
1079 | typedef struct II { int pos; int val;} II; | ||
1080 | |||
1081 | int compare_ints_i (const void *a, const void *b) { | ||
1082 | return ((II*)a)->val > ((II*)b)->val; | ||
1083 | } | ||
1084 | |||
1085 | int sort_indexI(KIVEC(v),IVEC(r)) { | ||
1086 | SORTIDX_IMP(II,compare_ints_i) | ||
1087 | } | ||
1088 | |||
1089 | |||
1090 | //////////////////////////////////////////////////////////////////////////////// | ||
1091 | |||
1092 | int round_vector(KDVEC(v),DVEC(r)) { | ||
1093 | int k; | ||
1094 | for(k=0; k<vn; k++) { | ||
1095 | rp[k] = round(vp[k]); | ||
1096 | } | ||
1097 | OK | ||
1098 | } | ||
1099 | |||
1100 | //////////////////////////////////////////////////////////////////////////////// | ||
1101 | |||
1102 | int round_vector_i(KDVEC(v),IVEC(r)) { | ||
1103 | int k; | ||
1104 | for(k=0; k<vn; k++) { | ||
1105 | rp[k] = round(vp[k]); | ||
1106 | } | ||
1107 | OK | ||
1108 | } | ||
1109 | |||
1110 | |||
1111 | int mod_vector(int m, KIVEC(v), IVEC(r)) { | ||
1112 | int k; | ||
1113 | for(k=0; k<vn; k++) { | ||
1114 | rp[k] = vp[k] % m; | ||
1115 | } | ||
1116 | OK | ||
1117 | } | ||
1118 | |||
1119 | int div_vector(int m, KIVEC(v), IVEC(r)) { | ||
1120 | int k; | ||
1121 | for(k=0; k<vn; k++) { | ||
1122 | rp[k] = vp[k] / m; | ||
1123 | } | ||
1124 | OK | ||
1125 | } | ||
1126 | |||
1127 | int range_vector(IVEC(r)) { | ||
1128 | int k; | ||
1129 | for(k=0; k<rn; k++) { | ||
1130 | rp[k] = k; | ||
1131 | } | ||
1132 | OK | ||
1133 | } | ||
1134 | |||