summaryrefslogtreecommitdiff
path: root/packages/base/src/Internal/C/vector-aux.c
diff options
context:
space:
mode:
authorAlberto Ruiz <aruiz@um.es>2015-06-04 12:39:33 +0200
committerAlberto Ruiz <aruiz@um.es>2015-06-04 12:39:33 +0200
commitb7e57952112eae61054fc9171ddb311fbaca0841 (patch)
treeef72da1ad7d661a3bc0a2f72fd65a2074ccf1a73 /packages/base/src/Internal/C/vector-aux.c
parent27334e233edd3d891d2837330289a26e54d05fd1 (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.c1134
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
3typedef double complex TCD;
4typedef 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
40int 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
50int 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
60int 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
70int 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
85int 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
101int 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
111int 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
121int 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
132int 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
149int 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
167double dnrm2_(integer*, const double*, integer*);
168double dasum_(integer*, const double*, integer*);
169
170double 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
181double 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
192double 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
202double 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
212int 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
232float snrm2_(integer*, const float*, integer*);
233float sasum_(integer*, const float*, integer*);
234
235float 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
246float 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
257float 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
267float 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
278int 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
297int 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
308int 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
319int 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
329int 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
340int 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
355double dznrm2_(integer*, const doublecomplex*, integer*);
356double dzasum_(integer*, const doublecomplex*, integer*);
357
358int 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
374double scnrm2_(integer*, const complex*, integer*);
375double scasum_(integer*, const complex*, integer*);
376
377int 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
393inline 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
403inline 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 }
416int 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
442int 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
469int 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
481inline double abs_complex(doublecomplex z) {
482 return sqrt(z.r*z.r + z.i*z.i);
483}
484
485inline doublecomplex complex_abs_complex(doublecomplex z) {
486 doublecomplex r;
487 r.r = abs_complex(z);
488 r.i = 0;
489 return r;
490}
491
492inline 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 }
507int 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
537inline 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 }
557int 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
586int 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
602int 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
618int 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
627int 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
645inline 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 }
653int 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
672int 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
696int zipR(int code, KDVEC(a), KDVEC(b), DVEC(r)) {
697REQUIRES(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
710int zipF(int code, KFVEC(a), KFVEC(b), FVEC(r)) {
711REQUIRES(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
725int zipI(int code, KIVEC(a), KIVEC(b), IVEC(r)) {
726REQUIRES(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 }
742int 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
764int 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
783int 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
812int 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
840inline 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
854double 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
880int 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
907inline 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
915double 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
942int 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
978int 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
989int 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
1004int
1005compare_doubles (const void *a, const void *b) {
1006 return *(double*)a > *(double*)b;
1007}
1008
1009int 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
1015int
1016compare_floats (const void *a, const void *b) {
1017 return *(float*)a > *(float*)b;
1018}
1019
1020int 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
1026int
1027compare_ints(const void *a, const void *b) {
1028 return *(int*)a > *(int*)b;
1029}
1030
1031int 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
1057typedef struct SDI { int pos; double val;} DI;
1058
1059int compare_doubles_i (const void *a, const void *b) {
1060 return ((DI*)a)->val > ((DI*)b)->val;
1061}
1062
1063int sort_indexD(KDVEC(v),IVEC(r)) {
1064 SORTIDX_IMP(DI,compare_doubles_i)
1065}
1066
1067
1068typedef struct FI { int pos; float val;} FI;
1069
1070int compare_floats_i (const void *a, const void *b) {
1071 return ((FI*)a)->val > ((FI*)b)->val;
1072}
1073
1074int sort_indexF(KFVEC(v),IVEC(r)) {
1075 SORTIDX_IMP(FI,compare_floats_i)
1076}
1077
1078
1079typedef struct II { int pos; int val;} II;
1080
1081int compare_ints_i (const void *a, const void *b) {
1082 return ((II*)a)->val > ((II*)b)->val;
1083}
1084
1085int sort_indexI(KIVEC(v),IVEC(r)) {
1086 SORTIDX_IMP(II,compare_ints_i)
1087}
1088
1089
1090////////////////////////////////////////////////////////////////////////////////
1091
1092int 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
1102int 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
1111int 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
1119int 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
1127int range_vector(IVEC(r)) {
1128 int k;
1129 for(k=0; k<rn; k++) {
1130 rp[k] = k;
1131 }
1132 OK
1133}
1134