September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -1,6 +1,6 @@
|
|||
Given a mapping between items and their required probability of occurrence, generate a million items ''randomly'' subject to the given probabilities and compare the target probability of occurrence versus the generated values.
|
||||
|
||||
The total of all the probabilities should equal one. (Because floating point arithmetic is involved this is subject to rounding errors).
|
||||
The total of all the probabilities should equal one. (Because floating point arithmetic is involved, this is subject to rounding errors).
|
||||
|
||||
Use the following mapping to test your programs:<pre>
|
||||
aleph 1/5.0
|
||||
|
|
@ -11,3 +11,7 @@ he 1/9.0
|
|||
waw 1/10.0
|
||||
zayin 1/11.0
|
||||
heth 1759/27720 # adjusted so that probabilities add to 1</pre>
|
||||
|
||||
;Related task:
|
||||
* [[Random number generator (device)]]
|
||||
<br><br>
|
||||
|
|
|
|||
|
|
@ -1,20 +1,26 @@
|
|||
import System.Random
|
||||
import Data.List
|
||||
import Control.Monad
|
||||
import Control.Arrow
|
||||
import System.Random (newStdGen, randomRs)
|
||||
|
||||
labels = ["aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth" ]
|
||||
piv n = take n . (++ repeat ' ')
|
||||
dataBinCounts :: [Float] -> [Float] -> [Int]
|
||||
dataBinCounts thresholds range =
|
||||
let sampleSize = length range
|
||||
xs = ((-) sampleSize . length . flip filter range . (<)) <$> thresholds
|
||||
in zipWith (-) (xs ++ [sampleSize]) (0 : xs)
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
g <- newStdGen
|
||||
let rs,ps :: [Float]
|
||||
rs = take 1000000 $ randomRs(0,1) g
|
||||
ps = ap (++) (return. (1 -) .sum) $ map recip [5..11]
|
||||
sps = scanl1 (+) ps
|
||||
qs = (\xs -> map ((/1000000.0).fromIntegral.length. flip filter xs. (==))sps)
|
||||
$ map (head . flip dropWhile sps . (>)) rs
|
||||
putStrLn $ " expected actual"
|
||||
mapM_ putStrLn $ zipWith3
|
||||
(\l s c-> (piv 7 l) ++ (piv 13 $ show $ s)
|
||||
++(piv 12 $ show $ c)) labels ps qs
|
||||
let fractions = recip <$> [5 .. 11] :: [Float]
|
||||
expected = fractions ++ [1 - sum fractions]
|
||||
actual =
|
||||
((/ 1000000.0) . fromIntegral) <$>
|
||||
dataBinCounts (scanl1 (+) expected) (take 1000000 (randomRs (0, 1) g))
|
||||
|
||||
piv n = take n . (++ repeat ' ')
|
||||
|
||||
putStrLn " expected actual"
|
||||
mapM_ putStrLn $
|
||||
zipWith3
|
||||
(\l s c -> piv 7 l ++ piv 13 (show s) ++ piv 12 (show c))
|
||||
["aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth"]
|
||||
expected
|
||||
actual
|
||||
|
|
|
|||
106
Task/Probabilistic-choice/JavaScript/probabilistic-choice-2.js
Normal file
106
Task/Probabilistic-choice/JavaScript/probabilistic-choice-2.js
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
(() => {
|
||||
'use strict';
|
||||
|
||||
// GENERIC FUNCTIONS -----------------------------------------------------
|
||||
|
||||
// transpose :: [[a]] -> [[a]]
|
||||
const transpose = xs =>
|
||||
xs[0].map((_, iCol) => xs.map(row => row[iCol]));
|
||||
|
||||
// justifyLeft :: Int -> Char -> Text -> Text
|
||||
const justifyLeft = (n, cFiller, strText) =>
|
||||
n > strText.length ? (
|
||||
(strText + cFiller.repeat(n))
|
||||
.substr(0, n)
|
||||
) : strText;
|
||||
|
||||
// 2 or more arguments
|
||||
// curry :: Function -> Function
|
||||
const curry = (f, ...args) => {
|
||||
const go = xs => xs.length >= f.length ? (f.apply(null, xs)) :
|
||||
function () {
|
||||
return go(xs.concat([].slice.apply(arguments)));
|
||||
};
|
||||
return go([].slice.call(args, 1));
|
||||
};
|
||||
|
||||
// zipWith :: (a -> b -> c) -> [a] -> [b] -> [c]
|
||||
const zipWith = (f, xs, ys) => {
|
||||
const ny = ys.length;
|
||||
return (xs.length <= ny ? xs : xs.slice(0, ny))
|
||||
.map((x, i) => f(x, ys[i]));
|
||||
};
|
||||
|
||||
// subtract :: (Num a) => a -> a -> a
|
||||
const subtract = (x, y) => y - x;
|
||||
|
||||
// scanl1 :: (a -> a -> a) -> [a] -> [a]
|
||||
const scanl1 = (f, xs) =>
|
||||
xs.length > 0 ? scanl(f, xs[0], xs.slice(1)) : [];
|
||||
|
||||
// scanl :: (b -> a -> b) -> b -> [a] -> [b]
|
||||
const scanl = (f, startValue, xs) =>
|
||||
xs.reduce((a, x) => {
|
||||
const v = f(a.acc, x);
|
||||
return {
|
||||
acc: v,
|
||||
scan: a.scan.concat(v)
|
||||
};
|
||||
}, {
|
||||
acc: startValue,
|
||||
scan: [startValue]
|
||||
})
|
||||
.scan;
|
||||
|
||||
// unwords :: [String] -> String
|
||||
const unwords = xs => xs.join(' ');
|
||||
|
||||
|
||||
// PROBABILISTIC CHOICE --------------------------------------------------
|
||||
|
||||
// samples :: Int -> Int -> [Float]
|
||||
const samples = n =>
|
||||
Array.from({
|
||||
length: n
|
||||
}, Math.random);
|
||||
|
||||
// thresholds :: Float
|
||||
const thresholds = scanl1(
|
||||
(a, b) => a + b, [5, 6, 7, 8, 9, 10, 11].map(x => 1 / x)
|
||||
)
|
||||
.concat(1);
|
||||
|
||||
// expected :: Float -> Float
|
||||
const expected = limits =>
|
||||
limits.map((x, i, xs) => i > 0 ? (x - xs[i - 1]) : x);
|
||||
|
||||
// dataBinCounts :: [Float] -> [Float] -> [Int]
|
||||
const dataBinCounts = (thresholds, samples) => {
|
||||
const
|
||||
lng = samples.length,
|
||||
xs = thresholds
|
||||
.map(x => lng - samples.filter(v => v > x)
|
||||
.length);
|
||||
return zipWith(subtract, [0].concat(xs), xs.concat(lng));
|
||||
};
|
||||
|
||||
// intSamples :: Integer
|
||||
const intSamples = 1000000;
|
||||
|
||||
// aligned :: a -> String
|
||||
const aligned = x => justifyLeft(12, ' ', isNaN(x) ? x : x.toFixed(7));
|
||||
|
||||
return transpose([
|
||||
['', 'Aleph', 'Beit', 'Gimel', 'Dalet', 'He', 'Vav', 'Zayin', 'Chet']
|
||||
.map(curry(justifyLeft)(7, ' ')),
|
||||
|
||||
['Expected'].concat(expected(thresholds))
|
||||
.map(aligned),
|
||||
|
||||
['Observed'].concat(dataBinCounts(thresholds, samples(intSamples))
|
||||
.map(x => x / intSamples))
|
||||
.map(aligned)
|
||||
])
|
||||
.map(unwords)
|
||||
.join('\n');
|
||||
})();
|
||||
38
Task/Probabilistic-choice/Kotlin/probabilistic-choice.kotlin
Normal file
38
Task/Probabilistic-choice/Kotlin/probabilistic-choice.kotlin
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// version 1.0.6
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val letters = arrayOf("aleph", "beth", "gimel", "daleth", "he", "waw", "zayin", "heth")
|
||||
val actual = IntArray(8)
|
||||
val probs = doubleArrayOf(1/5.0, 1/6.0, 1/7.0, 1/8.0, 1/9.0, 1/10.0, 1/11.0, 0.0)
|
||||
val cumProbs = DoubleArray(8)
|
||||
|
||||
cumProbs[0] = probs[0]
|
||||
for (i in 1..6) cumProbs[i] = cumProbs[i - 1] + probs[i]
|
||||
cumProbs[7] = 1.0
|
||||
probs[7] = 1.0 - cumProbs[6]
|
||||
val n = 1000000
|
||||
(1..n).forEach {
|
||||
val rand = Math.random()
|
||||
when {
|
||||
rand <= cumProbs[0] -> actual[0]++
|
||||
rand <= cumProbs[1] -> actual[1]++
|
||||
rand <= cumProbs[2] -> actual[2]++
|
||||
rand <= cumProbs[3] -> actual[3]++
|
||||
rand <= cumProbs[4] -> actual[4]++
|
||||
rand <= cumProbs[5] -> actual[5]++
|
||||
rand <= cumProbs[6] -> actual[6]++
|
||||
else -> actual[7]++
|
||||
}
|
||||
}
|
||||
|
||||
var sumActual = 0.0
|
||||
println("Letter\t Actual Expected")
|
||||
println("------\t-------- --------")
|
||||
for (i in 0..7) {
|
||||
val generated = actual[i].toDouble() / n
|
||||
println("${letters[i]}\t${String.format("%8.6f %8.6f", generated, probs[i])}")
|
||||
sumActual += generated
|
||||
}
|
||||
println("\t-------- --------")
|
||||
println("\t${"%8.6f".format(sumActual)} 1.000000")
|
||||
}
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
import tables, math, strutils, times
|
||||
|
||||
const
|
||||
num_trials = 1000000
|
||||
precsn = 6
|
||||
|
||||
var start = cpuTime()
|
||||
|
||||
var probs = initTable[string,float](16)
|
||||
probs.add("aleph", 1/5.0)
|
||||
probs.add("beth", 1/6.0)
|
||||
probs.add("gimel", 1/7.0)
|
||||
probs.add("daleth", 1/8.0)
|
||||
probs.add("he", 1/9.0)
|
||||
probs.add("waw", 1/10.0)
|
||||
probs.add("zayin", 1/11.0)
|
||||
probs.add("heth", 1759/27720)
|
||||
|
||||
var samples = initTable[string,int](16)
|
||||
for i, j in pairs(probs):
|
||||
samples.add(i,0)
|
||||
|
||||
randomize()
|
||||
for i in 1 .. num_trials:
|
||||
var z = random(1.0)
|
||||
|
||||
for j,k in pairs(probs):
|
||||
if z < probs[j]:
|
||||
samples[j] = samples[j] + 1
|
||||
break
|
||||
else:
|
||||
z = z - probs[j]
|
||||
|
||||
var s1, s2: float
|
||||
|
||||
echo("Item ","\t","Target ","\t","Results ","\t","Difference")
|
||||
echo("==== ","\t","====== ","\t","======= ","\t","==========")
|
||||
for i, j in pairs(probs):
|
||||
s1 += samples[i]/num_trials*100.0
|
||||
s2 += probs[i]*100.0
|
||||
echo( i,
|
||||
"\t", formatFloat(probs[i],ffDecimal,precsn),
|
||||
"\t", formatFloat(samples[i]/num_trials,ffDecimal,precsn),
|
||||
"\t", formatFloat(100.0*(1.0-(samples[i]/num_trials)/probs[i]),ffDecimal,precsn),"%")
|
||||
echo("======","\t","======= ","\t","======== ")
|
||||
echo("Total:","\t",formatFloat(s2,ffDecimal,2)," \t",formatFloat(s1,ffDecimal,2))
|
||||
echo("\n",formatFloat(cpuTime()-start,ffDecimal,2)," secs")
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
$character = [PSCustomObject]@{
|
||||
aleph = [PSCustomObject]@{Expected=1/5 ; Alpha="א"}
|
||||
beth = [PSCustomObject]@{Expected=1/6 ; Alpha="ב"}
|
||||
gimel = [PSCustomObject]@{Expected=1/7 ; Alpha="ג"}
|
||||
daleth = [PSCustomObject]@{Expected=1/8 ; Alpha="ד"}
|
||||
he = [PSCustomObject]@{Expected=1/9 ; Alpha="ה"}
|
||||
waw = [PSCustomObject]@{Expected=1/10 ; Alpha="ו"}
|
||||
zayin = [PSCustomObject]@{Expected=1/11 ; Alpha="ז"}
|
||||
heth = [PSCustomObject]@{Expected=1759/27720; Alpha="ח"}
|
||||
}
|
||||
|
||||
$sum = 0
|
||||
$iterations = 1000000
|
||||
$cumulative = [ordered]@{}
|
||||
$randomly = [ordered]@{}
|
||||
|
||||
foreach ($name in $character.PSObject.Properties.Name)
|
||||
{
|
||||
$sum += $character.$name.Expected
|
||||
$cumulative.$name = $sum
|
||||
$randomly.$name = 0
|
||||
}
|
||||
|
||||
for ($i = 0; $i -lt $iterations; $i++)
|
||||
{
|
||||
$random = Get-Random -Minimum 0.0 -Maximum 1.0
|
||||
|
||||
foreach ($name in $cumulative.Keys)
|
||||
{
|
||||
if ($random -le $cumulative.$name)
|
||||
{
|
||||
$randomly.$name++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($name in $character.PSObject.Properties.Name)
|
||||
{
|
||||
[PSCustomObject]@{
|
||||
Name = $name
|
||||
Expected = $character.$name.Expected
|
||||
Actual = $randomly.$name / $iterations
|
||||
Character = $character.$name.Alpha
|
||||
}
|
||||
}
|
||||
|
|
@ -1,32 +1,30 @@
|
|||
/*REXX program displays results of probabilistic choices, gen random #s per probability.*/
|
||||
parse arg trials digits seed . /*obtain the optional arguments from CL*/
|
||||
parse arg trials digs seed . /*obtain the optional arguments from CL*/
|
||||
if trials=='' | trials=="," then trials=1000000 /*Not specified? Then use the default.*/
|
||||
if digits=='' | digits=="," then digits=15 /* " " " " " " */
|
||||
if datatype(seed,'W') then call random ,,seed /*allows repeatability for RANDOM nums.*/
|
||||
names= 'aleph beth gimel daleth he waw zayin heth ──totals───►'
|
||||
cells=words(names) - 1; high=100000; s=0; !.=0
|
||||
_=4
|
||||
do n=1 for 7; _=_+1; prob.n=1/_; Hprob.n=prob.n*high; s=s+prob.n
|
||||
end /*n*/ /* [↑] determine the probabilities. */
|
||||
if digs=='' | digs=="," then digs=15 /* " " " " " " */
|
||||
if datatype(seed, 'W') then call random ,,seed /*allows repeatability for RANDOM nums.*/
|
||||
numeric digits digs /*use a specific number of decimal digs*/
|
||||
names= 'aleph beth gimel daleth he waw zayin heth ───totals───►' /*names of cells.*/
|
||||
#= words(names) - 1; s=0
|
||||
HI=100000
|
||||
do n=1 for #-1; prob.n=1 / (n+4); Hprob.n=prob.n * HI; s=s + prob.n
|
||||
end /*n*/
|
||||
!.=0
|
||||
prob.#=1759/27720; !.9=trials; Hprob.#=prob.# * HI; s=s + prob.#
|
||||
prob.9=s
|
||||
do j=1 for trials; r=random(1, HI) /*generate X number of random numbers.*/
|
||||
do k=1 for # /*for each cell, compute percentages. */
|
||||
if r<=Hprob.k then !.k=!.k + 1 /* " " " range, bump the counter*/
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
@= '═' /*@: a literal used for CENTER BIF pad*/
|
||||
w=digs +6 /*W: display width for the percentages*/
|
||||
d=4 + max( length(trials), length('count') ) /* [↓] display a formatted top header.*/
|
||||
say center('name',15,@) center('count',d,@) center('target %',w,@) center('actual %',w,@)
|
||||
|
||||
prob.8=1759/27720; Hprob.8=prob.8*high; s=s+prob.8; prob.9=s; !.9=trials
|
||||
|
||||
do j=1 for trials; r=random(1, high) /*generate X number of random numbers.*/
|
||||
do k=1 for cells /*for each cell, compute percentages. */
|
||||
if r<=Hprob.k then !.k=!.k+1 /*for each range, bump the counter. */
|
||||
end /*k*/
|
||||
end /*j*/
|
||||
|
||||
w=digits+6; d=max(length(trials), length('count')) + 4
|
||||
say centr('name',15) centr('count',d) centr('target %') centr('actual %')
|
||||
/* [↑] display a formatted header line*/
|
||||
do i=1 for cells+1 /*show for each of the cells and totals*/
|
||||
say ' ' left(word(names,i) , 12),
|
||||
right(!.i , d-2) " ",
|
||||
left(format(prob.i *100, d), w-2),
|
||||
left(format(!.i/trials*100, d), w-2)
|
||||
if i==8 then say centr(,15) centr(,d) centr() centr()
|
||||
end /*i*/
|
||||
exit /*stick a fork in it, we are all done.*/
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
centr: return center( arg(1), word(arg(2) w, 1), '─')
|
||||
do i=1 for #+1 /*display each of the cells and totals.*/
|
||||
say ' ' left( word(names, i), 13) right(!.i, d-2) " ",
|
||||
left( format( prob.i * 100, d), w-2),
|
||||
left( format( !.i/trials * 100, d), w-2)
|
||||
if i==# then say center(@,15,@) center(@,d,@) center(@,w,@) center(@,w,@)
|
||||
end /*i*/ /*stick a fork in it, we are all done.*/
|
||||
|
|
|
|||
22
Task/Probabilistic-choice/Zkl/probabilistic-choice.zkl
Normal file
22
Task/Probabilistic-choice/Zkl/probabilistic-choice.zkl
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
var names=T("aleph", "beth", "gimel", "daleth",
|
||||
"he", "waw", "zayin", "heth");
|
||||
var ptable=T(5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0).apply('/.fp(1.0));
|
||||
ptable=ptable.append(1.0-ptable.sum(0.0)); // add last weight to sum to 1.0
|
||||
var [const] N=ptable.len();
|
||||
|
||||
fcn ridx{ i:=0; s:=(0.0).random(1);
|
||||
while((s-=ptable[i]) > 0) { i+=1 }
|
||||
i
|
||||
}
|
||||
|
||||
const M=0d1_000_000;
|
||||
var r=(0).pump(N,List,T(Ref,0)); // list of references to int 0
|
||||
(0).pump(M,Void,fcn{r[ridx()].inc()}); // 1,000,000 weighted random #s
|
||||
|
||||
r=r.apply("value").apply("toFloat"); // (reference to int)-->int-->float
|
||||
|
||||
println(" Name Count Ratio Expected");
|
||||
foreach i in (N){
|
||||
"%6s%7d %7.4f%% %7.4f%%".fmt(names[i], r[i], r[i]/M*100,
|
||||
ptable[i]*100).println();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue