comparison vbang.c @ 0:e0bbaa717f41 draft default tip

lol J
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Mon, 25 Nov 2013 11:56:30 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:e0bbaa717f41
1 /* Copyright 1990-2011, Jsoftware Inc. All rights reserved. */
2 /* License in license.txt. */
3 /* */
4 /* Verbs: ! */
5
6 #include "j.h"
7
8
9 static Z z1={1, 0};
10
11 static D coeff[]={
12 0.0, 1.0, 0.5772156649015329, -0.6558780715202538,
13 -0.0420026350340952, 0.1665386113822915, -0.0421977345555443,
14 -0.009621971527877, 0.007218943246663, -0.0011651675918591,
15 -0.0002152416741149, 0.0001280502823882, -0.0000201348547807,
16 -0.0000012504934821, 0.000001133027232, -0.0000002056338417,
17 6.116095e-9, 5.0020075e-9, -1.1812746e-9,
18 1.043427e-10, 7.7823e-12, -3.6968e-12,
19 5.1e-13, -2.06e-14, -5.4e-15,
20 1.4e-15, 1.0e-16
21 };
22
23 static I terms=sizeof(coeff)/sizeof(D);
24
25 static Z jtzhorner(J jt,I n,D*c,Z v){Z s;D*d=n+c;
26 s=zeroZ;
27 DO(n, s=zplus(zrj0(*--d),ztymes(v,s)););
28 R s;
29 }
30
31 static D dgps(D v){D*d=terms+coeff,s=0.0; DO(terms, s=*--d+v*s;); R 1/s;}
32 /* Abramowitz & Stegun, 6.1.34 */
33
34 static Z jtzgps(J jt,Z z){R zdiv(z1,zhorner(terms,coeff,z));}
35
36 static D jtdgamma(J jt,D x){B b;D t;
37 t=1.0; b=x==jfloor(x);
38 if(b&&0>=x){ASSERT(x>x-1,EVLIMIT); R x==2*jfloor(x/2)?inf:infm;}
39 if(0<=x) while(1<x){t*=--x; if(t==inf)R inf;}
40 else {while(0>x){t*=x++; if(t==inf)R 0.0;} t=1.0/t;}
41 R b?t:t*dgps(x);
42 } /* gamma(x) using recurrence formula */
43
44 static Z jtzgrecur(J jt,Z z){Z t;
45 t=z1;
46 if(0<=z.re) while( 0.5<z.re){--z.re; t=ztymes(t,z); if(t.re==inf)R t; }
47 else {while(-0.5>z.re){t=ztymes(t,z); ++z.re; if(t.re==inf)R zeroZ;} t=zdiv(z1,t);}
48 R ztymes(t,zgps(z));
49 } /* gamma(z) using recurrence formula */
50
51 static Z jtzgauss(J jt,D n,Z z){D d=1/n;Z p,t;
52 if(1>=n)R zgrecur(z);
53 p=ztymes(zpow(zrj0(2*PI),zrj0((1-n)/2)),zpow(zrj0(n),zminus(z,zrj0(0.5))));
54 t=zdiv(z,zrj0(n));
55 DO((I)n, p=ztymes(p,zgrecur(t)); t.re+=d;);
56 R p;
57 } /* Abramowitz & Stegun, 6.1.20 */
58
59 static Z jtzstirling(J jt,Z z){Z p,q;
60 static D c[]={1.0, 1.0/12, 1.0/288, -139.0/51840, -571.0/2488320},
61 e=2.718281828459045235360287;
62 p=ztymes(zsqrt(zdiv(zrj0(2*PI),z)),zpow(zdiv(z,zrj0(e)),z));
63 q=zhorner(5L,c,zdiv(z1,z));
64 R ztymes(p,q);
65 } /* Abramowitz & Stegun, 6.1.37 */
66
67 static Z jtzgamma(J jt,Z z){D y=ABS(z.im);
68 R !y?zrj0(dgamma(z.re)):20<y?zstirling(z):zgauss(ceil(y/0.8660254),z);
69 }
70
71 AMON(factI, D,I, *z=dgamma(1.0+(D)*x);)
72 AMON(factD, D,D, *z=_isnan(*x)?*x:dgamma(1.0+*x);)
73 AMON(factZ, Z,Z, *z=zgamma(zplus(z1,*x));)
74
75
76 #define PQLOOP(expr) while(n&&h&&h!=inf&&h!=infm){h*=expr; --n;}
77
78 static D pq(D h,D m,D*c,D*d){D x=*c,y=*d;I n=(I)MIN(m,IMAX);
79 if(0>=m)R h;
80 switch(2*(0>x)+(0>y)){
81 case 0: if(x!= y)PQLOOP(x--/y--); break;
82 case 1: if(x!=-y)PQLOOP(x--/y++)else if(m>2*jfloor(0.5*m))h=-h; break;
83 case 2: if(x!=-y)PQLOOP(x++/y--)else if(m>2*jfloor(0.5*m))h=-h; break;
84 case 3: if(x!= y)PQLOOP(x++/y++); break;
85 }
86 if(0>=*c)*c+=m; else *c-=m;
87 if(0>=*d)*d+=m; else *d-=m;
88 R h;
89 }
90
91 static I signf(D x){R 0<=x||1<=x-2*jfloor(0.5*x)?1:-1;}
92 /* sign of !x */
93
94 static D jtdbin(J jt,D x,D y){D c,d,e,h=1.0,p,q,r;I k=0;
95 c=y; if(0<=c)p=jfloor(c); else{k+=4; ++c; p=jfloor(-c);}
96 d=y-x; if(0<=d)q=jfloor(d); else{k+=2; ++d; q=jfloor(-d);}
97 e=x; if(0<=e)r=jfloor(e); else{k+=1; ++e; r=jfloor(-e);}
98 switch(k){
99 case 0: h=pq(h,q,&c,&d); h=pq(h,r,&c,&e); break;
100 case 1: h=pq(h,p,&c,&d); h=pq(h,r,&e,&d); --e; break;
101 case 2: h=pq(h,p,&c,&e); h=pq(h,q,&d,&e); --d; break;
102 case 5: h=pq(h,p,&e,&c); h=pq(h,q,&e,&d); --c; --e; break;
103 case 6: h=pq(h,p,&d,&c); h=pq(h,r,&d,&e); --c; --d; break;
104 case 7: h=pq(h,q,&d,&c); h=pq(h,r,&e,&c); --c; --d; --e; break;
105 }
106 if(!h)R 0;
107 if(h==inf||h==infm)R inf*signf(x)*signf(y)*signf(y-x);
108 R h*dgamma(1+c)/(dgamma(1+d)*dgamma(1+e));
109 } /* x and y-x are not negative integers */
110
111 static D ibin(D x,D y){D d=MIN(x,y-x),p=1;
112 DO((I)d, p*=y--/d--; if(p==inf)R p;);
113 R jfloor(0.5+p);
114 } /* x and y are non-negative integers; x<=y */
115
116 static Z jtzbin(J jt,Z x,Z y){Z a,b,c;
117 a=zgamma(zplus(z1,y));
118 b=zgamma(zplus(z1,x));
119 c=zgamma(zplus(z1,zminus(y,x)));
120 R zdiv(a,ztymes(b,c));
121 }
122
123 #define MOD2(x) ((x)-2*jfloor(0.5*(x)))
124
125 static D jtbindd(J jt,D x,D y){B id,ix,iy;D d;
126 if(_isnan(x))R x; else if(_isnan(y))R y;
127 d=y-x;
128 id=d==jfloor(d);
129 ix=x==jfloor(x);
130 iy=y==jfloor(y);
131 switch(4*(ix&&0>x)+2*(iy&&0>y)+(id&&0>d)){
132 default: ASSERTSYS(0,"bindd");
133 case 5: /* 1 0 1 */ /* Impossible */
134 case 0: /* 0 0 0 */
135 case 2: /* 0 1 0 */ R ix&&iy?ibin(x,y):dbin(x,y);
136 case 3: /* 0 1 1 */ R (MOD2(x)?-1:1)*ibin(x,x-y-1);
137 case 6: /* 1 1 0 */ R (MOD2(d)?-1:1)*ibin(-1-y,-1-x);
138 case 1: /* 0 0 1 */
139 case 4: /* 1 0 0 */
140 case 7: /* 1 1 1 */ R 0;
141 }} /* P.C. Berry, Sharp APL Reference Manual, 1979, p. 132 */
142
143 static Z jtbinzz(J jt,Z x,Z y){B id,ix,iy;D rd,rx,ry;Z d;
144 if(!x.im&&!y.im)R zrj0(bindd(x.re,y.re));
145 d=zminus(y,x);
146 rd=d.re; id=rd==jfloor(rd)&&0==d.im;
147 rx=x.re; ix=rx==jfloor(rx)&&0==x.im;
148 ry=y.re; iy=ry==jfloor(ry)&&0==y.im;
149 switch(4*(ix&&0>rx)+2*(iy&&0>ry)+(id&&0>rd)){
150 default: ZASSERT(0,EVSYSTEM);
151 case 5: /* 1 0 1 */ /* Impossible */
152 case 0: /* 0 0 0 */
153 case 2: /* 0 1 0 */ R zbin(x,y);
154 case 3: /* 0 1 1 */ R zrj0((MOD2(rx)?-1:1)*ibin(rx,rx-ry-1));
155 case 6: /* 1 1 0 */ R zrj0((MOD2(rd)?-1:1)*ibin(-1-ry,-1-rx));
156 case 1: /* 0 0 1 */
157 case 4: /* 1 0 0 */
158 case 7: /* 1 1 1 */ R zeroZ;
159 }}
160
161
162 ANAN(binDD, D,D,D, bindd)
163 ANAN(binZZ, Z,Z,Z, binzz)