Merge pull request #39 from mlochbaum/misc

Things
This commit is contained in:
dzaima 2022-09-01 00:25:56 +03:00 committed by GitHub
commit 6f707a5f9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 150 additions and 31 deletions

View File

@ -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)

View File

@ -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) {

View File

@ -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];

View File

@ -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

View File

@ -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);