typed •rand.Range
This commit is contained in:
parent
26e3432caa
commit
c5b65b9246
@ -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;
|
||||
|
||||
@ -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?
|
||||
|
||||
@ -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
41
test/random.bqn
Normal file
@ -0,0 +1,41 @@
|
||||
u ← ⌊100×(•UnixTime+1|100וMonoTime)@
|
||||
|
||||
Range ← (•MakeRand •Show u).Range
|
||||
|
||||
ExpectedRangeStep ← { n‿len𝕊depth‿max:
|
||||
ls ← {𝕊:len Range max}¨↕n
|
||||
maxGot ← ⌈´⌈´¨ls
|
||||
! maxGot<max⌈1
|
||||
{𝕊: ! 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}⍟⊢ max≠0
|
||||
diff ← sumGot-sumExp
|
||||
dev ← diff ÷ √12÷˜ n×len
|
||||
{𝕊:
|
||||
depth≥4? •Out ∾⟨"Unlikely sum (dev=", •Repr dev, ": expected ", •Repr sumExp, ", got ", •Repr sumGot, "; n=", •Repr n," len=", •Repr len, " range=", •Repr max⟩;
|
||||
n‿len 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"
|
||||
(100‿128∾˜↕20) {(⌊(10×am)÷𝕨⌈1)‿𝕨 ExpectedRange 𝕩}⌜ 3‿10‿100‿1000‿10000‿100000‿1e8‿1e15∾2⋆2↓↕34
|
||||
(↕10) {! ∧´0=𝕩 Range 1}⌜ ↕200
|
||||
|
||||
•Out "bit boolean"
|
||||
{⟨5×am,𝕩⟩ ExpectedRange 2}¨ ⥊31‿32‿33×⌜↕100
|
||||
•Out "float"
|
||||
{⟨2×am,𝕩⟩ ExpectedRange 0}¨ ↕100
|
||||
Loading…
Reference in New Issue
Block a user