Data update

This commit is contained in:
Ingy döt Net 2026-04-30 12:34:36 -04:00
parent 4bb20c9b71
commit cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions

View file

@ -0,0 +1,12 @@
generic
Sample_Size: Positive;
type Item_Type is private;
package S_Of_N_Creator is
subtype Index_Type is Positive range 1 .. Sample_Size;
type Item_Array is array (Index_Type) of Item_Type;
procedure Update(New_Item: Item_Type);
function Result return Item_Array;
end S_Of_N_Creator;

View file

@ -0,0 +1,38 @@
with Ada.Numerics.Float_Random, Ada.Numerics.Discrete_Random;
package body S_Of_N_Creator is
package F_Rnd renames Ada.Numerics.Float_Random;
F_Gen: F_Rnd.Generator;
package D_Rnd is new Ada.Numerics.Discrete_Random(Index_Type);
D_Gen: D_Rnd.Generator;
Item_Count: Natural := 0; -- this is a global counter
Sample: Item_Array; -- also used globally
procedure Update(New_Item: Item_Type) is
begin
Item_Count := Item_Count + 1;
if Item_Count <= Sample_Size then
-- select the first Sample_Size items as the sample
Sample(Item_Count) := New_Item;
else
-- for I-th item, I > Sample_Size: Sample_Size/I chance of keeping it
if (Float(Sample_Size)/Float(Item_Count)) > F_Rnd.Random(F_Gen) then
-- randomly (1/Sample_Size) replace one of the items of the sample
Sample(D_Rnd.Random(D_Gen)) := New_Item;
end if;
end if;
end Update;
function Result return Item_Array is
begin
Item_Count := 0; -- ready to start another run
return Sample;
end Result;
begin
D_Rnd.Reset(D_Gen); -- at package instantiation, initialize rnd-generators
F_Rnd.Reset(F_Gen);
end S_Of_N_Creator;

View file

@ -0,0 +1,34 @@
with S_Of_N_Creator, Ada.Text_IO;
procedure Test_S_Of_N is
Repetitions: constant Positive := 100_000;
type D_10 is range 0 .. 9;
-- the instantiation of the generic package S_Of_N_Creator generates
-- a package with the desired functionality
package S_Of_3 is new S_Of_N_Creator(Sample_Size => 3, Item_Type => D_10);
Sample: S_Of_3.Item_Array;
Result: array(D_10) of Natural := (others => 0);
begin
for J in 1 .. Repetitions loop
-- get Sample
for Dig in D_10 loop
S_Of_3.Update(Dig);
end loop;
Sample := S_Of_3.Result;
-- update current Result
for Item in Sample'Range loop
Result(Sample(Item)) := Result(Sample(Item)) + 1;
end loop;
end loop;
-- finally: output Result
for Dig in Result'Range loop
Ada.Text_IO.Put(D_10'Image(Dig) & ":"
& Natural'Image(Result(Dig)) & "; ");
end loop;
end Test_S_Of_N;

View file

@ -0,0 +1,165 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. RESERVOIR-SAMPLING.
DATA DIVISION.
WORKING-STORAGE SECTION.
*> ---------------------------------------------------------
*> Test Parameters
*> ---------------------------------------------------------
01 TEST-PARAMETERS.
05 CURRENT-N PIC 99.
05 CURRENT-M PIC 99.
*> ---------------------------------------------------------
*> Loop and Array Indices
*> ---------------------------------------------------------
01 LOOP-COUNTERS.
05 ITER-IDX PIC 9(6).
05 ITEM-VAL PIC 99.
05 IDX PIC 99.
05 FREQ-IDX PIC 99.
05 SAMPLE-IDX PIC 99.
*> ---------------------------------------------------------
*> Reservoir Class Equivalent State
*> ---------------------------------------------------------
01 RESERVOIR-STATE.
05 RES-M PIC 9(6).
05 RES-S-COUNT PIC 99.
05 RES-SAMPLE OCCURS 10 TIMES PIC 99.
*> ---------------------------------------------------------
*> Output / Frequency Array
*> ---------------------------------------------------------
01 RESULTS-DATA.
05 FREQS OCCURS 10 TIMES PIC 9(6) VALUE 0.
*> ---------------------------------------------------------
*> Random Number Variables
*> ---------------------------------------------------------
01 RANDOM-DATA.
05 SEED PIC 9(7).
05 DUMMY PIC V9(9).
05 RAND-INT PIC 9(6).
*> ---------------------------------------------------------
*> String Formatting Variables
*> ---------------------------------------------------------
01 DISPLAY-FORMATTING.
05 OUT-BUFFER PIC X(120).
05 PTR PIC 999.
05 DISP-N PIC 9.
05 DISP-M PIC Z9.
05 DISP-FREQ PIC Z(5)9.
PROCEDURE DIVISION.
MAIN-LOGIC.
*> Seed the random number generator using system time
MOVE FUNCTION CURRENT-DATE(10:7) TO SEED
COMPUTE DUMMY = FUNCTION RANDOM(SEED)
*> Execute First Test Case: n=3, m=3
MOVE 3 TO CURRENT-N
MOVE 3 TO CURRENT-M
PERFORM RUN-TEST-CASE
*> Execute Second Test Case: n=3, m=10
MOVE 3 TO CURRENT-N
MOVE 10 TO CURRENT-M
PERFORM RUN-TEST-CASE
STOP RUN.
*> ---------------------------------------------------------
*> Handles 100,000 iterations for a specific test case
*> ---------------------------------------------------------
RUN-TEST-CASE.
*> Reset frequencies array to zeros
PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > CURRENT-M
MOVE 0 TO FREQS(IDX)
END-PERFORM
*> Run simulation loop 1e5 (100,000) times
PERFORM VARYING ITER-IDX FROM 1 BY 1 UNTIL ITER-IDX > 100000
PERFORM RUN-SINGLE-ITERATION
END-PERFORM
PERFORM PRINT-RESULTS.
*> ---------------------------------------------------------
*> One single iteration (creating a new reservoir simulation)
*> ---------------------------------------------------------
RUN-SINGLE-ITERATION.
*> Initialize class variables
MOVE CURRENT-N TO RES-M
MOVE 0 TO RES-S-COUNT
*> Loop over items x from 0 to m-1
PERFORM VARYING ITEM-VAL FROM 0 BY 1
UNTIL ITEM-VAL = CURRENT-M
PERFORM ADD-TO-RESERVOIR
END-PERFORM
*> Count frequencies in our resulting sample array
PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > CURRENT-N
*> COBOL arrays are 1-indexed, map item value to 1-index
COMPUTE FREQ-IDX = RES-SAMPLE(IDX) + 1
ADD 1 TO FREQS(FREQ-IDX)
END-PERFORM.
*> ---------------------------------------------------------
*> The `add(item)` method logic
*> ---------------------------------------------------------
ADD-TO-RESERVOIR.
IF RES-S-COUNT < CURRENT-N
*> Array isn't full yet, add item
ADD 1 TO RES-S-COUNT
MOVE ITEM-VAL TO RES-SAMPLE(RES-S-COUNT)
ELSE
*> Increment items seen
ADD 1 TO RES-M
*> Math.floor(Math.random() * ++this.m)
COMPUTE RAND-INT =
FUNCTION INTEGER(FUNCTION RANDOM * RES-M)
*> If random number is less than n, replace an item
IF RAND-INT < CURRENT-N
*> Convert 0-based random to 1-based COBOL index
COMPUTE SAMPLE-IDX = RAND-INT + 1
MOVE ITEM-VAL TO RES-SAMPLE(SAMPLE-IDX)
END-IF
END-IF.
*> ---------------------------------------------------------
*> Formats and Prints the array (equivalent to console.log)
*> ---------------------------------------------------------
PRINT-RESULTS.
MOVE SPACES TO OUT-BUFFER
MOVE 1 TO PTR
MOVE CURRENT-N TO DISP-N
MOVE CURRENT-M TO DISP-M
*> Build the string prefix
STRING "Results for n=" DELIMITED BY SIZE
DISP-N DELIMITED BY SIZE
", m=" DELIMITED BY SIZE
DISP-M DELIMITED BY SIZE
": [" DELIMITED BY SIZE
INTO OUT-BUFFER WITH POINTER PTR
*> Join the array numbers
PERFORM VARYING IDX FROM 1 BY 1 UNTIL IDX > CURRENT-M
MOVE FREQS(IDX) TO DISP-FREQ
IF IDX = CURRENT-M
STRING DISP-FREQ DELIMITED BY SIZE
"]" DELIMITED BY SIZE
INTO OUT-BUFFER WITH POINTER PTR
ELSE
STRING DISP-FREQ DELIMITED BY SIZE
"," DELIMITED BY SIZE
INTO OUT-BUFFER WITH POINTER PTR
END-IF
END-PERFORM
DISPLAY OUT-BUFFER.

View file

@ -0,0 +1,24 @@
def s_or_n_creator (n, t : T.class) forall T
arr = Array(T).new(n)
i = 0
->(item : T) {
i += 1
if i <= n
arr << item
elsif rand(i) < n
arr[rand(n)] = item
end
arr
}
end
buckets = Array.new(10, 0)
100_000.times do
s_or_n = s_or_n_creator 3, Int32
(0...9).each do |i|
s_or_n.call i
end
s_or_n.call(9).each do |i| buckets[i] += 1 end
end
puts buckets

View file

@ -0,0 +1,38 @@
with javascript_semantics
function s_of_n(integer i, sequence samples, integer item)
samples = deep_copy(samples)
integer n = length(samples)
i += 1
if i<=n then
samples[i] = item
elsif n/i>rnd() then
samples[rand(n)] = item
end if
return {{i,samples},samples}
end function
function s_of_n_creator(integer n)
return define_lambda(s_of_n,{0,repeat(0,n)},true)
end function
function test(integer n, sequence items)
lambda l = s_of_n_creator(n)
sequence samples
for item in items do
samples = call_lambda(l,item)
end for
return samples
end function
procedure main()
sequence items_set = tagset(9,0),
frequencies = repeat(0,length(items_set))
for i=1 to 100000 do
sequence res = test(3, items_set)
for fdx in res do
frequencies[fdx+1] += 1
end for
end for
?frequencies
end procedure
main()

View file

@ -0,0 +1,29 @@
require "table2"
local function s_of_n_creator(n)
local s = table.rep(n, 0)
local next = 1
local m = n
return function(item)
if next <= n then
s[next] = item
next += 1
else
m += 1
if math.random(m) <= n then
local t = math.random(n)
s[t] = item
if next <= t then next = t + 1 end
end
end
return s
end
end
local freq = table.rep(10, 0)
for r = 0, 99_999 do
local son = s_of_n_creator(3)
for d = 48, 56 do son(d) end
for son(57) as d do freq[d - 47] += 1 end
end
print(freq:concat(", "))