Mercurial > hg > jgplsrc
comparison ar.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 /* Adverbs: Reduce (Insert) and Outer Product */ | |
5 | |
6 #include "j.h" | |
7 #include "vasm.h" | |
8 #include "ve.h" | |
9 #include "vcomp.h" | |
10 #include "ar.h" | |
11 | |
12 static DF1(jtreduce); | |
13 | |
14 | |
15 #define PARITY2 u=(UC*)&s; b=0; b^=*u++; b^=*u++; | |
16 #define PARITY4 u=(UC*)&s; b=0; b^=*u++; b^=*u++; b^=*u++; b^=*u++; | |
17 #define PARITY8 u=(UC*)&s; b=0; b^=*u++; b^=*u++; b^=*u++; b^=*u++; b^=*u++; b^=*u++; b^=*u++; b^=*u++; | |
18 | |
19 #if SY_64 | |
20 #define PARITYW PARITY8 | |
21 #else | |
22 #define PARITYW PARITY4 | |
23 #endif | |
24 | |
25 #if SY_ALIGN | |
26 #define VDONE(T,PAR) \ | |
27 {I q=n/sizeof(T);T s,*y=(T*)x; DO(m, s=0; DO(q, s^=*y++;); PAR; *z++=b==pc;);} | |
28 | |
29 static void vdone(I m,I n,B*x,B*z,B pc){B b,*u; | |
30 if(1==m){UI s,*xi; | |
31 s=0; b=0; | |
32 xi=(I*)x; DO(n/SZI, s^=*xi++;); | |
33 u=(B*)xi; DO(n%SZI, b^=*u++;); | |
34 u=(B*)&s; DO(SZI, b^=*u++;); | |
35 *z=b==pc; | |
36 }else if(0==n%sizeof(UI ))VDONE(UI, PARITYW) | |
37 else if(0==n%sizeof(UINT))VDONE(UINT,PARITY4) | |
38 else if(0==n%sizeof(US ))VDONE(US, PARITY2) | |
39 else DO(m, b=0; DO(n, b^=*x++;); *z++=b==pc;); | |
40 } | |
41 #else | |
42 static void vdone(I m,I n,B*x,B*z,B pc){B b;I q,r;UC*u;UI s,*y; | |
43 q=n/SZI; r=n%SZI; y=(UI*)x; | |
44 switch((r?2:0)+pc){ | |
45 case 0: DO(m, s=0; DO(q, s^=*y++;); PARITYW; *z++=!b;); break; | |
46 case 1: DO(m, s=0; DO(q, s^=*y++;); PARITYW; *z++= b;); break; | |
47 case 2: DO(m, s=0; DO(q, s^=*y++;); PARITYW; u=(UC*)y; DO(r, b^=*u++;); *z++=!b; x+=n; y=(UI*)x;); break; | |
48 case 3: DO(m, s=0; DO(q, s^=*y++;); PARITYW; u=(UC*)y; DO(r, b^=*u++;); *z++= b; x+=n; y=(UI*)x;); break; | |
49 }} | |
50 #endif | |
51 | |
52 #define RBFXLOOP(T,pfx) \ | |
53 {T*xx=(T*)x,*yy,*z0,*zz=(T*)z; \ | |
54 q=d/sizeof(T); \ | |
55 for(j=0;j<m;++j){ \ | |
56 yy=xx; xx-=q; z0=zz; DO(q, --xx; --yy; --zz; *zz=pfx(*xx,*yy);); \ | |
57 DO(n-2, zz=z0; DO(q, --xx; --zz; *zz=pfx(*xx,*zz););); \ | |
58 }} /* non-commutative */ | |
59 | |
60 #define RCFXLOOP(T,pfx) \ | |
61 {T*xx=(T*)x,*yy,*z0,*zz=(T*)z; \ | |
62 q=d/sizeof(T); \ | |
63 for(j=0;j<m;++j){ \ | |
64 yy=xx; xx+=q; z0=zz; DO(q, *zz++=pfx(*yy,*xx); ++xx; ++yy;); \ | |
65 DO(n-2, zz=z0; DO(q, *zz++=pfx(*zz,*xx); ++xx; );); \ | |
66 }} /* commutative */ | |
67 | |
68 #if SY_ALIGN | |
69 #define RBFXODDSIZE(pfx,bpfx) RBFXLOOP(C,bpfx) | |
70 #define REDUCECFX REDUCEBFX | |
71 #else | |
72 #define RBFXODDSIZE(pfx,bpfx) \ | |
73 {B*zz;I r,t,*xi,*yi,*zi; \ | |
74 q=d/SZI; r=d%SZI; xi=(I*)x; zz=z; \ | |
75 for(j=0;j<m;++j,zz-=d){ \ | |
76 yi=xi; xi=(I*)((B*)xi-d); zi=(I*)zz; \ | |
77 DO(q, --xi; --yi; *--zi=pfx(*xi,*yi);); \ | |
78 xi=(I*)((B*)xi-r); yi=(I*)((B*)yi-r); t=pfx(*xi,*yi); MC((B*)zi-r,&t,r); \ | |
79 DO(n-2, zi=(I*)zz; DO(q, --xi; --zi; *zi=pfx(*xi,*zi);); \ | |
80 xi=(I*)((B*)xi-r); zi=(I*)((B*)zi-r); t=pfx(*xi,*zi); MC( zi, &t,r);); \ | |
81 }} /* non-commutative */ | |
82 | |
83 #define RCFXODDSIZE(pfx,bpfx) \ | |
84 {I r,t,*xi,*yi,*zi; \ | |
85 q=d/SZI; r=d%SZI; \ | |
86 for(j=0;j<m;++j,x+=d,z+=d){ \ | |
87 yi=(I*)x; x+=d; xi=(I*)x; zi=(I*)z; DO(q, *zi++=pfx(*yi,*xi); ++xi; ++yi;); t=pfx(*yi,*xi); MC(zi,&t,r); \ | |
88 DO(n-2, x+=d; xi=(I*)x; zi=(I*)z; DO(q, *zi++=pfx(*zi,*xi); ++xi; ); t=pfx(*zi,*xi); MC(zi,&t,r);); \ | |
89 }} /* commutative */ | |
90 | |
91 #define REDUCECFX(f,pfx,ipfx,spfx,bpfx,vdo) \ | |
92 AHDRP(f,B,B){B*y=0;I d,j,q; \ | |
93 if(c==n){vdo; R;} \ | |
94 d=c/n; \ | |
95 if(1==n)DO(d, *z++=*x++;) \ | |
96 else if(0==d%sizeof(UI ))RCFXLOOP(UI, pfx) \ | |
97 else if(0==d%sizeof(UINT))RCFXLOOP(UINT,ipfx) \ | |
98 else if(0==d%sizeof(US ))RCFXLOOP(US, spfx) \ | |
99 else RCFXODDSIZE(pfx,bpfx) \ | |
100 } /* commutative */ | |
101 | |
102 #endif | |
103 | |
104 #define REDUCEBFX(f,pfx,ipfx,spfx,bpfx,vdo) \ | |
105 AHDRP(f,B,B){B*y=0;I d,j,q; \ | |
106 if(c==n){vdo; R;} \ | |
107 d=c/n; x+=m*c; z+=m*d; \ | |
108 if(1==n)DO(d, *--z=*--x;) \ | |
109 else if(0==d%sizeof(UI ))RBFXLOOP(UI, pfx) \ | |
110 else if(0==d%sizeof(UINT))RBFXLOOP(UINT,ipfx) \ | |
111 else if(0==d%sizeof(US ))RBFXLOOP(US, spfx) \ | |
112 else RBFXODDSIZE(pfx,bpfx) \ | |
113 } /* non-commutative */ | |
114 | |
115 REDUCECFX( eqinsB, EQ, IEQ, SEQ, BEQ, vdone(m,n,x,z,(B)(n%2))) | |
116 REDUCECFX( neinsB, NE, INE, SNE, BNE, vdone(m,n,x,z,1 )) | |
117 REDUCECFX( orinsB, OR, IOR, SOR, BOR, DO(m, *z++=1&&memchr(x,C1,n); x+=c;)) | |
118 REDUCECFX( andinsB, AND, IAND, SAND, BAND, DO(m, *z++=! memchr(x,C0,n); x+=c;)) | |
119 REDUCEBFX( ltinsB, LT, ILT, SLT, BLT, DO(m, *z++= *(x+n-1)&&!memchr(x,C1,n-1)?1:0; x+=c;)) | |
120 REDUCEBFX( leinsB, LE, ILE, SLE, BLE, DO(m, *z++=!*(x+n-1)&&!memchr(x,C0,n-1)?0:1; x+=c;)) | |
121 REDUCEBFX( gtinsB, GT, IGT, SGT, BGT, DO(m, y=memchr(x,C0,n); *z++=1&&(y?1&(y-x):1&n); x+=c;)) | |
122 REDUCEBFX( geinsB, GE, IGE, SGE, BGE, DO(m, y=memchr(x,C1,n); *z++=! (y?1&(y-x):1&n); x+=c;)) | |
123 REDUCEBFX( norinsB, NOR, INOR, SNOR, BNOR, DO(m, y=memchr(x,C1,n); d=y?y-x:n; *z++=(1&d)==d<n-1; x+=c;)) | |
124 REDUCEBFX(nandinsB, NAND,INAND,SNAND,BNAND,DO(m, y=memchr(x,C0,n); d=y?y-x:n; *z++=(1&d)!=d<n-1; x+=c;)) | |
125 | |
126 | |
127 #if SY_ALIGN | |
128 REDUCEPFX(plusinsB,I,B,PLUS) | |
129 #else | |
130 AHDRR(plusinsB,I,B){I d,dw,i,p,q,r,r1,s;UC*tu;UI*v; | |
131 if(c==n&&n<SZI)DO(m, s=0; DO(n, s+=*x++;); *z++=s;) | |
132 else if(c==n){UI t; | |
133 p=n/SZI; q=p/255; r=p%255; r1=n%SZI; tu=(UC*)&t; | |
134 for(i=0;i<m;++i){ | |
135 s=0; v=(UI*)x; | |
136 DO(q, t=0; DO(255, t+=*v++;); DO(SZI, s+=tu[i];)); | |
137 t=0; DO(r, t+=*v++;); DO(SZI, s+=tu[i];); | |
138 x=(B*)v; DO(r1, s+=*x++;); | |
139 *z++=s; | |
140 }}else{A t;UI*tv; | |
141 d=c/n; dw=(d+SZI-1)/SZI; p=dw*SZI; memset(z,C0,m*d*SZI); | |
142 q=n/255; r=n%255; | |
143 t=ga(INT,dw,1,0); if(!t)R; | |
144 tu=(UC*)AV(t); tv=(UI*)tu; v=(UI*)x; | |
145 for(i=0;i<m;++i,z+=d){ | |
146 DO(q, memset(tv,C0,p); DO(255, DO(dw,tv[i]+=v[i];); x+=d; v=(UI*)x;); DO(d,z[i]+=tu[i];)); | |
147 memset(tv,C0,p); DO(r, DO(dw,tv[i]+=v[i];); x+=d; v=(UI*)x;); DO(d,z[i]+=tu[i];) ; | |
148 }}} /* +/"r w on boolean w, originally by Roger Moore */ | |
149 #endif | |
150 | |
151 | |
152 REDUCEOVF( plusinsI, I, I, PLUSR, PLUSVV, PLUSRV) | |
153 REDUCEOVF(minusinsI, I, I, MINUSR,MINUSVV,MINUSRV) | |
154 REDUCEOVF(tymesinsI, I, I, TYMESR,TYMESVV,TYMESRV) | |
155 | |
156 REDUCCPFX( plusinsO, D, I, PLUSO) | |
157 REDUCCPFX(minusinsO, D, I, MINUSO) | |
158 REDUCCPFX(tymesinsO, D, I, TYMESO) | |
159 | |
160 REDUCENAN( plusinsD, D, D, PLUS ) | |
161 REDUCENAN( plusinsZ, Z, Z, zplus ) | |
162 REDUCEPFX( plusinsX, X, X, xplus ) | |
163 | |
164 REDUCEPFX(minusinsB, I, B, MINUS ) | |
165 REDUCENAN(minusinsD, D, D, MINUS ) | |
166 REDUCENAN(minusinsZ, Z, Z, zminus) | |
167 | |
168 REDUCEPFX(tymesinsD, D, D, TYMES ) | |
169 REDUCEPFX(tymesinsZ, Z, Z, ztymes) | |
170 | |
171 REDUCENAN( divinsD, D, D, DIV ) | |
172 REDUCENAN( divinsZ, Z, Z, zdiv ) | |
173 | |
174 REDUCEPFX( maxinsI, I, I, MAX ) | |
175 REDUCEPFX( maxinsD, D, D, MAX ) | |
176 REDUCEPFX( maxinsX, X, X, XMAX ) | |
177 REDUCEPFX( maxinsS, SB,SB,SBMAX ) | |
178 | |
179 REDUCEPFX( mininsI, I, I, MIN ) | |
180 REDUCEPFX( mininsD, D, D, MIN ) | |
181 REDUCEPFX( mininsX, X, X, XMIN ) | |
182 REDUCEPFX( mininsS, SB,SB,SBMIN ) | |
183 | |
184 | |
185 static DF1(jtred0){DECLF;A x;I f,r,wr,*s; | |
186 wr=AR(w); r=jt->rank?jt->rank[1]:wr; f=wr-r; s=AS(w); | |
187 jt->rank=0; | |
188 GA(x,AT(w),0L,r,f+s); | |
189 R reitem(vec(INT,f,s),lamin1(df1(x,iden(fs)))); | |
190 } /* f/"r w identity case */ | |
191 | |
192 static DF1(jtredg){PROLOG;DECLF;A y,z;B p;C*u,*v;I i,k,n,old,r,wr,yn,yr,*ys,yt; | |
193 RZ(w); | |
194 ASSERT(DENSE&AT(w),EVNONCE); | |
195 wr=AR(w); r=jt->rank?jt->rank[1]:wr; jt->rank=0; | |
196 if(r<wr)R rank1ex(w,self,r,jtredg); | |
197 n=IC(w); p=ARELATIVE(w); | |
198 RZ(z=tail(w)); yt=AT(z); yn=AN(z); yr=AR(z); ys=1+AS(w); | |
199 k=yn*bp(yt); v=CAV(w)+k*(n-1); | |
200 old=jt->tbase+jt->ttop; | |
201 for(i=1;i<n;++i){ | |
202 v-=k; | |
203 GA(y,yt,yn,yr,ys); u=CAV(y); | |
204 if(p){A1*wv=(A1*)v,*yv=(A1*)u;I d=(I)w-(I)y; AFLAG(y)=AFREL; DO(yn, yv[i]=d+wv[i];);}else MC(u,v,k); | |
205 RZ(z=CALL2(f2,y,z,fs)); | |
206 gc(z,old); | |
207 } | |
208 EPILOG(z); | |
209 } /* f/"r w for general f and 1<(-r){$w */ | |
210 | |
211 | |
212 static C fca[]={CSTAR, CPLUS, CEQ, CMIN, CMAX, CPLUSDOT, CSTARDOT, CNE, 0}; /* commutative & associative */ | |
213 | |
214 static A jtredsp1a(J jt,C id,A z,A e,I n,I r,I*s){A t;B b,p=0;D d=1; | |
215 switch(id){ | |
216 default: ASSERT(0,EVNONCE); | |
217 case CPLUSDOT: R n?gcd(z,e):ca(e); | |
218 case CSTARDOT: R n?lcm(z,e):ca(e); | |
219 case CMIN: R n?minimum(z,e):ca(e); | |
220 case CMAX: R n?maximum(z,e):ca(e); | |
221 case CPLUS: if(n&&equ(e,zero))R z; DO(r, d*=s[i];); t=tymes(e,d>IMAX?scf(d-n):sc((I)d-n)); R n?plus (z,t):t; | |
222 case CSTAR: if(n&&equ(e,one ))R z; DO(r, d*=s[i];); t=expn2(e,d>IMAX?scf(d-n):sc((I)d-n)); R n?tymes(z,t):t; | |
223 case CEQ: p=1; /* fall thru */ | |
224 case CNE: | |
225 ASSERT(B01&AT(e),EVNONCE); | |
226 if(!n)*BAV(z)=p; | |
227 b=1; DO(r, if(!(s[i]%2)){b=0; break;}); | |
228 R !p==*BAV(e)&&b!=n%2?not(z):z; | |
229 }} /* f/w on sparse vector w, post processing */ | |
230 | |
231 static A jtredsp1(J jt,A w,A self,C id,VF ado,I cv,I f,I r,I zt){A e,x,z;I m,n;P*wp; | |
232 RZ(w); | |
233 wp=PAV(w); e=SPA(wp,e); x=SPA(wp,x); n=AN(x); m=*AS(w); | |
234 GA(z,zt,1,0,0); | |
235 if(n){ado(jt,1L,n,n,AV(z),AV(x)); RE(0); if(m==n)R z;} | |
236 R redsp1a(id,z,e,n,AR(w),AS(w)); | |
237 } /* f/"r w for sparse vector w */ | |
238 | |
239 DF1(jtredravel){A f,x,z;C id;I cv,n;P*wp;VF ado; | |
240 RZ(w); | |
241 f=VAV(self)->f; | |
242 if(!(SPARSE&AT(w)))R reduce(AN(w)?gah(1L,w):mtv,f); | |
243 wp=PAV(w); x=SPA(wp,x); n=AN(x); | |
244 id=vaid(VAV(f)->f); | |
245 while(1){ | |
246 vains(id,AT(x),&ado,&cv); | |
247 ASSERT(ado,EVNONCE); | |
248 GA(z,rtype(cv),1,0,0); | |
249 if(n)ado(jt,1L,n,n,AV(z),AV(x)); | |
250 if(jt->jerr!=EWOV)R redsp1a(id,z,SPA(wp,e),n,AR(w),AS(w));; | |
251 }} /* f/@, w */ | |
252 | |
253 static A jtredspd(J jt,A w,A self,C id,VF ado,I cv,I f,I r,I zt){A a,e,x,z,zx;I c,m,n,*s,t,*v,wr,*ws,xf,xr;P*wp,*zp; | |
254 RZ(w); | |
255 ASSERT(strchr(fca,id),EVNONCE); | |
256 wp=PAV(w); a=SPA(wp,a); e=SPA(wp,e); x=SPA(wp,x); s=AS(x); | |
257 xr=r; v=AV(a); DO(AN(a), if(f<v[i])--xr;); xf=AR(x)-xr; | |
258 m=prod(xf,s); c=m?AN(x)/m:0; n=s[xf]; | |
259 GA(zx,zt,AN(x)/n,AR(x)-1,s); ICPY(xf+AS(zx),1+xf+s,xr-1); | |
260 ado(jt,m,c,n,AV(zx),AV(x)); RE(0); | |
261 switch(id){ | |
262 case CPLUS: if(!equ(e,zero))RZ(e=tymes(e,sc(n))); break; | |
263 case CSTAR: if(!equ(e,one )&&!equ(e,zero))RZ(e=expn2(e,sc(n))); break; | |
264 case CEQ: ASSERT(B01&AT(x),EVNONCE); if(!*BAV(e)&&0==n%2)e=one; break; | |
265 case CNE: ASSERT(B01&AT(x),EVNONCE); if( *BAV(e)&&1==n%2)e=zero; | |
266 } | |
267 if(AT(e)!=AT(zx)){t=maxtype(AT(e),AT(zx)); if(t!=AT(zx))RZ(zx=cvt(t,zx));} | |
268 wr=AR(w); ws=AS(w); | |
269 GA(z,STYPE(AT(zx)),1,wr-1,ws); if(1<wr)ICPY(f+AS(z),f+1+ws,wr-1); | |
270 zp=PAV(z); | |
271 RZ(a=ca(a)); v=AV(a); DO(AN(a), if(f<v[i])--v[i];); | |
272 SPB(zp,a,a); | |
273 SPB(zp,e,cvt(AT(zx),e)); | |
274 SPB(zp,i,SPA(wp,i)); | |
275 SPB(zp,x,zx); | |
276 R z; | |
277 } /* f/"r w for sparse w, rank > 1, dense axis */ | |
278 | |
279 static B jtredspsprep(J jt,C id,I f,I zt,A a,A e,A x,A y,I*zm,I**zdv,B**zpv,I**zqv,C**zxxv,A*zsn){ | |
280 A d,p,q,sn=0,xx;B*pv;C*xxv;I*dv,j,k,m,mm,*qv=0,*u,*v,yc,yr,yr1,*yv; | |
281 v=AS(y); yr=v[0]; yc=v[1]; yr1=yr-1; | |
282 RZ(d=grade1(eq(a,sc(f)))); dv=AV(d); | |
283 DO(AN(a), if(i!=dv[i]){RZ(q=grade1p(d,y)); qv=AV(q); break;}); | |
284 GA(p,B01,yr,1,0); pv=BAV(p); memset(pv,C0,yr); | |
285 u=yv=AV(y); m=mm=0; j=-1; if(qv)v=yv+yc*qv[0]; | |
286 for(k=0;k<yr1;++k){ | |
287 if(qv){u=v; v=yv+yc*qv[1+k];}else v=u+yc; | |
288 DO(yc-1, if(u[dv[i]]!=v[dv[i]]){++m; pv[k]=1; mm=MAX(mm,k-j); j=k; break;}); | |
289 if(!qv)u+=yc; | |
290 } | |
291 if(yr){++m; pv[yr1]=1; mm=MAX(mm,yr1-j);} | |
292 if(qv){j=mm*aii(x); GA(xx,AT(x),j,1,0); xxv=CAV(xx);} | |
293 switch(id){ | |
294 case CPLUS: case CPLUSDOT: j=!equ(e,zero); break; | |
295 case CSTAR: case CSTARDOT: j=!equ(e,one); break; | |
296 case CMIN: j=!equ(e,zt&B01?one :zt&INT?sc(IMAX):ainf ); break; | |
297 case CMAX: j=!equ(e,zt&B01?zero:zt&INT?sc(IMIN):scf(infm)); break; | |
298 case CEQ: j=!*BAV(e); break; | |
299 case CNE: j= *BAV(e); break; | |
300 } | |
301 if(j)GA(sn,INT,m,1,0); | |
302 *zm=m; *zdv=dv; *zpv=pv; *zqv=qv; *zxxv=xxv; *zsn=sn; | |
303 R 1; | |
304 } | |
305 | |
306 static B jtredspse(J jt,C id,I wm,I xt,A e,A zx,A sn,A*ze,A*zzx){A b;B nz;I t,zt; | |
307 RZ(b=ne(zero,sn)); nz=!all0(b); zt=AT(zx); | |
308 switch(id){ | |
309 case CPLUS: if(nz)RZ(zx=plus (zx, tymes(e,sn) )); RZ(e= tymes(e,sc(wm)) ); break; | |
310 case CSTAR: if(nz)RZ(zx=tymes(zx,bcvt(1,expn2(e,sn)))); RZ(e=bcvt(1,expn2(e,sc(wm)))); break; | |
311 case CPLUSDOT: if(nz)RZ(zx=gcd(zx,from(b,over(zero,e)))); break; | |
312 case CSTARDOT: if(nz)RZ(zx=lcm(zx,from(b,over(one ,e)))); break; | |
313 case CMIN: if(nz)RZ(zx=minimum(zx,from(b,over(zt&B01?one: zt&INT?sc(IMAX):ainf, e)))); break; | |
314 case CMAX: if(nz)RZ(zx=maximum(zx,from(b,over(zt&B01?zero:zt&INT?sc(IMIN):scf(infm),e)))); break; | |
315 case CEQ: ASSERT(B01&xt,EVNONCE); if(nz)RZ(zx=eq(zx,eq(zero,residue(num[2],sn)))); if(!(wm%2))e=one; break; | |
316 case CNE: ASSERT(B01&xt,EVNONCE); if(nz)RZ(zx=ne(zx,eq(one, residue(num[2],sn)))); if(!(wm%2))e=zero; break; | |
317 } | |
318 if(AT(e)!=AT(zx)){t=maxtype(AT(e),AT(zx)); if(t!=AT(zx))RZ(zx=cvt(t,zx));} | |
319 *ze=e; *zzx=zx; | |
320 R 1; | |
321 } | |
322 | |
323 static A jtredsps(J jt,A w,A self,C id,VF ado,I cv,I f,I r,I zt){A a,a1,e,sn,x,x1=0,y,z,zx,zy;B*pv; | |
324 C*xv,*xxv,*zv;I*dv,i,m,n,*qv,*sv,*v,wr,xk,xt,wm,*ws,xc,yc,yr,*yu,*yv,zk;P*wp,*zp; | |
325 RZ(w); | |
326 ASSERT(strchr(fca,id),EVNONCE); | |
327 wr=AR(w); ws=AS(w); wm=ws[f]; | |
328 wp=PAV(w); a=SPA(wp,a); e=SPA(wp,e); | |
329 y=SPA(wp,i); v=AS(y); yr=v[0]; yc=v[1]; yv=AV(y); | |
330 x=SPA(wp,x); xt=AT(x); xc=aii(x); | |
331 RZ(redspsprep(id,f,zt,a,e,x,y,&m,&dv,&pv,&qv,&xxv,&sn)); | |
332 xv=CAV(x); xk=xc*bp(xt); | |
333 GA(zx,zt,m*xc,AR(x),AS(x)); *AS(zx)=m; zv=CAV(zx); zk=xc*bp(zt); | |
334 GA(zy,INT,m*(yc-1),2,0); v=AS(zy); v[0]=m; v[1]=yc-1; yu=AV(zy); | |
335 v=qv; if(sn)sv=AV(sn); | |
336 for(i=0;i<m;++i){A y;B*p1;C*u;I*vv; | |
337 p1=1+(B*)memchr(pv,C1,yr); n=p1-pv; if(sn)sv[i]=wm-n; pv=p1; | |
338 vv=qv?yv+yc**v:yv; DO(yc-1, *yu++=vv[dv[i]];); | |
339 if(1<n){if(qv){u=xxv; DO(n, MC(u,xv+xk*v[i],xk); u+=xk;);} ado(jt,1L,n*xc,n,zv,qv?xxv:xv); RE(0);} | |
340 else if(zk==xk)MC(zv,qv?xv+xk**v:xv,xk); | |
341 else {if(!x1)GA(x1,xt,xc,1,0); MC(AV(x1),qv?xv+xk**v:xv,xk); RZ(y=cvt(zt,x1)); MC(zv,AV(y),zk);} | |
342 zv+=zk; if(qv)v+=n; else{xv+=n*xk; yv+=n*yc;} | |
343 } | |
344 if(sn)RZ(redspse(id,wm,xt,e,zx,sn,&e,&zx)); | |
345 RZ(a1=ca(a)); v=AV(a1); n=0; DO(AN(a), if(f!=v[i])v[n++]=v[i]-(f<v[i]);); | |
346 GA(z,STYPE(AT(zx)),1,wr-1,ws); if(1<r)ICPY(f+AS(z),f+1+ws,r-1); | |
347 zp=PAV(z); | |
348 SPB(zp,a,vec(INT,n,v)); | |
349 SPB(zp,e,cvt(AT(zx),e)); | |
350 SPB(zp,x,zx); | |
351 SPB(zp,i,zy); | |
352 R z; | |
353 } /* f/"r w for sparse w, rank > 1, sparse axis */ | |
354 | |
355 static DF1(jtreducesp){A a,g,x,y,z;B b;C id;I cv,f,n,r,rr[2],*v,wn,wr,*ws,wt,zt;P*wp;VF ado; | |
356 RZ(w); | |
357 wr=AR(w); r=jt->rank?jt->rank[1]:wr; f=wr-r; | |
358 wn=AN(w); ws=AS(w); n=r?ws[f]:1; | |
359 wt=AT(w); wt=wn?DTYPE(wt):B01; | |
360 g=VAV(self)->f; id=vaid(g); | |
361 if(!n)R red0(w,self); | |
362 vains(id,wt,&ado,&cv); | |
363 if(2==n&&!(ado&&strchr(fca,id))){ | |
364 rr[0]=0; rr[1]=r; | |
365 jt->rank=rr; x=from(zero,w); | |
366 jt->rank=rr; y=from(one, w); | |
367 R df2(x,y,g); | |
368 } | |
369 if(!ado)R redg(w,self); | |
370 if(1==n)R tail(w); | |
371 zt=rtype(cv); | |
372 jt->rank=0; | |
373 if(1==wr)z=redsp1(w,self,id,ado,cv,f,r,zt); | |
374 else{ | |
375 wp=PAV(w); a=SPA(wp,a); v=AV(a); | |
376 b=0; DO(AN(a), if(f==v[i]){b=1; break;}); | |
377 z=b?redsps(w,self,id,ado,cv,f,r,zt):redspd(w,self,id,ado,cv,f,r,zt); | |
378 } | |
379 R jt->jerr==EWOV?(rr[1]=r,jt->rank=rr,reducesp(w,self)):z; | |
380 } /* f/"r for sparse w */ | |
381 | |
382 #define BR2IFX(T,F) {T*u=(T*)wv,*v=u+d,x,y; \ | |
383 GA(z,B01,wn/2,wr-1,ws); zv=BAV(z); \ | |
384 if(1<d)DO(m, DO(d, x=*u++; y=*v++; *zv++=x F y; ); u+=d; v+=d;) \ | |
385 else DO(m, x=*u++; y=*u++; *zv++=x F y; ); \ | |
386 } | |
387 #define BR2PFX(T,F) {T*u=(T*)wv,*v=u+d,x,y; \ | |
388 GA(z,B01,wn/2,wr-1,ws); zv=BAV(z); \ | |
389 if(1<d)DO(m, DO(d, x=*u++; y=*v++; *zv++=F(x,y);); u+=d; v+=d;) \ | |
390 else DO(m, x=*u++; y=*u++; *zv++=F(x,y); ); \ | |
391 } | |
392 #define BTABIFX(F) {btab[0 ]=0 F 0; \ | |
393 btab[SYS&SYS_LILENDIAN?256: 1]=0 F 1; \ | |
394 btab[SYS&SYS_LILENDIAN? 1:256]=1 F 0; \ | |
395 btab[257 ]=1 F 1; \ | |
396 } | |
397 #define BTABPFX(F) {btab[0 ]=F(0,0); \ | |
398 btab[SYS&SYS_LILENDIAN?256: 1]=F(0,1); \ | |
399 btab[SYS&SYS_LILENDIAN? 1:256]=F(1,0); \ | |
400 btab[257 ]=F(1,1); \ | |
401 } | |
402 #define BR2CASE(t,id) ((id)+256*(t)) | |
403 | |
404 static B jtreduce2(J jt,A w,C id,I f,I r,A*zz){A z=0;B b=0,btab[258],*zv;I c,d,m,wn,wr,*ws,*wv; | |
405 wn=AN(w); wr=AR(w); ws=AS(w); wv=AV(w); | |
406 m=prod(f,ws); c=m?wn/m:prod(r,f+ws); d=c/2; | |
407 switch(BR2CASE(AT(w),id)){ | |
408 case BR2CASE(B01,CEQ ): if(b=1==r)BTABIFX(== ); break; | |
409 case BR2CASE(B01,CNE ): if(b=1==r)BTABIFX(!= ); break; | |
410 case BR2CASE(B01,CLT ): if(b=1==r)BTABIFX(< ); break; | |
411 case BR2CASE(B01,CLE ): if(b=1==r)BTABIFX(<= ); break; | |
412 case BR2CASE(B01,CGT ): if(b=1==r)BTABIFX(> ); break; | |
413 case BR2CASE(B01,CGE ): if(b=1==r)BTABIFX(>= ); break; | |
414 case BR2CASE(B01,CMAX ): | |
415 case BR2CASE(B01,CPLUSDOT): if(b=1==r)BTABIFX(|| ); break; | |
416 case BR2CASE(B01,CPLUSCO ): if(b=1==r)BTABPFX(BNOR ); break; | |
417 case BR2CASE(B01,CMIN ): | |
418 case BR2CASE(B01,CSTAR ): | |
419 case BR2CASE(B01,CSTARDOT): if(b=1==r)BTABIFX(&& ); break; | |
420 case BR2CASE(B01,CSTARCO ): if(b=1==r)BTABPFX(BNAND); break; | |
421 case BR2CASE(LIT,CEQ ): BR2IFX(C,== ); break; | |
422 case BR2CASE(LIT,CNE ): BR2IFX(C,!= ); break; | |
423 case BR2CASE(INT,CEQ ): BR2IFX(I,== ); break; | |
424 case BR2CASE(INT,CLT ): BR2IFX(I,< ); break; | |
425 case BR2CASE(INT,CLE ): BR2IFX(I,<= ); break; | |
426 case BR2CASE(INT,CGT ): BR2IFX(I,> ); break; | |
427 case BR2CASE(INT,CGE ): BR2IFX(I,>= ); break; | |
428 case BR2CASE(INT,CNE ): BR2IFX(I,!= ); break; | |
429 case BR2CASE(FL, CEQ ): BR2PFX(D,TEQ); break; | |
430 case BR2CASE(FL, CLT ): BR2PFX(D,TLT); break; | |
431 case BR2CASE(FL, CLE ): BR2PFX(D,TLE); break; | |
432 case BR2CASE(FL, CGT ): BR2PFX(D,TGT); break; | |
433 case BR2CASE(FL, CGE ): BR2PFX(D,TGE); break; | |
434 case BR2CASE(FL, CNE ): BR2PFX(D,TNE); break; | |
435 } | |
436 if(b){S*u=(S*)wv; GA(z,B01,wn/2,wr-1,ws); zv=BAV(z); DO(m, *zv++=btab[*u++];);} | |
437 if(z&&1<r){I*u=f+AS(z),*v=f+1+ws; DO(r-1, *u++=*v++;);} | |
438 *zz=z; | |
439 R 1; | |
440 } /* f/"r for dense w over an axis of length 2 */ | |
441 | |
442 static DF1(jtreduce){A z;C id;I c,cv,f,m,n,r,rr[2],t,wn,wr,*ws,wt,zt;VF ado; | |
443 RZ(w); | |
444 wr=AR(w); r=jt->rank?jt->rank[1]:wr; f=wr-r; | |
445 wn=AN(w); ws=AS(w); n=r?ws[f]:1; | |
446 if(SPARSE&AT(w))R reducesp(w,self); | |
447 wt=AT(w); wt=wn?wt:B01; | |
448 id=vaid(VAV(self)->f); | |
449 switch(n){ | |
450 case 0: R red0(w,self); | |
451 case 1: R tail(w); | |
452 case 2: RZ(reduce2(w,id,f,r,&z)); if(z)R z; | |
453 } | |
454 vains(id,wt,&ado,&cv); | |
455 if(!ado)R redg(w,self); | |
456 zt=rtype(cv); jt->rank=0; | |
457 GA(z,zt,wn/n,MAX(0,wr-1),ws); if(1<r)ICPY(f+AS(z),f+1+ws,r-1); | |
458 if((t=atype(cv))&&t!=wt)RZ(w=cvt(t,w)); | |
459 m=prod(f,ws); c=m?wn/m:prod(r,f+ws); | |
460 ado(jt,m,c,n,AV(z),AV(w)); | |
461 if(jt->jerr)R jt->jerr==EWOV?(rr[1]=r,jt->rank=rr,reduce(w,self)):0; else R cv&VRI+VRD?cvz(cv,z):z; | |
462 } /* f/"r w main control */ | |
463 | |
464 static A jtredcatsp(J jt,A w,A z,I r){A a,q,x,y;B*b;I c,d,e,f,j,k,m,n,n1,p,*u,*v,wr,*ws,xr;P*wp,*zp; | |
465 ws=AS(w); wr=AR(w); f=wr-r; p=ws[1+f]; | |
466 wp=PAV(w); x=SPA(wp,x); y=SPA(wp,i); a=SPA(wp,a); v=AV(a); | |
467 m=*AS(y); n=AN(a); n1=n-1; xr=AR(x); | |
468 RZ(b=bfi(wr,a,1)); | |
469 c=b[f]; d=b[1+f]; if(c&&d)b[f]=0; e=f+!c; | |
470 j=0; DO(n, if(e==v[i]){j=i; break;}); | |
471 k=1; DO(f, if(!b[i])++k;); | |
472 zp=PAV(z); SPB(zp,e,ca(SPA(wp,e))); | |
473 GA(q,INT,n-(c&&d),1,0); v=AV(q); DO(wr, if(b[i])*v++=i-(i>f);); SPB(zp,a,q); | |
474 if(c&&d){ /* sparse sparse */ | |
475 SPB(zp,x,ca(x)); | |
476 SPB(zp,i,q=repeatr(ne(a,sc(f)),y)); | |
477 v=j+AV(q); u=j+AV(y); | |
478 DO(m, *v=p*u[0]+u[1]; v+=n1; u+=n;); | |
479 }else if(!c&&!d){ /* dense dense */ | |
480 u=AS(x); GA(q,AT(x),AN(x),xr-1,u); v=k+AS(q); *v=u[k]*u[1+k]; ICPY(1+v,2+k+u,xr-k-2); | |
481 MC(AV(q),AV(x),AN(x)*bp(AT(x))); | |
482 SPB(zp,x,q); SPB(zp,i,ca(y)); | |
483 }else{ /* other */ | |
484 GA(q,INT,xr,1,0); v=AV(q); | |
485 if(1!=k){*v++=0; *v++=k; e=0; DO(xr-1, ++e; if(e!=k)*v++=e;); RZ(x=cant2(q,x));} | |
486 v=AV(q); u=AS(x); *v=u[0]*u[1]; ICPY(1+v,2+u,xr-1); RZ(x=reshape(vec(INT,xr-1,v),x)); | |
487 e=ws[f+c]; RZ(y=repeat(sc(e),y)); v=j+AV(y); | |
488 if(c)DO(m, k=p**v; DO(e, *v=k+ i; v+=n;);) | |
489 else DO(m, k= *v; DO(e, *v=k+p*i; v+=n;);); | |
490 RZ(q=grade1(y)); RZ(y=from(q,y)); RZ(x=from(q,x)); | |
491 SPB(zp,x,x); SPB(zp,i,y); | |
492 } | |
493 R z; | |
494 } /* ,/"r w for sparse w, 2<r */ | |
495 | |
496 static DF1(jtredcat){A z;B b;I f,r,*s,*v,wr; | |
497 RZ(w); | |
498 wr=AR(w); r=jt->rank?jt->rank[1]:wr; f=wr-r; s=AS(w); jt->rank=0; | |
499 b=1==r&&1==s[f]; | |
500 if(2>r&&!b)R ca(w); | |
501 GA(z,AT(w),AN(w),wr-1,s); | |
502 if(!b){v=f+AS(z); RE(*v=mult(s[f],s[1+f])); ICPY(1+v,2+f+s,r-2);} | |
503 if(SPARSE&AT(w))R redcatsp(w,z,r); | |
504 MC(AV(z),AV(w),AN(w)*bp(AT(w))); | |
505 if(ARELATIVE(w)){AFLAG(z)=AFREL; z=relocate((I)w-(I)z,z);} | |
506 R z; | |
507 } /* ,/"r w */ | |
508 | |
509 static DF1(jtredsemi){I f,n,r,*s,wr; | |
510 RZ(w); | |
511 wr=AR(w); r=jt->rank?jt->rank[1]:wr; f=wr-r; s=AS(w); n=r?s[f]:1; | |
512 if(2>n){ASSERT(n,EVDOMAIN); R tail(w);} | |
513 if(BOX&AT(w))R irs2(rank1ex(curtail(w),0L,r-1,jtbox),tail(w),0L,r,r-1,jtover); | |
514 else R irs1(w,0L,r-1,jtbox); | |
515 } /* ;/"r w */ | |
516 | |
517 static DF1(jtredstitch){A c,y;I f,n,r,*s,*v,wr; | |
518 RZ(w); | |
519 wr=AR(w); r=jt->rank?jt->rank[1]:wr; f=wr-r; jt->rank=0; | |
520 s=AS(w); n=r?s[f]:1; | |
521 ASSERT(n,EVDOMAIN); | |
522 if(1==n)R irs1(w,0L,r,jthead); | |
523 if(1==r)R 2==n?ca(w):irs2(irs2(num[-2],w,0L,0L,1L,jtdrop),irs2(num[-2],w,0L,0L,1L,jttake),0L,1L,0L,jtover); | |
524 if(2==r)R irs1(w,0L,2L,jtcant1); | |
525 RZ(c=IX(wr)); v=AV(c); v[f]=f+1; v[f+1]=f; RZ(y=cant2(c,w)); | |
526 if(SPARSE&AT(w)){A x; | |
527 GA(x,INT,f+r-1,1,0); v=AV(x); ICPY(v,AS(y),f+1); | |
528 RE(v[f+1]=mult(s[f],s[f+2])); ICPY(v+f+2,s+3+f,r-3); | |
529 R reshape(x,y); | |
530 }else{ | |
531 v=AS(y); | |
532 RE(v[f+1]=mult(s[f],s[f+2])); ICPY(v+f+2,s+3+f,r-3); | |
533 --AR(y); | |
534 R y; | |
535 }} /* ,./"r w */ | |
536 | |
537 static DF1(jtredstiteach){A*wv,y;I n,p,r,t,wd; | |
538 RZ(w); | |
539 n=AN(w); | |
540 if(!(2<n&&1==AR(w)&&BOX&AT(w)))R reduce(w,self); | |
541 wv=AAV(w); wd=(I)w*ARELATIVE(w); y=WVR(0); p=IC(y); t=AT(y); | |
542 DO(n, y=WVR(i); r=AR(y); if(!(r&&r<=2&&p==IC(y)&&t==AT(y)))R reduce(w,self);); | |
543 R box(razeh(w)); | |
544 } /* ,.&.>/ w */ | |
545 | |
546 static DF1(jtredcateach){A*u,*v,*wv,x,*xv,z,*zv;I f,m,mn,n,r,wd,wr,*ws,zm,zn; | |
547 RZ(w); | |
548 wr=AR(w); ws=AS(w); r=jt->rank?jt->rank[1]:wr; f=wr-r; jt->rank=0; | |
549 n=r?ws[f]:1; | |
550 if(!r||1>=n)R reshape(repeat(ne(sc(f),IX(wr)),shape(w)),n?w:ace); | |
551 if(!(BOX&AT(w)))R df1(cant2(sc(f),w),qq(ds(CBOX),one)); | |
552 zn=AN(w)/n; zm=prod(f,ws); m=zm?AN(w)/(zm*n):prod(r-1,ws+f+1); mn=m*n; | |
553 GA(z,BOX,zn,wr-1,ws); ICPY(AS(z)+f,ws+f+1,r-1); | |
554 GA(x,BOX,n,1,0); xv=AAV(x); | |
555 zv=AAV(z); wv=AAV(w); wd=(I)w*ARELATIVE(w); | |
556 DO(zm, u=wv; DO(m, v=u++; DO(n, xv[i]=AADR(wd,*v); v+=m;); RZ(*zv++=raze(x));); wv+=mn;); | |
557 R z; | |
558 } /* ,&.>/"r w */ | |
559 | |
560 static DF2(jtoprod){R df2(a,w,VAV(self)->h);} | |
561 | |
562 | |
563 F1(jtslash){A h;AF f1=jtreduce;C c;V*v; | |
564 RZ(w); | |
565 if(NOUN&AT(w))R evger(w,sc(GINSERT)); | |
566 v=VAV(w); | |
567 switch(v->id){ | |
568 case CCOMMA: f1=jtredcat; break; | |
569 case CCOMDOT: f1=jtredstitch; break; | |
570 case CSEMICO: f1=jtredsemi; break; | |
571 case CUNDER: if(COPE==ID(v->g)){c=ID(v->f); if(c==CCOMMA)f1=jtredcateach; else if(c==CCOMDOT)f1=jtredstiteach;} | |
572 } | |
573 RZ(h=qq(w,v2(lr(w),RMAX))); | |
574 R fdef(CSLASH,VERB, f1,jtoprod, w,0L,h, 0L, RMAX,RMAX,RMAX); | |
575 } | |
576 | |
577 A jtaslash (J jt,C c, A w){RZ( w); R df1( w, slash(ds(c)) );} | |
578 A jtaslash1(J jt,C c, A w){RZ( w); R df1( w,qq(slash(ds(c)),one));} | |
579 A jtatab (J jt,C c,A a,A w){RZ(a&&w); R df2(a,w, slash(ds(c)) );} | |
580 | |
581 | |
582 static AHDRR(jtmeanD,D,D){I d,i;D*y;D v,*zz; | |
583 d=c/n; | |
584 NAN0; | |
585 if(1==d)DO(m, v= *x++; DO(n-1, v+=*x++;); *z++=v/n;) | |
586 else for(i=0;i<m;++i){ | |
587 y=x; x+=d; zz=z; DO(d, *z++ =*x+++ *y++;); | |
588 DO(n-3, z=zz; DO(d, *z+++=*x++; )); | |
589 z=zz; DO(d, *z =(*z+*x++)/n; ++z;); | |
590 } | |
591 NAN1V; | |
592 } /* based on REDUCEPFX; 2<n */ | |
593 | |
594 static AHDRR(jtmeanI,D,I){I d,i;I*y;D v,*zz; | |
595 d=c/n; | |
596 if(1==d)DO(m, v=(D)*x++; DO(n-1, v+=*x++;); *z++=v/n;) | |
597 else for(i=0;i<m;++i){ | |
598 y=x; x+=d; zz=z; DO(d, *z++ =*x+++(D)*y++;); | |
599 DO(n-3, z=zz; DO(d, *z+++=*x++; )); | |
600 z=zz; DO(d, *z =(*z+*x++)/n; ++z;); | |
601 }} /* based on REDUCEPFX; 2<n */ | |
602 | |
603 DF1(jtmean){A z;I c,f,m,n,r,wn,wr,*ws,wt; | |
604 RZ(w); | |
605 wr=AR(w); r=jt->rank?jt->rank[1]:wr; f=wr-r; jt->rank=0; | |
606 wt=AT(w); wn=AN(w); ws=AS(w); n=r?ws[f]:1; | |
607 if(!(wn&&2<n&&wt&INT+FL))R divide(df1(w,qq(slash(ds(CPLUS)),sc(r))),sc(n)); | |
608 GA(z,FL,wn/n,MAX(0,wr-1),ws); if(1<r)ICPY(f+AS(z),f+1+ws,r-1); | |
609 m=prod(f,ws); c=m?wn/m:prod(r,f+ws); | |
610 if(wt&INT)meanI(m,c,n,DAV(z), AV(w)); | |
611 else meanD(m,c,n,DAV(z),DAV(w)); | |
612 RE(0); R z; | |
613 } /* (+/%#)"r w */ |