diff --git a/makefile b/makefile index 317394a9..cfae1da0 100644 --- a/makefile +++ b/makefile @@ -192,7 +192,7 @@ ${bd}/%.o: src/jit/%.c @echo $< | cut -c 5- @$(CC_INC) $@.d -o $@ -c $< -builtins: ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o squeeze.o select.o sort.o md1.o md2.o fns.o sysfn.o internal.o inverse.o} +builtins: ${addprefix ${bd}/, arithm.o arithd.o cmp.o sfns.o squeeze.o select.o sort.o selfsearch.o md1.o md2.o fns.o sysfn.o internal.o inverse.o} ${bd}/%.o: src/builtins/%.c @echo $< | cut -c 5- @$(CC_INC) $@.d -o $@ -c $< diff --git a/src/builtins/fns.c b/src/builtins/fns.c index 4912d416..9f1e55a4 100644 --- a/src/builtins/fns.c +++ b/src/builtins/fns.c @@ -122,70 +122,6 @@ B fne_c2(B t, B w, B x) { extern B rt_indexOf; -B indexOf_c1(B t, B x) { - if (isAtm(x)) thrM("⊐: 𝕩 cannot have rank 0"); - usz xia = IA(x); - if (xia==0) { decG(x); return emptyIVec(); } - if (RNK(x)==1 && TI(x,elType)==el_i32) { - i32* xp = i32any_ptr(x); - i32 min=I32_MAX, max=I32_MIN; - for (usz i = 0; i < xia; i++) { - i32 c = xp[i]; - if (cmax) max = c; - } - i64 dst = 1 + (max-(i64)min); - if ((dsta[p].val; - else rp[i] = map->a[p].val = ctr++; - } - free_b2i(map); decG(x); - // u64 e = nsTime(); q1+= e-s; - return r; - } - return c1(rt_indexOf, x); -} B indexOf_c2(B t, B w, B x) { if (!isArr(w) || RNK(w)==0) thrM("⊐: 𝕨 must have rank at least 1"); if (RNK(w)==1) { @@ -235,18 +171,6 @@ B indexOf_c2(B t, B w, B x) { B enclosed_0; B enclosed_1; extern B rt_memberOf; -B memberOf_c1(B t, B x) { - if (isAtm(x) || RNK(x)==0) thrM("∊: Argument cannot have rank 0"); - if (RNK(x)!=1) x = toCells(x); - usz xia = IA(x); - - u64* rp; B r = m_bitarrv(&rp, xia); - H_Sb* set = m_Sb(64); - SGetU(x) - for (usz i = 0; i < xia; i++) bitp_set(rp, i, !ins_Sb(&set, GetU(x,i))); - free_Sb(set); decG(x); - return r; -} B memberOf_c2(B t, B w, B x) { if (isAtm(x) || RNK(x)!=1) goto bad; if (isAtm(w)) goto single; @@ -293,41 +217,11 @@ B memberOf_c2(B t, B w, B x) { } extern B rt_find; -B find_c1(B t, B x) { - if (isAtm(x) || RNK(x)==0) thrM("⍷: Argument cannot have rank 0"); - usz xia = IA(x); - B xf = getFillQ(x); - if (RNK(x)!=1) return c1(rt_find, x); - - B r = emptyHVec(); - H_Sb* set = m_Sb(64); - SGetU(x) - for (usz i = 0; i < xia; i++) { - B c = GetU(x,i); - if (!ins_Sb(&set, c)) r = vec_add(r, inc(c)); - } - free_Sb(set); decG(x); - return withFill(r, xf); -} B find_c2(B t, B w, B x) { return c2(rt_find, w, x); } extern B rt_count; -B count_c1(B t, B x) { - if (isAtm(x) || RNK(x)==0) thrM("⊒: Argument cannot have rank 0"); - if (RNK(x)>1) x = toCells(x); - usz xia = IA(x); - i32* rp; B r = m_i32arrv(&rp, xia); - H_b2i* map = m_b2i(64); - SGetU(x) - for (usz i = 0; i < xia; i++) { - bool had; u64 p = mk_b2i(&map, GetU(x,i), &had); - rp[i] = had? ++map->a[p].val : (map->a[p].val = 0); - } - decG(x); free_b2i(map); - return r; -} B count_c2(B t, B w, B x) { return c2(rt_count, w, x); } diff --git a/src/builtins/selfsearch.c b/src/builtins/selfsearch.c new file mode 100644 index 00000000..1c15d939 --- /dev/null +++ b/src/builtins/selfsearch.c @@ -0,0 +1,275 @@ +#include "../core.h" +#include "../utils/hash.h" +#include "../utils/mut.h" +#include "../utils/talloc.h" + +B memberOf_c1(B t, B x) { + if (isAtm(x) || RNK(x)==0) thrM("∊: Argument cannot have rank 0"); + usz n = *SH(x); + if (n==0) { decG(x); return emptyIVec(); } + if (RNK(x)>1) x = toCells(x); + u8 xe = TI(x,elType); + + #define BRUTE(T) \ + i##T* xp = i##T##any_ptr(x); \ + u64* rp; B r = m_bitarrv(&rp, n); bitp_set(rp, 0, 1); \ + for (usz i=1; i8 && n3*n?tn:3*n)+(2*rx+1)*sizeof(usz))); + // timeline + // Allocations len count radix hash deradix bytes layout: + usz *c0 = (usz*)(alloc+1); // rx [+++................] c0 rx # + usz *c1 = (usz*)(c0+rx); // rx [++................] c1 rx # + u8 *k0 = (u8 *)(c1+rx); // n [+.............] k0 n ## + u32 *v2 = (u32*)(k0+n); // n+1 [+.......] v2 4*n+4 ######## + u8 *k1 = (u8 *)(v2+n+1); // n [+............] k1 n ## + u32 *v1 = (u32*)(k1); // n [+-] v1 4*n ######## + u8 *r2 = (u8 *)(v2); // n [+.....] r2 n ## + u8 *r1 = (u8 *)(k1+n); // n [+..] r1 n ## + u8 *tab= (u8 *)(r1); // tn [+] tab tn ##### + + // Count keys + for (usz j=0; j<2*rx; j++) c0[j] = 0; + for (usz i=0; i>24)]++; c1[(u8)(v>>16)]++; } + // Exclusive prefix sum + usz s0=0, s1=0; + for (usz j=0; j>24); usz c=c0[k]++; v1[c]=v; } + for (usz i=0; i>16); usz c=c1[k]++; v2[c]=v; } + // Table lookup + u32 tv=v2[0]>>16; v2[n]=~v2[n-1]; + for (usz l=0, i=0; l>16; if (tv!=t0) break; tab[(u16)v]=1; } + for (; i(usz)I32_MAX+1) thrM("⊒: Argument length >2⋆31 not supported"); + if (RNK(x)>1) x = toCells(x); + u8 xe = TI(x,elType); + + #define BRUTE(T) \ + i##T* xp = i##T##any_ptr(x); \ + i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \ + for (usz i=1; i8 && nn?tn:n)+(2*rx+1)*sizeof(usz))); + + // timeline + // Allocations len count radix hash deradix bytes layout: + usz *c0 = (usz*)(alloc+1); // rx [+++................] c0 rx # + usz *c1 = (usz*)(c0+rx); // rx [++................] c1 rx # + u8 *k0 = (u8 *)(c1+rx); // n [+.............] k0 n ## + u8 *k1 = (u8 *)(k0+n); // n [+............] k1 n ## + u32 *v2 = (u32*)(k1+n); // n+1 [+....-] v2 4*n ######## + u32 *v1 = (u32*)(v2+n+1); // n [+..] v1 4*n ######## + u32 *r2 = (u32*)v2; // n [+.....] r2 4*n ######## + u32 *r1 = (u32*)v1; // n [+..] r1 4*n ######## + u32 *tab= (u32*)v1; // tn [+] tab 4*tn ########### + + // Count keys + for (usz j=0; j<2*rx; j++) c0[j] = 0; + for (usz i=0; i>24)]++; c1[(u8)(v>>16)]++; } + // Exclusive prefix sum + usz s0=0, s1=0; + for (usz j=0; j>24); usz c=c0[k]++; v1[c]=v; } + for (usz i=0; i>16); usz c=c1[k]++; v2[c]=v; } + // Table lookup + u32 tv=v2[0]>>16; v2[n]=~v2[n-1]; + for (usz l=0, i=0; l>16; if (tv!=t0) break; tab[(u16)v]=0; } + for (; ia[p].val : (map->a[p].val = 0); + } + decG(x); free_b2i(map); + return r; +} + +extern B rt_indexOf; +B indexOf_c1(B t, B x) { + if (isAtm(x) || RNK(x)==0) thrM("⊐: 𝕩 cannot have rank 0"); + usz n = *SH(x); + if (n==0) { decG(x); return emptyIVec(); } + 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); + + #define BRUTE(T) \ + i##T* xp = i##T##any_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; i8 && nmax) max = c; + } + i64 dst = 1 + (max-(i64)min); + if ((dsta[p].val; + else rp[i] = map->a[p].val = ctr++; + } + free_b2i(map); decG(x); + return r; +} + +extern B rt_find; +B find_c1(B t, B x) { + if (isAtm(x) || RNK(x)==0) thrM("⍷: Argument cannot have rank 0"); + usz n = *SH(x); + if (n<=1) return x; + if (RNK(x)>1) return c1(rt_find, x); + B xf = getFillQ(x); + + B r = emptyHVec(); + H_Sb* set = m_Sb(64); + SGetU(x) + for (usz i = 0; i < n; i++) { + B c = GetU(x,i); + if (!ins_Sb(&set, c)) r = vec_add(r, inc(c)); + } + free_Sb(set); decG(x); + return withFill(r, xf); +} diff --git a/src/opt/single.c b/src/opt/single.c index 8737219d..fd4224b6 100644 --- a/src/opt/single.c +++ b/src/opt/single.c @@ -18,6 +18,7 @@ #include "../builtins/select.c" #include "../builtins/sysfn.c" #include "../builtins/sort.c" +#include "../builtins/selfsearch.c" #include "../builtins/arithm.c" #include "../builtins/arithd.c" #include "../builtins/cmp.c"