Mercurial > hg > jgplsrc
view vs.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 |
line wrap: on
line source
/* Copyright 1990-2011, Jsoftware Inc. All rights reserved. */ /* License in license.txt. */ /* */ /* Verbs: $. Sparse Arrays */ #include "j.h" B jtscheck(J jt,A w){A a,e,x,y;I r,*s,t;P*p; RZ(w); r=AR(w); s=AS(w); t=AT(w); if(t&DENSE)R 1; ASSERTSYS(r,"scheck rank"); DO(r, ASSERTSYS(0<=s[i],"scheck shape");); p=PAV(w); a=SPA(p,a); e=SPA(p,e); y=SPA(p,i); x=SPA(p,x); ASSERTSYS(a,"scheck a missing"); ASSERTSYS(e,"scheck e missing"); ASSERTSYS(y,"scheck i missing"); ASSERTSYS(x,"scheck x missing"); ASSERTSYS(1==AR(a),"scheck a rank"); ASSERTSYS(all1(eps(a,IX(r))),"scheck a index"); ASSERTSYS(equ(a,nub(a)),"scheck a unique"); ASSERTSYS(!AR(e),"scheck e rank"); ASSERTSYS(AT(e)==DTYPE(t),"scheck e type"); ASSERTSYS(AT(e)==AT(x),"scheck e/x type"); ASSERTSYS(2==AR(y),"scheck i rank"); ASSERTSYS(INT&AT(y),"scheck i type"); ASSERTSYS(IC(y)==IC(x),"scheck i/x tally"); ASSERTSYS(*(1+AS(y))==IC(a),"scheck i/a length"); ASSERTSYS(equ(y,nub(y)),"scheck i unique"); ASSERTSYS(all1(le(zero,y)),"scheck i negative"); ASSERTSYS(all1(irs2(y,from(a,shape(w)),0L,1L,1L,jtlt)),"scheck i index"); ASSERTSYS(equ(grade1(y),IX(*AS(y))),"scheck i sorted"); ASSERTSYS(AR(x)==1+r-AN(a),"scheck x rank"); ASSERTSYS(equ(behead(shape(x)),from(less(IX(r),a),shape(w))),"scheck x shape"); R 1; } /* assertions on sparse array w */ static A jtselm(J jt,I t){R t&NUMERIC?cvt(t,zero):t&BOX?ace:chr[' '];} A jtpaxis(J jt,I r,A a){A y,z;B*b;I j,*u,*v; RZ(a); if(!(INT&AT(a)))RZ(a=cvt(INT,a)); u=AV(a); GA(y,B01,r,1,0); b=BAV(y); memset(b,C0,r); DO(AN(a), j=u[i]; b[0>j?j+r:j]=1;); GA(z,INT,r,1,0); v= AV(z); DO(r, if( b[i])*v++=i;); DO(r, if(!b[i])*v++=i;); R z; } /* permuted axes per sparse axes specification a */ static A jtvaxis(J jt,I r,A a){A y;B*b;I j,n,*v; RZ(a=cvt(INT,a)); n=AN(a); v=AV(a); ASSERT(1>=AR(a),EVRANK); GA(y,B01,r,1,0); b=BAV(y); memset(b,C0,r); DO(n, j=v[i]; if(0>j)j+=r; ASSERT(0<=j&&j<r&&!b[j],EVINDEX); b[j]=1;); R ifb(r,b); } /* standardize axes to be non-negative, sorted */ A jtdaxis(J jt,I r,A a){R less(IX(r),a);} /* dense axes relative to sparse axes a */ static A jtsparse1a(J jt,A s,A a,A e,A y,A x){A z;B*b;I an,*av,et,r,*sv,t,*v;P*p; RZ(s&&a&&e); RZ(s=vi(s)); r=AN(s); sv=AV(s); ASSERT(1>=AR(s),EVRANK); ASSERT(r,EVLENGTH); ASSERT(r<=RMAX,EVLIMIT); DO(r, ASSERT(0<=sv[i],EVDOMAIN);); RZ(a=vaxis(r,a==mark?IX(r):a)); an=AN(a); av=AV(a); if(e==mark)RZ(e=scf(0.0)); ASSERT(!AR(e),EVRANK); et=AT(e); ASSERT(!(et&LIT+BOX),EVNONCE); ASSERT(STYPE(et),EVDOMAIN); RZ(b=bfi(r,a,0)); if(y==mark){ GA(y,INT,0L,2L,0L); v=AS(y); v[0]=0; v[1]=an; GA(x,et,0L,1+r-an,0L); v=AS(x); v[0]=0; DO(r, if(b[i])*++v=sv[i];); }else{A q,x1,y1;C*xu,*xv;I i,j,k,m,n,*qv,*u,*yu,*yv; ASSERT(2==AR(y),EVRANK); ASSERT(an==*(1+AS(y)),EVLENGTH); if(!(INT&AT(y)))RZ(y=cvt(INT,y)); GA(q,INT,an,1,0); qv=AV(q); DO(an, qv[i]=sv[av[i]];); u=AV(y); DO(*AS(y), DO(an, j=*u++; ASSERT(0<=j&&j<qv[i],EVINDEX););); ASSERT(AR(x)==1+r-an,EVRANK); v=AS(x); DO(r, if(b[i]){j=*++v; ASSERT(j==sv[i],EVLENGTH);}); ASSERT(*AS(x)==*AS(y),EVLENGTH); ASSERT(HOMO(et,AT(x)),EVDOMAIN); t=maxtype(et,AT(x)); if(t!=et )RZ(e=cvt(t,e)); if(t!=AT(x))RZ(x=cvt(t,x)); n=*AS(y)-1; u=AV(y); v=an+u; for(i=0;i<n;++i){ j=0; DO(an, if(u[i]<v[i]){j=-1; break;}else if(u[i]>v[i]){j=1; break;}); if(0<=j)break; u+=an; v+=an; } if(n&&0<=j){ m=aii(x); k=m*bp(t); RZ(q=grade1(y)); qv=AV(q); GA(y1,INT,AN(y),AR(y),AS(y)); yv= AV(y1); yu= AV(y); ICPY(yv,yu+an**qv,an); GA(x1,t, AN(x),AR(x),AS(x)); xv=CAV(x1); xu=CAV(x); MC(xv,xu+k**qv,k); for(i=0;i<n;++i){ ++qv; v=yu+an**qv; DO(an, if(yv[i]<v[i]){yv+=an; ICPY(yv,v,an); xv+=k; MC(xv,xu+k**qv,k); break;}); } yv+=an; AN(y1)=yv-AV(y1); *AS(y1)=AN(y1)/an; y=y1; xv+=k; *AS(x1)=(xv-CAV(x1))/k; AN(x1)=m**AS(x1); x=x1; }} t=STYPE(AT(x)); ASSERT(t,EVDOMAIN); GA(z,t,1,r,sv); p=PAV(z); SPB(p,a,a); SPB(p,e,e); SPB(p,i,y); SPB(p,x,x); R z; } A jtsparseit(J jt,A w,A a,A e){PROLOG;A ax,c,x,y,z;B b,*cv;I cm,cn,m,n,r,*s,t,*u,*v,wn;P*p; RZ(w&&a&&e); r=AR(w); t=AT(w); wn=AN(w); n=AN(a); ASSERT(!(t&LIT+BOX),EVNONCE); ASSERT(STYPE(t),EVDOMAIN); if(!r){ASSERT(!AN(a),EVINDEX); R ca(w);} RZ(z=sparse1a(shape(w),a,e,mark,mark)); p=PAV(z); RZ(ax=paxis(r,a)); GA(y,INT,r,1,0); s=AV(y); u=AV(ax); v=AS(w); DO(r, s[i]=v[u[i]];); RE(m=prod(n,s)); b=equ(a,IX(r)); RZ(x=gah(1+r-n,b?w:cant2(ax,w))); v=AS(x); *v=m; if(r>n)ICPY(1+v,n+s,r-n); b=b&&SB01&AT(z)&&equ(e,zero); c=w; if(!b)RZ(c=not(irs2(reshape(vec(INT,r-n,n+s),SPA(p,e)),x,0L,RMAX,-1L,jtmatch))); cn=AN(c); cv=BAV(c); cm=bsum(cn,cv); /* RZ(y=abase2(vec(INT,n,s),repeat(c,IX(cn)))); */ GA(y,INT,cm*n,2,0); u=AS(y); *u++=cm; *u=n; if(cm){I d,e,k,q,*sn,*yv; k=cn-1; cv+=cn; yv=AN(y)+AV(y); sn=s+n; d=*(sn-1); e=*(sn-2); switch(n){ case 1: cv=BAV(c); yv=AV(y); DO(cn, if(*cv++)*yv++=i;); break; case 2: DO(cn, if(*--cv){q=k-i; *--yv=q%d; *--yv=q/d;}); break; case 3: DO(cn, if(*--cv){q=k-i; *--yv=q%d; q/=d; *--yv=q%e; *--yv=q/e;}); break; default: DO(cn, if(*--cv){q=k-i; u=sn; DO(n, d=*--u; *--yv=q%d; q/=d;);}); }} SPB(p,i,y); SPB(p,x,b?reshape(sc(cm),one):repeat(c,x)); EPILOG(z); } F1(jtdenseit){A a,e,q,s1,x,y,z;B b;C*xv,*zv;I an,ck,k,n,r,t,*s,xn,*yv;P*wp; RZ(w); r=AR(w); t=AT(w); if(!r||t&DENSE)R ca(w); t=DTYPE(t); wp=PAV(w); a=SPA(wp,a); e=SPA(wp,e); x=SPA(wp,x); y=SPA(wp,i); xn=AN(x); an=AN(a); b=equ(a,IX(an)); if(!an||!xn)R reshape(shape(w),xn?x:e); if(b)s=AS(w); else{RZ(q=over(a,less(IX(r),a))); RZ(s1=from(q,shape(w))); s=AV(s1);} RE(n=prod(r,s)); GA(z,t,n,r,s); zv=CAV(z); xv=CAV(x); if(1<an)RZ(y=base2(vec(INT,an,s),y)); yv=AV(y); k=bp(t); ck=k*aii(x); mvc(k*n,zv,k,AV(e)); DO(IC(y), MC(zv+ck**yv,xv,ck); ++yv; xv+=ck;); R b?z:cant2(pinv(q),z); } /* $.^:_1 */ F2(jtreaxis){A a1,e,p,q,x,y,z;B*b;I c,d,j,k,m,r,*u,*v,*ws,wt;P*wp,*zp; RZ(a&&w); wt=AT(w); if(wt&DENSE)R sparseit(w,a,selm(wt)); r=AR(w); ws=AS(w); wp=PAV(w); GA(z,wt,1L,r,ws); zp=PAV(z); SPB(zp,a,a1=vaxis(r,a)); SPB(zp,e,e=ca(SPA(wp,e))); a=SPA(wp,a); x=SPA(wp,x); y=SPA(wp,i); m=*AS(y); if(all1(eps(a,a1))){I*s; /* old is subset of new */ RZ(p=eps(daxis(r,a),a1)); b=BAV(p); GA(q,INT,1+r,1,0); u=AV(q); j=1; GA(q,INT,1+r,1,0); v=AV(q); k=0; s=AS(x); c=1; DO(AN(p), d=s[1+i]; if(b[i]){c*=d; v[k++]=d;}else u[j++]=d;); *u=c*m; RZ(x=reshape(vec(INT,j,u),cant2(increm(dgrade1(p)),x))); RZ(q=not(irs2(x,reshape(vec(INT,AR(x)-1,1+AS(x)),e),0L,-1L,RMAX,jtmatch))); SPB(zp,x,x=repeat(q,x)); RZ(y=stitch(repeat(sc(c),y),reshape(v2(c*m,k),abase2(vec(INT,k,v),IX(c))))); RZ(p=grade1(over(a,less(a1,a)))); if(equ(p,IX(AN(p))))SPB(zp,i,repeat(q,y)) else{y=fromr(p,repeat(q,y)); q=grade1(y); SPB(zp,i,from(q,y)); SPB(zp,x,from(q,x));} R z; } if(all1(eps(a1,a))){A x1,y1;B*pv;C*s,*t;I g,h,*iv,n; /* new is subset of old */ c=AN(a); d=AN(a1); RZ(p=eps(a,a1)); RZ(y=fromr(dgrade1(p),y)); RZ(q=grade1(y)); RZ(y=from(q,y)); RZ(x=from(q,x)); GA(q,B01,m,1,0); b=BAV(q); n=0; if(m){b[m-1]=1; n=1; u=AV(y); DO(m-1, if(b[i]=1&&ICMP(u,u+c,d))++n; u+=c;);} GA(q,INT,1+r,1,0); u=AV(q); j=0; v=AV(a); pv=BAV(p); DO(AN(p), if(!pv[i])u[j++]=ws[v[i]];); RE(prod(j,u)); u[j]=k=1; DO(c-d, --j; u[j]=k*=u[j];); RZ(q=pdt(take(v2(m,d-c),y),vec(INT,c-d,1+u))); iv=AV(q); RZ(p=over(less(a,a1),daxis(r,a))); v=AV(p); *u=n; j=1; DO(AN(p), u[j++]=ws[*v++];); RE(h=prod(1+r-d,u)); GA(x1,AT(x),h,1+r-d,u); t=CAV(x1); s=CAV(x); GA(y1,INT,n*d,2,0); *AS(y1)=n; *(1+AS(y1))=d; v= AV(y1); u= AV(y); k=bp(AT(x)); g=k*aii(x); h=k*aii(x1); mvc(k*AN(x1),t,k,AV(e)); DO(m, MC(t+g*iv[i],s,g); s+=g; if(b[i]){ICPY(v,u+i*c,d); v+=d; t+=h;}); SPB(zp,i,y1); SPB(zp,x,cant2(increm(indexof(p,daxis(r,a1))),x1)); R z; } R reaxis(a1,reaxis(over(a,less(a1,a)),w)); } /* (2;a)$.w */ static A jtaxbytes1(J jt,I t,I an,I m,I xr,I*xs){I k,z; k=bp(t); z =SZI*AH+SZI*(an+xr)+sizeof(P); z+=SZI*AH+k; z+=SZI*AH+SZI*(1+xr)+k*m*prod(xr,xs); z+=SZI*AH+SZI*2+SZI*m*an; R sc(z); } static F2(jtaxbytes){A a1,e,p,q,x;B*b;I c,d,j,m,n=0,r,*u,*v,*ws,wt;P*wp; RZ(a&&w); r=AR(w); ws=AS(w); wt=AT(w); GA(q,INT,r,1,0); u=AV(q); j=0; RZ(a1=vaxis(r,a)); d=AN(a1); if(wt&SPARSE){wp=PAV(w); a=SPA(wp,a); e=SPA(wp,e); x=SPA(wp,x); c=1;} else { a=mtv; RZ(e=selm(wt)); x=w; c=0;} if(all1(eps(a,a1))){ /* old is subset of new */ RZ(p=eps(daxis(r,a),a1)); b=BAV(p); v=c+AS(x); DO(AN(p), if(!b[i])u[j++]=v[i];); RZ(q=irs2(cant2(plus(sc(c),dgrade1(p)),x),reshape(vec(INT,j,u),e),0L,j,j,jtmatch)); b=BAV(q); n=AN(q); DO(n, if(*b++)--n;); R axbytes1(AT(e),d,n,j,u); } if(all1(eps(a1,a))){A y=SPA(wp,i); /* new is subset of old */ RZ(y=fromr(indexof(a,a1),y)); RZ(y=grade2(y,y)); if(m=*AS(y)){n=1; u=AV(y); DO(m-1, if(ICMP(u,u+d,d))++n; u+=d;);} RZ(p=over(less(a,a1),daxis(r,a))); v=AV(p); DO(AN(p), u[j++]=ws[*v++];); R axbytes1(AT(e),d,n,j,u); } R axbytes(a1,reaxis(over(a,less(a1,a)),w)); } /* bytes required for (2;a)$.w */ static F2(jtaxtally){A a1,e,p,q,x;B*b;I c,d,j,m,n=0,r,*u,*v,*ws,wt;P*wp; RZ(a&&w); r=AR(w); ws=AS(w); wt=AT(w); GA(q,INT,r,1,0); u=AV(q); j=0; RZ(a1=vaxis(r,a)); d=AN(a1); if(wt&SPARSE){wp=PAV(w); a=SPA(wp,a); e=SPA(wp,e); x=SPA(wp,x); c=1;} else { a=mtv; RZ(e=selm(wt)); x=w; c=0;} if(all1(eps(a,a1))){ /* old is subset of new */ RZ(p=eps(daxis(r,a),a1)); b=BAV(p); v=c+AS(x); DO(AN(p), if(!b[i])u[j++]=v[i];); RZ(q=irs2(cant2(plus(sc(c),dgrade1(p)),x),reshape(vec(INT,j,u),e),0L,j,j,jtmatch)); b=BAV(q); n=AN(q); DO(n, if(*b++)--n;); R sc(n); } if(all1(eps(a1,a))){A y=SPA(wp,i); /* new is subset of old */ RZ(y=fromr(indexof(a,a1),y)); RZ(y=grade2(y,y)); if(m=*AS(y)){n=1; u=AV(y); DO(m-1, if(ICMP(u,u+d,d))++n; u+=d;);} R sc(n); } R axtally(a1,reaxis(over(a,less(a1,a)),w)); } /* #4$.(2;a)$.w */ F2(jtrezero){A x,z;I at,t,wt,zt;P*wp,*zp; RZ(a&&w); at=AT(a); wp=PAV(w); x=SPA(wp,x); wt=AT(x); ASSERT(!AR(a),EVRANK); ASSERT(HOMO(at,wt),EVDOMAIN); RE(t=maxtype(at,wt)); zt=STYPE(t); ASSERT(zt,EVDOMAIN); GA(z,zt,1,AR(w),AS(w)); zp=PAV(z); SPB(zp,e,t==at?ca(a):cvt(t,a)); SPB(zp,a,ca(SPA(wp,a))); SPB(zp,i,ca(SPA(wp,i))); SPB(zp,x,t==wt?ca(x):cvt(t,x)); R z; } /* respecify the sparse element */ F1(jtunzero){A e,q,x,z;I r;P*wp,*zp; RZ(w); wp=PAV(w); e=SPA(wp,e); x=SPA(wp,x); r=AR(x)-1; GA(z,AT(w),1,AR(w),AS(w)); zp=PAV(z); RZ(q=not(irs2(x,reshape(vec(INT,r,1+AS(x)),e),0L,r,r,jtmatch))); SPB(zp,x,repeat(q,x)); SPB(zp,i,repeat(q,SPA(wp,i))); SPB(zp,a,ca(SPA(wp,a))); SPB(zp,e,ca(e)); R z; } /* remove completely sparse cells */ static F1(jtsparsep1){A*wv;I n=0,wd=0; RZ(w); ASSERT(1>=AR(w),EVRANK); if(BOX&AT(w)){n=AN(w); wv=AAV(w); wd=(I)w*ARELATIVE(w); ASSERT(1<=n&&n<=3||5==n,EVLENGTH);} R sparse1a(0<n?WVR(0):w,1<n?WVR(1):mark,2<n?WVR(2):mark,3<n?WVR(3):mark,4<n?WVR(4):mark); } static F1(jtsparsen1){A*u,z;P*p; RZ(w); ASSERT(SPARSE&AT(w),EVDOMAIN); GA(z,BOX,3,1,0); u=AAV(z); p=PAV(w); u[0]=shape(w); u[1]=ca(SPA(p,a)); u[2]=ca(SPA(p,e)); RE(0); R z; } F1(jtsparse1){ RZ(w); if(!AR(w)||SPARSE&AT(w))R ca(w); R sparseit(w,IX(AR(w)),selm(AT(w))); } /* $. y */ F2(jtsparse2){A*av,q=0;B b;I ad,j,k,t,*v;P*p; RZ(a&&w); if(BOX&AT(a)){ ASSERT(1==AR(a),EVRANK); ASSERT(2==AN(a),EVLENGTH); av=AAV(a); ad=(I)a*ARELATIVE(a); a=AVR(0); q=AVR(1); } RZ(a=cvt(INT,a)); ASSERT(1>=AR(a),EVRANK); v=AV(a); k=*v; ASSERT(2==k||!AR(a),EVRANK); ASSERT(2>=AN(a),EVLENGTH); p=PAV(w); t=AT(w); b=1&&t&SPARSE; ASSERT(b||0<=k&&k<=2,EVDOMAIN); switch(k){ case 0: ASSERT(!q,EVDOMAIN); R t&SPARSE?denseit(w):sparse1(w); case 1: ASSERT(!q,EVDOMAIN); R sparsep1(w); case -1: ASSERT(!q,EVDOMAIN); R sparsen1(w); case 2: if(AR(a)){j=v[1]; ASSERT(q&&(1==j||2==j),EVDOMAIN); R 1==j?axbytes(q,w):axtally(q,w);} if(q)R reaxis(q,w); else if(b)R rat(SPA(p,a)); else{ASSERT(STYPE(t),EVDOMAIN); R IX(AR(w));} case 3: R q?rezero(q,w):rat(SPA(p,e)); case 4: ASSERT(!q,EVDOMAIN); R rat(SPA(p,i)); case 5: ASSERT(!q,EVDOMAIN); R rat(SPA(p,x)); case 7: ASSERT(!q,EVDOMAIN); R sc(IC(SPA(p,i))); case 8: ASSERT(!q,EVDOMAIN); R unzero(w); default: ASSERT(0,EVDOMAIN); }} /* x $. y */