commit
6f707a5f9d
@ -76,9 +76,80 @@ B ud_c1(B t, B x) {
|
||||
return taga(r);
|
||||
}
|
||||
|
||||
extern B rt_ud;
|
||||
B ud_c2(B t, B w, B x) {
|
||||
return c2(rt_ud, w, x);
|
||||
usz wia=1;
|
||||
if (isArr(w)) {
|
||||
if (RNK(w)>1) thrM("↕: 𝕨 must have rank at most 1");
|
||||
wia = IA(w);
|
||||
if (wia==0) { decG(w); return x; }
|
||||
}
|
||||
ur xr;
|
||||
if (isAtm(x) || (xr=RNK(x))<wia) thrM("↕: Length of 𝕨 must be at most rank of 𝕩");
|
||||
if (xr+wia > UR_MAX) thrM("↕: Result rank too large");
|
||||
ur wr = wia;
|
||||
ur rr = xr + wr;
|
||||
ShArr* sh = m_shArr(rr);
|
||||
usz* rsh = sh->a;
|
||||
usz* wsh = rsh + wr;
|
||||
if (isAtm(w)) {
|
||||
wsh[0] = o2s(w);
|
||||
} else {
|
||||
SGetU(w)
|
||||
for (usz i=0; i<wr; i++) wsh[i] = o2s(GetU(w, i));
|
||||
decG(w);
|
||||
}
|
||||
|
||||
usz* xsh = SH(x);
|
||||
bool empty = IA(x)==0;
|
||||
for (usz i=0; i<wr; i++) {
|
||||
usz l = xsh[i] + 1;
|
||||
usz m = wsh[i];
|
||||
if (l<m) thrM("↕: Window length 𝕨 must be at most axis length plus one");
|
||||
empty|= m==0 | m==l;
|
||||
rsh[i] = l - m;
|
||||
}
|
||||
for (usz i=wr; i<xr; i++) wsh[i] = xsh[i];
|
||||
|
||||
if (empty) {
|
||||
Arr* ra = m_fillarrp(0);
|
||||
arr_shSetU(ra, rr, sh);
|
||||
fillarr_setFill(ra, getFillQ(x));
|
||||
decG(x);
|
||||
return taga(ra);
|
||||
}
|
||||
ur fr=2*wr; // Frame rank in result
|
||||
usz cia=1; // Cell length
|
||||
for (usz i=fr; i<rr; i++) if (mulOn(cia, rsh[i])) thrM("↕: result shape too large");
|
||||
usz ria=cia;
|
||||
for (usz i=0; i<fr; i++) if (mulOn(ria, rsh[i])) thrM("↕: result shape too large");
|
||||
B xf = getFillQ(x);
|
||||
TALLOC(usz, ri, fr-1);
|
||||
MAKE_MUT(r, ria); mut_init(r, TI(x,elType));
|
||||
MUTG_INIT(r);
|
||||
usz k = cia*rsh[fr-1];
|
||||
if (wr==1) {
|
||||
for (usz i=0, j=0; i<ria; i+=k, j+=cia) mut_copyG(r, i, x, j, k);
|
||||
} else {
|
||||
for (usz i=0; i<fr-1; i++) ri[i]=0;
|
||||
for (usz i=0, j=0;;) {
|
||||
mut_copyG(r, i, x, j, k);
|
||||
usz str = cia*xsh[xr-1];
|
||||
i += k;
|
||||
if (i == ria) break;
|
||||
j += str;
|
||||
for (usz a=fr-2, b=xr-2; RARE(++ri[a] == rsh[a]); ) {
|
||||
ri[a] = 0;
|
||||
j -= rsh[a] * str;
|
||||
str *= xsh[b]; if (!b) { str=cia; b=xr; }
|
||||
a--; b--;
|
||||
j += str;
|
||||
}
|
||||
}
|
||||
}
|
||||
decG(x); TFREE(ri);
|
||||
Arr* ra = mut_fp(r);
|
||||
arr_shSetU(ra, rr, sh);
|
||||
return withFill(taga(ra), xf);
|
||||
}
|
||||
|
||||
B ltack_c1(B t, B x) { return x; }
|
||||
@ -171,6 +242,8 @@ B indexOf_c2(B t, B w, B x) {
|
||||
B enclosed_0;
|
||||
B enclosed_1;
|
||||
extern B rt_memberOf;
|
||||
extern B eq_c2(B,B,B);
|
||||
extern B or_c2(B,B,B);
|
||||
B memberOf_c2(B t, B w, B x) {
|
||||
if (isAtm(x) || RNK(x)!=1) goto bad;
|
||||
if (isAtm(w)) goto single;
|
||||
@ -198,8 +271,15 @@ B memberOf_c2(B t, B w, B x) {
|
||||
|
||||
|
||||
many: {
|
||||
usz xia = IA(x);
|
||||
usz wia = IA(w);
|
||||
u8 we = TI(w,elType); usz wia = IA(w);
|
||||
u8 xe = TI(x,elType); usz xia = IA(x);
|
||||
if (xia<=16 && wia>16 && we<el_B && xe<el_B) {
|
||||
SGetU(x);
|
||||
Arr* ba=allZeroes(wia); arr_shVec(ba); r=taga(ba);
|
||||
for (usz i=0; i<xia; i++) r = or_c2(m_f64(0), r, eq_c2(m_f64(0), inc(w), GetU(x,i)));
|
||||
decG(w);
|
||||
goto dec_x;
|
||||
}
|
||||
// TODO O(wia×xia) for small wia or xia
|
||||
H_Sb* set = m_Sb(64);
|
||||
SGetU(x) SGetU(w)
|
||||
|
||||
@ -220,25 +220,28 @@ B GRADE_CAT(c1)(B t, B x) {
|
||||
if (xe==el_i32 || xe==el_c32) { // safe to use the same comparison for i32 & c32 as c32 is 0≤x≤1114111
|
||||
i32* xp = tyany_ptr(x);
|
||||
i32 min=I32_MAX, max=I32_MIN;
|
||||
i32 sum=0;
|
||||
for (usz i = 0; i < ia; i++) {
|
||||
i32 c = xp[i];
|
||||
sum += c;
|
||||
if (c<min) min=c;
|
||||
if (c>max) max=c;
|
||||
}
|
||||
i64 range = max - (i64)min + 1;
|
||||
u64 range = max - (i64)min + 1;
|
||||
if (range/2 < ia) {
|
||||
TALLOC(usz, tmp, range+1);
|
||||
for (i64 i = 0; i < range+1; i++) tmp[i] = 0;
|
||||
GRADE_UD( // i32 range-based
|
||||
for (usz i = 0; i < ia; i++) (tmp-min+1)[xp[i]]++;
|
||||
for (i64 i = 1; i < range; i++) tmp[i]+= tmp[i-1];
|
||||
for (usz i = 0; i < ia; i++) rp[(tmp-min)[xp[i]]++] = i;
|
||||
,
|
||||
for (usz i = 0; i < ia; i++) (tmp-min)[xp[i]]++;
|
||||
for (i64 i = range-2; i >= 0; i--) tmp[i]+= tmp[i+1];
|
||||
for (usz i = 0; i < ia; i++) rp[(tmp-min+1)[xp[i]]++] = i;
|
||||
)
|
||||
TFREE(tmp); decG(x);
|
||||
// First try to invert it as a permutation
|
||||
if (range==ia && sum==(i32)((i64)ia*(min+max)/2)) {
|
||||
for (usz i = 0; i < ia; i++) rp[i]=ia;
|
||||
for (usz i = 0; i < ia; i++) { i32 v=xp[i]; GRADE_UD(rp[v-min],rp[max-v])=i; }
|
||||
bool done=1; for (usz i = 0; i < ia; i++) done &= rp[i]!=ia;
|
||||
if (done) { decG(x); return r; }
|
||||
}
|
||||
TALLOC(usz, c0, range); usz *c0o=c0-min;
|
||||
for (usz i = 0; i < range; i++) c0[i] = 0;
|
||||
for (usz i = 0; i < ia; i++) c0o[xp[i]]++;
|
||||
usz s=0; FOR (i, range) { usz p=s; s+=c0[i]; c0[i]=p; }
|
||||
for (usz i = 0; i < ia; i++) rp[c0o[xp[i]]++] = i;
|
||||
TFREE(c0); decG(x);
|
||||
return r;
|
||||
}
|
||||
if (ia > 40) {
|
||||
|
||||
@ -9,9 +9,10 @@ B memberOf_c1(B t, B x) {
|
||||
if (n==0) { decG(x); return emptyIVec(); }
|
||||
if (RNK(x)>1) x = toCells(x);
|
||||
u8 xe = TI(x,elType);
|
||||
if (elChr(xe)) xe -= el_c8-el_i8;
|
||||
|
||||
#define BRUTE(T) \
|
||||
i##T* xp = i##T##any_ptr(x); \
|
||||
i##T* xp = tyany_ptr(x); \
|
||||
u64* rp; B r = m_bitarrv(&rp, n); bitp_set(rp, 0, 1); \
|
||||
for (usz i=1; i<n; i++) { \
|
||||
bool c=1; i##T xi=xp[i]; \
|
||||
@ -21,7 +22,7 @@ B memberOf_c1(B t, B x) {
|
||||
decG(x); return r;
|
||||
#define LOOKUP(T) \
|
||||
usz tn = 1<<T; \
|
||||
u##T* xp = (u##T*)i##T##any_ptr(x); \
|
||||
u##T* xp = (u##T*)tyany_ptr(x); \
|
||||
i8* rp; B r = m_i8arrv(&rp, n); \
|
||||
TALLOC(u8, tab, tn); \
|
||||
if (T>8 && n<tn/64) for (usz i=0; i<n; i++) tab[xp[i]]=1; \
|
||||
@ -36,7 +37,7 @@ B memberOf_c1(B t, B x) {
|
||||
if (n<=32) { BRUTE(32); }
|
||||
// Radix-assisted lookup
|
||||
usz rx = 256, tn = 1<<16; // Radix; table length
|
||||
u32* v0 = (u32*)i32any_ptr(x);
|
||||
u32* v0 = (u32*)tyany_ptr(x);
|
||||
i8* r0; B r = m_i8arrv(&r0, n);
|
||||
|
||||
TALLOC(u8, alloc, 6*n+(4+(tn>3*n?tn:3*n)+(2*rx+1)*sizeof(usz)));
|
||||
@ -95,9 +96,10 @@ B count_c1(B t, B x) {
|
||||
if (n>(usz)I32_MAX+1) thrM("⊒: Argument length >2⋆31 not supported");
|
||||
if (RNK(x)>1) x = toCells(x);
|
||||
u8 xe = TI(x,elType);
|
||||
if (elChr(xe)) xe -= el_c8-el_i8;
|
||||
|
||||
#define BRUTE(T) \
|
||||
i##T* xp = i##T##any_ptr(x); \
|
||||
i##T* xp = tyany_ptr(x); \
|
||||
i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \
|
||||
for (usz i=1; i<n; i++) { \
|
||||
usz c=0; i##T xi=xp[i]; \
|
||||
@ -107,7 +109,7 @@ B count_c1(B t, B x) {
|
||||
decG(x); return r;
|
||||
#define LOOKUP(T) \
|
||||
usz tn = 1<<T; \
|
||||
u##T* xp = (u##T*)i##T##any_ptr(x); \
|
||||
u##T* xp = (u##T*)tyany_ptr(x); \
|
||||
i32* rp; B r = m_i32arrv(&rp, n); \
|
||||
TALLOC(i32, tab, tn); \
|
||||
if (T>8 && n<tn/16) for (usz i=0; i<n; i++) tab[xp[i]]=0; \
|
||||
@ -122,7 +124,7 @@ B count_c1(B t, B x) {
|
||||
if (n<=32) { BRUTE(32); }
|
||||
// Radix-assisted lookup
|
||||
usz rx = 256, tn = 1<<16; // Radix; table length
|
||||
u32* v0 = (u32*)i32any_ptr(x);
|
||||
u32* v0 = (u32*)tyany_ptr(x);
|
||||
i32* r0; B r = m_i32arrv(&r0, n);
|
||||
|
||||
TALLOC(u8, alloc, 6*n+(4+4*(tn>n?tn:n)+(2*rx+1)*sizeof(usz)));
|
||||
@ -186,9 +188,10 @@ B indexOf_c1(B t, B x) {
|
||||
if (n>(usz)I32_MAX+1) thrM("⊐: Argument length >2⋆31 not supported");
|
||||
if (RNK(x)>1) x = toCells(x);
|
||||
u8 xe = TI(x,elType);
|
||||
if (elChr(xe)) xe -= el_c8-el_i8;
|
||||
|
||||
#define BRUTE(T) \
|
||||
i##T* xp = i##T##any_ptr(x); \
|
||||
i##T* xp = tyany_ptr(x); \
|
||||
i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \
|
||||
TALLOC(i##T, uniq, n); uniq[0]=xp[0]; \
|
||||
for (usz i=1, u=1; i<n; i++) { \
|
||||
@ -199,7 +202,7 @@ B indexOf_c1(B t, B x) {
|
||||
decG(x); TFREE(uniq); return r;
|
||||
#define LOOKUP(T) \
|
||||
usz tn = 1<<T; \
|
||||
u##T* xp = (u##T*)i##T##any_ptr(x); \
|
||||
u##T* xp = (u##T*)tyany_ptr(x); \
|
||||
i32* rp; B r = m_i32arrv(&rp, n); \
|
||||
TALLOC(i32, tab, tn); \
|
||||
if (T>8 && n<tn/16) for (usz i=0; i<n; i++) tab[xp[i]]=n; \
|
||||
@ -217,7 +220,7 @@ B indexOf_c1(B t, B x) {
|
||||
|
||||
if (xe==el_i32) {
|
||||
if (n<32) { BRUTE(32); }
|
||||
i32* xp = i32any_ptr(x);
|
||||
i32* xp = tyany_ptr(x);
|
||||
i32 min=I32_MAX, max=I32_MIN;
|
||||
for (usz i = 0; i < n; i++) {
|
||||
i32 c = xp[i];
|
||||
|
||||
@ -443,10 +443,26 @@ B slash_c1(B t, B x) {
|
||||
B r;
|
||||
u8 xe = TI(x,elType);
|
||||
#if SINGELI && defined(__BMI2__)
|
||||
if (xia<=32768 && xe==el_bit) {
|
||||
if (xe==el_bit) {
|
||||
u64* xp = bitarr_ptr(x);
|
||||
if (xia<=128) { i8* rp = m_tyarrvO(&r, 1, s, t_i8arr , 8); bmipopc_1slash8 (xp, rp, xia); }
|
||||
else { i16* rp = m_tyarrvO(&r, 2, s, t_i16arr, 16); bmipopc_1slash16(xp, rp, xia); }
|
||||
if (xia<=128) { i8* rp = m_tyarrvO(&r, 1, s, t_i8arr , 8); bmipopc_1slash8 (xp, rp, xia); }
|
||||
else if (xia<=32768) { i16* rp = m_tyarrvO(&r, 2, s, t_i16arr, 16); bmipopc_1slash16(xp, rp, xia); }
|
||||
else {
|
||||
usz b = 1<<12;
|
||||
i32* rp; r = m_i32arrv(&rp, s);
|
||||
TALLOC(i16, buf, b);
|
||||
i32* rq=rp; usz i=0;
|
||||
for (; i+b<xia; i+=b) {
|
||||
bmipopc_1slash16(xp, buf, b);
|
||||
usz bs = bit_sum(xp, b);
|
||||
for (usz j=0; j<bs; j++) rq[j] = i+buf[j];
|
||||
rq+= bs;
|
||||
xp+= b/64;
|
||||
}
|
||||
bmipopc_1slash16(xp, buf, xia-i);
|
||||
for (usz j=0, bs=s-(rq-rp); j<bs; j++) rq[j] = i+buf[j];
|
||||
TFREE(buf);
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
@ -535,6 +551,24 @@ B slash_c2(B t, B w, B x) {
|
||||
#if SINGELI
|
||||
case el_i8: case el_c8: { i8* xp=tyany_ptr(x); i8* rp=m_tyarrvO(&r,1,wsum,el2t(xe), 8); bmipopc_2slash8 (wp, xp, rp, wia); goto bit_ret; }
|
||||
case el_i16:case el_c16: { i16* xp=tyany_ptr(x); i16* rp=m_tyarrvO(&r,2,wsum,el2t(xe), 16); bmipopc_2slash16(wp, xp, rp, wia); goto bit_ret; }
|
||||
case el_i32:case el_c32: {
|
||||
i32* xp=tyany_ptr(x); i32* rp=m_tyarrv(&r,4,wsum,el2t(xe));
|
||||
usz b = 1<<7;
|
||||
TALLOC(i8, buf, b);
|
||||
i32* rq=rp; i32* end=xp+xia-b;
|
||||
while (xp < end) {
|
||||
bmipopc_1slash8(wp, buf, b);
|
||||
usz bs = bit_sum(wp, b);
|
||||
for (usz j=0; j<bs; j++) rq[j] = xp[buf[j]];
|
||||
rq+= bs;
|
||||
wp+= b/64;
|
||||
xp+= b;
|
||||
}
|
||||
bmipopc_1slash8(wp, buf, (end+b)-xp);
|
||||
for (usz j=0, bs=wsum-(rq-rp); j<bs; j++) rq[j] = xp[buf[j]];
|
||||
TFREE(buf);
|
||||
goto bit_ret;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -103,7 +103,7 @@ B comp_currArgs;
|
||||
B comp_currSrc;
|
||||
B comp_currRe;
|
||||
|
||||
B rt_undo, rt_select, rt_slash, rt_ud, rt_pick, rt_take, rt_drop, rt_insert, rt_depth,
|
||||
B rt_undo, rt_select, rt_slash, rt_pick, rt_take, rt_drop, rt_insert, rt_depth,
|
||||
rt_group, rt_under, rt_reverse, rt_indexOf, rt_count, rt_memberOf, rt_find, rt_transp;
|
||||
Block* load_compObj(B x, B src, B path, Scope* sc) { // consumes x,src
|
||||
SGet(x)
|
||||
@ -386,7 +386,6 @@ void load_init() { // very last init function
|
||||
rt_undo = Get(rtObjRaw, n_undo ); gc_add(rt_undo);
|
||||
rt_select = Get(rtObjRaw, n_select ); gc_add(rt_select);
|
||||
rt_slash = Get(rtObjRaw, n_slash ); gc_add(rt_slash);
|
||||
rt_ud = Get(rtObjRaw, n_ud ); gc_add(rt_ud);
|
||||
rt_take = Get(rtObjRaw, n_take ); gc_add(rt_take);
|
||||
rt_drop = Get(rtObjRaw, n_drop ); gc_add(rt_drop);
|
||||
rt_group = Get(rtObjRaw, n_group ); gc_add(rt_group);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user