Type-independent Replicate by constant

This commit is contained in:
Marshall Lochbaum 2022-09-22 21:42:18 -04:00
parent ec12dd4502
commit d647978c8f

View File

@ -527,18 +527,30 @@ B slash_c1(B t, B x) {
} }
B slash_c2(B t, B w, B x) { B slash_c2(B t, B w, B x) {
B r; i32 wv = -1;
if (isArr(w) && RNK(w)==1 && depth(w)==1) { usz wia;
usz wia = IA(w); if (isArr(w)) {
if (depth(w)>1) goto base;
ur wr = RNK(w);
if (wr>1) thrF("/: Simple 𝕨 must have rank 0 or 1 (%i≡=𝕨)", wr);
if (wr<1) { B v=IGet(w, 0); decG(w); w=v; goto atom; }
wia = IA(w);
if (wia==0) { decG(w); return isArr(x)? x : m_atomUnit(x); } if (wia==0) { decG(w); return isArr(x)? x : m_atomUnit(x); }
if (isAtm(x) || RNK(x)==0) thrM("/: 𝕩 must have rank at least 1 for simple 𝕨"); } else {
ur xr = RNK(x); atom:
usz xlen = *SH(x); if (!q_i32(w)) goto base;
wv = o2i(w);
}
if (isAtm(x) || RNK(x)==0) thrM("/: 𝕩 must have rank at least 1 for simple 𝕨");
ur xr = RNK(x);
usz xlen = *SH(x);
u8 xl = cellWidthLog(x);
u8 xt = arrNewType(TY(x));
B r;
if (wv < 0) { // Array w
if (RARE(wia!=xlen)) thrF("/: Lengths of components of 𝕨 must match 𝕩 (%s ≠ %s)", wia, xlen); if (RARE(wia!=xlen)) thrF("/: Lengths of components of 𝕨 must match 𝕩 (%s ≠ %s)", wia, xlen);
u8 xl = cellWidthLog(x);
u8 xt = arrNewType(TY(x));
u8 we = TI(w,elType); u8 we = TI(w,elType);
if (!elInt(we)) { if (!elInt(we)) {
w=any_squeeze(w); we=TI(w,elType); w=any_squeeze(w); we=TI(w,elType);
@ -580,9 +592,9 @@ B slash_c2(B t, B w, B x) {
// Make shape if needed; all cases below use it // Make shape if needed; all cases below use it
usz* rsh = NULL; usz* rsh = NULL;
if (xr > 1) { if (xr > 1) {
usz* sh = rsh = m_shArr(xr)->a; rsh = m_shArr(xr)->a;
sh[0] = s; rsh[0] = s;
shcpy(sh+1, SH(x)+1, xr-1); shcpy(rsh+1, SH(x)+1, xr-1);
} }
if (xl == 0) { if (xl == 0) {
@ -665,19 +677,37 @@ B slash_c2(B t, B w, B x) {
} }
} }
goto decWX_ret; goto decWX_ret;
} } else {
if (isArr(x) && RNK(x)==1 && q_i32(w)) { if (wv <= 1) {
usz xia = IA(x); if (wv < 0) thrM("/: 𝕨 cannot be negative");
i32 wv = o2i(w);
if (wv<=1) {
if (wv<0) thrM("/: 𝕨 cannot be negative");
return wv ? x : taga(arr_shVec(TI(x,slice)(x, 0, 0))); return wv ? x : taga(arr_shVec(TI(x,slice)(x, 0, 0)));
} }
u8 xe = TI(x,elType); if (xlen == 0) return x;
#define CONST_REP(T) \ usz s = xlen * wv;
usz s = xia*wv; \ if (xl>6 || xl<3 || TI(x,elType)==el_B) {
T* xp = tyany_ptr(x); \ if (xr != 1) goto base;
T* rp = m_tyarrv(&r, elWidth(xe), s, el2t(xe)); \ SLOW2("𝕨/𝕩", w, x);
B xf = getFillQ(x);
HArr_p r0 = m_harrUv(s);
SGetU(x)
for (usz i = 0; i < xlen; i++) {
B cx = incBy(GetU(x, i), wv);
for (i64 j = 0; j < wv; j++) *r0.a++ = cx;
}
r = withFill(r0.b, xf);
goto decX_ret;
}
u8 xk = xl-3;
void* rv = m_tyarrv(&r, 1<<xk, s, xt);
if (xr > 1) {
usz* rsh = m_shArr(xr)->a;
rsh[0] = s;
shcpy(rsh+1, SH(x)+1, xr-1);
Arr* ra=a(r); SPRNK(ra,xr); PSH(ra)=rsh; PIA(ra)=s*arr_csz(x);
}
void* xv = tyany_ptr(x);
#define CONST_REP(T) { \
T* xp = xv; T* rp = rv; \
usz b = 1<<10; \ usz b = 1<<10; \
T js=xp[0], px=js; \ T js=xp[0], px=js; \
for (usz k=0, j=0, ij=wv; ; ) { \ for (usz k=0, j=0, ij=wv; ; ) { \
@ -686,25 +716,14 @@ B slash_c2(B t, B w, B x) {
while (ij<e) { j++; T sx=px; rp[ij]+=(px=xp[j])-sx; ij+=wv; } \ while (ij<e) { j++; T sx=px; rp[ij]+=(px=xp[j])-sx; ij+=wv; } \
PLUS_SCAN(T) \ PLUS_SCAN(T) \
if (e==s) {break;} k=e; \ if (e==s) {break;} k=e; \
} \ } goto decX_ret; }
goto decX_ret; switch (xk) { default: UD;
if (xe==el_i8 ) { CONST_REP(u8 ) } case 0: CONST_REP(u8 )
else if (xe==el_i16) { CONST_REP(u16) } case 1: CONST_REP(u16)
else if (xe==el_i32) { CONST_REP(u32) } case 2: CONST_REP(u32)
else if (xe==el_f64) { CONST_REP(u64) } case 3: CONST_REP(u64)
#undef CONST_REP
else {
SLOW2("𝕨/𝕩", w, x);
B xf = getFillQ(x);
HArr_p r0 = m_harrUv(xia*wv);
SGetU(x)
for (usz i = 0; i < xia; i++) {
B cx = incBy(GetU(x, i), wv);
for (i64 j = 0; j < wv; j++) *r0.a++ = cx;
}
r = withFill(r0.b, xf);
goto decX_ret;
} }
#undef CONST_REP
} }
base: base:
return c2(rt_slash, w, x); return c2(rt_slash, w, x);