Scalar implementation of 𝔽˝ for generic arithmetic 𝔽 and short rows

This commit is contained in:
Marshall Lochbaum 2025-03-10 12:00:09 -04:00
parent e09fb53fb9
commit bbe4549aff

View File

@ -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; i<csz; i++) r.a[i] = Get(fxw, i);
decG(fxw);
} else {
rf = getFillR(x);
for (usz i=0; i<csz; i++) r.a[i] = Get(x, xi+i);
}
while (xi) {
xi -= csz;
for (usz i=0; i<csz; i++) r.a[i] = fc2(f, Get(x, xi+i), r.a[i]);
}
decG(x);
return withFill(r.b, rf);
}
B insert_c1(Md1D* d, B x) { B f = d->f;
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; i<rr; i++) rsh->a[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; i<rr; i++) rsh->a[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) {