Mercurial > hg > jgplsrc
view ai.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. */ /* */ /* Adverbs: Inverse & Identity Functions */ #include "j.h" static F1(jtinvamp); static B ip(A w,C c,C d){A f,g;V*v; v=VAV(w); f=v->f; g=v->g; R CSLASH==ID(f)&&c==ID(VAV(f)->f)&&d==ID(g); } static B consf(A w){A f;C c; c=ID(w); if(c==CFCONS||c==CQQ&&(f=VAV(w)->f,NOUN&AT(f)))R 1; R 0; } /* 1 iff w is a constant function */ static F2(jtfong){A f;C c;V*v; RZ(a&&w); v=VAV(a); c=v->id; f=v->f; R c==CRIGHT ? w : c==CFORK&&(NOUN&AT(f)||CCAP==ID(f)) ? folk(f,v->g,fong(v->h,w)) : folk(ds(CCAP),a,w); } /* [: f g with simplifications */ static F1(jtinvfork){A f,fi,g,gi,h,k;B b,c;V*v; RZ(w); v=VAV(w); RZ(f=unname(v->f)); g=v->g; RZ(h=unname(v->h)); if(CCAP==ID(f))R fong(inv(h),inv(g)); c=1&&NOUN&AT(f); b=c||consf(f); ASSERT(b!=consf(h),EVDOMAIN); RZ(k=c?f:df1(zero,b?f:h)); RZ(gi=inv(b?amp(k,g):amp(g,k))); RZ(fi=inv(b?h:f)); if(CAMP==ID(gi)){ v=VAV(gi); if (NOUN&AT(v->f))RZ(gi=folk(v->f, v->g, ds(CRIGHT))) else if(NOUN&AT(v->g))RZ(gi=folk(v->g,swap(v->f),ds(CRIGHT))); } R fong(fi,gi); } static DF1(jtexpandf){A f; RZ(w&&self); f=VAV(self)->f; R expand(VAV(f)->f,w);} static DF1(jtexpandg){A f,g,z;V*v; RZ(w&&self); f=VAV(self)->f; v=VAV(f); g=v->g; jt->fill=VAV(g)->g; z=expand(v->f,w); jt->fill=0; R z; } static F2(jtdiag){I d,k,m,p,r,t,*v; RZ(a&&w); r=AR(w); t=AT(w); k=bp(t); v=AS(w); m=0; DO(r, m=MIN(m,v[i]);); v=AS(w)+r; p=1; d=0; DO(r, d+=p; p*=*--v;); if(t!=AT(a))RZ(a=cvt(t,a)); if(AR(a)){ ASSERT(m==AN(a),EVLENGTH); ASSERT(0,EVNONCE); }else{ ASSERT(0,EVNONCE); }} static F1(jtbminv){A*wv,x,z=w;I i,j,m,r,*s,t=0,*u,**v,*y,wn,wr,*ws,wd; RZ(w); ASSERT(0,EVNONCE); ASSERT(BOX&AT(w),EVDOMAIN); wn=AN(w); wr=AR(w); ws=AS(w); wv=AAV(w); wd=(I)w*ARELATIVE(w); if(1>=wr)R raze(w); if(!wn)R iota(reshape(sc(wr),zero)); GA(x,INT,wr,1,0); u=AV(x); memset(u,C0,wr*SZI); GA(x,INT,wr,1,0); v=(I**)AV(x); DO(wr, m=ws[i]; GA(x,INT,m,1,0); memset(v[i]=AV(x),CFF,m*SZI);); for(i=0;i<wn;++i){ x=WVR(i); r=AR(x); s=AS(x); if(AN(x)){if(!t)t=AT(x); ASSERT(HOMO(t,AT(x)),EVDOMAIN);} ASSERT(2>r||r==wr,EVRANK); if(2>r)z=0; else DO(wr, y=v[i]+u[i]; if(0>*y)*y=s[i]; else ASSERT(*y==s[i],EVLENGTH);); j=wr; while(1){--j; ++u[j]; if(ws[j]>u[j])break; u[j]=0;} } if(!z){A f,h,*zv;I*hv; GA(z,BOX,wn,2,ws); zv=AAV(z); GA(h,INT,wr,1,0); hv=AV(h); GA(f,t,1,1,0); RZ(f=filler(f)); memset(u,C0,wr*SZI); for(i=0;i<wn;++i){ zv[i]=x=WVR(i); if(2>AR(x)){DO(wr, hv[i]=*(v[i]+u[i]);); RZ(zv[i]=diag(x,reshape(h,f)));} j=wr-1; while(1){--j; ++u[j]; if(ws[j]>u[j])break; u[j]=0;} }} DO(wr, RZ(z=df1(z,slash(under(qq(ds(CCOMMA),sc(wr-i)),ds(COPE)))));); R ope(z); } /* <;.1 or <;.2 inverse on matrix argument */ static F1(jtinvamp){A f,ff,g,h,*q,x,y;B nf,ng;C c,d,*yv;I n;V*u,*v; RZ(w); v=VAV(w); f=v->f; nf=!!(NOUN&AT(f)); g=v->g; ng=!!(NOUN&AT(g)); h=nf?g:f; x=nf?f:g; c=ID(h); u=VAV(h); switch(c){ case CPLUS: R amp(negate(x),h); case CSTAR: R amp(recip(x), h); case CMINUS: R nf?w:amp(x,ds(CPLUS)); case CDIV: R nf?w:amp(x,ds(CSTAR)); case CROOT: R amp(ds(nf?CEXP:CLOG),x); case CEXP: R ng&&equ(x,num[2])?ds(CROOT):amp(x,ds(nf?CLOG:CROOT)); case CLOG: R nf?amp(x,ds(CEXP)):amp(ds(CROOT),x); case CJDOT: R nf?atop(inv(ds(CJDOT)),amp(ds(CMINUS),x)):amp(ds(CMINUS),jdot1(x)); case CRDOT: R nf?atop(inv(ds(CRDOT)),amp(ds(CDIV ),x)):amp(ds(CDIV ),rdot1(x)); case CLBRACE: R nf?amp(pinv(x),h):amp(x,ds(CIOTA)); case COBVERSE: ff=VAV(h)->g; R amp(nf?x:ff,nf?ff:x); case CPDERIV: if(!AR(h))R ds(CPDERIV); case CXCO: RE(n=i0(x)); ASSERT(n&&-3<n&&n<3,EVDOMAIN); case CROT: case CCIRCLE: case CSPARSE: if(nf)R amp(negate(x),h); break; case CABASE: if(nf)R amp(x,ds(CBASE)); break; case CIOTA: if(nf)R amp(ds(CLBRACE),x); break; case CTHORN: if(nf)R ds(CEXEC); break; case CTILDE: if(ff=VAV(h)->f,VERB&AT(ff))R invamp(amp(nf?ff:x,nf?x:ff)); else{ff=unname(h); R invamp(amp(nf?x:ff,nf?ff:x));} case CSCO: ASSERT(nf,EVDOMAIN); RE(n=i0(x)); ASSERT(n&&-6<=n&&n<=6,EVDOMAIN); R amp(sc(-n),h); case CUCO: ASSERT(nf,EVDOMAIN); RE(n=i0(x)); ASSERT(1<=n&&n<=4||7<=n&&n<=8,EVDOMAIN); R amp(sc(1==n?2L:2==n?1L:3==n?4L:4==n?3L:7==n?8L:7L),h); case CCANT: ASSERT(nf,EVDOMAIN); R obverse(eva(x,"] |:~ x C.^:_1 i.@#@$"),w); case CPCO: if(nf){ RE(n=i0(x)); switch(n){ case -4: case 4: R amp(negate(x),h); case -1: R ds(CPCO); case 2: R obverse(eval("*/@(^/)\"2"),w); case 3: R eval("*/"); }} break; case CQCO: if(nf){ ASSERT(!AR(x),EVRANK); R obverse(eval(all1(lt(x,zero))?"*/@(^/)\"2":"(p:@i.@# */ .^ ])\"1"),w); } break; case CFIT: ASSERT(nf&&(CPOUND==ID(VAV(g)->f)),EVDOMAIN); ASSERT(1==AR(x),EVRANK); R fdef(CPOWOP,VERB, jtexpandg,0L, w,num[-1],0L, 0L, RMAX,0L,0L); case CPOUND: ASSERT(nf,EVDOMAIN); ASSERT(1==AR(x),EVRANK); R fdef(CPOWOP,VERB, jtexpandf,0L, w,num[-1],0L, 0L, RMAX,0L,0L); break; case CPOWOP: if(VGERL&u->flag){ff=*(1+AAV(u->h)); R amp(nf?x:ff,nf?ff:x);} break; case CCOMMA: n=IC(x); R obverse(1==n?ds(nf?CDROP:CCTAIL):amp(sc(nf?n:-n),ds(CDROP)),w); case CBASE: if(!nf)break; R AR(x) ? amp(x,ds(CABASE)) : obverse(evc(x,mag(x),"$&x@>:@(y&(<.@^.))@(1&>.)@(>./)@:|@, #: ]"),w); case CBANG: ASSERT(!AR(x),EVRANK); ASSERT(all1(lt(zero,x)),EVDOMAIN); GA(y,BOX,9,1,0); q=AAV(y); q[0]=cstr("3 :'(-("); q[1]=q[3]=lrep(w); q[2]=cstr("-y\"_)%1e_3&* "); q[4]=cstr("\"0 D:1 ])^:_["); h=lrep(x); if(nf){q[5]=over(over(h,cstr("&<@|@{:}")),over(h,cstr(",:"))); q[6]=over(h,cstr("%:y*!")); q[7]=h;} else {q[5]=cstr("1>.{.@/:\"1|y-/(i.!])"); q[6]=h; q[7]=mtv;} RE(q[8]=cstr("'")); RZ(y=raze(y)); R obverse(eval(CAV(y)),w); case CATOMIC: if(ng){ASSERT(equ(x,nub(x)),EVDOMAIN); R obverse(atop(f,amp(x,ds(CIOTA))),w);} case CCYCLE: if(nf&&AR(x)<=(c==CCYCLE))R obverse(eva(w,"/:@x@(i.@#) { ]"),w); break; case CDROP: if(!(nf&&1>=AR(x)))break; RZ(x=cvt(INT,x)); RZ(y=eps(v2(-1L,1L),signum(x))); yv=CAV(y); f=amp(mag(x),ds(CPLUS)); g=1==AN(x)?ds(CPOUND):atop(amp(tally(x),ds(CTAKE)),ds(CDOLLAR)); h=!yv[1]?f:atop(!yv[0]?ds(CMINUS):amp(negate(signum(x)),ds(CSTAR)),f); R obverse(hook(swap(ds(CTAKE)),atop(h,g)),w); case CDOMINO: if(!(2==AR(x)&&*AS(x)==*(1+AS(x))))break; ff=eval("+/ .*"); R nf?atop(h,amp(ff,minv(x))):amp(x,ff); case CDOT: if(ip(h,CPLUS,CSTAR)){ ASSERT(2==AR(x),EVRANK); ASSERT(*AS(x)==*(1+AS(x)),EVLENGTH); R nf?amp(ds(CDOMINO),x):amp(h,minv(x)); } break; case CQQ: if(ng&&equ(x,one)&&equ(f,eval("i.\"1")))R hook(ds(CFROM),ds(CEQ)); break; case CBSLASH: if(nf&&(n=i0(x),0>n)&&(d=ID(u->f),d==CLEFT||d==CRIGHT))R slash(ds(CCOMMA)); break; case CIBEAM: x=VAV(h)->f; y=VAV(h)->g; if(NOUN&AT(x)&&equ(x,num[3])&&NOUN&AT(y)){ RE(n=i0(f)); if(all1(eps(y,v2(4L,5L)))){ASSERT(n&&-2<=n&&n<=2,EVDOMAIN); R amp(sc(-n),g);} if(all1(eps(y,v2(1L,3L)))){ASSERT(0==n||1==n||10==n||11==n,EVDOMAIN); R foreign(x,num[2]);} } break; case CBDOT: RE(n=i0(x)); switch(i0(VAV(h)->f)){ case 22: case 25: R w; case 19: case 28: if(ng)R w; break; case 21: case 26: if(nf)R w; break; case 32: case 33: case 34: ASSERT(nf,EVDOMAIN); R amp(negate(x),h); } break; case CPOLY: if(nf&&1==AR(x)&&2==AN(x)&&NUMERIC&AT(x)&&!equ(zero,tail(x))){ RZ(y=recip(tail(x))); R amp(over(tymes(y,negate(head(x))),y),h); }} ASSERT(0,EVDOMAIN); } static C invf[2][29] = { CDIV, CPLUS, CMINUS, CLEFT, CRIGHT, CREV, CCANT, CPOLY, CNOT, CGRADE, CCYCLE, CDOMINO, COPE, CBOX, CLOG, CEXP, CGE, CLE, CHALVE, CPLUSCO, CSQRT, CSTARCO, CHEAD, CLAMIN, CABASE, CBASE, CTHORN, CEXEC, 0, CDIV, CPLUS, CMINUS, CLEFT, CRIGHT, CREV, CCANT, CPOLY, CNOT, CGRADE, CCYCLE, CDOMINO, CBOX, COPE, CEXP, CLOG, CLE, CGE, CPLUSCO, CHALVE, CSTARCO, CSQRT, CLAMIN, CHEAD, CBASE, CABASE, CEXEC, CTHORN, 0 }; F1(jtinv){A f,ff,g;B b,nf,ng,vf,vg;C id,*s;I p,q;V*v; RZ(w); ASSERT(VERB&AT(w),EVDOMAIN); id=ID(w); v=VAV(w); if(s=strchr(invf[0],id))R ds(invf[1][s-invf[0]]); f=v->f; nf=f&&AT(f)&NOUN+NAME; vf=f&&!nf; g=v->g; ng=g&&AT(g)&NOUN+NAME; vg=g&&!ng; switch(id){ case CCIRCLE: R eval("1p_1&*"); case CJDOT: R eval("0j_1&*"); case CRDOT: R eval("%&0j1@^."); case CPLUSDOT: R eval("j./\"1\"_ :. +."); case CSTARDOT: R eval("r./\"1\"_ :. *."); case CDGRADE: R eval("/:@|."); case CWORDS: R eval("}:@;@(,&' '&.>\"1) :. ;:"); case CBANG: R eval("3 :'(-(!-y\"_)%1e_3&* !\"0 D:1 ])^:_ <.&170^:(-:+)^.y' :. !"); case CXCO: R amp(num[-1],w); case CSPARSE: R fdef(CPOWOP,VERB,jtdenseit,0L, w,num[-1],0L, 0L, RMAX,RMAX,RMAX); case CPCO: R fdef(CPOWOP,VERB,jtplt, 0L, w,num[-1],0L, 0L, 0L, 0L, 0L ); case CQCO: R eval("*/"); case CUCO: R amp(num[3],w); case CUNDER: R under(inv(f),g); case CFORK: R invfork(w); case CAMP: if(nf!=ng)R invamp(w); /* fall thru */ case CAT: if(vf&&vg)R atop(inv(g),inv(f)); break; case CAMPCO: case CATCO: if(vf&&vg)R atco(inv(g),inv(f)); break; case CSLASH: if(CSTAR==ID(f))R ds(CQCO); break; case CQQ: if(vf)R qq(inv(f),g); break; case COBVERSE: if(vf&&vg)R obverse(g,f); break; case CSCO: R amp(num[5],w); case CPOWOP: if(vf&&ng){RE(p=i0(g)); R -1==p?f:1==p?inv(f):powop(0>p?f:inv(f),sc(ABS(p)));} if(VGERL&v->flag)R*(1+AAV(v->h)); break; case CTILDE: if(nf)R inv(symbrd(f)); switch(ID(f)){ case CPLUS: R ds(CHALVE); case CSTAR: R ds(CSQRT); case CJDOT: R eval("0.5j_0.5&*"); case CLAMIN: R eval("{. :. (,:~)"); case CSEMICO:R eval(">@{. :. (;~)"); case CCOMMA: R eval("<.@-:@# {. ] :. (,~)"); case CEXP: R eval("3 : '(- -&b@(*^.) % >:@^.)^:_ ]1>.b=.^.y' \" 0 :. (^~)"); } break; case CBSLASH: case CBSDOT: if(CSLASH==ID(f)&&(ff=VAV(f)->f,ff&&VERB&AT(ff))){ b=id==CBSDOT; switch(ID(ff)){ case CPLUS: R obverse(eval(b?"- 1&(|.!.0)":" - |.!.0"),w); case CSTAR: R obverse(eval(b?"% 1&(|.!.1)":" % |.!.1"),w); case CEQ: R obverse(eval(b?"= 1&(|.!.1)":" = |.!.1"),w); case CNE: R obverse(eval(b?"~:1&(|.!.0)":" ~:|.!.0"),w); case CMINUS:R obverse(eval(b?"+ 1&(|.!.0)":"(- |.!.0) *\"_1 $&1 _1@#"),w); case CDIV: R obverse(eval(b?"* 1&(|.!.1)":"(% |.!.1) ^\"_1 $&1 _1@#"),w); }} break; case CCUT: if(CBOX==ID(f)&&ng&&(p=i0(g),1==p||2==p))R fdef(CPOWOP,VERB, jtbminv,0L, w,num[-1], 0L,0L, RMAX,RMAX,RMAX); break; case CIBEAM: p=i0(f); q=i0(g); if(3==p&&1==q)R foreign(f,num[2]); if(3==p&&2==q)R foreign(f,one ); if(3==p&&3==q)R foreign(f,num[2]); break; case CHOOK: if(CFROM==ID(f)&&CEQ==ID(g))R eval("i.\"1&1"); break; } if(!nameless(w))R inv(fix(w)); ASSERT(0,EVDOMAIN); } static F1(jtneutral){A x,y;B b;V*v; RZ(w); v=VAV(w); ASSERT(!v->lr&&!v->rr,EVDOMAIN); RZ(y=v2(0L,1L)); RZ(x=scf(infm)); b=equ(y,CALL2(v->f2,x,y,w)); RESETERR; if(b)R x; x=ainf; b=equ(y,CALL2(v->f2,x,y,w)); RESETERR; if(b)R x; x=zero; b=equ(y,CALL2(v->f2,x,y,w)); RESETERR; if(b)R x; x=one; b=equ(y,CALL2(v->f2,x,y,w)); RESETERR; if(b)R x; RZ(x=scf(infm)); b=equ(y,CALL2(v->f2,y,x,w)); RESETERR; if(b)R x; x=ainf; b=equ(y,CALL2(v->f2,y,x,w)); RESETERR; if(b)R x; x=zero; b=equ(y,CALL2(v->f2,y,x,w)); RESETERR; if(b)R x; x=one; b=equ(y,CALL2(v->f2,y,x,w)); RESETERR; if(b)R x; ASSERT(0,EVDOMAIN); } /* neutral of arbitrary rank-0 function */ F1(jtiden){A f,g,x=0;V*u,*v; RZ(w=fix(w)); ASSERT(VERB&AT(w),EVDOMAIN); v=VAV(w); f=v->f; g=v->g; switch(v->id){ default: RZ(x=neutral(w)); break; case CCOMMA: R eval("i.@(0&,)@(2&}.)@$"); case CDOT: if(!(ip(w,CPLUS,CSTAR)||ip(w,CPLUSDOT,CSTARDOT)||ip(w,CNE,CSTARDOT)))break; case CDOMINO: R atop(atop(ds(CEQ),ds(CGRADE)),ds(CHEAD)); case CCYCLE: case CLBRACE: R atop(ds(CGRADE),ds(CHEAD)); case CSLASH: if(VERB&AT(f))R atop(iden(f),ds(CPOUND)); break; case CPLUS: case CMINUS: case CSTILE: case CNE: case CGT: case CLT: case CPLUSDOT: case CJDOT: case CRDOT: x=zero; break; case CSTAR: case CDIV: case CEXP: case CROOT: case CBANG: case CEQ: case CGE: case CLE: case CSTARDOT: x=one; break; case CMAX: x=scf(infm); break; case CMIN: x=ainf; break; case CUNDER: x=df1(df1(mtv,iden(f)),inv(g)); break; case CAT: if(CAMP==ID(f)&&(u=VAV(f),NOUN&AT(u->f)&&!AR(u->f)&&CSTILE==ID(u->g)))switch(ID(g)){ case CSTAR: case CEXP: x=one; break; case CPLUS: x=zero; } break; case CBDOT: switch(i0(f)){ case 25: x=num[-1]; break; case 2: case 4: case 5: case 6: case 7: case 18: case 20: case 21: case 22: case 23: x=zero; break; case 1: case 9: case 11: case 13: case 17: case 27: case 29: x=one; }} ASSERT(x,EVDOMAIN); R folk(x,swap(ds(CDOLLAR)),atop(ds(CBEHEAD),ds(CDOLLAR))); }