Merge pull request #114 from mlochbaum/simplify
Miscellaneous strength reductions
This commit is contained in:
commit
c466db24bc
@ -7,10 +7,18 @@
|
||||
B fne_c1(B, B);
|
||||
B shape_c2(B, B, B);
|
||||
B transp_c2(B, B, B);
|
||||
B fold_rows(Md1D* d, B x); // from fold.c
|
||||
B fold_rows_bit(Md1D* d, B x, usz n, usz m); // from fold.c
|
||||
B take_c2(B, B, B);
|
||||
B join_c2(B, B, B);
|
||||
|
||||
// from fold.c:
|
||||
B fold_rows(Md1D* d, B x, usz n, usz m);
|
||||
B fold_rows_bit(Md1D* d, B x, usz n, usz m);
|
||||
B insert_cells_join(B x, usz* xsh, ur cr, ur k);
|
||||
B insert_cells_identity(B x, B f, usz* xsh, ur xr, ur k, u8 rtid);
|
||||
|
||||
B scan_rows_bit(u8, B x, usz m); // from scan.c
|
||||
B takedrop_highrank(bool take, B w, B x); // from sfns.c
|
||||
B rotate_highrank(bool inv, B w, B x); // from sfns.c
|
||||
B try_interleave_cells(B w, B x, ur xr, ur xk, usz* xsh); // from transpose.c
|
||||
|
||||
// X - variable name; XSH - its shape; K - number of leading axes that get iterated over; SLN - number of slices that will be made; DX - additional refcount count to add to x
|
||||
@ -165,7 +173,7 @@ NOINLINE B leading_axis_arith(FC2 fc2, B w, B x, usz* wsh, usz* xsh, ur mr) { //
|
||||
if (mr==wr) w=s; else x=s;
|
||||
return fc2(m_f64(0), w, x);
|
||||
} else {
|
||||
M_APD_SH(r, mr, bsh);
|
||||
M_APD_SH_N(r, mr, bsh, cam);
|
||||
S_KSLICES(b, bsh, mr, cam, 1) usz bp=0;
|
||||
if (mr==wr) { SGetU(w); for (usz i=0; i<cam; i++) APDD(r, fc2(m_f64(0), GetU(w,i), SLICEI(b))); }
|
||||
else { SGetU(x); for (usz i=0; i<cam; i++) APDD(r, fc2(m_f64(0), SLICEI(b), GetU(x,i))); }
|
||||
@ -178,52 +186,58 @@ NOINLINE B leading_axis_arith(FC2 fc2, B w, B x, usz* wsh, usz* xsh, ur mr) { //
|
||||
|
||||
// fast special-case implementations
|
||||
extern void (*const si_select_cells_bit_lt64)(uint64_t*,uint64_t*,uint32_t,uint32_t,uint32_t); // from fold.c (fold.singeli)
|
||||
static NOINLINE B select_cells(usz n, B x, usz cam, usz k, bool leaf) { // n {leaf? <∘⊑; ⊏}⎉¯k x; TODO probably can share some parts with takedrop_highrank and/or call ⊏?
|
||||
static NOINLINE B select_cells(usz ind, B x, usz cam, usz k, bool leaf) { // ind {leaf? <∘⊑; ⊏}⎉¯k x; TODO probably can share some parts with takedrop_highrank and/or call ⊏?
|
||||
ur xr = RNK(x);
|
||||
assert(xr>1 && k<xr);
|
||||
usz* xsh = SH(x);
|
||||
usz csz = shProd(xsh, k+1, xr);
|
||||
usz take = leaf? 1 : csz;
|
||||
usz jump = xsh[k] * csz;
|
||||
assert(cam*jump == IA(x));
|
||||
usz l = xsh[k];
|
||||
assert(0<=ind && ind<l);
|
||||
assert(cam*l*csz == IA(x));
|
||||
Arr* ra;
|
||||
if (take==jump) {
|
||||
usz take = leaf? 1 : csz;
|
||||
if (l==1 && take==csz) {
|
||||
ra = cpyWithShape(incG(x));
|
||||
arr_shErase(ra, 1);
|
||||
} else if (take==1) {
|
||||
} else {
|
||||
u8 xe = TI(x,elType);
|
||||
if (xe==el_B) {
|
||||
u8 ewl= elwBitLog(xe);
|
||||
u8 xl = leaf? ewl : multWidthLog(csz, ewl);
|
||||
usz ria = cam*take;
|
||||
if (xl>=7 || (xl<3 && xl>0)) { // generic case
|
||||
MAKE_MUT_INIT(rm, ria, TI(x,elType)); MUTG_INIT(rm);
|
||||
usz jump = l * csz;
|
||||
usz xi = take*ind;
|
||||
usz ri = 0;
|
||||
for (usz i = 0; i < cam; i++) {
|
||||
mut_copyG(rm, ri, x, xi, take);
|
||||
xi+= jump;
|
||||
ri+= take;
|
||||
}
|
||||
ra = mut_fp(rm);
|
||||
} else if (xe==el_B) {
|
||||
assert(take == 1);
|
||||
SGet(x)
|
||||
HArr_p rp = m_harrUv(cam);
|
||||
for (usz i = 0; i < cam; i++) rp.a[i] = Get(x, i*jump+n);
|
||||
HArr_p rp = m_harrUv(ria);
|
||||
for (usz i = 0; i < cam; i++) rp.a[i] = Get(x, i*l+ind);
|
||||
NOGC_E; ra = (Arr*)rp.c;
|
||||
} else {
|
||||
void* rp = m_tyarrlbp(&ra, elwBitLog(xe), cam, el2t(xe));
|
||||
void* rp = m_tyarrlbp(&ra, ewl, ria, el2t(xe));
|
||||
void* xp = tyany_ptr(x);
|
||||
switch(xe) {
|
||||
case el_bit:
|
||||
switch(xl) {
|
||||
case 0:
|
||||
#if SINGELI
|
||||
if (jump < 64) si_select_cells_bit_lt64(xp, rp, cam, jump, n);
|
||||
if (l < 64) si_select_cells_bit_lt64(xp, rp, cam, l, ind);
|
||||
else
|
||||
#endif
|
||||
for (usz i=0; i<cam; i++) bitp_set(rp, i, bitp_get(xp, i*jump+n));
|
||||
for (usz i=0; i<cam; i++) bitp_set(rp, i, bitp_get(xp, i*l+ind));
|
||||
break;
|
||||
case el_i8: case el_c8: PLAINLOOP for (usz i=0; i<cam; i++) ((u8* )rp)[i] = ((u8* )xp)[i*jump+n]; break;
|
||||
case el_i16: case el_c16: PLAINLOOP for (usz i=0; i<cam; i++) ((u16*)rp)[i] = ((u16*)xp)[i*jump+n]; break;
|
||||
case el_i32: case el_c32: PLAINLOOP for (usz i=0; i<cam; i++) ((u32*)rp)[i] = ((u32*)xp)[i*jump+n]; break;
|
||||
case el_f64: PLAINLOOP for (usz i=0; i<cam; i++) ((f64*)rp)[i] = ((f64*)xp)[i*jump+n]; break;
|
||||
case 3: PLAINLOOP for (usz i=0; i<cam; i++) ((u8* )rp)[i] = ((u8* )xp)[i*l+ind]; break;
|
||||
case 4: PLAINLOOP for (usz i=0; i<cam; i++) ((u16*)rp)[i] = ((u16*)xp)[i*l+ind]; break;
|
||||
case 5: PLAINLOOP for (usz i=0; i<cam; i++) ((u32*)rp)[i] = ((u32*)xp)[i*l+ind]; break;
|
||||
case 6: PLAINLOOP for (usz i=0; i<cam; i++) ((f64*)rp)[i] = ((f64*)xp)[i*l+ind]; break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
MAKE_MUT_INIT(rm, cam*take, TI(x,elType)); MUTG_INIT(rm);
|
||||
usz xi = take*n;
|
||||
usz ri = 0;
|
||||
for (usz i = 0; i < cam; i++) {
|
||||
mut_copyG(rm, ri, x, xi, take);
|
||||
xi+= jump;
|
||||
ri+= take;
|
||||
}
|
||||
ra = mut_fp(rm);
|
||||
}
|
||||
usz* rsh = arr_shAlloc(ra, leaf? k : xr-1);
|
||||
if (rsh) {
|
||||
@ -444,8 +458,12 @@ B for_cells_c1(B f, u32 xr, u32 cr, u32 k, B x, u32 chr) { // F⎉cr x, with arr
|
||||
return taga(arr_shReplace(r, k+1, rsh));
|
||||
}
|
||||
case n_shifta: case n_shiftb: {
|
||||
if (IA(x)==0) goto noSpecial;
|
||||
if (cr!=1) goto base;
|
||||
if (IA(x)==0) return x;
|
||||
if (cr!=1) {
|
||||
if (cr==0) goto base;
|
||||
if (!(xsh[k]==1 // handled by fill case
|
||||
|| shProd(xsh, k+1, xr)==1)) goto base;
|
||||
}
|
||||
B xf = getFillR(x);
|
||||
if (noFill(xf)) goto base;
|
||||
return shift_cells(xf, x, cam, xsh[k], TI(x,elType), rtid);
|
||||
@ -453,47 +471,74 @@ B for_cells_c1(B f, u32 xr, u32 cr, u32 k, B x, u32 chr) { // F⎉cr x, with arr
|
||||
case n_transp: {
|
||||
return cr<=1? x : transp_cells(xr-1, k, x);
|
||||
}
|
||||
// trivial cases for unhandled functions
|
||||
case n_reverse: case n_and: case n_or: case n_find:
|
||||
if (cr == 0) break;
|
||||
if (xsh[k] <= 1) return x;
|
||||
break;
|
||||
case n_gradeUp: case n_gradeDown: case n_indexOf: case n_memberOf: case n_count: {
|
||||
if (cr == 0) break;
|
||||
usz l = xsh[k];
|
||||
if (l <= 1) {
|
||||
usz ia = l*cam;
|
||||
Arr* r = rtid==n_memberOf? allOnes(ia) : allZeroes(ia);
|
||||
usz* rsh = arr_shAlloc(r, k+1);
|
||||
shcpy(rsh, xsh, k+1);
|
||||
decG(x); return taga(r);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (TY(f) == t_md1D) {
|
||||
Md1D* fd = c(Md1D,f);
|
||||
u8 rtid = fd->m1->flags-1;
|
||||
if (rtid==n_const) { f=fd->f; goto const_f; }
|
||||
usz *sh = SH(x);
|
||||
if (((rtid==n_fold && cr==1) || rtid==n_insert) && TI(x,elType)!=el_B
|
||||
&& isFun(fd->f) && 1==shProd(sh, k+1, xr) && sh[k] > 0) {
|
||||
usz m = sh[k];
|
||||
u8 frtid = v(fd->f)->flags-1;
|
||||
if (m==1 || frtid==n_ltack) return select_cells(0 , x, cam, k, false);
|
||||
if ( frtid==n_rtack) return select_cells(m-1, x, cam, k, false);
|
||||
if (isPervasiveDyExt(fd->f)) {
|
||||
if (TI(x,elType)==el_bit) {
|
||||
incG(x); // keep shape alive
|
||||
B r = fold_rows_bit(fd, x, shProd(sh, 0, k), m);
|
||||
if (!q_N(r)) {
|
||||
if (xr > 2) {
|
||||
usz* rsh = arr_shAlloc(a(r), xr-1);
|
||||
shcpy(rsh, sh, k);
|
||||
shcpy(rsh+k, sh+k+1, xr-1-k);
|
||||
}
|
||||
decG(x); return r;
|
||||
switch(rtid) {
|
||||
case n_const: f=fd->f; goto const_f;
|
||||
case n_cell: cr-= cr>0; return for_cells_c1(fd->f, xr, cr, xr-cr, x, U'˘');
|
||||
case n_fold: if (cr != 1) break; // else fall through
|
||||
case n_insert: if (cr>0 && isFun(fd->f)) {
|
||||
u8 frtid = v(fd->f)->flags-1;
|
||||
if (frtid==n_join && rtid==n_insert) return insert_cells_join(x, xsh, cr, k);
|
||||
usz m = xsh[k];
|
||||
if (m==0) return insert_cells_identity(x, fd->f, xsh, xr, k, rtid);
|
||||
if (TI(x,elType)==el_B) break;
|
||||
if (m==1 || frtid==n_ltack) return select_cells(0 , x, cam, k, false);
|
||||
if ( frtid==n_rtack) return select_cells(m-1, x, cam, k, false);
|
||||
if (isPervasiveDyExt(fd->f) && 1==shProd(xsh, k+1, xr)) {
|
||||
B r;
|
||||
// special cases always return rank 1
|
||||
// incG(x) preserves the shape to restore afterwards if needed
|
||||
if (TI(x,elType)==el_bit) {
|
||||
incG(x); r = fold_rows_bit(fd, x, cam, m);
|
||||
if (q_N(r)) decG(x); // will try fold_rows
|
||||
else goto finish_fold;
|
||||
}
|
||||
decG(x);
|
||||
if (m<=64 && m<cam) {
|
||||
incG(x); r = fold_rows (fd, x, cam, m);
|
||||
}
|
||||
else break;
|
||||
finish_fold:
|
||||
if (xr > 2) {
|
||||
usz* rsh = arr_shAlloc(a(r), xr-1);
|
||||
shcpy(rsh, xsh, k);
|
||||
shcpy(rsh+k, xsh+k+1, xr-1-k);
|
||||
}
|
||||
decG(x); return r;
|
||||
}
|
||||
// TODO extend to any rank
|
||||
if (xr==2 && k==1 && m<=64 && m<sh[0]) return fold_rows(fd, x);
|
||||
}
|
||||
}
|
||||
if (rtid==n_scan) {
|
||||
if (cr==0) goto noSpecial;
|
||||
usz *sh = SH(x); usz m = sh[k];
|
||||
if (m<=1 || IA(x)==0) return x;
|
||||
if (!isFun(fd->f)) goto base;
|
||||
u8 frtid = v(fd->f)->flags-1;
|
||||
if (frtid==n_rtack) return x;
|
||||
if (TI(x,elType)==el_bit && (isPervasiveDyExt(fd->f)||frtid==n_ltack)
|
||||
&& 1==shProd(sh, k+1, xr)) {
|
||||
B r = scan_rows_bit(frtid, x, m); if (!q_N(r)) return r;
|
||||
} break;
|
||||
case n_scan: {
|
||||
if (cr==0) break;
|
||||
usz m = xsh[k];
|
||||
if (m<=1 || IA(x)==0) return x;
|
||||
if (!isFun(fd->f)) break;
|
||||
u8 frtid = v(fd->f)->flags-1;
|
||||
if (frtid==n_rtack) return x;
|
||||
if (TI(x,elType)==el_bit && (isPervasiveDyExt(fd->f)||frtid==n_ltack)
|
||||
&& 1==shProd(xsh, k+1, xr)) {
|
||||
B r = scan_rows_bit(frtid, x, m); if (!q_N(r)) return r;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (TY(f) == t_md2D) {
|
||||
@ -531,7 +576,7 @@ B for_cells_c1(B f, u32 xr, u32 cr, u32 k, B x, u32 chr) { // F⎉cr x, with arr
|
||||
|
||||
base:;
|
||||
|
||||
M_APD_SH(r, k, xsh);
|
||||
M_APD_SH_N(r, k, xsh, cam);
|
||||
S_KSLICES(x, xsh, k, cam, 1); FC1 fc1 = c1fn(f);
|
||||
for (usz i=0,xp=0; i<cam; i++) APDD(r, fc1(f, SLICEI(x)));
|
||||
decG(x);
|
||||
@ -608,7 +653,7 @@ NOINLINE B for_cells_AS(B f, B w, B x, ur wcr, ur wr, u32 chr) {
|
||||
}
|
||||
generic:;
|
||||
S_KSLICES(w, wsh, wk, cam, 1) incBy(x, cam-1);
|
||||
M_APD_SH(r, wk, wsh); FC2 fc2 = c2fn(f);
|
||||
M_APD_SH_N(r, wk, wsh, cam); FC2 fc2 = c2fn(f);
|
||||
for (usz i=0,wp=0; i<cam; i++) APDD(r, fc2(f, SLICEI(w), x));
|
||||
decG(w); return taga(APD_SH_GET(r, chr));
|
||||
}
|
||||
@ -618,40 +663,79 @@ NOINLINE B for_cells_SA(B f, B w, B x, ur xcr, ur xr, u32 chr) {
|
||||
usz* xsh=SH(x); usz cam=shProd(xsh,0,xk);
|
||||
if (cam==0) return rank2_empty(f, w, 0, x, xk, chr);
|
||||
if (isFun(f)) {
|
||||
if (IA(x)==0) goto generic;
|
||||
u8 rtid = v(f)->flags-1;
|
||||
if (rtid==n_rtack) { dec(w); return x; }
|
||||
if (rtid==n_ltack) return const_cells(x, xk, xsh, w, chr);
|
||||
if (rtid==n_select && xk==1 && isF64(w) && xr==2) return select_cells(WRAP(o2i64(w), SH(x)[1], thrF("⊏: Indexing out-of-bounds (𝕨≡%R, %s≡≠𝕩)", w, cam)), x, cam, 1, false);
|
||||
if (rtid==n_pick && xk==1 && TI(x,arrD1) && xr==2 && isF64(w)) return select_cells(WRAP(o2i64(w), SH(x)[1], thrF("⊑: Indexing out-of-bounds (𝕨≡%R, %s≡≠𝕩)", w, cam)), x, cam, 1, true);
|
||||
if ((rtid==n_shifta || rtid==n_shiftb) && xk==1 && xr==2 && isAtm(w)) {
|
||||
if (isArr(w)) { B w0=w; w = IGet(w,0); decG(w0); }
|
||||
return shift_cells(w, x, SH(x)[0], SH(x)[1], el_or(TI(x,elType), selfElType(w)), rtid);
|
||||
}
|
||||
if (rtid==n_take || rtid==n_drop) {
|
||||
if (xcr==0 || !isF64(w)) goto generic;
|
||||
bool take = rtid==n_take;
|
||||
f64* ap;
|
||||
B a = m_f64arrv(&ap, xk+1);
|
||||
if (!take) { FILL_TO(ap, el_f64, 0, m_f64(0), xk); }
|
||||
else { usz* xsh=SH(x); PLAINLOOP for (usz i=0; i<xk; i++) ap[i] = xsh[i]; }
|
||||
ap[xk] = o2fG(w);
|
||||
return takedrop_highrank(take, a, x);
|
||||
}
|
||||
if (rtid==n_transp && q_usz(w)) { usz a=o2sG(w); if (a<xcr) return transp_cells(a+xk, xk, x); }
|
||||
if (isPervasiveDy(f)) {
|
||||
if (isAtm(w)) return c2(f, w, x);
|
||||
if (RNK(w)!=xcr || !eqShPart(SH(w), xsh+xk, xcr)) goto generic;
|
||||
if (TI(w,elType)==el_B || TI(x,elType)==el_B || (IA(w)>(2048*8)>>arrTypeBitsLog(TY(w)) && IA(w)!=IA(x))) goto generic;
|
||||
return c2(f, C2(shape, C1(fne, incG(x)), w), x);
|
||||
switch(rtid) {
|
||||
case n_rtack: dec(w); return x;
|
||||
case n_ltack: return const_cells(x, xk, xsh, w, chr);
|
||||
case n_select: if (isF64(w) && xcr>=1) {
|
||||
usz l = xsh[xk];
|
||||
return select_cells(WRAP(o2i64(w), l, thrF("⊏: Indexing out-of-bounds (𝕨≡%R, %s≡≠𝕩)", w, l)), x, cam, xk, false);
|
||||
} break;
|
||||
case n_pick: if (isF64(w) && xcr==1 && TI(x,arrD1)) {
|
||||
usz l = xsh[xk];
|
||||
return select_cells(WRAP(o2i64(w), l, thrF("⊑: Indexing out-of-bounds (𝕨≡%R, %s≡≠𝕩)", w, l)), x, cam, xk, true);
|
||||
} break;
|
||||
case n_shifta: case n_shiftb: if (isAtm(w)) {
|
||||
if (IA(x)==0) return x;
|
||||
if (xcr!=1) {
|
||||
if (xcr==0) break;
|
||||
if (!(xsh[xk]==1 || shProd(xsh, xk+1, xr)==1)) break;
|
||||
}
|
||||
if (isArr(w)) { B w0=w; w = IGet(w,0); decG(w0); }
|
||||
return shift_cells(w, x, cam, xsh[xk], el_or(TI(x,elType), selfElType(w)), rtid);
|
||||
} break;
|
||||
case n_take: case n_drop: {
|
||||
bool take = rtid==n_take;
|
||||
B a;
|
||||
if (isF64(w)) {
|
||||
if (xcr < 1) break;
|
||||
f64* ap;
|
||||
a = m_f64arrv(&ap, xk+1);
|
||||
if (!take) { FILL_TO(ap, el_f64, 0, m_f64(0), xk); }
|
||||
else { PLAINLOOP for (usz i=0; i<xk; i++) ap[i] = xsh[i]; }
|
||||
ap[xk] = o2fG(w);
|
||||
} else {
|
||||
if (!isArr(w) || RNK(w)>1) break;
|
||||
usz wia = IA(w);
|
||||
if (xcr < wia) break; // needs rank extension in the middle of x's shape
|
||||
if (!take) a = C2(take, m_f64(-(i32)(xk+wia)), w);
|
||||
else a = C2(join, C2(take, m_f64(xk), C1(fne, incG(x))), w); // (k↑≢𝕩)∾𝕨
|
||||
}
|
||||
return takedrop_highrank(take, a, x);
|
||||
} break;
|
||||
case n_reverse: {
|
||||
B a;
|
||||
if (isF64(w)) {
|
||||
if (xcr < 1) break;
|
||||
f64* ap;
|
||||
a = m_f64arrv(&ap, xk+1);
|
||||
FILL_TO(ap, el_f64, 0, m_f64(0), xk);
|
||||
ap[xk] = o2fG(w);
|
||||
} else {
|
||||
if (!isArr(w) || RNK(w)>1) break;
|
||||
usz wia = IA(w);
|
||||
if (xcr < wia) break;
|
||||
a = C2(take, m_f64(-(i32)(xk+wia)), w);
|
||||
}
|
||||
return rotate_highrank(0, a, x);
|
||||
}
|
||||
case n_transp:
|
||||
if (q_usz(w)) { usz a=o2sG(w); if (a<xcr) return transp_cells(a+xk, xk, x); }
|
||||
break;
|
||||
default: if (isPervasiveDy(f)) {
|
||||
if (isAtm(w)) return c2(f, w, x);
|
||||
if (IA(x)==0) break;
|
||||
if (RNK(w)!=xcr || !eqShPart(SH(w), xsh+xk, xcr)) break;
|
||||
if (TI(w,elType)==el_B || TI(x,elType)==el_B || (IA(w)>(2048*8)>>arrTypeBitsLog(TY(w)) && IA(w)!=IA(x))) break;
|
||||
return c2(f, C2(shape, C1(fne, incG(x)), w), x);
|
||||
}
|
||||
}
|
||||
} else if (!isMd(f)) {
|
||||
dec(w);
|
||||
return const_cells(x, xk, xsh, inc(f), chr);
|
||||
}
|
||||
generic:;
|
||||
S_KSLICES(x, xsh, xk, cam, 1) incBy(w, cam-1);
|
||||
M_APD_SH(r, xk, xsh); FC2 fc2 = c2fn(f);
|
||||
M_APD_SH_N(r, xk, xsh, cam); FC2 fc2 = c2fn(f);
|
||||
for (usz i=0,xp=0; i<cam; i++) APDD(r, fc2(f, w, SLICEI(x)));
|
||||
decG(x); return taga(APD_SH_GET(r, chr));
|
||||
}
|
||||
@ -705,7 +789,7 @@ NOINLINE B for_cells_AA(B f, B w, B x, ur wcr, ur xcr, u32 chr) {
|
||||
}
|
||||
generic:;
|
||||
|
||||
M_APD_SH(r, zk, zsh);
|
||||
M_APD_SH_N(r, zk, zsh, cam);
|
||||
S_KSLICES(w, wsh, wk, xkM? cam0 : cam, 1) usz wp=0;
|
||||
S_KSLICES(x, xsh, xk, xkM? cam : cam0, 1) usz xp=0;
|
||||
FC2 fc2 = c2fn(f);
|
||||
|
||||
@ -14,7 +14,8 @@
|
||||
// Insert with rank (˝˘ or ˝⎉k), or fold on flat array
|
||||
// SHOULD optimize dyadic insert with rank
|
||||
// Length 1, ⊣⊢: implemented as ⊏˘
|
||||
// SHOULD reshape identity for fast ˝˘ on empty rows
|
||||
// ∾˝ with rank: reshape argument
|
||||
// Arithmetic on empty: reshape identity
|
||||
// Boolean operand, cell size 1:
|
||||
// +: popcount
|
||||
// Rows length ≤64: extract rows, popcount each
|
||||
@ -375,28 +376,58 @@ u64 usum(B x) { // doesn't consume; will error on non-integers, or elements <0,
|
||||
|
||||
B select_c1(B, B);
|
||||
B select_c2(B, B, B);
|
||||
B shape_c1(B, B);
|
||||
static B m1c1(B t, B f, B x) { // consumes x
|
||||
B fn = m1_d(inc(t), inc(f));
|
||||
B r = c1(fn, x);
|
||||
decG(fn);
|
||||
return r;
|
||||
}
|
||||
extern GLOBAL B rt_insert;
|
||||
extern B insert_base(B f, B x, bool has_w, B w); // from cells.c
|
||||
|
||||
B insert_c1(Md1D* d, B x) { B f = d->f;
|
||||
if (isAtm(x) || RNK(x)==0) thrM("˝: 𝕩 must have rank at least 1");
|
||||
ur xr;
|
||||
if (isAtm(x) || (xr=RNK(x))==0) thrM("˝: 𝕩 must have rank at least 1");
|
||||
usz len = *SH(x);
|
||||
if (len==0) { SLOW2("!𝕎˝𝕩", f, x); return m1c1(rt_insert, f, x); }
|
||||
if (len==0) {
|
||||
if (isFun(f)) {
|
||||
B id = TI(f,identity)(f);
|
||||
if (!q_N(id)) {
|
||||
if (isArr(id)) { decG(x); return id; } // arithmetic with table
|
||||
usz* xsh = SH(x);
|
||||
Arr* r = reshape_one(shProd(xsh, 1, xr), id);
|
||||
if (xr == 2) arr_shVec(r); else {
|
||||
usz* rsh = arr_shAlloc(r, xr-1);
|
||||
shcpy(rsh, xsh+1, xr-1);
|
||||
}
|
||||
decG(x); return taga(r);
|
||||
} else if (v(f)->flags == n_join+1) {
|
||||
if (xr <= 1) thrM("˝: Identity does not exist");
|
||||
goto join;
|
||||
}
|
||||
}
|
||||
thrM("˝: Identity not found");
|
||||
}
|
||||
if (len==1) return C1(select, x);
|
||||
if (RARE(!isFun(f))) { decG(x); if (isMd(f)) thrM("Calling a modifier"); return inc(f); }
|
||||
ur xr = RNK(x);
|
||||
if (xr==1 && isPervasiveDyExt(f)) return m_unit(fold_c1(d, x));
|
||||
if (isPervasiveDyExt(f)) {
|
||||
if (xr==1) return m_unit(fold_c1(d, x));
|
||||
if (len==IA(x)) {
|
||||
B r = m_vec1(fold_c1(d, C1(shape, x)));
|
||||
ur rr = xr - 1;
|
||||
if (rr > 1) {
|
||||
ShArr* rsh = m_shArr(rr);
|
||||
PLAINLOOP for (ur i=0; i<rr; i++) rsh->a[i] = 1;
|
||||
arr_shReplace(a(r), rr, rsh);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
if (v(f)->flags) {
|
||||
u8 rtid = v(f)->flags-1;
|
||||
if (rtid==n_ltack) return C1(select, x);
|
||||
if (rtid==n_rtack) return C2(select, m_f64(-1), x);
|
||||
if (rtid==n_join) {
|
||||
if (rtid==n_join) { join:;
|
||||
if (xr==1) return x;
|
||||
ShArr* rsh;
|
||||
if (xr>2) {
|
||||
@ -414,17 +445,32 @@ B insert_c1(Md1D* d, B x) { B f = d->f;
|
||||
return insert_base(f, x, 0, m_f64(0));
|
||||
}
|
||||
B insert_c2(Md1D* d, B w, B x) { B f = d->f;
|
||||
if (isAtm(x) || RNK(x)==0) thrM("˝: 𝕩 must have rank at least 1");
|
||||
if (*SH(x)==0) { decG(x); return w; }
|
||||
ur xr;
|
||||
if (isAtm(x) || (xr=RNK(x))==0) thrM("˝: 𝕩 must have rank at least 1");
|
||||
usz len = *SH(x);
|
||||
if (len==0) { decG(x); return w; }
|
||||
if (RARE(!isFun(f))) { dec(w); decG(x); if (isMd(f)) thrM("Calling a modifier"); return inc(f); }
|
||||
if (RNK(x)==1 && isPervasiveDyExt(f)) {
|
||||
if (isAtm(w)) {
|
||||
to_fold: return m_unit(fold_c2(d, w, x));
|
||||
}
|
||||
if (RNK(w)==0) {
|
||||
if (isPervasiveDyExt(f) && len==IA(x)) {
|
||||
// 1-element arrays are always conformable
|
||||
// final rank is higher of w, cell rank of x
|
||||
ur rr = xr - 1;
|
||||
if (isArr(w)) {
|
||||
if (IA(w) != 1) goto skip;
|
||||
ur wr = RNK(w); if (wr>rr) rr = wr;
|
||||
B w0=w; w = IGet(w,0); decG(w0);
|
||||
goto to_fold;
|
||||
}
|
||||
if (xr > 1) x = C1(shape, x);
|
||||
B r = m_unit(fold_c2(d, w, x));
|
||||
if (rr > 0) {
|
||||
if (rr == 1) arr_shVec(a(r));
|
||||
else {
|
||||
ShArr* rsh = m_shArr(rr);
|
||||
PLAINLOOP for (ur i=0; i<rr; i++) rsh->a[i] = 1;
|
||||
arr_shReplace(a(r), rr, rsh);
|
||||
}
|
||||
}
|
||||
return r;
|
||||
skip:;
|
||||
}
|
||||
if (v(f)->flags) {
|
||||
u8 rtid = v(f)->flags-1;
|
||||
@ -434,19 +480,56 @@ B insert_c2(Md1D* d, B w, B x) { B f = d->f;
|
||||
return insert_base(f, x, 1, w);
|
||||
}
|
||||
|
||||
// Arithmetic fold/insert on rows of flat rank-2 array x
|
||||
B insert_cells_join(B x, usz* xsh, ur cr, ur k) {
|
||||
assert(k > 0);
|
||||
if (cr <= 1) {
|
||||
if (xsh[k]==0) thrM("˝: Identity does not exist");
|
||||
return x;
|
||||
}
|
||||
ur rr = k+cr-1; // result rank (>1)
|
||||
ShArr* rsh;
|
||||
rsh = m_shArr(rr);
|
||||
shcpy(rsh->a, xsh, k);
|
||||
rsh->a[k] = xsh[k] * xsh[k+1];
|
||||
shcpy(rsh->a+k+1, xsh+k+2, cr-2);
|
||||
Arr* r = TI(x,slice)(x, 0, IA(x));
|
||||
arr_shSetUG(r, rr, rsh);
|
||||
decG(x); return taga(r);
|
||||
}
|
||||
B insert_cells_identity(B x, B f, usz* xsh, ur xr, ur k, u8 rtid) {
|
||||
B id;
|
||||
if (!isFun(f) || q_N(id = TI(f,identity)(f))) thrF("%c: Identity not found", rtid==n_fold? U'´' : U'˝');
|
||||
bool cs = !isArr(id); // if x cell shape is used (not table)
|
||||
usz ria = shProd(xsh, 0, k);
|
||||
if (cs) ria*= shProd(xsh, k+1, xr);
|
||||
Arr* r = reshape_one(ria, id);
|
||||
ur rr = cs? xr-1 : k;
|
||||
if (rr == 1) arr_shVec(r); else {
|
||||
usz* rsh = arr_shAlloc(r, rr);
|
||||
shcpy(rsh, xsh, k);
|
||||
if (cs) shcpy(rsh+k, xsh+k+1, rr-k);
|
||||
}
|
||||
decG(x); return taga(r);
|
||||
}
|
||||
|
||||
// Arithmetic fold/insert on -k-cells of flat array x
|
||||
// Return a vector regardless of argument shape
|
||||
B transp_c1(B, B);
|
||||
B join_c2(B, B, B);
|
||||
B fold_rows(Md1D* fd, B x) {
|
||||
assert(isArr(x) && RNK(x)==2);
|
||||
B fold_rows(Md1D* fd, B x, usz n, usz m) {
|
||||
assert(isArr(x) && IA(x)==n*m);
|
||||
// Target block size trying to avoid power-of-two lengths, from:
|
||||
// {𝕩/˜⌊´⊸= +˝˘ +˝¬∨`2|>⌊∘÷⟜2⍟(↕12) ⌊0.5+32÷˜𝕩÷⌜1+↕64} +⟜↕2⋆16
|
||||
u64 block = (116053*8) >> arrTypeBitsLog(TY(x));
|
||||
if (TI(x,elType)==el_bit || IA(x)/2 <= block) {
|
||||
if (RNK(x) > 2) {
|
||||
Arr* xc = cpyWithShape(x);
|
||||
ShArr* sh = m_shArr(2);
|
||||
sh->a[0] = n; sh->a[1] = m;
|
||||
x = taga(arr_shReplace(xc, 2, sh));
|
||||
}
|
||||
x = C1(transp, x);
|
||||
return insert_c1(fd, x);
|
||||
} else {
|
||||
usz *sh = SH(x); usz n = sh[0]; usz m = sh[1];
|
||||
usz b = (block + m - 1) / m; // Normal block length
|
||||
usz b_max = b + b/4; // Last block max length
|
||||
MAKE_MUT(r, n); MUT_APPEND_INIT(r);
|
||||
|
||||
@ -998,7 +998,10 @@ B shiftb_c1(B t, B x) {
|
||||
if (ia==0) return x;
|
||||
B xf = getFillE(x);
|
||||
usz csz = arr_csz(x);
|
||||
|
||||
if (ia==csz) { // length 1
|
||||
Arr* r = arr_shCopy(reshape_one(ia, xf), x);
|
||||
decG(x); return taga(r);
|
||||
}
|
||||
MAKE_MUT_INIT(r, ia, el_or(TI(x,elType), selfElType(xf))); MUTG_INIT(r);
|
||||
mut_copyG(r, csz, x, 0, ia-csz);
|
||||
mut_fillG(r, 0, xf, csz);
|
||||
@ -1025,6 +1028,10 @@ B shifta_c1(B t, B x) {
|
||||
if (ia==0) return x;
|
||||
B xf = getFillE(x);
|
||||
usz csz = arr_csz(x);
|
||||
if (ia==csz) { // length 1
|
||||
Arr* r = arr_shCopy(reshape_one(ia, xf), x);
|
||||
decG(x); return taga(r);
|
||||
}
|
||||
MAKE_MUT_INIT(r, ia, el_or(TI(x,elType), selfElType(xf))); MUTG_INIT(r);
|
||||
mut_copyG(r, 0, x, csz, ia-csz);
|
||||
mut_fillG(r, ia-csz, xf, csz);
|
||||
@ -1059,7 +1066,7 @@ static u64 bit_reverse(u64 x) {
|
||||
B reverse_c1(B t, B x) {
|
||||
if (isAtm(x) || RNK(x)==0) thrM("⌽: Argument cannot be a unit");
|
||||
usz n = *SH(x);
|
||||
if (n==0) return x;
|
||||
if (n<=1) return x;
|
||||
u8 xl = cellWidthLog(x);
|
||||
u8 xt = arrNewType(TY(x));
|
||||
if (xl<=6 && (xl>=3 || xl==0)) {
|
||||
@ -1115,7 +1122,7 @@ B reverse_c1(B t, B x) {
|
||||
B reverse_c2(B t, B w, B x);
|
||||
|
||||
#define WRAP_ROT(V, L) ({ i64 v_ = (V); usz l_ = (L); if ((u64)v_ >= (u64)l_) { v_%= (i64)l_; if(v_<0) v_+= l_; } v_; })
|
||||
static NOINLINE B rotate_highrank(bool inv, B w, B x) {
|
||||
NOINLINE B rotate_highrank(bool inv, B w, B x) {
|
||||
#define INV (inv? "⁼" : "")
|
||||
if (RNK(w)>1) thrF("⌽%U: 𝕨 must have rank at most 1 (%H ≡ ≢𝕨)", INV, w);
|
||||
B r;
|
||||
|
||||
@ -73,11 +73,15 @@ SHOULD_INLINE void arr_check_size(u64 sz, u8 type, usz ia) {
|
||||
#endif
|
||||
}
|
||||
// Log of width in bits: max of 7, and also return 7 if not power of 2
|
||||
SHOULD_INLINE u8 cellWidthLog(B x) {
|
||||
SHOULD_INLINE u8 multWidthLog(usz n, u8 lw) { // Of n elements, 1<<lw bit
|
||||
if (n & (n-1)) return 7; // Not power of 2
|
||||
return lw + CTZ(n | 128>>lw); // Max of 7; also handle n==0
|
||||
}
|
||||
SHOULD_INLINE u8 kCellWidthLog(B x, ur k) {
|
||||
assert(isArr(x) && RNK(x)>=1);
|
||||
u8 lw = arrTypeBitsLog(TY(x));
|
||||
if (LIKELY(RNK(x)==1)) return lw;
|
||||
usz csz = arr_csz(x);
|
||||
if (csz & (csz-1)) return 7; // Not power of 2
|
||||
return lw + CTZ(csz | 128>>lw); // Max of 7; also handle csz==0
|
||||
ur xr = RNK(x);
|
||||
if (LIKELY(xr <= k)) return lw;
|
||||
return multWidthLog(shProd(SH(x), k, xr), lw);
|
||||
}
|
||||
SHOULD_INLINE u8 cellWidthLog(B x) { return kCellWidthLog(x, 1); }
|
||||
|
||||
@ -460,7 +460,7 @@ B bqn_merge(B x, u32 type) {
|
||||
return taga(r);
|
||||
}
|
||||
|
||||
M_APD_SH(r, xr, SH(x));
|
||||
M_APD_SH_N(r, xr, SH(x), xia);
|
||||
SGetU(x)
|
||||
for (usz i = 0; i < xia; i++) APD(r, GetU(x, i));
|
||||
decG(x);
|
||||
|
||||
@ -129,7 +129,7 @@ NOINLINE B load_fullpath(B path, B name) {
|
||||
|
||||
GLOBAL HArr* comps_curr;
|
||||
|
||||
GLOBAL B rt_undo, rt_select, rt_slash, rt_insert, rt_depth,
|
||||
GLOBAL B rt_undo, rt_select, rt_slash, rt_depth,
|
||||
rt_group, rt_under, rt_find;
|
||||
Block* load_buildBlock(B x, B src, B path, B name, Scope* sc, i32 nsResult) { // consumes x,src
|
||||
B fullpath = load_fullpath(path, name);
|
||||
@ -500,7 +500,6 @@ void load_init() { // very last init function
|
||||
gc_add(rt_under = Get(rtObjRaw, n_under ));
|
||||
gc_add(rt_find = Get(rtObjRaw, n_find ));
|
||||
gc_add(rt_depth = Get(rtObjRaw, n_depth ));
|
||||
gc_add(rt_insert = Get(rtObjRaw, n_insert));
|
||||
|
||||
for (usz i = 0; i < RT_LEN; i++) {
|
||||
#ifdef RT_WRAP
|
||||
@ -542,7 +541,7 @@ void load_init() { // very last init function
|
||||
load_rt = frtObj;
|
||||
|
||||
rt_select = rt_slash = rt_group = rt_find = bi_invalidFn;
|
||||
rt_undo = rt_insert = bi_invalidMd1;
|
||||
rt_undo = bi_invalidMd1;
|
||||
rt_under = rt_depth = bi_invalidMd2;
|
||||
|
||||
rt_invFnRegFn = rt_invFnSwapFn = invalidFn_c1;
|
||||
|
||||
@ -665,6 +665,37 @@ NOINLINE void apd_sh_init(ApdMut* m, B x) {
|
||||
else m->apd(m, x);
|
||||
if (xe==el_B) NOGC_E;
|
||||
}
|
||||
// used if this is the only append: only need to add leading 1s to shape
|
||||
NOINLINE void apd_reshape(ApdMut* m, B x) {
|
||||
ur rr0 = m->rr0; // need to be read before union fields are written
|
||||
for (ur i=0; i<rr0; i++) assert(m->rsh0[i] == 1);
|
||||
|
||||
inc(x);
|
||||
if (isAtm(x)) x = m_unit(x);
|
||||
|
||||
if (rr0 > 0) {
|
||||
ur xr = RNK(x);
|
||||
if (rr0 + xr > UR_MAX) {
|
||||
m->failEl = x;
|
||||
m->end = apd_rnk_err;
|
||||
return;
|
||||
}
|
||||
ur rr = rr0 + xr;
|
||||
Arr* r = cpyWithShape(x);
|
||||
if (rr <= 1) {
|
||||
arr_shErase(r, rr);
|
||||
} else {
|
||||
usz* xsh = PSH(r);
|
||||
ShArr* rsh = m_shArr(rr);
|
||||
PLAINLOOP for (ur i=0; i<rr0; i++) rsh->a[i] = 1;
|
||||
shcpy(rsh->a + rr0, xsh, xr);
|
||||
arr_shReplace(r, rr, rsh);
|
||||
}
|
||||
x = taga(r);
|
||||
}
|
||||
m->obj = a(x);
|
||||
m->end = apd_ret_end;
|
||||
}
|
||||
|
||||
NOINLINE void apd_widen(ApdMut* m, B x, ApdFn* const* fns) {
|
||||
u8 xe = isArr(x)? TI(x,elType) : selfElType(x);
|
||||
|
||||
@ -265,7 +265,7 @@ struct ApdMut {
|
||||
};
|
||||
};
|
||||
|
||||
ApdFn apd_tot_init, apd_sh_init;
|
||||
ApdFn apd_tot_init, apd_sh_init, apd_reshape;
|
||||
#if DEBUG
|
||||
ApdFn apd_dbg_apd;
|
||||
ApdEnd apd_dbg_end;
|
||||
@ -275,6 +275,7 @@ ApdFn apd_tot_init, apd_sh_init;
|
||||
#endif
|
||||
#define M_APD_TOT(M, IA) M_APD_BASE(M) M.apd = apd_tot_init; M.ia0 = (IA); // end gives uninitialized shape
|
||||
#define M_APD_SH(M, RR, RSH) M_APD_BASE(M) M.apd = apd_sh_init; M.rsh0 = (RSH); M.rr0 = (RR); // end gives full shape; will error on invalid at the end; rsh must be alive until at least the first APD call
|
||||
#define M_APD_SH_N(M, RR, RSH, N) M_APD_BASE(M) M.apd = N==1? apd_reshape : apd_sh_init; M.rsh0 = (RSH); M.rr0 = (RR); // same, with known number of appends
|
||||
#define M_APD_SH1(M, RIA) usz M##_sh0 = (RIA); M_APD_SH(M, 1, &M##_sh0);
|
||||
#define APD(M, A) M.apd(&M, A) // doesn't consume A
|
||||
#define APDD(M, A) ({ B av_ = (A); M.apd(&M, av_); dec(av_); }) // consumes A
|
||||
|
||||
@ -21,6 +21,51 @@
|
||||
!"˘: Argument frames don't agree (⟨3⟩ ≡ ≢𝕨, ⟨2⟩ ≡ ≢𝕩, common frame of 1 axes)" % "abc" ⊢˘ "ab"
|
||||
! ∧´{𝕊: ! (∾≡{𝕨∾𝕩}´) (<•rand.Range∘≠⊸⊑ ⟨"ab",1‿2,⟨⟩,↕0,""⟩) ∾˜ (4•rand.Range≠)⊸⊏ ⟨1, {⇐}, 'a', <'a', <{⇐}, "ab", ↕0, ""⟩}¨↕10000
|
||||
|
||||
# error cases that could be affected by special code
|
||||
!"∧: Argument cannot have rank 0" % ∧˘↕2
|
||||
!"∨: Argument cannot have rank 0" % ∨˘"a"
|
||||
!"Expected non-negative integer, got ¯3" % 2‿¯3/⎉1 6‿2⥊0
|
||||
!"/: Lengths of components of 𝕨 must match 𝕩 (3 ≠ 4)" % 1‿2‿3⊸/˘≍4‿5‿6‿7
|
||||
!"/: Simple 𝕨 must have rank 0 or 1 (2≡=𝕨)" % (2‿3‿1⥊↕4) /˘ ↕2
|
||||
!"𝕨/𝕩: Length of compound 𝕨 must be at most rank of 𝕩" % (<↕0)/˘○(5⊸⥊)<"ab"
|
||||
!"⊏: Indexing out-of-bounds (24∊𝕨, 4≡≠𝕩)" % 1‿24⊏⎉1↕4‿4
|
||||
!"⊏: Indexing out-of-bounds (4∊𝕨, 4≡≠𝕩)" % ⊏⎉1˜6‿4⥊↕24
|
||||
!"𝕨⊏𝕩: 𝕨 must be an array of numbers or list of such arrays" % 0‿@‿¯1⊏⎉1 5‿2⥊0.5
|
||||
!"Expected integer, got ¯5.25" % ¯5.25⊏˘∘‿4⥊↕24
|
||||
!"⊏: Indexing out-of-bounds (1∊𝕨, 1≡≠𝕩)" % 0‿0‿1 ⊏˘○(≍˘) 10000×↕3
|
||||
!"⊏: 𝕩 cannot be a unit" % 0⊏˘5⥊<"a"
|
||||
!"⊏: 𝕩 cannot be a unit" % (3‿0⥊⟨⟩)⊏˘↕3
|
||||
!"Expected integer, got 0.1" % 0.1⊑˘3‿5⥊↕15
|
||||
!"⊑: 𝕩 must be a list when 𝕨 is a number (3‿4 ≡ ≢𝕩)" % 5⊑˘↕2‿3‿4
|
||||
!">: Result rank too large (80 ≡ =𝕩, 205 ≡ =⊑𝕩)" % >⎉80 (200⥊1)⥊<(205⥊1)⥊1
|
||||
!"⎉: Result rank too large (195 ≡ =𝕩, 210 ≡ =𝔽v)" % >⎉5 (200⥊1)⥊<(205⥊1)⥊1
|
||||
!"∾: Lengths not matchable (⟨6⟩ ≡ ≢𝕨, 1‿1 ≡ ≢𝕩)" % ("abc"∾"def")∾˘○(3/≍)≍"a"
|
||||
!"∾: Argument ranks must differ by 1 or less (0≡=𝕨, 2≡=𝕩)" % 1∾˘↕3‿3‿3
|
||||
!"∾: Lengths not matchable (4‿2 ≡ ≢𝕨, 3‿3 ≡ ≢𝕩)" % (3‿4‿2⥊4)∾˘3‿3‿3⥊5
|
||||
!"≍: 𝕨 and 𝕩 must have equal shapes (3‿4 ≡ ≢𝕨, 3‿3 ≡ ≢𝕩)" % (↕3‿4)≍⎉2 2‿3‿3⥊↕18
|
||||
!"≍: Result rank too large (255≡=𝕩)" % ≍⎉∞ 0⥊˜255⥊1
|
||||
!"shift: Lengths not matchable (⟨6⟩ ≡ ≢𝕨, 1‿1 ≡ ≢𝕩)" % ("abc"∾"def")«˘○(3/≍)≍"a"
|
||||
!"shift: =𝕨 must be =𝕩 or ¯1+=𝕩 (0≡=𝕨, 2≡=𝕩)" % 1«˘↕2‿2‿2
|
||||
!"»: Argument cannot be a scalar" % »⎉0 2‿3‿1⥊↕6
|
||||
!"⌽: Argument cannot be a unit" % ⌽˘↕10
|
||||
!"Expected integer, got 1.5" % 1.5↑˘↕2‿3‿2
|
||||
!"↑: 𝕨 must have rank at most 1 (1‿2 ≡ ≢𝕨)" % (≍1‿2)⊸↑˘↕2‿3‿2
|
||||
!"↓: 𝕨 must have rank at most 1 (4‿2 ≡ ≢𝕨)" % (4‿2⥊↕8)↓˘○≍@
|
||||
!"Integer out of range: 1e20" % 1e20⌽˘3‿10⥊10
|
||||
!"Expected number" % 3‿4‿@⌽˘↕3‿4
|
||||
!"Expected integer, got 0.5" % 0.5⊸⌽˘4‿3⥊↕12
|
||||
!"↑: Argument must have rank at least 1" % ↑˘↕2
|
||||
!"↓: Argument must have rank at least 1" % ↓⎉0 2‿1⥊0
|
||||
!"⊐: 𝕩 cannot have rank 0" % ⊐˘"abcd"
|
||||
!"⊒: Argument cannot have rank 0" % ⊒˘"abcd"
|
||||
!"∊: Argument cannot have rank 0" % ∊˘"abcd"
|
||||
!"⍋: 𝕨 must be sorted" % 0‿2‿1⊸⍋˘ 3‿4⥊↕12
|
||||
!"`: Shape of 𝕨 must match the cell of 𝕩 (⟨2⟩ ≡ ≢𝕨, 2‿3 ≡ ≢𝕩)" % (2‿2⥊1)+`˘2‿2‿3⥊0.4
|
||||
!"`: Shape of 𝕨 must match the cell of 𝕩 (⟨⟩ ≡ ≢𝕨, 3‿3 ≡ ≢𝕩)" % 2+`˘↕3‿3‿3
|
||||
!"´: Argument must be a list (3‿3 ≡ ≢𝕩)" % +´˘2‿3‿3⥊↕18
|
||||
!"´: 𝕩 must be a list (3‿3 ≡ ≢𝕩)" % 1+´˘2‿3‿3⥊↕18
|
||||
!"˝: 𝕩 must have rank at least 1" % +˝˘˘10‿10⥊↕100
|
||||
|
||||
%USE tcc ⋄ ⟨2, 20, ¯2, ¯20, 0⟩ {𝕨 ↑_tcc 𝕩 ⋄ 𝕨 ↓_tcc 𝕩}⌜ ⟨<4, ↕5, 4‿5⥊↕20, 4‿5‿6⥊↕120⟩
|
||||
%USE tcc ⋄ ⟨<, ≍, ⊏, ⥊⟩ {𝕎 _tcc 𝕩}⌜ ⟨<4, ↕5, 4‿5⥊↕20, 4‿5‿6⥊↕120, 2‿3‿4‿5⥊↕120⟩
|
||||
%USE tcc ⋄ ⟨<, ≍, ⥊⟩ {𝕎 _tcc 𝕩}⌜ ⟨<4, ↕5, 4‿5⥊↕20, 4‿5‿6⥊↕120, 2‿3‿4‿5⥊↕120⟩
|
||||
|
||||
Loading…
Reference in New Issue
Block a user