Modified random distribution: Difference between revisions

m
→‎{{header|UNIX Shell}}: change loop style
m (→‎{{header|Phix}}: added header, not<-shaped)
m (→‎{{header|UNIX Shell}}: change loop style)
 
(39 intermediate revisions by 19 users not shown)
Line 1:
{{draft task}}
 
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:
 
<pre>
while True:
random1 = rgen()
random2 = rgen()
Line 16 ⟶ 14:
;Task:
* Create a modifier function that generates a 'V' shaped probability of number generation using something like, for example:
<pre> modifier(x) = 2*(0.5 - x) if x < 0.5 else 2*(x - 0.5)</pre>
 
* 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>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">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</syntaxhighlight>
 
{{out}}
<pre>
BIN, COUNTS, DELTA: HISTOGRAM
 
0.00, 6218, N/A: #######################################
0.07, 5313, -905: #################################
0.13, 4328, -985: ###########################
0.20, 3572, -756: ######################
0.27, 2642, -930: ################
0.33, 1805, -837: ###########
0.40, 877, -928: #####
0.47, 216, -661: #
0.53, 887, 671: #####
0.60, 1779, 892: ###########
0.67, 2644, 865: ################
0.73, 3618, 974: #######################
0.80, 4495, 877: ############################
0.87, 5341, 846: ##################################
0.93, 6265, 924: ########################################
</pre>
 
=={{header|Ada}}==
<syntaxhighlight lang="ada">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;</syntaxhighlight>
{{out}}
<pre>Range Observations: 20000 Buckets: 25
0.00..0.04 ****************************************************************************
0.04..0.08 ************************************************************************
0.08..0.12 **************************************************************
0.12..0.16 **********************************************************
0.16..0.20 **************************************************
0.20..0.24 ******************************************
0.24..0.28 ***************************************
0.28..0.32 *******************************
0.32..0.36 *************************
0.36..0.40 *******************
0.40..0.44 ************
0.44..0.48 *****
0.48..0.52 *
0.52..0.56 *******
0.56..0.60 ***********
0.60..0.64 ********************
0.64..0.68 ***************************
0.68..0.72 **********************************
0.72..0.76 **************************************
0.76..0.80 ********************************************
0.80..0.84 *************************************************
0.84..0.88 **********************************************************
0.88..0.92 ****************************************************************
0.92..0.96 *******************************************************************
0.96..1.00 ************************************************************************</pre>
 
=={{header|ALGOL 68}}==
{{Trans|Wren|with slightly modified output}}
<syntaxhighlight lang="algol68">
BEGIN # Modified random distribution - translation of the Wren sample #
 
next random; # initialise the random number generator #
 
PROC rng = ( PROC(REAL)REAL modifier )REAL:
BEGIN
REAL r1, r2;
WHILE
r1 := random;
r2 := random;
r2 >= modifier( r1 )
DO SKIP OD;
r1
END # rng # ;
 
PROC modifier = ( REAL x )REAL: 2 * ABS ( 0.5 - x );
 
INT n = 100 000;
INT num bins = 21;
REAL bin size = 1 / num bins;
CHAR hist char = "#";
INT hist char size = 125;
[ 0 : num bins - 1 ]INT bins ; FOR i FROM LWB bins TO UPB bins DO bins[ i ] := 0 OD;
FOR i FROM 0 TO n DO
bins[ ENTIER ( rng( modifier ) / bin size ) ] +:= 1
OD;
 
PROC f2 = ( REAL v )STRING: # formatting routine #
BEGIN
STRING result := fixed( ABS v, 0, 2 );
IF result[ LWB result ] = "." THEN "0" +=: result FI;
IF v < 0 THEN "-" +=: result FI;
result
END # FMT # ;
 
print( ( "Modified random distribution with ", whole( n, 0 ), " samples in range [0, 1):", newline ) );
print( ( " Range Number of samples within that range", newline ) );
FOR i FROM LWB bins TO UPB bins DO
STRING hist = hist char * ROUND ( bins[ i ] / hist char size );
print( ( f2( bin size * i ), " ..< " ) );
print( ( f2( bin size * ( i + 1 ) ), " ", whole( bins[ i ], -5 ), " ", hist, newline ) )
OD
 
END
</syntaxhighlight>
{{out}}
<pre>
Modified random distribution with 100000 samples in range [0, 1):
Range Number of samples within that range
0.00 ..< 0.05 8990 ########################################################################
0.05 ..< 0.10 8043 ################################################################
0.10 ..< 0.14 7265 ##########################################################
0.14 ..< 0.19 6366 ###################################################
0.19 ..< 0.24 5442 ############################################
0.24 ..< 0.29 4631 #####################################
0.29 ..< 0.33 3805 ##############################
0.33 ..< 0.38 2780 ######################
0.38 ..< 0.43 1725 ##############
0.43 ..< 0.48 907 #######
0.48 ..< 0.52 236 ##
0.52 ..< 0.57 915 #######
0.57 ..< 0.62 1778 ##############
0.62 ..< 0.67 2696 ######################
0.67 ..< 0.71 3657 #############################
0.71 ..< 0.76 4539 ####################################
0.76 ..< 0.81 5382 ###########################################
0.81 ..< 0.86 6337 ###################################################
0.86 ..< 0.90 7230 ##########################################################
0.90 ..< 0.95 8173 #################################################################
0.95 ..< 1.00 9104 #########################################################################
</pre>
 
=={{header|C++}}==
<syntaxhighlight lang="c++">
#include <cmath>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <iostream>
#include <random>
#include <string>
#include <vector>
 
std::random_device random;
std::mt19937 generator(random());
std::uniform_real_distribution<double> distribution(0.0F, 1.0F);
 
double modifier(const double& x) {
return ( x < 0.5 ) ? 2 * ( 0.5 - x ) : 2 * ( x - 0.5 );
}
 
double modified_random(const std::function<double(double)>& modify) {
double result = -1.0;
 
while ( result < 0.0 ) {
double random_one = distribution(generator);
double random_two = distribution(generator);
if ( random_two < modify(random_one) ) {
result = random_one;
}
}
return result;
}
 
int main() {
const int32_t sample_size = 100'000;
const int32_t bin_count = 20;
const double bin_size = 1.0 / bin_count;
 
std::vector<int32_t> bins(bin_count, 0);
 
for ( int32_t i = 0; i < sample_size; ++i ) {
double random = modified_random(modifier);
int32_t bin_number = floor(random / bin_size);
bins[bin_number]++;
}
 
std::cout << "Modified random distribution with " << sample_size << " samples in range [0, 1):"
<< std::endl << std::endl;
std::cout << " Range Number of samples within range" << std::endl;
 
const int32_t scale_factor = 125;
for ( float i = 0.0; i < bin_count; ++i ) {
std::string histogram = " " + std::string(bins[i] / scale_factor, '#') + " ";
std::cout << std::fixed << std::setw(4)<< std::setprecision(2) << i / bin_count << " ..< "
<< std::setw(4) << ( i + 1.0 ) / bin_count << histogram << bins[i] << std::endl;
}
}
</syntaxhighlight>
{{ out }}
<pre>
Modified random distribution with 100000 samples in range [0, 1):
 
Range Number of samples within range
0.00 ..< 0.05 ############################################################################ 9581
0.05 ..< 0.10 ##################################################################### 8662
0.10 ..< 0.15 ############################################################ 7516
0.15 ..< 0.20 ################################################### 6405
0.20 ..< 0.25 ############################################ 5595
0.25 ..< 0.30 #################################### 4502
0.30 ..< 0.35 ########################### 3464
0.35 ..< 0.40 ################### 2466
0.40 ..< 0.45 ############ 1525
0.45 ..< 0.50 #### 508
0.50 ..< 0.55 ### 482
0.55 ..< 0.60 ########### 1479
0.60 ..< 0.65 ################### 2494
0.65 ..< 0.70 ########################### 3440
0.70 ..< 0.75 ##################################### 4656
0.75 ..< 0.80 ############################################ 5544
0.80 ..< 0.85 ################################################### 6483
0.85 ..< 0.90 ########################################################### 7411
0.90 ..< 0.95 ################################################################### 8389
0.95 ..< 1.00 ########################################################################### 9398
</pre>
 
=={{header|Factor}}==
{{works with|Factor|0.99 2021-02-05}}
<langsyntaxhighlight lang="factor">USING: assocs assocs.extras formatting io kernel math
math.functions math.statistics random sequences
tools.memory.private ;
Line 57 ⟶ 408:
 
"Modified random distribution of values in [0, 1):" print nl
100,000 [ modifier ] 20 data .histogram</langsyntaxhighlight>
{{out}}
<pre>
Line 84 ⟶ 435:
[0.95, 1.00) ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 9,543
</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">#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</syntaxhighlight>
{{out}}
<pre>
Bin 0 (0.00 to 0.05): ############################################################################################## 9479
Bin 1 (0.05 to 0.10): #################################################################################### 8499
Bin 2 (0.10 to 0.15): ########################################################################## 7416
Bin 3 (0.15 to 0.20): ################################################################## 6650
Bin 4 (0.20 to 0.25): ###################################################### 5457
Bin 5 (0.25 to 0.30): ############################################ 4416
Bin 6 (0.30 to 0.35): ################################## 3469
Bin 7 (0.35 to 0.40): ######################## 2481
Bin 8 (0.40 to 0.45): ############## 1466
Bin 9 (0.45 to 0.50): #### 489
Bin 10 (0.50 to 0.55): #### 475
Bin 11 (0.55 to 0.60): ############## 1472
Bin 12 (0.60 to 0.65): ######################### 2548
Bin 13 (0.65 to 0.70): #################################### 3617
Bin 14 (0.70 to 0.75): ############################################# 4538
Bin 15 (0.75 to 0.80): ####################################################### 5590
Bin 16 (0.80 to 0.85): ############################################################### 6395
Bin 17 (0.85 to 0.90): ########################################################################### 7538
Bin 18 (0.90 to 0.95): #################################################################################### 8401
Bin 19 (0.95 to 1.00): ################################################################################################ 9604
</pre>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Modified_random_distribution}}
 
'''Solution'''
 
The following is the modifier random distribution function. It does not contain the modifier function, it is passed as a lambda expression:
 
[[File:Fōrmulæ - Modified random distribution 01.png]]
 
The example modifier is the following:
 
[[File:Fōrmulæ - Modified random distribution 02.png]]
 
The following functions groups a list of numbers in the given number of bins, producing the data necessary for a histogram.
 
[[File:Fōrmulæ - Modified random distribution 03.png]]
 
[[File:Fōrmulæ - Modified random distribution 04.png]]
 
[[File:Fōrmulæ - Modified random distribution 05.png]]
 
'''Test case 1. Showing the histogram of 50,000 numbers in 5 bins'''
 
[[File:Fōrmulæ - Modified random distribution 06.png]]
 
[[File:Fōrmulæ - Modified random distribution 07.png]]
 
'''Test case 2. Showing the histogram of 50,000 numbers in 20 bins'''
 
[[File:Fōrmulæ - Modified random distribution 08.png]]
 
[[File:Fōrmulæ - Modified random distribution 09.png]]
 
'''Test case 3. Showing the histogram of 50,000 numbers in 100 bins'''
 
[[File:Fōrmulæ - Modified random distribution 10.png]]
 
[[File:Fōrmulæ - Modified random distribution 11.png]]
 
=={{header|Go}}==
{{trans|Wren}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 151 ⟶ 610:
fmt.Printf("%4.2f ..< %4.2f %s %s\n", binSize*fi, binSize*(fi+1), hist, commatize(bins[i]))
}
}</langsyntaxhighlight>
 
{{out}}
Line 179 ⟶ 638:
0.90 ..< 0.95 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 8,592
0.95 ..< 1.00 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 9,332
</pre>
 
=={{header|Haskell}}==
 
The modifier is a pure function which consumes a sequence of numbers (probably, random) and applies a modification rule to it.
 
<syntaxhighlight lang="haskell">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</syntaxhighlight>
 
<pre>λ> showHist $ hist 0.05 $ take 50000 $ modify vShape $ randoms $ mkStdGen 1234
0.00 ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 28%
0.05 ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 25%
0.10 ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 22%
0.15 ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 19%
0.20 ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 16%
0.25 ▇▇▇▇▇▇▇▇▇▇▇▇▇ 13%
0.30 ▇▇▇▇▇▇▇▇▇▇ 10%
0.35 ▇▇▇▇▇▇▇ 7%
0.40 ▇▇▇▇ 4%
0.45 ▇ 1%
0.50 ▇ 1%
0.55 ▇▇▇▇ 4%
0.60 ▇▇▇▇▇▇▇ 7%
0.65 ▇▇▇▇▇▇▇▇▇▇▇ 11%
0.70 ▇▇▇▇▇▇▇▇▇▇▇▇▇ 13%
0.75 ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 16%
0.80 ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 19%
0.85 ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 22%
0.90 ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 25%
0.95 ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 29%</pre>
 
=={{header|J}}==
 
Implementation:
 
<syntaxhighlight lang="j">probmod=: {{y
while.do.r=.?0 0
if. (<u)/r do. {:r return.end.
end.
}}
 
mod=: {{|1-2*y}}</syntaxhighlight>
 
Task example:
 
<syntaxhighlight lang="j"> 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 ###################################################################</syntaxhighlight>
 
=={{header|Java}}==
<syntaxhighlight lang="java">
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;
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).collect(Collectors.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();
 
}
</syntaxhighlight>
{{ out }}
<pre>
Modified random distribution with 100000 samples in range [0, 1):
 
Range Number of samples within range
0.00 ..< 0.05 ############################################################################ 9545
0.05 ..< 0.10 ################################################################### 8457
0.10 ..< 0.15 ############################################################ 7519
0.15 ..< 0.20 #################################################### 6513
0.20 ..< 0.25 ############################################ 5515
0.25 ..< 0.30 ################################### 4412
0.30 ..< 0.35 ############################ 3545
0.35 ..< 0.40 #################### 2507
0.40 ..< 0.45 ########### 1497
0.45 ..< 0.50 ### 475
0.50 ..< 0.55 #### 500
0.55 ..< 0.60 ########### 1496
0.60 ..< 0.65 #################### 2511
0.65 ..< 0.70 ############################ 3539
0.70 ..< 0.75 ################################### 4444
0.75 ..< 0.80 ########################################### 5494
0.80 ..< 0.85 ################################################### 6429
0.85 ..< 0.90 ############################################################ 7571
0.90 ..< 0.95 ################################################################### 8474
0.95 ..< 1.00 ############################################################################ 9557
</pre>
 
=={{header|javascript}}==
 
<syntaxhighlight lang=javascript>function modifier(x) { return (x < .5 ? -1 : +1)*(2*(x-.5)) }
 
function random(m) {
let random1, random2;
while (true) {
random1 = Math.random();
random2 = Math.random();
if (random2 < m(random1)) {
return random1;
}
}
}
 
const N = 10000;
const bins = 20;
var numbers = [];
for (i=0;i<N;i++) {
let number = random(modifier);
numbers.push(number);
}
 
const delta = 1.0/bins;
var count = 0;
for (ceil=delta; ceil<1.0+delta; ceil+=delta) {
for (n of numbers) {
if ((n < ceil) && (ceil - delta <= n)) {
count++;
}
}
let width = count/N * 80;
let bar = '';
 
for (i = 0; i<width; i++) bar+='#';
console.log(bar);
count = 0;
}</syntaxhighlight>
{{out}}
<pre>########
#######
#######
######
#####
####
###
###
##
#
#
##
###
###
####
#####
######
######
#######
########
</pre>
 
=={{header|Julia}}==
 
<lang>using UnicodePlots
<syntaxhighlight lang="text">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)
</langsyntaxhighlight>{{out}}
<pre>
 
Line 215 ⟶ 905:
 
</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">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]</syntaxhighlight>
{{out}}
<pre>{0.,0.05} - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
{0.05,0.1} - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
{0.1,0.15} - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
{0.15,0.2} - XXXXXXXXXXXXXXXXXXXXXXXXXX
{0.2,0.25} - XXXXXXXXXXXXXXXXXXXXXX
{0.25,0.3} - XXXXXXXXXXXXXXXXXX
{0.3,0.35} - XXXXXXXXXXXXXX
{0.35,0.4} - XXXXXXXXXX
{0.4,0.45} - XXXXXX
{0.45,0.5} - XX
{0.5,0.55} - XX
{0.55,0.6} - XXXXXX
{0.6,0.65} - XXXXXXXXXX
{0.65,0.7} - XXXXXXXXXXXXXX
{0.7,0.75} - XXXXXXXXXXXXXXXXXX
{0.75,0.8} - XXXXXXXXXXXXXXXXXXXXXX
{0.8,0.85} - XXXXXXXXXXXXXXXXXXXXXXXXXX
{0.85,0.9} - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
{0.9,0.95} - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
{0.95,1.} - XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX</pre>
 
=={{header|Nim}}==
{{trans|Wren}}
<syntaxhighlight lang="nim">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]}"</syntaxhighlight>
 
{{out}}
<pre>Modified random distribution with 100000 samples in range [0, 1):
Range Number of samples within that range
0.00 ..< 0.05 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 9480
0.05 ..< 0.10 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 8469
0.10 ..< 0.15 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 7631
0.15 ..< 0.20 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 6484
0.20 ..< 0.25 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 5472
0.25 ..< 0.30 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 4327
0.30 ..< 0.35 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 3523
0.35 ..< 0.40 ■■■■■■■■■■■■■■■■■■■■ 2528
0.40 ..< 0.45 ■■■■■■■■■■■■ 1500
0.45 ..< 0.50 ■■■■ 444
0.50 ..< 0.55 ■■■■ 513
0.55 ..< 0.60 ■■■■■■■■■■■■ 1536
0.60 ..< 0.65 ■■■■■■■■■■■■■■■■■■■■ 2459
0.65 ..< 0.70 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 3505
0.70 ..< 0.75 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 4600
0.75 ..< 0.80 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 5525
0.80 ..< 0.85 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 6512
0.85 ..< 0.90 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 7482
0.90 ..< 0.95 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 8581
0.95 ..< 1.00 ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 9429</pre>
 
=={{header|Perl}}==
{{trans|Raku}}
Uses any supplied distribution function, but defaults to uniform otherwise.
<syntaxhighlight lang="perl">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);</syntaxhighlight>
{{out}}
<pre>Bin Counts Histogram
0.00 10114: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.10 9958: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.20 9960: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.30 10043: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.40 9874: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.50 10013: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.60 10085: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.70 9877: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.80 10079: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.90 9997: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
 
Bin Counts Histogram
0.00 4772: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.05 4329: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.10 3728: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.15 3249: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.20 2749: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.25 2163: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.30 1735: ■■■■■■■■■■■■■■■■■■■■■■■
0.35 1317: ■■■■■■■■■■■■■■■■■
0.40 764: ■■■■■■■■■■
0.45 259: ■■■
0.50 231: ■■■
0.55 721: ■■■■■■■■■
0.60 1255: ■■■■■■■■■■■■■■■■
0.65 1730: ■■■■■■■■■■■■■■■■■■■■■■■
0.70 2282: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.75 2720: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.80 3302: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.85 3712: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.90 4219: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
0.95 4763: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■</pre>
 
=={{header|Phix}}==
<langsyntaxhighlight Phixlang="phix">function rng(integer modifier)
while true do
atom r1 := rnd()
Line 248 ⟶ 1,110:
sequence hist := repeat('#', round(bins[i]/HIST_CHAR_SIZE))
printf(1,"%s %s %,d\n", {LBLS[i], hist, bins[i]})
end for</langsyntaxhighlight>
{{out}}
<pre>
Line 277 ⟶ 1,139:
{{libheader|Phix/pGUI}}
A simple graphical plot. Note the labels are on the X-axis, so it's <code>v</code>-shaped, not <code><</code>-shaped: IupPlot does not support putting user-supplied labels on the Y-axis.
<langsyntaxhighlight Phixlang="phix">include pGUI.e
IupOpen()
Ihandle plot = IupPlot("GRID=YES, AXS_YAUTOMIN=NO")
Line 289 ⟶ 1,151:
IupShow(IupDialog(plot, `TITLE=Histogram, RASTERSIZE=1300x850`))
IupMainLoop()
IupClose()</langsyntaxhighlight>
 
=={{header|Python}}==
<langsyntaxhighlight lang="python">import random
from typing import List, Callable, Optional
 
Line 354 ⟶ 1,216:
print(f" {b / bins:5.2f}, {count:4}, {delta:>4}: "
f"{'#' * int(40 * count / mx)}")
last = count</langsyntaxhighlight>
 
{{out}}
Line 374 ⟶ 1,236:
0.87, 5422, 1039: ##################################
0.93, 6205, 783: #######################################</pre>
=={{header|R}}==
Although it may not be immediately obvious, both modifier and gen are equivalent to the corresponding functions in the task.
<syntaxhighlight lang="rsplus">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 = "#")</syntaxhighlight>
{{out}}
<pre>> NostalgiR::nos.hist(data, breaks = 20, pch = "#")
10000 +--+---------------------+---------------------+----------------------+---------------------+---------------------+--+
| # |
| # # |
| # # |
| # # # # |
| # # # # |
8000 + # # # # +
| # # # # |
| # # # # # # |
| # # # # # # |
| # # # # # # # # |
F | # # # # # # # # |
r 6000 + # # # # # # # # +
e | # # # # # # # # # # |
q | # # # # # # # # # # |
u | # # # # # # # # # # |
e | # # # # # # # # # # # # |
n 4000 + # # # # # # # # # # # # +
c | # # # # # # # # # # # # # |
y | # # # # # # # # # # # # # # |
| # # # # # # # # # # # # # # |
| # # # # # # # # # # # # # # # |
| # # # # # # # # # # # # # # # # |
2000 + # # # # # # # # # # # # # # # # +
| # # # # # # # # # # # # # # # # # # |
| # # # # # # # # # # # # # # # # # # |
| # # # # # # # # # # # # # # # # # # |
| # # # # # # # # # # # # # # # # # # # # |
| # # # # # # # # # # # # # # # # # # # # |
0 + # # # # # # # # # # # # # # # # # # # # +
+--+---------------------+---------------------+----------------------+---------------------+---------------------+--+
0 0.2 0.4 0.6 0.8 1 </pre>
 
=={{header|REXX}}==
If a vertical histograph &nbsp; (instead of a &nbsp; <big><big><big>&lt;</big></big></big> &nbsp; shaped horizontal histograph) &nbsp; were to be used, &nbsp; it would be a &nbsp; <big><big>V</big></big> &nbsp; shaped.
<lang rexx>/*REXX program generates a "V" shaped probability of number generation using a modifier.*/
<syntaxhighlight lang="rexx">/*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.*/
Line 408 ⟶ 1,319:
#= # + 1; @.#= r /*bump counter; assign the MRD to array*/
end /*until*/
return</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default inputs:}}
<pre>
Line 436 ⟶ 1,347:
 
=={{header|Raku}}==
<syntaxhighlight lang="raku" perl6line>sub modified_random_distribution ( Code $modifier --> Seq ) {
return lazy gather loop {
my ( $r1, $r2 ) = rand, rand;
Line 456 ⟶ 1,367:
my @d = modified_random_distribution( &modifier );
 
print_histogram( @d.head(50_000), :n-bins(20), :width(64) );</langsyntaxhighlight>
{{out}}
<pre>
Line 481 ⟶ 1,392:
0.95, 4758: ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
</pre>
=={{header|Ruby}}==
<syntaxhighlight lang="ruby" line>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] }
</syntaxhighlight>
{{out}}
<pre>0.000000...0.066667 **************************************** 6241
0.066667...0.133333 ********************************* 5286
0.133333...0.200000 *************************** 4365
0.200000...0.266667 ********************** 3576
0.266667...0.333333 ***************** 2724
0.333333...0.400000 *********** 1837
0.400000...0.466667 ***** 925
0.466667...0.533333 * 207
0.533333...0.600000 ***** 843
0.600000...0.666667 *********** 1761
0.666667...0.733333 ***************** 2699
0.733333...0.800000 *********************** 3629
0.800000...0.866667 **************************** 4514
0.866667...0.933333 ********************************* 5301
0.933333...1.000000 *************************************** 6092
</pre>
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">use ndhistogram::{Histogram, ndhistogram, axis::Uniform};
use rand::Rng;
 
/// change x in [0.0, 1.0) to a split with minimum probability at 0.5
fn modifier(x: f64) -> f64 {
if x < 0.5 {
return 2.0 * (0.5 - &x);
} else {
return 2.0 * (&x - 0.5);
}
}
 
const WANTED: usize = 20_000;
 
fn main() {
let mut hist = ndhistogram!(Uniform::new(19, -0.0, 1.0));
let mut rng = rand::thread_rng();
for _ in 0.. WANTED {
loop {
let x: f64 = rng.gen::<f64>();
let y: f64 = rng.gen::<f64>();
if y < modifier(x) {
hist.fill(&f64::from(x));
break;
}
}
}
println!("{}", hist);
}
</syntaxhighlight>{{out}}
<pre>
VecHistogram1D(21 bins, sum=20000)
(-inf, -0.00) |
[0.00, 0.05) | #################################################
[0.05, 0.11) | ############################################
[0.11, 0.16) | #######################################
[0.16, 0.21) | ##################################
[0.21, 0.26) | ###########################
[0.26, 0.32) | ######################
[0.32, 0.37) | ################
[0.37, 0.42) | ###########
[0.42, 0.47) | #####
[0.47, 0.53) | #
[0.53, 0.58) | #####
[0.58, 0.63) | ###########
[0.63, 0.68) | ###############
[0.68, 0.74) | ######################
[0.74, 0.79) | ############################
[0.79, 0.84) | #################################
[0.84, 0.89) | ######################################
[0.89, 0.95) | ############################################
[0.95, 1.00) | ##################################################
[1.00, inf) |
</pre>
 
=={{header|UNIX Shell}}==
{{works with|bash}}
<syntaxhighlight lang=bash># NOTE: In bash, RANDOM returns an integer from 0 to 32767 (2**15-1)
random() {
local m="$1"
local -i random1 random2
while true
do
random1=RANDOM
random2=RANDOM
if ((random2 < $("$m" $random1)))
then echo $random1; break
fi
done
}
 
modifier() {
local -i x=$1
echo $((x < 2**14 ? 2**14 - x : x - 2**14 ))
}
 
declare -i N=10000 bins=20
declare -a histogram
for ((i=0;i<N;i++))
do ((histogram[bins*$(random modifier)/2**15]++))
done
 
for ((i=0;i<bins;i++))
do
for ((j=0;j< ${histogram[i]-0}*bins*50/N;j++))
do echo -n '#'
done
echo
done</syntaxhighlight>
{{out}}
<pre>#################################################################################################
################################################################################
############################################################################
###################################################################
#######################################################
###############################################
###################################
##########################
#############
######
#####
###############
##########################
##################################
#############################################
#####################################################
##############################################################
#######################################################################
####################################################################################
################################################################################################</pre>
 
=={{header|Wren}}==
{{libheader|Wren-fmt}}
<langsyntaxhighlight ecmascriptlang="wren">import "random" for Random
import "./fmt" for Fmt
 
var rgen = Random.new()
Line 518 ⟶ 1,577:
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])
}</langsyntaxhighlight>
 
{{out}}
1,934

edits