Benford's law: Difference between revisions

Added a Scheme implementation.
(Add VBA code)
(Added a Scheme implementation.)
Line 3,440:
9: 4.50% | 4.58% | 0.0757%
</pre>
=={{header|Scheme}}==
{{works with|Chez Scheme}}
<lang scheme>; Compute the probability of leading digit d (an integer [1,9]) according to Benford's law.
 
(define benford-probability
(lambda (d)
(- (log (1+ d) 10) (log d 10))))
 
; Determine the distribution of the leading digit of the sequence provided by the given
; generator. Return as a vector of 10 elements -- the 0th element will always be 0.
 
(define leading-digit-distribution
(lambda (seqgen count)
(let ((digcounts (make-vector 10 0)))
(do ((index 0 (1+ index)))
((>= index count))
(let* ((value (seqgen))
(string (format "~a" value))
(leadchr (string-ref string 0))
(leaddig (- (char->integer leadchr) (char->integer #\0))))
(vector-set! digcounts leaddig (1+ (vector-ref digcounts leaddig)))))
(vector-map (lambda (digcnt) (/ digcnt count)) digcounts))))
 
; Create a Fibonacci sequence generator.
 
(define make-fibgen
(lambda ()
(let ((fn-2 0) (fn-1 1))
(lambda ()
(let ((fn fn-1))
(set! fn-1 (+ fn-2 fn-1))
(set! fn-2 fn)
fn)))))
 
; Create a sequence generator that returns elements of the given vector.
 
(define make-vecgen
(lambda (vector)
(let ((index 0))
(lambda ()
(set! index (1+ index))
(vector-ref vector (1- index))))))
 
; Read all the values in the given file into a list.
 
(define list-read-file
(lambda (filenm)
(call-with-input-file filenm
(lambda (ip)
(let accrue ((value (read ip)))
(if (eof-object? value)
'()
(cons value (accrue (read ip)))))))))
 
; Display a table of digit, Benford's law, sequence distribution, and difference.
 
(define display-table
(lambda (seqnam seqgen count)
(printf "~%~3@a ~11@a ~11@a ~11@a~%" "dig" "Benford's" seqnam "difference")
(let ((dist (leading-digit-distribution seqgen count)))
(do ((digit 1 (1+ digit)))
((> digit 9))
(let* ((fraction (vector-ref dist digit))
(benford (benford-probability digit))
(diff (- fraction benford)))
(printf "~3d ~11,5f ~11,5f ~11,5f~%" digit benford fraction diff))))))
 
; Emit tables of various sequence distributions.
 
(display-table "Fib/1000" (make-fibgen) 1000)
(display-table "Rnd/1T/1M" (lambda () (1+ (random 1000000000000))) 1000000)
(let ((craters (list->vector (list-read-file "moon_craters.lst"))))
(display-table "Craters/D" (make-vecgen craters) (vector-length craters)))</lang>
{{out}}
The first one thousand Fibonnaci numbers.
<pre>dig Benford's Fib/1000 difference
1 0.30103 0.30100 -0.00003
2 0.17609 0.17700 0.00091
3 0.12494 0.12500 0.00006
4 0.09691 0.09600 -0.00091
5 0.07918 0.08000 0.00082
6 0.06695 0.06700 0.00005
7 0.05799 0.05600 -0.00199
8 0.05115 0.05300 0.00185
9 0.04576 0.04500 -0.00076</pre>
{{out}}
One million pseudo-random numbers from one to one trillion.
<pre>dig Benford's Rnd/1T/1M difference
1 0.30103 0.11055 -0.19048
2 0.17609 0.11100 -0.06509
3 0.12494 0.11126 -0.01368
4 0.09691 0.11129 0.01438
5 0.07918 0.11141 0.03223
6 0.06695 0.11088 0.04394
7 0.05799 0.11120 0.05321
8 0.05115 0.11112 0.05997
9 0.04576 0.11128 0.06553</pre>
{{out}}
Diameters of 1,595 Lunar craters in meters.
<br />
From the Gazetteer of Planetary Nomenclature [https://planetarynames.wr.usgs.gov/],
referred to by the Wikipedia Planetary nomenclature page [https://en.wikipedia.org/wiki/Planetary_nomenclature].
<pre>dig Benford's Craters/D difference
1 0.30103 0.23950 -0.06153
2 0.17609 0.10658 -0.06951
3 0.12494 0.11912 -0.00582
4 0.09691 0.12414 0.02723
5 0.07918 0.11034 0.03116
6 0.06695 0.10596 0.03901
7 0.05799 0.06959 0.01160
8 0.05115 0.06646 0.01531
9 0.04576 0.05831 0.01255</pre>
 
=={{header|Sidef}}==