September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -1,48 +1,69 @@
{-# LANGUAGE BangPatterns #-}
import Data.Foldable
import System.Random
import Data.Foldable (foldl') --'
import System.Random (randomRs, newStdGen)
import Control.Monad (zipWithM_)
import System.Environment (getArgs)
intervals :: [(Double,Double)]
intervals = map conv [0..9]
where xs = [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.0]
conv s = let { [h,l] = take 2 $ drop s xs } in (h,l)
intervals :: [(Double, Double)]
intervals = map conv [0 .. 9]
where
xs = [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1.0]
conv s =
let [h, l] = take 2 $ drop s xs
in (h, l)
count :: [Double] -> [Int]
count rands = map (\iv -> foldl' (loop iv) 0 rands) intervals
where loop :: (Double,Double) -> Int -> Double -> Int
loop (lo,hi) n x | lo <= x && x < hi = n+1
| otherwise = n
-- ^ fuses length and filter within (lo,hi)
count rands = map (\iv -> foldl'' (loop iv) 0 rands) intervals
where
loop :: (Double, Double) -> Int -> Double -> Int
loop (lo, hi) n x
| lo <= x && x < hi = n + 1
| otherwise = n
data Pair a b = Pair !a !b
-- ^ fuses length and filter within (lo,hi)
data Pair a b =
Pair !a
!b
-- accumulate sum and length in one fold
sumLen :: [Double] -> Pair Double Double
sumLen = fion2 . foldl' (\(Pair s l) x -> Pair (s+x) (l+1)) (Pair 0.0 0)
where fion2 :: Pair Double Int -> Pair Double Double
fion2 (Pair s l) = Pair s (fromIntegral l)
sumLen = fion2 . foldl'' (\(Pair s l) x -> Pair (s + x) (l + 1)) (Pair 0.0 0)
where
fion2 :: Pair Double Int -> Pair Double Double
fion2 (Pair s l) = Pair s (fromIntegral l)
-- safe division on pairs
divl :: Pair Double Double -> Double
divl (Pair _ 0.0) = 0.0
divl (Pair s l) = s / l
divl (Pair s l) = s / l
-- sumLen and divl are separate for stddev below
mean :: [Double] -> Double
mean = divl . sumLen
stddev :: [Double] -> Double
stddev xs = sqrt $ foldl' (\s x -> s+(x-m)^2) 0 xs / l
where p@(Pair s l) = sumLen xs
m = divl p
stddev xs = sqrt $ foldl'' (\s x -> s + (x - m) ^ 2) 0 xs / l
where
p@(Pair s l) = sumLen xs
m = divl p
main = do nr <- read.head <$> getArgs
rands <- take nr . randomRs (0.0,1.0) <$> newStdGen
putStrLn $ "The mean is " ++ show (mean rands) ++ " !"
putStrLn $ "The standard deviation is " ++ show (stddev rands) ++ " !"
zipWithM_ (\iv fq -> putStrLn $ ivstr iv ++ ": " ++ fqstr fq) intervals (count rands)
where
fqstr i = replicate (if i > 50 then div i (div i 50) else i) '*'
ivstr (lo,hi) = show lo ++ " - " ++ show hi
main = do
nr <- read . head <$> getArgs
-- or in code, e.g. let nr = 1000
rands <- take nr . randomRs (0.0, 1.0) <$> newStdGen
putStrLn $ "The mean is " ++ show (mean rands) ++ " !"
putStrLn $ "The standard deviation is " ++ show (stddev rands) ++ " !"
zipWithM_
(\iv fq -> putStrLn $ ivstr iv ++ ": " ++ fqstr fq)
intervals
(count rands)
where
fqstr i =
replicate
(if i > 50
then div i (div i 50)
else i)
'*'
ivstr (lo, hi) = show lo ++ " - " ++ show hi
-- To avoid Wiki formatting issue
foldl'' = foldl'

View file

@ -0,0 +1,49 @@
// version 1.1.2
val rand = java.util.Random()
fun basicStats(sampleSize: Int) {
if (sampleSize < 1) return
val r = DoubleArray(sampleSize)
val h = IntArray(10) // all zero by default
/*
Generate 'sampleSize' random numbers in the interval [0, 1)
and calculate in which box they will fall when drawing the histogram
*/
for (i in 0 until sampleSize) {
r[i] = rand.nextDouble()
h[(r[i] * 10).toInt()]++
}
// adjust one of the h[] values if necessary to ensure they sum to sampleSize
val adj = sampleSize - h.sum()
if (adj != 0) {
for (i in 0..9) {
h[i] += adj
if (h[i] >= 0) break
h[i] -= adj
}
}
val mean = r.average()
val sd = Math.sqrt(r.map { (it - mean) * (it - mean) }.average())
// Draw a histogram of the data with interval 0.1
var numStars: Int
// If sample size > 500 then normalize histogram to 500
val scale = if (sampleSize <= 500) 1.0 else 500.0 / sampleSize
println("Sample size $sampleSize\n")
println(" Mean ${"%1.6f".format(mean)} SD ${"%1.6f".format(sd)}\n")
for (i in 0..9) {
print(" %1.2f : ".format(i / 10.0))
print("%5d ".format(h[i]))
numStars = (h[i] * scale + 0.5).toInt()
println("*".repeat(numStars))
}
println()
}
fun main(args: Array<String>) {
val sampleSizes = intArrayOf(100, 1_000, 10_000, 100_000)
for (sampleSize in sampleSizes) basicStats(sampleSize)
}

View file

@ -5,6 +5,6 @@ for 100, 1_000, 10_000 -> $N {
printf "stddev: %f\n", sqrt
$mean**2 R- $N R/ [+] @data »**» 2;
printf "%.1f %s\n", .key, '=' x (500 * .value.elems / $N)
for sort *.key, @data.classify: (10 * *).Int / 10;
for sort @data.classify: (10 * *).Int / 10;
&say;
}

View file

@ -0,0 +1,34 @@
function generate_statistics(integer n)
sequence hist = repeat(0,10)
atom sum_r = 0,
sum_squares = 0.0
for i=1 to n do
atom r = rnd()
sum_r += r
sum_squares += r*r
hist[floor(10*r)+1] += 1
end for
atom mean = sum_r / n
atom stddev = sqrt((sum_squares / n) - mean*mean)
return {n, mean, stddev, hist}
end function
procedure display_statistics(sequence x)
atom n, mean, stddev
sequence hist
{n, mean, stddev, hist} = x
printf(1,"-- Stats for sample size %d\n",{n})
printf(1,"mean: %g\n",{mean})
printf(1,"sdev: %g\n",{stddev})
for i=1 to length(hist) do
integer cnt = hist[i]
string bars = repeat('=',floor(cnt*300/n))
printf(1,"%.1f: %s %d\n",{i/10,bars,cnt})
end for
end procedure
for n=2 to 5 do
display_statistics(generate_statistics(power(10,n+(n=5))))
end for

View file

@ -11,12 +11,11 @@ if datatype(seed,'W') then call random ,,seed /*allow a seed for the RANDO
#._=#._+1 /* ··· and bump its count. */
end /*j*/
do k=0 for 10 /*show a histogram of the bins. */
do k=0 for 10; kp=k+1 /*show a histogram of the bins. */
lr='0.'k ; if k==0 then lr="0 " /*adjust for the low range. */
hr='0.'||(k+1); if k==9 then hr="1 " /* " " " high range. */
range=lr"──►"hr' ' /*construct the range. */
hr='0.'kp ; if k==9 then hr="1 " /* " " " high range. */
barPC=right(strip(left(format(100*#.k/size, , 2), 5)) ,5) /*compute the %. */
say range barPC copies('', format(barPC*1, , 0)) /*display histogram*/
say lr"──►"hr' ' barPC copies('', format(barPC*1, , 0)) /*display histogram*/
end /*k*/
say
say 'sample size = ' size; say

View file

@ -0,0 +1,10 @@
. clear all
. set obs 100000
number of observations (_N) was 0, now 100,000
. gen x=runiform()
. summarize x
Variable | Obs Mean Std. Dev. Min Max
-------------+---------------------------------------------------------
x | 100,000 .4991874 .2885253 1.18e-06 .9999939
. hist x

View file

@ -0,0 +1,4 @@
fcn mean(ns) { ns.sum(0.0)/ns.len() }
fcn stdDev(ns){
m:=mean(ns); (ns.reduce('wrap(p,n){ x:=(n-m); p+x*x },0.0)/ns.len()).sqrt()
}

View file

@ -0,0 +1,9 @@
reg ns;
foreach n in (T(100,1000,10000)){
ns=(0).pump(n,List,(0.0).random.fp(1.0));
println("N:%,6d mean:%.5f std dev:%.5f".fmt(n,mean(ns),stdDev(ns)));
}
foreach r in ([0.0 .. 0.9, 0.1]){ // using the last data set (10000 randoms)
n:=ns.filter('wrap(x){ r<=x<(r+0.1) }).len();
println("%.2f..%.2f:%4d%s".fmt(r,r+0.1,n,"*"*(n/20)));
}

View file

@ -0,0 +1,13 @@
var pipe=Thread.Pipe(); // used to connect the two threads
fcn{ while(1){ pipe.write((0.0).random(1.0)) } }.launch(); // generator
fcn{ // consumer/calculator
N:=0; M:=SD:=sum:=ssum:=0.0;
while(1){
x:=pipe.read(); N+=1; sum+=x; ssum+=x*x;
M=sum/N; SD=(ssum/N - M*M).sqrt();
if(0==N%100000)
println("N:%,10d mean:%.5f std dev:%.5f".fmt(N,M,SD));
}
}.launch();
Atomic.sleep(60*60); // wait because exiting the VM kills the threads