Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
2
Task/Modified-random-distribution/00-META.yaml
Normal file
2
Task/Modified-random-distribution/00-META.yaml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Modified_random_distribution
|
||||
22
Task/Modified-random-distribution/00-TASK.txt
Normal file
22
Task/Modified-random-distribution/00-TASK.txt
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
Given a random number generator, (rng), generating numbers in the range 0.0 .. 1.0 called rgen, for example; and a function modifier(x)
|
||||
taking an number in the same range and generating the probability that the input should be generated, in the same range 0..1; then implement the following algorithm for generating random numbers to the probability given by function modifier:
|
||||
<pre>while True:
|
||||
random1 = rgen()
|
||||
random2 = rgen()
|
||||
if random2 < modifier(random1):
|
||||
answer = random1
|
||||
break
|
||||
endif
|
||||
endwhile</pre>
|
||||
|
||||
;Task:
|
||||
* Create a modifier function that generates a 'V' shaped probability of number generation using something like, for example:
|
||||
modifier(x) = 2*(0.5 - x) if x < 0.5 else 2*(x - 0.5)
|
||||
* Create a generator of random numbers with probabilities modified by the above function.
|
||||
* Generate >= 10,000 random numbers subject to the probability modification.
|
||||
* Output a textual histogram with from 11 to 21 bins showing the distribution of the random numbers generated.
|
||||
|
||||
|
||||
Show your output here, on this page.
|
||||
<br><br>
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
F modifier(Float x) -> Float
|
||||
R I x < 0.5 {2 * (.5 - x)} E 2 * (x - .5)
|
||||
|
||||
F modified_random_distribution((Float -> Float) modifier, Int n) -> [Float]
|
||||
[Float] d
|
||||
L d.len < n
|
||||
V prob = random:()
|
||||
I random:() < modifier(prob)
|
||||
d.append(prob)
|
||||
R d
|
||||
|
||||
V data = modified_random_distribution(modifier, 50'000)
|
||||
V bins = 15
|
||||
DefaultDict[Int, Int] counts
|
||||
L(d) data
|
||||
counts[d I/ (1 / bins)]++
|
||||
|
||||
V mx = max(counts.values())
|
||||
print(" BIN, COUNTS, DELTA: HISTOGRAM\n")
|
||||
Float? last
|
||||
L(b, count) sorted(counts.items())
|
||||
V delta = I last == N {‘N/A’} E String(count - last)
|
||||
print(‘ #2.2, #4, #4: ’.format(Float(b) / bins, count, delta)‘’(‘#’ * Int(40 * count / mx)))
|
||||
last = count
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
with Ada.Text_Io;
|
||||
with Ada.Numerics.Float_Random;
|
||||
with Ada.Strings.Fixed;
|
||||
|
||||
procedure Modified_Distribution is
|
||||
|
||||
Observations : constant := 20_000;
|
||||
Buckets : constant := 25;
|
||||
Divider : constant := 12;
|
||||
Char : constant Character := '*';
|
||||
|
||||
generic
|
||||
with function Modifier (X : Float) return Float;
|
||||
package Generic_Random is
|
||||
function Random return Float;
|
||||
end Generic_Random;
|
||||
|
||||
package body Generic_Random is
|
||||
package Float_Random renames Ada.Numerics.Float_Random;
|
||||
Generator : Float_Random.Generator;
|
||||
|
||||
function Random return Float is
|
||||
Random_1 : Float;
|
||||
Random_2 : Float;
|
||||
begin
|
||||
loop
|
||||
Random_1 := Float_Random.Random (Generator);
|
||||
Random_2 := Float_Random.Random (Generator);
|
||||
if Random_2 < Modifier (Random_1) then
|
||||
return Random_1;
|
||||
end if;
|
||||
end loop;
|
||||
end Random;
|
||||
|
||||
begin
|
||||
Float_Random.Reset (Generator);
|
||||
end Generic_Random;
|
||||
|
||||
generic
|
||||
Buckets : in Positive;
|
||||
package Histograms is
|
||||
type Bucket_Index is new Positive range 1 .. Buckets;
|
||||
Bucket_Width : constant Float := 1.0 / Float (Buckets);
|
||||
procedure Clean;
|
||||
procedure Increment_Bucket (Observation : Float);
|
||||
function Observations_In (Bucket : Bucket_Index) return Natural;
|
||||
function To_Bucket (X : Float) return Bucket_Index;
|
||||
function Range_Image (Bucket : Bucket_Index) return String;
|
||||
end Histograms;
|
||||
|
||||
package body Histograms is
|
||||
Hist : array (Bucket_Index) of Natural := (others => 0);
|
||||
|
||||
procedure Clean is
|
||||
begin
|
||||
Hist := (others => 0);
|
||||
end Clean;
|
||||
|
||||
procedure Increment_Bucket (Observation : Float) is
|
||||
Bin : constant Bucket_Index := To_Bucket (Observation);
|
||||
begin
|
||||
Hist (Bin) := Hist (Bin) + 1;
|
||||
end Increment_Bucket;
|
||||
|
||||
function Observations_In (Bucket : Bucket_Index) return Natural
|
||||
is (Hist (Bucket));
|
||||
|
||||
function To_Bucket (X : Float) return Bucket_Index
|
||||
is (1 + Bucket_Index'Base (Float'Floor (X / Bucket_Width)));
|
||||
|
||||
function Range_Image (Bucket : Bucket_Index) return String is
|
||||
package Float_Io is new Ada.Text_Io.Float_Io (Float);
|
||||
Image : String := "F.FF..L.LL";
|
||||
First : constant Float := Float (Bucket - 1) / Float (Buckets);
|
||||
Last : constant Float := Float (Bucket - 1 + 1) / Float (Buckets);
|
||||
begin
|
||||
Float_Io.Put (Image (1 .. 4), First, Exp => 0, Aft => 2);
|
||||
Float_Io.Put (Image (7 .. 10), Last, Exp => 0, Aft => 2);
|
||||
return Image;
|
||||
end Range_Image;
|
||||
|
||||
begin
|
||||
Clean;
|
||||
end Histograms;
|
||||
|
||||
function Modifier (X : Float) return Float
|
||||
is (if X in Float'First .. 0.5
|
||||
then 2.0 * (0.5 - X)
|
||||
else 2.0 * (X - 0.5));
|
||||
|
||||
package Modified_Random is
|
||||
new Generic_Random (Modifier => Modifier);
|
||||
|
||||
package Histogram_20 is
|
||||
new Histograms (Buckets => Buckets);
|
||||
|
||||
function Column (Height : Natural; Char : Character) return String
|
||||
renames Ada.Strings.Fixed."*";
|
||||
|
||||
use Ada.Text_Io;
|
||||
begin
|
||||
for N in 1 .. Observations loop
|
||||
Histogram_20.Increment_Bucket (Modified_Random.Random);
|
||||
end loop;
|
||||
|
||||
Put ("Range Observations: "); Put (Observations'Image);
|
||||
Put (" Buckets: "); Put (Buckets'Image);
|
||||
New_Line;
|
||||
for I in Histogram_20.Bucket_Index'Range loop
|
||||
Put (Histogram_20.Range_Image (I));
|
||||
Put (" ");
|
||||
Put (Column (Histogram_20.Observations_In (I) / Divider, Char));
|
||||
New_Line;
|
||||
end loop;
|
||||
end Modified_Distribution;
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
USING: assocs assocs.extras formatting io kernel math
|
||||
math.functions math.statistics random sequences
|
||||
tools.memory.private ;
|
||||
|
||||
: modifier ( x -- y ) 0.5 over 0.5 < [ swap ] when - dup + ;
|
||||
|
||||
: random-unit-by ( quot: ( x -- y ) -- z )
|
||||
random-unit dup pick call random-unit 2dup >
|
||||
[ 2drop nip ] [ 3drop random-unit-by ] if ; inline recursive
|
||||
|
||||
: data ( n quot bins -- histogram )
|
||||
'[ _ random-unit-by _ * >integer ] replicate histogram ;
|
||||
inline
|
||||
|
||||
:: .histogram ( h -- )
|
||||
|
||||
h assoc-size :> buckets ! number of buckets
|
||||
h sum-values :> total ! items in histogram
|
||||
h values supremum :> max ! largest bucket (as in most occurrences)
|
||||
40 :> size ! max size of a bar
|
||||
|
||||
total commas buckets
|
||||
"Bin Histogram (%s items, %d buckets)\n" printf
|
||||
|
||||
h [| k v |
|
||||
k buckets / dup buckets recip + "[%.2f, %.2f) " printf
|
||||
size v * max / ceiling
|
||||
[ "▇" write ] times bl bl v commas print
|
||||
] assoc-each ;
|
||||
|
||||
"Modified random distribution of values in [0, 1):" print nl
|
||||
100,000 [ modifier ] 20 data .histogram
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
#define NRUNS 100000
|
||||
#define NBINS 20
|
||||
|
||||
function modifier( x as double ) as double
|
||||
return iif(x < 0.5, 2*(0.5 - x), 2*(x - 0.5))
|
||||
end function
|
||||
|
||||
function modrand() as double
|
||||
dim as double random1, random2
|
||||
do
|
||||
random1 = rnd
|
||||
random2 = rnd
|
||||
if random2 < modifier(random1) then
|
||||
return random1
|
||||
endif
|
||||
loop
|
||||
end function
|
||||
|
||||
function histo( byval bn as uinteger ) as string
|
||||
dim as double db = NRUNS/(50*NBINS)
|
||||
dim as string h
|
||||
while bn > db:
|
||||
h = h + "#"
|
||||
bn -= db
|
||||
wend
|
||||
return h
|
||||
|
||||
end function
|
||||
|
||||
dim as uinteger bins(0 to NBINS-1), i, b
|
||||
dim as double db = 1./NBINS, rand
|
||||
|
||||
randomize timer
|
||||
|
||||
for i = 1 to NRUNS
|
||||
rand = modrand()
|
||||
b = int(rand/db)
|
||||
bins(b) += 1
|
||||
next i
|
||||
|
||||
for b = 0 to NBINS-1
|
||||
print using "Bin ## (#.## to #.##): & ####";b;b*db;(b+1)*db;histo(bins(b));bins(b)
|
||||
next b
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
func rng(modifier func(x float64) float64) float64 {
|
||||
for {
|
||||
r1 := rand.Float64()
|
||||
r2 := rand.Float64()
|
||||
if r2 < modifier(r1) {
|
||||
return r1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func commatize(n int) string {
|
||||
s := fmt.Sprintf("%d", n)
|
||||
if n < 0 {
|
||||
s = s[1:]
|
||||
}
|
||||
le := len(s)
|
||||
for i := le - 3; i >= 1; i -= 3 {
|
||||
s = s[0:i] + "," + s[i:]
|
||||
}
|
||||
if n >= 0 {
|
||||
return s
|
||||
}
|
||||
return "-" + s
|
||||
}
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
modifier := func(x float64) float64 {
|
||||
if x < 0.5 {
|
||||
return 2 * (0.5 - x)
|
||||
}
|
||||
return 2 * (x - 0.5)
|
||||
}
|
||||
const (
|
||||
N = 100000
|
||||
NUM_BINS = 20
|
||||
HIST_CHAR = "■"
|
||||
HIST_CHAR_SIZE = 125
|
||||
)
|
||||
bins := make([]int, NUM_BINS) // all zero by default
|
||||
binSize := 1.0 / NUM_BINS
|
||||
for i := 0; i < N; i++ {
|
||||
rn := rng(modifier)
|
||||
bn := int(math.Floor(rn / binSize))
|
||||
bins[bn]++
|
||||
}
|
||||
|
||||
fmt.Println("Modified random distribution with", commatize(N), "samples in range [0, 1):\n")
|
||||
fmt.Println(" Range Number of samples within that range")
|
||||
for i := 0; i < NUM_BINS; i++ {
|
||||
hist := strings.Repeat(HIST_CHAR, int(math.Round(float64(bins[i])/HIST_CHAR_SIZE)))
|
||||
fi := float64(i)
|
||||
fmt.Printf("%4.2f ..< %4.2f %s %s\n", binSize*fi, binSize*(fi+1), hist, commatize(bins[i]))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import System.Random
|
||||
import Data.List
|
||||
import Text.Printf
|
||||
|
||||
modify :: Ord a => (a -> a) -> [a] -> [a]
|
||||
modify f = foldMap test . pairs
|
||||
where
|
||||
pairs lst = zip lst (tail lst)
|
||||
test (r1, r2) = if r2 < f r1 then [r1] else []
|
||||
|
||||
vShape x = if x < 0.5 then 2*(0.5-x) else 2*(x-0.5)
|
||||
|
||||
hist b lst = zip [0,b..] res
|
||||
where
|
||||
res = (`div` sum counts) . (*300) <$> counts
|
||||
counts = map length $ group $
|
||||
sort $ floor . (/b) <$> lst
|
||||
|
||||
showHist h = foldMap mkLine h
|
||||
where
|
||||
mkLine (b,n) = printf "%.2f\t%s %d%%\n" b (replicate n '▇') n
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
probmod=: {{y
|
||||
while.do.r=.?0 0
|
||||
if. (<u)/r do. {:r return.end.
|
||||
end.
|
||||
}}
|
||||
|
||||
mod=: {{|1-2*y}}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
rnd=: mod probmod"0 i.1e4
|
||||
|
||||
bins=: 17%~i.18 NB. upper bounds (0 does not appear in result)
|
||||
(":,.' ',.'#'#"0~0.06 <.@* {:@|:)/:~(~.,.#/.~) bins{~bins I. rnd
|
||||
0.0588235 1128 ###################################################################
|
||||
0.117647 977 ##########################################################
|
||||
0.176471 843 ##################################################
|
||||
0.235294 670 ########################################
|
||||
0.294118 563 #################################
|
||||
0.352941 423 #########################
|
||||
0.411765 260 ###############
|
||||
0.470588 125 #######
|
||||
0.529412 27 #
|
||||
0.588235 129 #######
|
||||
0.647059 280 ################
|
||||
0.705882 408 ########################
|
||||
0.764706 559 #################################
|
||||
0.823529 628 #####################################
|
||||
0.882353 854 ###################################################
|
||||
0.941176 996 ###########################################################
|
||||
1 1130 ###################################################################
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import java.util.List;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
interface ModifierInterface {
|
||||
double modifier(double aDouble);
|
||||
}
|
||||
|
||||
public final class ModifiedRandomDistribution222 {
|
||||
|
||||
public static void main(String[] aArgs) {
|
||||
final int sampleSize = 100_000;
|
||||
final int binCount = 20;
|
||||
final double binSize = 1.0 / binCount;
|
||||
|
||||
List<Integer> bins = Stream.generate( () -> 0 ).limit(binCount).toList();
|
||||
|
||||
for ( int i = 0; i < sampleSize; i++ ) {
|
||||
double random = modifiedRandom(modifier);
|
||||
int binNumber = (int) Math.floor(random / binSize);
|
||||
bins.set(binNumber, bins.get(binNumber) + 1);
|
||||
}
|
||||
|
||||
System.out.println("Modified random distribution with " + sampleSize + " samples in range [0, 1):");
|
||||
System.out.println();
|
||||
System.out.println(" Range Number of samples within range");
|
||||
|
||||
final int scaleFactor = 125;
|
||||
for ( int i = 0; i < binCount; i++ ) {
|
||||
String histogram = String.valueOf("#").repeat(bins.get(i) / scaleFactor);
|
||||
System.out.println(String.format("%4.2f ..< %4.2f %s %s",
|
||||
(float) i / binCount, (float) ( i + 1.0 ) / binCount, histogram, bins.get(i)));
|
||||
}
|
||||
}
|
||||
|
||||
private static double modifiedRandom(ModifierInterface aModifier) {
|
||||
double result = -1.0;
|
||||
|
||||
while ( result < 0.0 ) {
|
||||
double randomOne = RANDOM.nextDouble();
|
||||
double randomTwo = RANDOM.nextDouble();
|
||||
if ( randomTwo < aModifier.modifier(randomOne) ) {
|
||||
result = randomOne;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ModifierInterface modifier = aX -> ( aX < 0.5 ) ? 2 * ( 0.5 - aX ) : 2 * ( aX - 0.5 );
|
||||
|
||||
private static final ThreadLocalRandom RANDOM = ThreadLocalRandom.current();
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
using UnicodePlots
|
||||
|
||||
modifier(x) = (y = 2x - 1; y < 0 ? -y : y)
|
||||
modrands(rands1, rands2) = [x for (i, x) in enumerate(rands1) if rands2[i] < modifier(x)]
|
||||
histogram(modrands(rand(50000), rand(50000)), nbins = 20)
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
ClearAll[Modifier, CreateRandomNumber]
|
||||
Modifier[x_] := If[x < 0.5, 2 (0.5 - x), 2 (x - 0.5)]
|
||||
CreateRandomNumber[] := Module[{r1, r2, done = True},
|
||||
While[done,
|
||||
r1 = RandomReal[];
|
||||
r2 = RandomReal[];
|
||||
If[r2 < Modifier[r1],
|
||||
Return[r1];
|
||||
done = False
|
||||
]
|
||||
]
|
||||
]
|
||||
numbers = Table[CreateRandomNumber[], 100000];
|
||||
{bins, counts} = HistogramList[numbers, {0, 1, 0.05}, "PDF"];
|
||||
Grid[MapThread[{#1, " - ", StringJoin@ConstantArray["X", Round[20 #2]]} &, {Partition[bins, 2, 1], counts}], Alignment -> Left]
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
import random, strformat, strutils, sugar
|
||||
|
||||
type ValRange = range[0.0..1.0]
|
||||
|
||||
func modifier(x: ValRange): ValRange =
|
||||
if x < 0.5: 2 * (0.5 - x) else: 2 * (x - 0.5)
|
||||
|
||||
proc rand(modifier: (float) -> float): ValRange =
|
||||
while true:
|
||||
let r1 = rand(1.0)
|
||||
let r2 = rand(1.0)
|
||||
if r2 < modifier(r1):
|
||||
return r1
|
||||
|
||||
const
|
||||
N = 100_000
|
||||
NumBins = 20
|
||||
HistChar = "■"
|
||||
HistCharSize = 125
|
||||
BinSize = 1 / NumBins
|
||||
|
||||
randomize()
|
||||
|
||||
var bins: array[NumBins, int]
|
||||
for i in 0..<N:
|
||||
let rn = rand(modifier)
|
||||
let bn = int(rn / BinSize)
|
||||
inc bins[bn]
|
||||
|
||||
echo &"Modified random distribution with {N} samples in range [0, 1):"
|
||||
echo " Range Number of samples within that range"
|
||||
for i in 0..<NumBins:
|
||||
let hist = repeat(HistChar, (bins[i] / HistCharSize).toInt)
|
||||
echo &"{BinSize * float(i):4.2f} ..< {BinSize * float(i + 1):4.2f} {hist} {bins[i]}"
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
use List::Util 'max';
|
||||
|
||||
sub distribution {
|
||||
my %param = ( function => \&{scalar sub {return 1}}, sample_size => 1e5, @_);
|
||||
my @values;
|
||||
do {
|
||||
my($r1, $r2) = (rand, rand);
|
||||
push @values, $r1 if &{$param{function}}($r1) > $r2;
|
||||
} until @values == $param{sample_size};
|
||||
wantarray ? @values : \@values;
|
||||
}
|
||||
|
||||
sub modifier_notch {
|
||||
my($x) = @_;
|
||||
return 2 * ( $x < 1/2 ? ( 1/2 - $x )
|
||||
: ( $x - 1/2 ) );
|
||||
}
|
||||
|
||||
sub print_histogram {
|
||||
our %param = (n_bins => 10, width => 80, @_);
|
||||
my %counts;
|
||||
$counts{ int($_ * $param{n_bins}) / $param{n_bins} }++ for @{$param{data}};
|
||||
our $max_value = max values %counts;
|
||||
print "Bin Counts Histogram\n";
|
||||
printf "%4.2f %6d: %s\n", $_, $counts{$_}, hist($counts{$_}) for sort keys %counts;
|
||||
sub hist { scalar ('■') x ( $param{width} * $_[0] / $max_value ) }
|
||||
}
|
||||
|
||||
print_histogram( data => \@{ distribution() } );
|
||||
print "\n\n";
|
||||
|
||||
my @samples = distribution( function => \&modifier_notch, sample_size => 50_000);
|
||||
print_histogram( data => \@samples, n_bins => 20, width => 64);
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
function rng(integer modifier)
|
||||
while true do
|
||||
atom r1 := rnd()
|
||||
if rnd() < modifier(r1) then
|
||||
return r1
|
||||
end if
|
||||
end while
|
||||
end function
|
||||
|
||||
function modifier(atom x)
|
||||
return iff(x < 0.5 ? 2 * (0.5 - x)
|
||||
: 2 * (x - 0.5))
|
||||
end function
|
||||
|
||||
constant N = 100000,
|
||||
NUM_BINS = 20,
|
||||
HIST_CHAR_SIZE = 125,
|
||||
BIN_SIZE = 1/NUM_BINS,
|
||||
LO = sq_mul(tagset(NUM_BINS-1,0),BIN_SIZE),
|
||||
HI = sq_mul(tagset(NUM_BINS),BIN_SIZE),
|
||||
LBLS = apply(true,sprintf,{{"[%4.2f,%4.2f)"},columnize({LO,HI})})
|
||||
|
||||
sequence bins := repeat(0, NUM_BINS)
|
||||
for i=1 to N do
|
||||
bins[floor(rng(modifier) / BIN_SIZE)+1] += 1
|
||||
end for
|
||||
|
||||
printf(1,"Modified random distribution with %,d samples in range [0, 1):\n\n",N)
|
||||
for i=1 to NUM_BINS do
|
||||
sequence hist := repeat('#', round(bins[i]/HIST_CHAR_SIZE))
|
||||
printf(1,"%s %s %,d\n", {LBLS[i], hist, bins[i]})
|
||||
end for
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
include pGUI.e
|
||||
IupOpen()
|
||||
Ihandle plot = IupPlot("GRID=YES, AXS_YAUTOMIN=NO")
|
||||
IupPlotBegin(plot, true) -- (true means x-axis are labels)
|
||||
for i=1 to length(bins) do
|
||||
IupPlotAddStr(plot, LBLS[i], bins[i]);
|
||||
end for
|
||||
{} = IupPlotEnd(plot)
|
||||
IupSetAttribute(plot,"DS_MODE","BAR")
|
||||
IupSetAttribute(plot,"DS_COLOR",IUP_DARK_BLUE)
|
||||
IupShow(IupDialog(plot, `TITLE=Histogram, RASTERSIZE=1300x850`))
|
||||
IupMainLoop()
|
||||
IupClose()
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
import random
|
||||
from typing import List, Callable, Optional
|
||||
|
||||
|
||||
def modifier(x: float) -> float:
|
||||
"""
|
||||
V-shaped, modifier(x) goes from 1 at 0 to 0 at 0.5 then back to 1 at 1.0 .
|
||||
|
||||
Parameters
|
||||
----------
|
||||
x : float
|
||||
Number, 0.0 .. 1.0 .
|
||||
|
||||
Returns
|
||||
-------
|
||||
float
|
||||
Target probability for generating x; between 0 and 1.
|
||||
|
||||
"""
|
||||
return 2*(.5 - x) if x < 0.5 else 2*(x - .5)
|
||||
|
||||
|
||||
def modified_random_distribution(modifier: Callable[[float], float],
|
||||
n: int) -> List[float]:
|
||||
"""
|
||||
Generate n random numbers between 0 and 1 subject to modifier.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
modifier : Callable[[float], float]
|
||||
Target random number gen. 0 <= modifier(x) < 1.0 for 0 <= x < 1.0 .
|
||||
n : int
|
||||
number of random numbers generated.
|
||||
|
||||
Returns
|
||||
-------
|
||||
List[float]
|
||||
n random numbers generated with given probability.
|
||||
|
||||
"""
|
||||
d: List[float] = []
|
||||
while len(d) < n:
|
||||
r1 = prob = random.random()
|
||||
if random.random() < modifier(prob):
|
||||
d.append(r1)
|
||||
return d
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from collections import Counter
|
||||
|
||||
data = modified_random_distribution(modifier, 50_000)
|
||||
bins = 15
|
||||
counts = Counter(d // (1 / bins) for d in data)
|
||||
#
|
||||
mx = max(counts.values())
|
||||
print(" BIN, COUNTS, DELTA: HISTOGRAM\n")
|
||||
last: Optional[float] = None
|
||||
for b, count in sorted(counts.items()):
|
||||
delta = 'N/A' if last is None else str(count - last)
|
||||
print(f" {b / bins:5.2f}, {count:4}, {delta:>4}: "
|
||||
f"{'#' * int(40 * count / mx)}")
|
||||
last = count
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
library(NostalgiR) #For the textual histogram.
|
||||
modifier <- function(x) 2*abs(x - 0.5)
|
||||
gen <- function()
|
||||
{
|
||||
repeat
|
||||
{
|
||||
random <- runif(2)
|
||||
if(random[2] < modifier(random[1])) return(random[1])
|
||||
}
|
||||
}
|
||||
data <- replicate(100000, gen())
|
||||
NostalgiR::nos.hist(data, breaks = 20, pch = "#")
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*REXX program generates a "<" shaped probability of number generation using a modifier.*/
|
||||
parse arg randn bins seed . /*obtain optional argument from the CL.*/
|
||||
if randN=='' | randN=="," then randN= 100000 /*Not specified? Then use the default.*/
|
||||
if bins=='' | bins=="," then bins= 20 /* " " " " " " */
|
||||
if datatype(seed, 'W') then call random ,,seed /* " " " " " " */
|
||||
call MRD
|
||||
!.= 0
|
||||
do j=1 for randN; bin= @.j*bins%1
|
||||
!.bin= !.bin + 1 /*bump the applicable bin counter. */
|
||||
end /*j*/
|
||||
mx= 0
|
||||
do k=1 for randN; mx= max(mx, !.k) /*find the maximum, used for histograph*/
|
||||
end /*k*/
|
||||
|
||||
say ' bin'
|
||||
say '────── ' center('(with ' commas(randN) " samples", 80 - 10)
|
||||
|
||||
do b=0 for bins; say format(b/bins,2,2) copies('■', 70*!.b%mx)" " commas(!.b)
|
||||
end /*b*/
|
||||
exit 0
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
commas: arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ?
|
||||
rand: return random(0, 100000) / 100000
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
modifier: parse arg y; if y<.5 then return 2 * (.5 - y)
|
||||
else return 2 * ( y - .5)
|
||||
/*──────────────────────────────────────────────────────────────────────────────────────*/
|
||||
MRD: #=0; @.= /*MRD: Modified Random distribution. */
|
||||
do until #==randN; r= rand() /*generate a random number; assign bkup*/
|
||||
if rand()>=modifier(r) then iterate /*Doesn't meet requirement? Then skip.*/
|
||||
#= # + 1; @.#= r /*bump counter; assign the MRD to array*/
|
||||
end /*until*/
|
||||
return
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
sub modified_random_distribution ( Code $modifier --> Seq ) {
|
||||
return lazy gather loop {
|
||||
my ( $r1, $r2 ) = rand, rand;
|
||||
take $r1 if $modifier.($r1) > $r2;
|
||||
}
|
||||
}
|
||||
sub modifier ( Numeric $x --> Numeric ) {
|
||||
return 2 * ( $x < 1/2 ?? ( 1/2 - $x )
|
||||
!! ( $x - 1/2 ) );
|
||||
}
|
||||
sub print_histogram ( @data, :$n-bins, :$width ) { # Assumes minimum of zero.
|
||||
my %counts = bag @data.map: { floor( $_ * $n-bins ) / $n-bins };
|
||||
my $max_value = %counts.values.max;
|
||||
sub hist { '■' x ( $width * $^count / $max_value ) }
|
||||
say ' Bin, Counts: Histogram';
|
||||
printf "%4.2f, %6d: %s\n", .key, .value, hist(.value) for %counts.sort;
|
||||
}
|
||||
|
||||
my @d = modified_random_distribution( &modifier );
|
||||
|
||||
print_histogram( @d.head(50_000), :n-bins(20), :width(64) );
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
def modifier(x) = (x - 0.5).abs * 2
|
||||
|
||||
def mod_rand
|
||||
loop do
|
||||
random1, random2 = rand, rand
|
||||
return random1 if random2 < modifier(random1)
|
||||
end
|
||||
end
|
||||
|
||||
bins = 15
|
||||
bin_size = 1.0/bins
|
||||
h = {}
|
||||
(0...bins).each{|b| h[b*bin_size] = 0}
|
||||
|
||||
tally = 50_000.times.map{ (mod_rand).div(bin_size) * bin_size}.tally(h)
|
||||
m = tally.values.max/40
|
||||
tally.each {|k,v| puts "%f...%f %s %d" % [k, k+bin_size, "*"*(v/m) , v] }
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import "random" for Random
|
||||
import "/fmt" for Fmt
|
||||
|
||||
var rgen = Random.new()
|
||||
|
||||
var rng = Fn.new { |modifier|
|
||||
while (true) {
|
||||
var r1 = rgen.float()
|
||||
var r2 = rgen.float()
|
||||
if (r2 < modifier.call(r1)) {
|
||||
return r1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var modifier = Fn.new { |x| (x < 0.5) ? 2 * (0.5 - x) : 2 * (x - 0.5) }
|
||||
|
||||
var N = 100000
|
||||
var NUM_BINS = 20
|
||||
var HIST_CHAR = "■"
|
||||
var HIST_CHAR_SIZE = 125
|
||||
var bins = List.filled(NUM_BINS, 0)
|
||||
var binSize = 1 / NUM_BINS
|
||||
for (i in 0...N) {
|
||||
var rn = rng.call(modifier)
|
||||
var bn = (rn / binSize).floor
|
||||
bins[bn] = bins[bn] + 1
|
||||
}
|
||||
|
||||
Fmt.print("Modified random distribution with $,d samples in range [0, 1):\n", N)
|
||||
System.print(" Range Number of samples within that range")
|
||||
for (i in 0...NUM_BINS) {
|
||||
var hist = HIST_CHAR * (bins[i] / HIST_CHAR_SIZE).round
|
||||
Fmt.print("$4.2f ..< $4.2f $s $,d", binSize * i, binSize * (i + 1), hist, bins[i])
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue