typed •rand.Range

This commit is contained in:
dzaima 2022-08-17 18:51:58 +03:00
parent 26e3432caa
commit c5b65b9246
4 changed files with 95 additions and 14 deletions

View File

@ -339,8 +339,33 @@ B rand_range_c2(B t, B w, B x) {
f64* rp; r = m_f64arrp(&rp, am);
for (usz i = 0; i < am; i++) rp[i] = wy2u0k(wyrand(&seed), max);
} else {
i32* rp; r = m_i32arrp(&rp, am);
for (usz i = 0; i < am; i++) rp[i] = wy2u0k(wyrand(&seed), max);
u8 t; usz u64am;
if (max>128) {
if (max>32768) { u64am = (am+ 1)>>1; t=t_i32arr; }
else { u64am = (am+ 3)>>2; t=t_i16arr; }
} else if (max!=2) { u64am = (am+ 7)>>3; t=t_i8arr; }
else { u64am = (am+63)>>6; t=t_bitarr; }
assert((u64am<<3) >= (t==t_bitarr? BIT_N(am)<<3 : am<<arrTypeWidthLog(t)));
r = m_arr(offsetof(TyArr,a) + (u64am<<3), t, am);
void* rp = ((TyArr*)r)->a;
if (max & (max-1)) { // not power of two
if (t==t_i32arr) for (usz i = 0; i < am; i++) ((i32*)rp)[i] = wy2u0k(wyrand(&seed), max);
else if (t==t_i16arr) for (usz i = 0; i < am; i++) ((i16*)rp)[i] = wy2u0k(wyrand(&seed), max);
else if (t==t_i8arr) for (usz i = 0; i < am; i++) (( i8*)rp)[i] = wy2u0k(wyrand(&seed), max);
else UD; // bitarr will be max==2, i.e. a power of two
} else {
u64 mask;
if (t==t_bitarr) { mask = ~0L; goto end; }
mask = max-1;
mask|= mask<<32;
if (t==t_i32arr) goto end; mask|= mask<<16;
if (t==t_i16arr) goto end; mask|= mask<<8;
end:
for (usz i = 0; i < u64am; i++) ((u64*)rp)[i] = wyrand(&seed) & mask;
}
}
RAND_END;

View File

@ -21,19 +21,33 @@ static void* tyany_ptr(B x) { assert(IS_ARR(v(x)->type) || IS_SLICE(v(x)->type))
return IS_SLICE(t)? c(TySlice,x)->a : c(TyArr,x)->a;
}
#define M_TYARR(OVER, MID, RV, PRE) { PRE \
Arr* r = m_arr(TYARR_SZW(w, ia) OVER, type, ia); \
MID \
*rp = RV; \
return ((TyArr*)r)->a; \
#define M_TYARR(WM, OVER, MID, RV, PRE) { PRE \
Arr* r = m_arr((offsetof(TyArr, a) + ( \
WM==0? ((u64)ia)*w \
: WM==1? ((u64)ia)<<w \
: ((((u64)ia)<<w)+7)>>3) \
) OVER, type, ia); \
MID \
*rp = RV; \
return ((TyArr*)r)->a; \
}
// width in bytes for m_tyarr*; overalloc is a byte count
static void* m_tyarrp (Arr** rp, usz w, usz ia, u8 type ) M_TYARR( , , r, )
static void* m_tyarrpO(Arr** rp, usz w, usz ia, u8 type, usz over) M_TYARR(+over, , r, )
static void* m_tyarrv (B* rp, usz w, usz ia, u8 type ) M_TYARR( , arr_shVec((Arr*)r);, taga(r), )
static void* m_tyarrvO(B* rp, usz w, usz ia, u8 type, usz over) M_TYARR(+over, arr_shVec((Arr*)r);, taga(r), )
static void* m_tyarrc (B* rp, usz w, B x, u8 type ) M_TYARR( , arr_shCopy((Arr*)r,x);, taga(r), usz ia = a(x)->ia;)
static void* m_tyarrcO(B* rp, usz w, B x, u8 type, usz over) M_TYARR(+over, arr_shCopy((Arr*)r,x);, taga(r), usz ia = a(x)->ia;)
// width in bytes; overalloc is a byte count
static void* m_tyarrp (Arr** rp, usz w, usz ia, u8 type ) M_TYARR(0, , , r, )
static void* m_tyarrpO(Arr** rp, usz w, usz ia, u8 type, usz over) M_TYARR(0,+over, , r, )
static void* m_tyarrv (B* rp, usz w, usz ia, u8 type ) M_TYARR(0, , arr_shVec((Arr*)r);, taga(r), )
static void* m_tyarrvO(B* rp, usz w, usz ia, u8 type, usz over) M_TYARR(0,+over, arr_shVec((Arr*)r);, taga(r), )
static void* m_tyarrc (B* rp, usz w, B x, u8 type ) M_TYARR(0, , arr_shCopy((Arr*)r,x);, taga(r), usz ia = a(x)->ia;)
static void* m_tyarrcO(B* rp, usz w, B x, u8 type, usz over) M_TYARR(0,+over, arr_shCopy((Arr*)r,x);, taga(r), usz ia = a(x)->ia;)
// width in log2(bytes)
static void* m_tyarrlp(Arr** rp, usz w, usz ia, u8 type) M_TYARR(1, , , r, )
static void* m_tyarrlv(B* rp, usz w, usz ia, u8 type) M_TYARR(1, , arr_shVec((Arr*)r);, taga(r), )
static void* m_tyarrlc(B* rp, usz w, B x, u8 type) M_TYARR(1, , arr_shCopy((Arr*)r,x);, taga(r), usz ia = a(x)->ia;)
// width in log2(bits)
static void* m_tyarrlbp(Arr** rp, usz w, usz ia, u8 type) M_TYARR(2, , , r, )
static void* m_tyarrlbv(B* rp, usz w, usz ia, u8 type) M_TYARR(2, , arr_shVec((Arr*)r);, taga(r), )
static void* m_tyarrlbc(B* rp, usz w, B x, u8 type) M_TYARR(2, , arr_shCopy((Arr*)r,x);, taga(r), usz ia = a(x)->ia;)
extern u8 elType2type[];
#define el2t(X) elType2type[X] // TODO maybe reorganize array types such that this can just be addition?

View File

@ -14,6 +14,7 @@ test/moreCfgs.sh path/to/mlochbaum/BQN // run "2+2" in a bunch of configurations
./BQN test/squeezeValid.bqn // fuzz-test squeezing giving a correct result; requires a CBQN build with -DEEQUAL_NEGZERO
./BQN test/squeezeExact.bqn // fuzz-test squeezing giving the exact smallest result; requires a CBQN build with -DEEQUAL_NEGZERO
./BQN test/various.bqn // tests for various small things
./BQN test/random.bqn // test (•MakeRand n).Range
make -C test/ffi // test FFI functionality; expects both regular and shared library CBQN builds to already exist
legacy utilities:

41
test/random.bqn Normal file
View File

@ -0,0 +1,41 @@
u 100×(•UnixTime+1|100וMonoTime)@
Range (•MakeRand •Show u).Range
ExpectedRangeStep { nlen𝕊depthmax:
ls {𝕊:len Range max}¨n
maxGot ´´¨ls
! maxGot<max1
{𝕊: ! 0<´´¨ls} max=0
{(max=0) (max>n×len÷20) maxGot=max-1? @; •Out "Maximum ", •Repr max-1, " likely should have been encountered, but max was ", •Repr maxGot, "; n=", •Repr n," len=", •Repr len, " range=", •Repr max}
# some very very crappy statistics
sumExp n×len÷2
sumGot +´ +´¨ ls
{𝕊: sumGot max÷˜ (2÷˜n×len) + sumGot} max0
diff sumGot-sumExp
dev diff ÷ 12÷˜ n×len
{𝕊:
depth4? •Out "Unlikely sum (dev=", •Repr dev, ": expected ", •Repr sumExp, ", got ", •Repr sumGot, "; n=", •Repr n," len=", •Repr len, " range=", •Repr max;
nlen ExpectedRangeStep depth+1, max
} 2 < |dev
dev
}
ExpectedRange ExpectedRangeStep(0)
# for whatever reason, the following don't all evaluate to the same number; but they're close enough so ¯\_(ツ)_/¯
# •Show (+´÷≠) |{𝕊: 100‿1000 ExpectedRange 2 }¨↕10000
# •Show (+´÷≠) |{𝕊: 10‿1000 ExpectedRange 3 }¨↕10000
# •Show (+´÷≠) |{𝕊: 10‿1000 ExpectedRange 1e3}¨↕10000
# •Show (+´÷≠) |{𝕊: 10‿1000 ExpectedRange 1e6}¨↕10000
am 10000
•Out "general"
(100128˜20) {((10×am)÷𝕨1)𝕨 ExpectedRange 𝕩} 3101001000100001000001e81e152234
(10) {! ´0=𝕩 Range 1} 200
•Out "bit boolean"
{5×am,𝕩 ExpectedRange 2}¨ 313233×100
•Out "float"
{2×am,𝕩 ExpectedRange 0}¨ 100