PageRenderTime 39ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/vcat.c

https://github.com/barak/core
C | 235 lines | 216 code | 15 blank | 4 comment | 70 complexity | e25525d25793d161226324a1c5323e5e MD5 | raw file
  1. /* Copyright 1990-2011, Jsoftware Inc. All rights reserved. */
  2. /* License in license.txt. */
  3. /* */
  4. /* Verbs: Catenate and Friends */
  5. #include "j.h"
  6. static A jtovs0(J jt,B p,I r,A a,A w){A a1,e,q,x,y,z;B*b;I at,*av,c,d,j,k,f,m,n,t,*v,wr,*ws,wt,zr;P*wp,*zp;
  7. ws=AS(w); wr=AR(w); f=wr-r; zr=wr+!r;
  8. ASSERT(IMAX>ws[f],EVLIMIT);
  9. wp=PAV(w); e=SPA(wp,e); x=SPA(wp,x); y=SPA(wp,i); m=*AS(y);
  10. a1=SPA(wp,a); c=AN(a1); av=AV(a1); RZ(b=bfi(zr,a1,1));
  11. at=AT(a); wt=AT(x);
  12. ASSERT(HOMO(at,wt),EVDOMAIN);
  13. t=maxtype(at,wt);
  14. if(t!=at)RZ(a=cvt(t,a));
  15. if(t!=wt){RZ(x=cvt(t,x)); RZ(e=cvt(t,e));}
  16. j=k=0; DO(f, if(b[i])++j; else ++k;);
  17. switch(2*b[f]+!equ(a,e)){
  18. case 0: /* dense and a equal e */
  19. RZ(y=ca(y));
  20. RZ(x=p?irs2(x,a,0L,AR(x)-(1+k),0L,jtover):irs2(a,x,0L,0L,AR(x)-(1+k),jtover));
  21. break;
  22. case 1: /* dense and a not equal to e */
  23. GA(q,INT,c,1,0); v=AV(q); DO(c, v[i]=ws[av[i]];); RZ(q=odom(2L,c,v));
  24. if(AN(q)>=AN(y)){
  25. RZ(z=shape(x)); *AV(z)=*AS(q);
  26. RZ(x=from(grade1(over(y,less(q,y))),over(x,reshape(z,e))));
  27. y=q;
  28. }
  29. RZ(x=p?irs2(x,a,0L,AR(x)-(1+k),0L,jtover):irs2(a,x,0L,0L,AR(x)-(1+k),jtover));
  30. break;
  31. case 2: /* sparse and a equals e */
  32. RZ(y=ca(y));
  33. if(!p){v=j+AV(y); DO(m, ++*v; v+=c;);}
  34. break;
  35. case 3: /* sparse and a not equal to e */
  36. GA(q,INT,c,1,0); v=AV(q); DO(c, v[i]=ws[av[i]];); v[j]=1; RZ(q=odom(2L,c,v)); n=*AS(q);
  37. if(p){RZ(y=over(y,q)); v=AV(y)+j+m*c; d=ws[f]; DO(n, *v=d; v+=c;);}
  38. else {RZ(y=over(q,y)); v=AV(y)+j+n*c; DO(m, ++*v; v+=c;);}
  39. RZ(q=shape(x)); *AV(q)=n; RZ(q=reshape(q,a)); RZ(x=p?over(x,q):over(q,x));
  40. if(f){RZ(q=grade1(y)); RZ(y=from(q,y)); RZ(x=from(q,x));}
  41. }
  42. GA(z,STYPE(t),1,zr,ws);
  43. if(r)++*(f+AS(z)); else *(wr+AS(z))=2;
  44. zp=PAV(z); SPB(zp,a,ifb(zr,b)); SPB(zp,e,e); SPB(zp,i,y); SPB(zp,x,x);
  45. R z;
  46. } /* a,"r w (0=p) or w,"r a (1=p) where a is scalar */
  47. static F2(jtovs){A ae,ax,ay,q,we,wx,wy,x,y,z,za,ze;B*ab,*wb,*zb;I acr,ar,*as,at,c,m,n,r,t,*v,wcr,wr,*ws,wt,*zs;P*ap,*wp,*zp;
  48. RZ(a&&w);
  49. at=AT(a); ar=AR(a); acr=jt->rank?jt->rank[0]:ar;
  50. wt=AT(w); wr=AR(w); wcr=jt->rank?jt->rank[1]:wr; jt->rank=0;
  51. if(!ar)R ovs0(0,wcr,a,w);
  52. if(!wr)R ovs0(1,acr,w,a);
  53. if(ar>acr||wr>wcr)R sprank2(a,w,0L,acr,wcr,jtover);
  54. r=MAX(ar,wr);
  55. if(r>ar)RZ(a=reshape(over(apv(r-ar,1L,0L),shape(a)),a)); as=AS(a);
  56. if(r>wr)RZ(w=reshape(over(apv(r-wr,1L,0L),shape(w)),w)); ws=AS(w);
  57. ASSERT(*as<IMAX-*ws,EVLIMIT);
  58. if(!(at&SPARSE)){wp=PAV(w); RZ(a=sparseit(a,SPA(wp,a),SPA(wp,e)));}
  59. if(!(wt&SPARSE)){ap=PAV(a); RZ(w=sparseit(w,SPA(ap,a),SPA(ap,e)));}
  60. ap=PAV(a); RZ(ab=bfi(r,SPA(ap,a),1)); ae=SPA(ap,e); at=AT(ae);
  61. wp=PAV(w); RZ(wb=bfi(r,SPA(wp,a),1)); we=SPA(wp,e); wt=AT(we);
  62. ASSERT(equ(ae,we),EVNONCE);
  63. GA(q,B01,r,1,0); zb=BAV(q); DO(r, zb[i]=ab[i]||wb[i];); RZ(za=ifb(r,zb)); c=AN(za);
  64. GA(q,INT,r,1,0); zs= AV(q); DO(r, zs[i]=MAX(as[i],ws[i]););
  65. DO(r, if(zb[i]>ab[i]){RZ(a=reaxis(za,a)); break;});
  66. DO(r, if(zb[i]>wb[i]){RZ(w=reaxis(za,w)); break;});
  67. *zs=*as; DO(r, if(zs[i]>as[i]){RZ(a=take(q,a)); break;});
  68. *zs=*ws; DO(r, if(zs[i]>ws[i]){RZ(w=take(q,w)); break;});
  69. *zs=*as+*ws; t=maxtype(at,wt);
  70. ap=PAV(a); ay=SPA(ap,i); ax=SPA(ap,x); if(t!=at)RZ(ax=cvt(t,ax));
  71. wp=PAV(w); wy=SPA(wp,i); wx=SPA(wp,x); if(t!=at)RZ(wx=cvt(t,wx));
  72. GA(z,STYPE(t),1,r,zs); zp=PAV(z);
  73. SPB(zp,a,za); SPB(zp,e,ze=ca(t==at?ae:we));
  74. if(*zb){
  75. SPB(zp,x, over(ax,wx));
  76. SPB(zp,i,y=over(ay,wy)); v=AV(y)+AN(ay); m=*as; DO(*AS(wy), *v+=m; v+=c;);
  77. }else{C*av,*wv,*xv;I am,ak,i,j,k,mn,p,*u,wk,wm,xk,*yv;
  78. i=j=p=0; k=bp(t);
  79. m=*AS(ay); u=AV(ay); av=CAV(ax); am=aii(ax); ak=k*am;
  80. n=*AS(wy); v=AV(wy); wv=CAV(wx); wm=aii(wx); wk=k*wm; mn=m+n; xk=k*(am+wm);
  81. GA(y,INT,mn*c, 2, AS(ay)); yv= AV(y); *AS(y)=mn;
  82. GA(x,t, mn*(am+wm),AR(ax),AS(ax)); xv=CAV(x); *AS(x)=mn; *(1+AS(x))=*zs; mvc(k*AN(x),xv,k,AV(ze));
  83. while(i<m||j<n){I cmp;
  84. if (i==m)cmp= 1;
  85. else if(j==n)cmp=-1;
  86. else {cmp=0; DO(c, if(u[i]!=v[i]){cmp=u[i]<v[i]?-1:1; break;});}
  87. switch(cmp){
  88. case -1: ICPY(yv,u,c); u+=c; ++i; memcpy(xv, av,ak); av+=ak; break;
  89. case 0: ICPY(yv,u,c); u+=c; ++i; memcpy(xv, av,ak); av+=ak; ++p; /* fall thru */
  90. case 1: ICPY(yv,v,c); v+=c; ++j; memcpy(xv+ak,wv,wk); wv+=wk;
  91. }
  92. yv+=c; xv+=xk;
  93. }
  94. SPB(zp,i,p?take(sc(mn-p),y):y); SPB(zp,x,p?take(sc(mn-p),x):x);
  95. }
  96. R z;
  97. } /* a,"r w where a or w or both are sparse */
  98. static C*jtovgmove(J jt,I k,I c,I m,A s,A w,C*x,A z){B b;I d,n,p=c*m,q,*u,*v;
  99. b=ARELATIVE(z);
  100. if(AR(w)){
  101. n=AN(w); d=AN(s)-AR(w);
  102. if((!n||d)&&!b)mvc(k*p,x,k,jt->fillv);
  103. if(n&&n<p){v=AV(s); *v=m; RZ(w=take(d?vec(INT,AR(w),d+v):s,w));}
  104. if(n){
  105. if(b){q=ARELATIVE(w)*(I)w-(I)z; u=(I*)x; v=AV(w); DO(AN(w), *u++=q+*v++;);}
  106. else MC(x,AV(w),k*AN(w));
  107. }
  108. }else{
  109. if(b){q=*AV(w)+ARELATIVE(w)*(I)w-(I)z; u=(I*)x; DO(p, *u++=q;);}
  110. else mvc(k*p,x,k,AV(w));
  111. }
  112. R x+k*p;
  113. } /* move an argument into the result area */
  114. static F2(jtovg){A s,z;C*x;I ar,*as,c,k,m,n,q,r,*sv,wr,*ws,zn;
  115. RZ(a&&w);
  116. RZ(w=setfv(a,w)); RZ(coerce2(&a,&w,0L));
  117. ar=AR(a); wr=AR(w); r=ar+wr?MAX(ar,wr):1;
  118. RZ(s=r?vec(INT,r,r==ar?AS(a):AS(w)):num[2]); sv=AV(s);
  119. if(m=MIN(ar,wr)){
  120. as=ar+AS(a); ws=wr+AS(w); k=r;
  121. DO(m, --as; --ws; sv[--k]=MAX(*as,*ws););
  122. DO(r-m, sv[i]=MAX(1,sv[i]););
  123. }
  124. RE(c=prod(r-1,1+sv)); m=r>ar?1:IC(a); n=r>wr?1:IC(w);
  125. RE(zn=mult(c,m+n)); ASSERT(0<=m+n,EVLIMIT);
  126. GA(z,AT(a),zn,r,sv); *AS(z)=m+n; x=CAV(z); k=bp(AT(a));
  127. if(ARELATIVE(a)||ARELATIVE(w)){AFLAG(z)=AFREL; q=(I)jt->fillv+(I)w-(I)z; mvc(k*zn,x,k,&q);}
  128. RZ(x=ovgmove(k,c,m,s,a,x,z));
  129. RZ(x=ovgmove(k,c,n,s,w,x,z));
  130. R z;
  131. } /* a,w general case for array with the same type; jt->rank=0 */
  132. static F2(jtovv){A z;I m,t;
  133. t=AT(a);
  134. GA(z,t,AN(a)+AN(w),1,0);
  135. if(t&BOX){A1*u,*v;B p,q,r;
  136. p=ARELATIVE(a); q=ARELATIVE(w); r=p||q; if(r)AFLAG(z)=AFREL; v=A1AV(z);
  137. u=A1AV(a); m=p*(I)a-r*(I)z; DO(AN(a), *v++=m+*u++;);
  138. u=A1AV(w); m=q*(I)w-r*(I)z; DO(AN(w), *v++=m+*u++;);
  139. }else{C*x;I k;
  140. k=bp(t); m=k*AN(a); x=CAV(z);
  141. MC(x, AV(a),m );
  142. MC(x+m,AV(w),k*AN(w));
  143. }
  144. R z;
  145. } /* a,w for vectors/scalars with the same type */
  146. static void om(I k,I c,I d,I m,I m1,I n,I r,C*u,C*v){I e,km,km1,kn;
  147. e=c/d; km=k*m; km1=k*m1; kn=k*n;
  148. if(!r&&m1!=n)DO(c, mvc(km1,u,kn,v); u+=km;)
  149. else if(1<e){
  150. if(m1>n)DO(c/e, DO(e, mvc(km1,u,kn,v); u+=km;); v+=kn;)
  151. else DO(c/e, DO(e, MC(u,v,kn); u+=km;); v+=kn;);
  152. }else{
  153. if(m1>n)DO(c, mvc(km1,u,kn,v); u+=km; v+=kn;)
  154. else DO(c, MC(u,v,kn); u+=km; v+=kn;);
  155. }} /* move an argument into the result area */
  156. F2(jtover){A z;B b;C*zv;I acn,acr,af,ar,*as,c,f,k,m,ma,mw,p,q,r,*s,t,wcn,wcr,wf,wr,*ws,zn;
  157. RZ(a&&w);
  158. if(SPARSE&AT(a)||SPARSE&AT(w))R ovs(a,w);
  159. RZ(t=coerce2(&a,&w,0L));
  160. ar=AR(a); wr=AR(w);
  161. if(!jt->rank&&2>ar&&2>wr)R ovv(a,w);
  162. acr=jt->rank?jt->rank[0]:ar; af=ar-acr; as=AS(a); p=acr?as[ar-1]:1;
  163. wcr=jt->rank?jt->rank[1]:wr; wf=wr-wcr; ws=AS(w); q=wcr?ws[wr-1]:1;
  164. r=acr+wcr?MAX(acr,wcr):1;
  165. if(2<r||!AN(a)||!AN(w)||2<acr+wcr&&p!=q||ARELATIVE(a)||ARELATIVE(w)){
  166. jt->rank=0; R rank2ex(a,w,0L,acr,wcr,jtovg);
  167. }
  168. acn=1>=acr?p:p*as[af+acr-2]; ma=!acr&&2==wcr?q:acn;
  169. wcn=1>=wcr?q:q*ws[wf+wcr-2]; mw=!wcr&&2==acr?p:wcn; m=ma+mw;
  170. b=af<=wf; f=b?wf:af; s=b?ws:as; RE(c=prod(f,s)); RE(zn=mult(c,m));
  171. GA(z,t,zn,f+r,s); zv=CAV(z); s=AS(z)+AR(z)-1;
  172. if(2>r)*s=m; else{*s=acr?p:q; *(s-1)=(1<acr?as[ar-2]:1)+(1<wcr?ws[wr-2]:1);}
  173. k=bp(t);
  174. om(k,c,prod(af,as),m,ma,acn,ar,zv, CAV(a));
  175. om(k,c,prod(wf,ws),m,mw,wcn,wr,zv+k*ma,CAV(w));
  176. R z;
  177. } /* overall control, and a,w and a,"r w for cell rank <: 2 */
  178. F2(jtstitch){B sp2;I ar,wr;
  179. RZ(a&&w);
  180. ar=AR(a); wr=AR(w); sp2=(SPARSE&AT(a)||SPARSE&AT(w))&&2>=ar&&2>=wr;
  181. ASSERT(!ar||!wr||*AS(a)==*AS(w),EVLENGTH);
  182. R sp2 ? stitchsp2(a,w) : irs2(a,w,0L,ar?ar-1:0,wr?wr-1:0,jtover);
  183. }
  184. F1(jtlamin1){A x;I*s,*v,wcr,wf,wr;
  185. RZ(w);
  186. wr=wcr=AR(w); if(jt->rank){wcr=MIN(wr,jt->rank[1]); jt->rank=0;} wf=wr-wcr;
  187. GA(x,INT,1+wr,1,0); v=AV(x);
  188. s=AS(w); ICPY(v,s,wf); *(v+wf)=1; ICPY(v+1+wf,s+wf,wcr);
  189. R reshape(x,w);
  190. } /* ,:"r w */
  191. F2(jtlamin2){A z;I ar,p,q,wr;
  192. RZ(a&&w);
  193. ar=AR(a); p=jt->rank?jt->rank[0]:ar;
  194. wr=AR(w); q=jt->rank?jt->rank[1]:wr;
  195. if(p)a=irs1(a,0L,p,jtlamin1);
  196. if(q)w=irs1(w,0L,q,jtlamin1);
  197. z=irs2(a,w,0L,p+!!p,q+!!q,jtover);
  198. if(!p&&!q)z=irs1(z,0L,0L,jtlamin1);
  199. R z;
  200. } /* a,:"r w */
  201. F2(jtapip){RZ(a&&w); R AC(a)>(AFNJA&AFLAG(a)?2:1)||!(DIRECT&AT(a))?over(a,w):apipx(a,w);}
  202. F2(jtapipx){A h;C*av,*wv;I ak,at,ar,*as,k,p,*u,*v,wk,wm,wn,wt,wr,*ws;
  203. RZ(a&&w);
  204. at=AT(a); ar=AR(a); as=AS(a);
  205. wt=AT(w); wr=AR(w); ws=AS(w); p=-1;
  206. if(AN(a)&&ar&&ar>=wr&&at>=wt&&5e8>AC(a)){
  207. p=0; u=as+ar-wr; v=ws; if(ar==wr){++u; ++v;}
  208. DO(wr-(ar==wr), k=*u++-*v++; if(0<k)p=1; else if(0>k){p=-1; break;});
  209. k=bp(at); ak=k*AN(a); wm=ar==wr?*ws:1; wn=wm*aii(a); wk=k*wn;
  210. }
  211. if(0<=p&&AM(a)>=ak+wk+(1&&at&LAST0)){
  212. if(at>wt)RZ(w=cvt(at,w));
  213. if(p){RZ(h=vec(INT,wr,as+ar-wr)); if(ar==wr)*AV(h)=*ws; RZ(w=take(h,w));}
  214. av=ak+CAV(a); wv=CAV(w);
  215. if(wr&&ar>1+wr){RZ(setfv(a,w)); mvc(wk,av,k,jt->fillv);}
  216. if(wr)MC(av,wv,k*AN(w)); else mvc(wk,av,k,wv);
  217. *as+=wm; AN(a)+=wn; if(at&LAST0)*(av+wk)=0;
  218. }else RZ(a=over(a,w));
  219. R a;
  220. } /* append in place if possible */