diff --git a/src/builtins/fold.c b/src/builtins/fold.c index bb9312ca..90b38382 100644 --- a/src/builtins/fold.c +++ b/src/builtins/fold.c @@ -383,6 +383,32 @@ static B m1c1(B t, B f, B x) { // consumes x } extern B insert_base(B f, B x, bool has_w, B w); // from cells.c +// Do arithmetic ๐”ฝห with short rows like ๐”ฝยจห to cut per-row overhead +static B insert_scal(B f, FC2 fc2, B x, bool has_w, B fxw, usz xia, ur rr) { + usz csz = arr_csz(x); + HArr_p r = m_harr0p(csz); + usz* rsh = arr_shAlloc((Arr*)r.c, rr); + if (rr>1) shcpy(rsh, SH(x)+1, rr); + usz xi = xia - csz; + SGet(x) + B rf; + if (has_w) { + rf = getFillR(fxw); + SGet(fxw) // (โŠขห๐•ฉ)๐”ฝ๐•จ so errors have been caught + for (usz i=0; if; ur xr; if (isAtm(x) || (xr=RNK(x))==0) thrM("๐”ฝห๐•ฉ: ๐•ฉ must have rank at least 1"); @@ -410,7 +436,8 @@ B insert_c1(Md1D* d, B x) { B f = d->f; if (RARE(!isFun(f))) { decG(x); if (isMd(f)) thrM("Calling a modifier"); return inc(f); } if (isPervasiveDyExt(f)) { if (xr==1) return m_unit(fold_c1(d, x)); - if (len==IA(x)) { + usz xia = IA(x); + if (len==xia) { B r = m_vec1(fold_c1(d, C1(shape, x))); ur rr = xr - 1; if (rr > 1) { @@ -420,6 +447,9 @@ B insert_c1(Md1D* d, B x) { B f = d->f; } return r; } + if (len>2 && xia<6*(u64)len) { + return insert_scal(f, c2fn(f), x, 0, m_f64(0), xia, xr-1); + } } if (RTID(f) != RTID_NONE) { u8 rtid = RTID(f); @@ -448,26 +478,34 @@ B insert_c2(Md1D* d, B w, B x) { B f = d->f; 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 (isPervasiveDyExt(f) && len==IA(x)) { - // 1-element arrays are always conformable - // final rank is higher of w, cell rank of x + if (isPervasiveDyExt(f)) { + usz xia = IA(x); ur rr = xr - 1; - if (isArr(w)) { - if (IA(w) != 1) goto skip; - ur wr = RNK(w); if (wr>rr) rr = wr; - w = TO_GET(w, 0); - } - 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; ia[i] = 1; - arr_shReplace(a(r), rr, rsh); + if (len==xia) { + // 1-element arrays are always conformable + // final rank is higher of w, cell rank of x + if (isArr(w)) { + if (IA(w) != 1) goto skip; + ur wr = RNK(w); if (wr>rr) rr = wr; + w = TO_GET(w, 0); } + 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; ia[i] = 1; + arr_shReplace(a(r), rr, rsh); + } + } + return r; + } + if (len>2 && xia<6*(u64)len && !(isArr(w) && RNK(w)>rr)) { + FC2 fc2 = c2fn(f); + w = fc2(f, C2(select, m_f64(-1), incG(x)), w); + return insert_scal(f, fc2, x, 1, w, xia, rr); } - return r; skip:; } if (RTID(f) != RTID_NONE) {