diff --git a/makefile b/makefile index 7d40b983..13f3958f 100644 --- a/makefile +++ b/makefile @@ -116,7 +116,7 @@ ${bd}/%.o: src/jit/%.c @echo $< | cut -c 5- @$(CMD) $@.d -o $@ -c $< -builtins: ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o sort.o md1.o md2.o fns.o sysfn.o internal.o inverse.o} +builtins: ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o select.o sort.o md1.o md2.o fns.o sysfn.o internal.o inverse.o} ${bd}/%.o: src/builtins/%.c @echo $< | cut -c 5- @$(CMD) $@.d -o $@ -c $< diff --git a/src/builtins/select.c b/src/builtins/select.c new file mode 100644 index 00000000..d6844640 --- /dev/null +++ b/src/builtins/select.c @@ -0,0 +1,256 @@ +#include "../core.h" +#include "../utils/talloc.h" +#include "../utils/mut.h" +#include "../builtins.h" + + +extern B rt_select; +B select_c1(B t, B x) { + if (isAtm(x)) thrM("⊏: Argument cannot be an atom"); + ur xr = rnk(x); + if (xr==0) thrM("⊏: Argument cannot be rank 0"); + if (a(x)->sh[0]==0) thrF("⊏: Argument shape cannot start with 0 (%H ≡ ≢𝕩)", x); + usz ia = 1; + for (i32 i = 1; i < xr; i++) ia*= a(x)->sh[i]; + Arr* r = TI(x,slice)(inc(x),0, ia); + usz* sh = arr_shAlloc(r, xr-1); + if (sh) for (i32 i = 1; i < xr; i++) sh[i-1] = a(x)->sh[i]; + decG(x); + return taga(r); +} +B select_c2(B t, B w, B x) { + if (isAtm(x)) thrM("⊏: 𝕩 cannot be an atom"); + ur xr = rnk(x); + if (isAtm(w)) { + if (xr==0) thrM("⊏: 𝕩 cannot be a unit"); + usz csz = arr_csz(x); + usz cam = a(x)->sh[0]; + usz wi = WRAP(o2i64(w), cam, thrF("⊏: Indexing out-of-bounds (𝕨≡%R, %s≡≠𝕩)", w, cam)); + Arr* r = TI(x,slice)(incG(x), wi*csz, csz); + usz* sh = arr_shAlloc(r, xr-1); + if (sh) memcpy(sh, a(x)->sh+1, (xr-1)*sizeof(usz)); + decG(x); + return taga(r); + } + B xf = getFillQ(x); + SGet(x) + usz wia = a(w)->ia; + + if (xr==1) { + usz xia = a(x)->ia; + u8 xe = TI(x,elType); + u8 we = TI(w,elType); + #define CASE(T,E) if (xe==el_##T) { \ + E* rp; B r = m_##T##arrc(&rp, w); \ + E* xp = T##any_ptr(x); \ + for (usz i = 0; i < wia; i++) rp[i] = xp[WRAP(wp[i], xia, thrF("⊏: Indexing out-of-bounds (%i∊𝕨, %s≡≠𝕩)", wp[i], xia))]; \ + decG(w); decG(x); return r; \ + } + #define TYPE(W) { W* wp = W##any_ptr(w); \ + if (xe==el_bit) { u64* xp=bitarr_ptr(x); \ + u64* rp; B r = m_bitarrc(&rp, w); \ + for (usz i = 0; i < wia; i++) bitp_set(rp, i, bitp_get(xp, WRAP(wp[i], xia, thrF("⊏: Indexing out-of-bounds (%i∊𝕨, %s≡≠𝕩)", wp[i], xia)))); \ + decG(w); decG(x); return r; \ + } \ + CASE(i8,i8) CASE(i16,i16) CASE(i32,i32) \ + CASE(c8,u8) CASE(c16,u16) CASE(c32,u32) CASE(f64,f64) \ + M_HARR(r, wia); \ + if (v(x)->type==t_harr || v(x)->type==t_hslice) { \ + B* xp = hany_ptr(x); \ + for (usz i=0; i < wia; i++) HARR_ADD(r, i, inc(xp[WRAP(wp[i], xia, thrF("⊏: Indexing out-of-bounds (%i∊𝕨, %s≡≠𝕩)", wp[i], xia))])); \ + decG(x); return HARR_FCD(r, w); \ + } SLOW2("𝕨⊏𝕩", w, x); \ + for (usz i=0; i < wia; i++) HARR_ADD(r, i, Get(x, WRAP(wp[i], xia, thrF("⊏: Indexing out-of-bounds (%i∊𝕨, %s≡≠𝕩)", wp[i], xia)))); \ + decG(x); return withFill(HARR_FCD(r,w),xf); \ + } + if (we==el_bit && xia>=2) { + SGetU(x) + B r = bit_sel(w, GetU(x,0), true, GetU(x,1), true); + decG(x); + return withFill(r, xf); + } + else if (we==el_i8) TYPE(i8) + else if (we==el_i16) TYPE(i16) + else if (we==el_i32) TYPE(i32) + else { + SLOW2("𝕨⊏𝕩", w, x); + M_HARR(r, wia) + SGetU(w) + for (usz i = 0; i < wia; i++) { + B cw = GetU(w, i); + if (!isNum(cw)) { HARR_ABANDON(r); goto base; } + usz c = WRAP(o2i64(cw), xia, thrF("⊏: Indexing out-of-bounds (%R∊𝕨, %s≡≠𝕩)", cw, xia)); + HARR_ADD(r, i, Get(x, c)); + } + decG(x); + return withFill(HARR_FCD(r,w),xf); + } + #undef CASE + } else { + SLOW2("𝕨⊏𝕩", w, x); + SGetU(w) + ur wr = rnk(w); + i32 rr = wr+xr-1; + if (xr==0) thrM("⊏: 𝕩 cannot be a unit"); + if (rr>UR_MAX) thrF("⊏: Result rank too large (%i≡=𝕨, %i≡=𝕩)", wr, xr); + usz csz = arr_csz(x); + usz cam = a(x)->sh[0]; + MAKE_MUT(r, wia*csz); mut_init(r, TI(x,elType)); + MUTG_INIT(r); + for (usz i = 0; i < wia; i++) { + B cw = GetU(w, i); + if (!isNum(cw)) { mut_pfree(r, i*csz); goto base; } + f64 c = o2f(cw); + if (c<0) c+= cam; + if ((usz)c >= cam) { mut_pfree(r, i*csz); thrF("⊏: Indexing out-of-bounds (%R∊𝕨, %s≡≠𝕩)", cw, cam); } + mut_copyG(r, i*csz, x, csz*(usz)c, csz); + } + Arr* ra = mut_fp(r); + usz* rsh = arr_shAlloc(ra, rr); + if (rsh) { + memcpy(rsh , a(w)->sh , wr *sizeof(usz)); + memcpy(rsh+wr, a(x)->sh+1, (xr-1)*sizeof(usz)); + } + decG(w); decG(x); + return withFill(taga(ra),xf); + } + base: + dec(xf); + return c2(rt_select, w, x); +} + + + + +B select_ucw(B t, B o, B w, B x) { + if (isAtm(x) || rnk(x)!=1 || isAtm(w)) return def_fn_ucw(t, o, w, x); + usz xia = a(x)->ia; + usz wia = a(w)->ia; + SGetU(w) + if (TI(w,elType)!=el_i32) for (usz i = 0; i < wia; i++) if (!q_i64(GetU(w,i))) return def_fn_ucw(t, o, w, x); + B arg = select_c2(t, inc(w), inc(x)); + B rep = c1(o, arg); + if (isAtm(rep) || !eqShape(w, rep)) thrF("𝔽⌾(a⊸⊏)𝕩: Result of 𝔽 must have the same shape as 'a' (expected %H, got %H)", w, rep); + #if CHECK_VALID + TALLOC(bool, set, xia); + for (i64 i = 0; i < xia; i++) set[i] = false; + #define EQ(F) if (set[cw] && (F)) thrM("𝔽⌾(a⊸⊏): Incompatible result elements"); set[cw] = true; + #define FREE_CHECK TFREE(set) + SLOWIF(xia>100 && wia100 && wiare?xe:re; + bool reuse = reusable(x); + if (me==el_i32) { + I32Arr* xn = reuse? toI32Arr(REUSE(x)) : cpyI32Arr(x); + i32* xp = i32arrv_ptr(xn); + rep = toI32Any(rep); i32* rp = i32any_ptr(rep); + for (usz i = 0; i < wia; i++) { + i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; // we're free to assume w is valid + i32 cr = rp[i]; + EQ(cr != xp[cw]); + xp[cw] = cr; + } + decG(w); decG(rep); FREE_CHECK; return taga(xn); + } else if (me==el_i8) { + I8Arr* xn = reuse? toI8Arr(REUSE(x)) : cpyI8Arr(x); + i8* xp = i8arrv_ptr(xn); + rep = toI8Any(rep); i8* rp = i8any_ptr(rep); + for (usz i = 0; i < wia; i++) { + i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; + i8 cr = rp[i]; + EQ(cr != xp[cw]); + xp[cw] = cr; + } + decG(w); decG(rep); FREE_CHECK; return taga(xn); + } else if (me==el_i16) { + I16Arr* xn = reuse? toI16Arr(REUSE(x)) : cpyI16Arr(x); + i16* xp = i16arrv_ptr(xn); + rep = toI16Any(rep); i16* rp = i16any_ptr(rep); + for (usz i = 0; i < wia; i++) { + i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; + i16 cr = rp[i]; + EQ(cr != xp[cw]); + xp[cw] = cr; + } + decG(w); decG(rep); FREE_CHECK; return taga(xn); + } else if (me==el_bit) { + BitArr* xn = reuse? toBitArr(REUSE(x)) : cpyBitArr(x); + u64* xp = bitarrv_ptr(xn); + rep = taga(toBitArr(rep)); u64* rp = bitarr_ptr(rep); + for (usz i = 0; i < wia; i++) { + i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; + bool cr = bitp_get(rp, i); + EQ(cr != bitp_get(xp,cw)); + bitp_set(xp,cw,cr); + } + decG(w); decG(rep); FREE_CHECK; return taga(xn); + } else if (me==el_f64) { + F64Arr* xn = reuse? toF64Arr(REUSE(x)) : cpyF64Arr(x); + f64* xp = f64arrv_ptr(xn); + rep = toF64Any(rep); f64* rp = f64any_ptr(rep); + for (usz i = 0; i < wia; i++) { + i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; + f64 cr = rp[i]; + EQ(cr != xp[cw]); + xp[cw] = cr; + } + decG(w); decG(rep); FREE_CHECK; return taga(xn); + } else UD; + } + if (reusable(x) && xe==re) { + if (v(x)->type==t_harr) { + B* xp = harr_ptr(REUSE(x)); + SGet(rep) + for (usz i = 0; i < wia; i++) { + i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; + B cr = Get(rep, i); + EQ(!equal(cr,xp[cw])); + dec(xp[cw]); + xp[cw] = cr; + } + decG(w); decG(rep); FREE_CHECK; + return x; + } + } + MAKE_MUT(r, xia); mut_init(r, el_or(xe, re)); + MUTG_INIT(r); + mut_copyG(r, 0, x, 0, xia); + SGet(rep) + for (usz i = 0; i < wia; i++) { + i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; + B cr = Get(rep, i); + EQ(!equal(mut_getU(r, cw), cr)); + mut_rm(r, cw); + mut_setG(r, cw, cr); + } + decG(w); decG(rep); FREE_CHECK; + return mut_fcd(r, x); + } + MAKE_MUT(r, xia); mut_init(r, el_or(xe, re)); + MUTG_INIT(r); + mut_copyG(r, 0, x, 0, xia); + SGet(rep) + for (usz i = 0; i < wia; i++) { + i64 cw = o2i64u(GetU(w, i)); if (RARE(cw<0)) cw+= (i64)xia; + B cr = Get(rep, i); + EQ(!equal(mut_getU(r, cw), cr)); + mut_rm(r, cw); + mut_setG(r, cw, cr); + } + decG(w); decG(rep); FREE_CHECK; + return mut_fcd(r, x); + #undef EQ + #undef FREE_CHECK +} diff --git a/src/builtins/sfns.c b/src/builtins/sfns.c index 06d8b1d9..7273cf2f 100644 --- a/src/builtins/sfns.c +++ b/src/builtins/sfns.c @@ -324,121 +324,6 @@ B pick_c2(B t, B w, B x) { return r; } -extern B rt_select; -B select_c1(B t, B x) { - if (isAtm(x)) thrM("⊏: Argument cannot be an atom"); - ur xr = rnk(x); - if (xr==0) thrM("⊏: Argument cannot be rank 0"); - if (a(x)->sh[0]==0) thrF("⊏: Argument shape cannot start with 0 (%H ≡ ≢𝕩)", x); - usz ia = 1; - for (i32 i = 1; i < xr; i++) ia*= a(x)->sh[i]; - Arr* r = TI(x,slice)(inc(x),0, ia); - usz* sh = arr_shAlloc(r, xr-1); - if (sh) for (i32 i = 1; i < xr; i++) sh[i-1] = a(x)->sh[i]; - decG(x); - return taga(r); -} -B select_c2(B t, B w, B x) { - if (isAtm(x)) thrM("⊏: 𝕩 cannot be an atom"); - ur xr = rnk(x); - if (isAtm(w)) { - if (xr==0) thrM("⊏: 𝕩 cannot be a unit"); - usz csz = arr_csz(x); - usz cam = a(x)->sh[0]; - usz wi = WRAP(o2i64(w), cam, thrF("⊏: Indexing out-of-bounds (𝕨≡%R, %s≡≠𝕩)", w, cam)); - Arr* r = TI(x,slice)(incG(x), wi*csz, csz); - usz* sh = arr_shAlloc(r, xr-1); - if (sh) memcpy(sh, a(x)->sh+1, (xr-1)*sizeof(usz)); - decG(x); - return taga(r); - } - B xf = getFillQ(x); - SGet(x) - usz wia = a(w)->ia; - - if (xr==1) { - usz xia = a(x)->ia; - u8 xe = TI(x,elType); - #define CASE(T,E) if (xe==el_##T) { \ - E* rp; B r = m_##T##arrc(&rp, w); \ - E* xp = T##any_ptr(x); \ - for (usz i = 0; i < wia; i++) rp[i] = xp[WRAP(wp[i], xia, thrF("⊏: Indexing out-of-bounds (%i∊𝕨, %s≡≠𝕩)", wp[i], xia))]; \ - decG(w); decG(x); return r; \ - } - #define TYPE(W) { W* wp = W##any_ptr(w); \ - if (xe==el_bit) { u64* xp=bitarr_ptr(x); \ - u64* rp; B r = m_bitarrc(&rp, w); \ - for (usz i = 0; i < wia; i++) bitp_set(rp, i, bitp_get(xp, WRAP(wp[i], xia, thrF("⊏: Indexing out-of-bounds (%i∊𝕨, %s≡≠𝕩)", wp[i], xia)))); \ - decG(w); decG(x); return r; \ - } \ - CASE(i8,i8) CASE(i16,i16) CASE(i32,i32) \ - CASE(c8,u8) CASE(c16,u16) CASE(c32,u32) CASE(f64,f64) \ - M_HARR(r, wia); \ - if (v(x)->type==t_harr || v(x)->type==t_hslice) { \ - B* xp = hany_ptr(x); \ - for (usz i=0; i < wia; i++) HARR_ADD(r, i, inc(xp[WRAP(wp[i], xia, thrF("⊏: Indexing out-of-bounds (%i∊𝕨, %s≡≠𝕩)", wp[i], xia))])); \ - decG(x); return HARR_FCD(r, w); \ - } SLOW2("𝕨⊏𝕩", w, x); \ - for (usz i=0; i < wia; i++) HARR_ADD(r, i, Get(x, WRAP(wp[i], xia, thrF("⊏: Indexing out-of-bounds (%i∊𝕨, %s≡≠𝕩)", wp[i], xia)))); \ - decG(x); return withFill(HARR_FCD(r,w),xf); \ - } - if (TI(w,elType)==el_bit && xia>=2) { - SGetU(x) - B r = bit_sel(w, GetU(x,0), true, GetU(x,1), true); - decG(x); - return withFill(r, xf); - } - else if (TI(w,elType)==el_i8) TYPE(i8) - else if (TI(w,elType)==el_i16) TYPE(i16) - else if (TI(w,elType)==el_i32) TYPE(i32) - else { - SLOW2("𝕨⊏𝕩", w, x); - M_HARR(r, wia) - SGetU(w) - for (usz i = 0; i < wia; i++) { - B cw = GetU(w, i); - if (!isNum(cw)) { HARR_ABANDON(r); goto base; } - usz c = WRAP(o2i64(cw), xia, thrF("⊏: Indexing out-of-bounds (%R∊𝕨, %s≡≠𝕩)", cw, xia)); - HARR_ADD(r, i, Get(x, c)); - } - decG(x); - return withFill(HARR_FCD(r,w),xf); - } - #undef CASE - } else { - SLOW2("𝕨⊏𝕩", w, x); - SGetU(w) - ur wr = rnk(w); - i32 rr = wr+xr-1; - if (xr==0) thrM("⊏: 𝕩 cannot be a unit"); - if (rr>UR_MAX) thrF("⊏: Result rank too large (%i≡=𝕨, %i≡=𝕩)", wr, xr); - usz csz = arr_csz(x); - usz cam = a(x)->sh[0]; - MAKE_MUT(r, wia*csz); mut_init(r, TI(x,elType)); - MUTG_INIT(r); - for (usz i = 0; i < wia; i++) { - B cw = GetU(w, i); - if (!isNum(cw)) { mut_pfree(r, i*csz); goto base; } - f64 c = o2f(cw); - if (c<0) c+= cam; - if ((usz)c >= cam) { mut_pfree(r, i*csz); thrF("⊏: Indexing out-of-bounds (%R∊𝕨, %s≡≠𝕩)", cw, cam); } - mut_copyG(r, i*csz, x, csz*(usz)c, csz); - } - Arr* ra = mut_fp(r); - usz* rsh = arr_shAlloc(ra, rr); - if (rsh) { - memcpy(rsh , a(w)->sh , wr *sizeof(usz)); - memcpy(rsh+wr, a(x)->sh+1, (xr-1)*sizeof(usz)); - } - decG(w); decG(x); - return withFill(taga(ra),xf); - } - base: - dec(xf); - return c2(rt_select, w, x); -} - - #ifdef __BMI2__ #include #if SINGELI @@ -1383,138 +1268,6 @@ B slash_ucw(B t, B o, B w, B x) { return mut_fcd(r, x); } -B select_ucw(B t, B o, B w, B x) { - if (isAtm(x) || rnk(x)!=1 || isAtm(w)) return def_fn_ucw(t, o, w, x); - usz xia = a(x)->ia; - usz wia = a(w)->ia; - SGetU(w) - if (TI(w,elType)!=el_i32) for (usz i = 0; i < wia; i++) if (!q_i64(GetU(w,i))) return def_fn_ucw(t, o, w, x); - B arg = select_c2(t, inc(w), inc(x)); - B rep = c1(o, arg); - if (isAtm(rep) || !eqShape(w, rep)) thrF("𝔽⌾(a⊸⊏)𝕩: Result of 𝔽 must have the same shape as 'a' (expected %H, got %H)", w, rep); - #if CHECK_VALID - TALLOC(bool, set, xia); - for (i64 i = 0; i < xia; i++) set[i] = false; - #define EQ(F) if (set[cw] && (F)) thrM("𝔽⌾(a⊸⊏): Incompatible result elements"); set[cw] = true; - #define FREE_CHECK TFREE(set) - SLOWIF(xia>100 && wia100 && wiare?xe:re; - bool reuse = reusable(x); - if (me==el_i32) { - I32Arr* xn = reuse? toI32Arr(REUSE(x)) : cpyI32Arr(x); - i32* xp = i32arrv_ptr(xn); - rep = toI32Any(rep); i32* rp = i32any_ptr(rep); - for (usz i = 0; i < wia; i++) { - i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; // we're free to assume w is valid - i32 cr = rp[i]; - EQ(cr != xp[cw]); - xp[cw] = cr; - } - decG(w); decG(rep); FREE_CHECK; return taga(xn); - } else if (me==el_i8) { - I8Arr* xn = reuse? toI8Arr(REUSE(x)) : cpyI8Arr(x); - i8* xp = i8arrv_ptr(xn); - rep = toI8Any(rep); i8* rp = i8any_ptr(rep); - for (usz i = 0; i < wia; i++) { - i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; - i8 cr = rp[i]; - EQ(cr != xp[cw]); - xp[cw] = cr; - } - decG(w); decG(rep); FREE_CHECK; return taga(xn); - } else if (me==el_i16) { - I16Arr* xn = reuse? toI16Arr(REUSE(x)) : cpyI16Arr(x); - i16* xp = i16arrv_ptr(xn); - rep = toI16Any(rep); i16* rp = i16any_ptr(rep); - for (usz i = 0; i < wia; i++) { - i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; - i16 cr = rp[i]; - EQ(cr != xp[cw]); - xp[cw] = cr; - } - decG(w); decG(rep); FREE_CHECK; return taga(xn); - } else if (me==el_bit) { - BitArr* xn = reuse? toBitArr(REUSE(x)) : cpyBitArr(x); - u64* xp = bitarrv_ptr(xn); - rep = taga(toBitArr(rep)); u64* rp = bitarr_ptr(rep); - for (usz i = 0; i < wia; i++) { - i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; - bool cr = bitp_get(rp, i); - EQ(cr != bitp_get(xp,cw)); - bitp_set(xp,cw,cr); - } - decG(w); decG(rep); FREE_CHECK; return taga(xn); - } else if (me==el_f64) { - F64Arr* xn = reuse? toF64Arr(REUSE(x)) : cpyF64Arr(x); - f64* xp = f64arrv_ptr(xn); - rep = toF64Any(rep); f64* rp = f64any_ptr(rep); - for (usz i = 0; i < wia; i++) { - i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; - f64 cr = rp[i]; - EQ(cr != xp[cw]); - xp[cw] = cr; - } - decG(w); decG(rep); FREE_CHECK; return taga(xn); - } else UD; - } - if (reusable(x) && xe==re) { - if (v(x)->type==t_harr) { - B* xp = harr_ptr(REUSE(x)); - SGet(rep) - for (usz i = 0; i < wia; i++) { - i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; - B cr = Get(rep, i); - EQ(!equal(cr,xp[cw])); - dec(xp[cw]); - xp[cw] = cr; - } - decG(w); decG(rep); FREE_CHECK; - return x; - } - } - MAKE_MUT(r, xia); mut_init(r, el_or(xe, re)); - MUTG_INIT(r); - mut_copyG(r, 0, x, 0, xia); - SGet(rep) - for (usz i = 0; i < wia; i++) { - i64 cw = wp[i]; if (RARE(cw<0)) cw+= (i64)xia; - B cr = Get(rep, i); - EQ(!equal(mut_getU(r, cw), cr)); - mut_rm(r, cw); - mut_setG(r, cw, cr); - } - decG(w); decG(rep); FREE_CHECK; - return mut_fcd(r, x); - } - MAKE_MUT(r, xia); mut_init(r, el_or(xe, re)); - MUTG_INIT(r); - mut_copyG(r, 0, x, 0, xia); - SGet(rep) - for (usz i = 0; i < wia; i++) { - i64 cw = o2i64u(GetU(w, i)); if (RARE(cw<0)) cw+= (i64)xia; - B cr = Get(rep, i); - EQ(!equal(mut_getU(r, cw), cr)); - mut_rm(r, cw); - mut_setG(r, cw, cr); - } - decG(w); decG(rep); FREE_CHECK; - return mut_fcd(r, x); - #undef EQ - #undef FREE_CHECK -} static B shape_uc1_t(B r, usz ia) { if (!isArr(r) || rnk(r)!=1 || a(r)->ia!=ia) thrM("𝔽⌾⥊: 𝔽 changed the shape of the argument"); @@ -1532,12 +1285,14 @@ B shape_uc1(B t, B o, B x) { return truncReshape(shape_uc1_t(c1(o, shape_c1(t, x)), xia), xia, xia, xr, sh); } +B select_ucw(B t, B o, B w, B x); + void sfns_init() { c(BFn,bi_pick)->uc1 = pick_uc1; c(BFn,bi_reverse)->uc1 = reverse_uc1; c(BFn,bi_pick)->ucw = pick_ucw; c(BFn,bi_slash)->ucw = slash_ucw; - c(BFn,bi_select)->ucw = select_ucw; + c(BFn,bi_select)->ucw = select_ucw; // TODO move to new init fn c(BFn,bi_shape)->uc1 = shape_uc1; c(BFn,bi_slash)->im = slash_im; } diff --git a/src/opt/single.c b/src/opt/single.c index 309dc206..96f01999 100644 --- a/src/opt/single.c +++ b/src/opt/single.c @@ -15,6 +15,7 @@ #include "../utils/bits.c" #include "../builtins/fns.c" #include "../builtins/sfns.c" +#include "../builtins/select.c" #include "../builtins/sysfn.c" #include "../builtins/sort.c" #include "../builtins/arithm.c"