Implement bit_find and fast self-search for booleans

This commit is contained in:
Marshall Lochbaum 2022-10-21 21:07:25 -04:00
parent 96740566e9
commit 0f7bfa2575
2 changed files with 25 additions and 0 deletions

View File

@ -3,6 +3,9 @@
#include "../utils/mut.h"
#include "../utils/talloc.h"
B not_c1(B t, B x);
B shape_c1(B t, B x);
B memberOf_c1(B t, B x) {
if (isAtm(x) || RNK(x)==0) thrM("∊: Argument cannot have rank 0");
usz n = *SH(x);
@ -10,6 +13,13 @@ B memberOf_c1(B t, B x) {
u8 lw = cellWidthLog(x);
void* xv = tyany_ptr(x);
if (lw == 0) {
usz i = bit_find(xv, n, 1 &~ *(u64*)xv); decG(x);
B r = taga(arr_shVec(allZeroes(n)));
u64* rp = tyany_ptr(r);
rp[0]=1; if (i<n) bitp_set(rp, i, 1);
return r;
}
#define BRUTE(T) \
i##T* xp = xv; \
u64* rp; B r = m_bitarrv(&rp, n); bitp_set(rp, 0, 1); \
@ -96,6 +106,7 @@ B count_c1(B t, B x) {
if (n>(usz)I32_MAX+1) thrM("⊒: Argument length >2⋆31 not supported");
u8 lw = cellWidthLog(x);
if (lw==0) { x = toI8Any(x); lw = cellWidthLog(x); }
void* xv = tyany_ptr(x);
#define BRUTE(T) \
i##T* xp = xv; \
@ -189,6 +200,10 @@ B indexOf_c1(B t, B x) {
u8 lw = cellWidthLog(x);
void* xv = tyany_ptr(x);
if (lw == 0) {
B r = 1&*(u64*)xv ? not_c1(m_f64(0), x) : x;
return shape_c1(m_f64(0), r);
}
#define BRUTE(T) \
i##T* xp = xv; \
i8* rp; B r = m_i8arrv(&rp, n); rp[0]=0; \

View File

@ -48,6 +48,16 @@ static inline bool bit_has(u64* arr, u64 ia, bool v) {
for (usz i=0; i<e; i++) if (arr[i]^w) return 1;
return q && ((arr[e]^w) & ((1ULL<<q)-1));
}
static inline u64 bit_find(u64* arr, u64 ia, bool v) {
u64 w = ~-(u64)v;
u64 e = ia/64;
for (u64 i=0; i<e; i++) {
u64 f = w ^ arr[i];
if (f) return 64*i + CTZ(f);
}
u64 q = ia%64;
return (ia - q) | CTZ((w^arr[e]) | ~(u64)0<<q);
}
// BitArr
#define BITARR_SZ(IA) fsizeof(BitArr, a, u64, BIT_N(IA))