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

@ -11,7 +11,7 @@ The&nbsp; n<sup>th</sup> &nbsp;Bernoulli number is expressed as&nbsp; '''B'''<su
:* &nbsp; suppress the output of values which are equal to zero. (Other than &nbsp; '''B'''<sub>1</sub>&nbsp;, all ''odd'' Bernoulli numbers have a value of zero.)
:* &nbsp; express the Bernoulli numbers as fractions &nbsp;(most are improper fractions).
:* &nbsp; the fractions should be reduced.
:* &nbsp; index each number in some way so that it can be discerned which number is being displayed.
:* &nbsp; index each number in some way so that it can be discerned which Bernoulli number is being displayed.
:* &nbsp; align the solidi &nbsp; (<big><b>/</b></big>) &nbsp; if used (extra credit).

View file

@ -0,0 +1,69 @@
BEGIN
# Show the non-zero Bernoulli numbers B0 to B60 #
# as rational numbers #
# Uses code from the Arithmetic/Rational task modified to use #
# LONG LONG INT to allow for the large number of digits requried #
PR precision 100 PR # sets the precision of LONG LONG INT #
# Code from the Arithmetic/Rational task #
# ============================================================== #
MODE FRAC = STRUCT( LONG LONG INT num #erator#, den #ominator#);
PROC gcd = (LONG LONG INT a, b) LONG LONG INT: # greatest common divisor #
(a = 0 | b |: b = 0 | a |: ABS a > ABS b | gcd(b, a MOD b) | gcd(a, b MOD a));
PROC lcm = (LONG LONG INT a, b)LONG LONG INT: # least common multiple #
a OVER gcd(a, b) * b;
PRIO // = 9; # higher then the ** operator #
OP // = (LONG LONG INT num, den)FRAC: ( # initialise and normalise #
LONG LONG INT common = gcd(num, den);
IF den < 0 THEN
( -num OVER common, -den OVER common)
ELSE
( num OVER common, den OVER common)
FI
);
OP + = (FRAC a, b)FRAC: (
LONG LONG INT common = lcm(den OF a, den OF b);
FRAC result := ( common OVER den OF a * num OF a + common OVER den OF b * num OF b, common );
num OF result//den OF result
);
OP - = (FRAC a, b)FRAC: a + -b,
* = (FRAC a, b)FRAC: (
LONG LONG INT num = num OF a * num OF b,
den = den OF a * den OF b;
LONG LONG INT common = gcd(num, den);
(num OVER common) // (den OVER common)
);
OP - = (FRAC frac)FRAC: (-num OF frac, den OF frac);
# ============================================================== #
# end code from the Arithmetic/Rational task #
# Additional FRACrelated operators #
OP * = ( INT a, FRAC b )FRAC: ( num OF b * a ) // den OF b;
OP // = ( INT a, INT b )FRAC: LONG LONG INT( a ) // LONG LONG INT( b );
# returns the nth Bernoulli number, n must be >= 0 #
# Uses the algorithm suggested by the task, so B(1) is +1/2 #
PROC bernoulli = ( INT n )FRAC:
IF n < 0
THEN # n is out of range # 0 // 1
ELSE # n is valid #
[ 0 : n ]FRAC a;
FOR i FROM LWB a TO UPB a DO a[ i ] := 0 // 1 OD;
FOR m FROM 0 TO n DO
a[ m ] := 1 // ( m + 1 );
FOR j FROM m BY -1 TO 1 DO
a[ j - 1 ] := j * ( a[ j - 1 ] - a[ j ] )
OD
OD;
a[ 0 ]
FI # bernoulli # ;
FOR n FROM 0 TO 60 DO
FRAC bn := bernoulli( n );
IF num OF bn /= 0 THEN
# have a non-0 Bn #
print( ( "B(", whole( n, -2 ), ") ", whole( num OF bn, -50 ), " / ", whole( den OF bn, 0 ), newline ) )
FI
OD
END

View file

@ -0,0 +1,42 @@
IN: scratchpad
[
0 1 1 "%2d : %d / %d\n" printf
1 -1 2 "%2d : %d / %d\n" printf
30 iota [
1 + 2 * dup bernoulli [ numerator ] [ denominator ] bi
"%2d : %d / %d\n" printf
] each
] time
0 : 1 / 1
1 : -1 / 2
2 : 1 / 6
4 : -1 / 30
6 : 1 / 42
8 : -1 / 30
10 : 5 / 66
12 : -691 / 2730
14 : 7 / 6
16 : -3617 / 510
18 : 43867 / 798
20 : -174611 / 330
22 : 854513 / 138
24 : -236364091 / 2730
26 : 8553103 / 6
28 : -23749461029 / 870
30 : 8615841276005 / 14322
32 : -7709321041217 / 510
34 : 2577687858367 / 6
36 : -26315271553053477373 / 1919190
38 : 2929993913841559 / 6
40 : -261082718496449122051 / 13530
42 : 1520097643918070802691 / 1806
44 : -27833269579301024235023 / 690
46 : 596451111593912163277961 / 282
48 : -5609403368997817686249127547 / 46410
50 : 495057205241079648212477525 / 66
52 : -801165718135489957347924991853 / 1590
54 : 29149963634884862421418123812691 / 798
56 : -2479392929313226753685415739663229 / 870
58 : 84483613348880041862046775994036021 / 354
60 : -1215233140483755572040304994079820246041491 / 56786730
Running time: 0.00489444 seconds

View file

@ -0,0 +1,35 @@
:: bernoulli-numbers ( n -- )
n 1 + 0 <array> :> tab
1 1 tab set-nth
2 n [a,b] [| k |
k 1 - dup
tab nth *
k tab set-nth
] each
2 n [a,b] [| k |
k n [a,b] [| j |
j tab nth
j k - 2 + *
j 1 - tab nth
j k - * +
j tab set-nth
] each
] each
1 :> s!
1 n [a,b] [| k |
k 2 * dup
2^ dup 1 - *
k tab nth
swap / *
s * k tab set-nth
s -1 * s!
] each
0 1 1 "%2d : %d / %d\n" printf
1 -1 2 "%2d : %d / %d\n" printf
1 n [a,b] [| k |
k 2 * k tab nth
[ numerator ] [ denominator ] bi
"%2d : %d / %d\n" printf
] each
;

View file

@ -0,0 +1,3 @@
[ 30 bernoulli-numbers ] time
...
Running time: 0.004331652 seconds

View file

@ -0,0 +1,23 @@
import Data.Ratio
import System.Environment
main = getArgs >>= printM . defaultArg
where
defaultArg as =
if null as
then 60
else read (head as)
printM m =
mapM_ (putStrLn . printP) .
takeWhile ((<= m) . fst) . filter (\(_, b) -> b /= 0 % 1) . zip [0 ..] $
bernoullis
printP (i, r) =
"B(" ++ show i ++ ") = " ++ show (numerator r) ++ "/" ++ show (denominator r)
bernoullis = map head . iterate (ulli 1) . map berno $ enumFrom 0
where
berno i = 1 % (i + 1)
ulli _ [_] = []
ulli i (x:y:xs) = (i % 1) * (x - y) : ulli (i + 1) (y : xs)

View file

@ -0,0 +1,17 @@
import Data.Ratio (numerator, denominator, (%))
bernouillis :: Integer -> [Rational]
bernouillis =
let faulhaber rs n = (:) =<< (-) 1 . sum $ zipWith ((*) . (n %)) [2 ..] rs
in fmap head . tail . scanl faulhaber [] . enumFromTo 0
bernouilliTable :: Integer -> String
bernouilliTable =
let row i x =
[ concat ["B(", show i, ") = ", show n, "/", show (denominator x)]
| let n = numerator x
, n /= 0 ]
in unlines . concat . zipWith row [0 ..] . bernouillis
main :: IO ()
main = putStrLn (bernouilliTable 60)

View file

@ -1,17 +0,0 @@
module Main where
import Data.Ratio
import System.Environment
main = getArgs >>= printM . defaultArg where
defaultArg as = if null as then 60 else read (head as)
printM m = mapM_ (putStrLn . printP) . takeWhile ((<= m).fst)
. filter (\(_,b) -> b /= 0%1) . zip [0..] $ bernoullis
printP (i,r) = "B(" ++ show i ++ ")=" ++ show (numerator r) ++ "/" ++ show (denominator r)
bernoullis = map head . iterate (ulli 1) . map berno $ enumFrom 0 where
berno i = 1 % (i+1)
ulli _ [_] = []
ulli i (x:y:xs) = (i%1)*(x-y) : ulli (i+1) (y:xs)

View file

@ -1 +0,0 @@
System.out.printf("B(%-2d) = %-1s%n", n, Bernoulli(n))

View file

@ -0,0 +1,115 @@
(* Taken from the 'Ada 99' project, https://marquisdegeek.com/code_ada99 *)
program BernoulliForAda99;
type
Fraction = object
private
numerator, denominator: Int64;
public
procedure assign(n, d: Int64);
procedure subtract(rhs: Fraction);
procedure multiply(value: Int64);
procedure reduce();
procedure writeOutput();
end;
function gcd(a, b: Int64):Int64;
begin
if (b = 0) then
gcd := a
else
gcd := gcd(b, a mod b)
end;
procedure Fraction.writeOutput();
begin
write(numerator);
if (numerator <> 0) then
begin
write('/');
write(denominator);
end;
end;
procedure Fraction.assign(n, d: Int64);
begin
numerator := n;
denominator := d;
end;
procedure Fraction.subtract(rhs: Fraction);
begin
numerator := numerator * rhs.denominator;
numerator := numerator - (rhs.numerator * denominator);
denominator := denominator * rhs.denominator;
end;
procedure Fraction.multiply(value: Int64);
begin
numerator := numerator * value;
end;
procedure Fraction.reduce();
var gcdResult: Int64;
begin
gcdResult := gcd(numerator, denominator);
begin
numerator := numerator div gcdResult; (* div is Int64 division *)
denominator := denominator div gcdResult; (* could also use round(d/r) *)
end;
end;
function calculateBernoulli(n: Int64) : Fraction;
var
m, j: Int64;
results: array of Fraction;
begin
setlength(results, n);
for m:= 0 to n do
begin
results[m].assign(1, m+1);
for j:= m downto 1 do
begin
results[j-1].subtract(results[j]);
results[j-1].multiply(j);
results[j-1].reduce();
end;
end;
calculateBernoulli := results[0];
end;
(* Main program starts here *)
var
b: Int64;
result: Fraction;
begin
writeln('Calculating Bernoulli numbers...');
for b:= 1 to 25 do
begin
write(b);
write(' : ');
result := calculateBernoulli(b);
result.writeOutput();
writeln;
end;
end.

View file

@ -1,7 +1,16 @@
my sub infix:<bop>(\prev,\this) { this.key => this.key * (this.value - prev.value) }
sub infix:<bop>(\prev, \this) {
this.key => this.key * (this.value - prev.value)
}
constant bernoulli = grep *.value, map { (.key => .value.[*-1]) }, do
0 => [FatRat.new(1,1)],
-> (:key($pm),:value(@pa)) {
$pm + 1 => [ map *.value, [\bop] ($pm + 2 ... 1) Z=> FatRat.new(1, $pm + 2), @pa ];
} ... *;
sub next-bernoulli ( (:key($pm), :value(@pa)) ) {
$pm + 1 => [
map *.value,
[\bop] ($pm + 2 ... 1) Z=> FatRat.new(1, $pm + 2), |@pa
]
}
constant bernoulli =
grep *.value,
map { .key => .value[*-1] },
(0 => [FatRat.new(1,1)], &next-bernoulli ... *)
;

View file

@ -0,0 +1,3 @@
# Bernoulli numbers. 12/8/16 aev
require(pracma)
bernoulli(60)

View file

@ -1,6 +1,6 @@
/*REXX program calculates N number of Bernoulli numbers expressed as fractions. */
parse arg N .; if N=='' then N=60 /*Not specified? Then use the default.*/
!.=0; w=max(length(N),4); Nw=N+N%5 /*used for aligning (output) fractions.*/
!.=0; w=max(length(N), 4); Nw=N + w + N % 4 /*used for aligning (output) fractions.*/
say 'B(n)' center("Bernoulli number expressed as a fraction", max(78-w, Nw)) /*title*/
say copies('',w) copies("",max(78-w,Nw+2*w)) /*display 2nd line of title, separators*/
do #=0 to N /*process the numbers from 0 ──► N. */
@ -10,43 +10,39 @@ say copies('─',w) copies("─",max(78-w,Nw+2*w)) /*display 2nd line of title
end /*#*/ /* [↑] align the Bernoulli fractions. */
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
bern: parse arg x /*obtain the subroutine argument. */
if x==0 then return '1/1' /*handle the special case of zero. */
if x==1 then return '-1/2' /* " " " " " one. */
if x//2 then return 0 /* " " " " " odds. */
/* [↓] process all numbers up to X, */
do j=2 to x by 2; jp=j+1; d=j+j /* ··· and set some shortcut vars.*/
bern: parse arg x; if x==0 then return '1/1' /*handle the special case of zero. */
if x==1 then return '-1/2' /* " " " " " one. */
if x//2 then return 0 /* " " " " " odds. */
do j=2 to x by 2; jp=j+1; d=j+j /*process the positive integers up to X*/
if d>digits() then numeric digits d /*increase the decimal digits if needed*/
sn=1-j /*set the numerator. */
sd=2 /* " " denominator. */
sn=1-j /*define the numerator. */
sd=2 /* " " denominator. */
do k=2 to j-1 by 2 /*calculate a SN/SD sequence. */
parse var @.k bn '/' ad /*get a previously calculated fraction.*/
an=comb(jp,k)*bn /*use COMBination for the next term. */
$lcm=lcm(sd,ad) /*use Least Common Denominator function*/
sn=$lcm%sd*sn; sd=$lcm /*calculate the current numerator. */
an=$lcm%ad*an; ad=$lcm /* " " next " */
an=comb(jp, k) * bn /*use COMBination for the next term. */
$lcm=lcm(sd, ad) /*use Least Common Denominator function*/
sn=$lcm % sd * sn; sd=$lcm /*calculate the current numerator. */
an=$lcm % ad * an; ad=$lcm /* " " next " */
sn=sn+an /* " " current " */
end /*k*/ /* [↑] calculate the SN/SD sequence.*/
sn=-sn /*adjust the sign for the numerator. */
sd=sd*jp /*calculate the denominator. */
if sn\==1 then do; _=gcd(sn, sd) /*get the Greatest Common Denominator.*/
sn=sn%_; sd=sd%_ /*reduce the numerator and denominator.*/
sn=sn %_; sd=sd %_ /*reduce the numerator and denominator.*/
end /* [↑] done with the reduction(s). */
@.j=sn'/'sd /*save the result for the next round. */
end /*j*/ /* [↑] done calculating Bernoulli #'s.*/
@.j= sn'/'sd /*save the result for the next round. */
end /*j*/ /* [↑] done calculating Bernoulli #'s.*/
return sn'/'sd
/*──────────────────────────────────────────────────────────────────────────────────────*/
comb: procedure expose !.; parse arg x,y; if x==y then return 1
if !.!c.x.y\==0 then return !.!c.x.y /*combination computed before?*/
if x-y<y then y=x-y; z=perm(x,y); do j=2 to y; z=z%j; end
!.!c.x.y=z; return z /*assign memoization; return. */
if !.c.x.y\==0 then return !.c.x.y /*combination computed before?*/
if x-y<y then y=x-y; z=perm(x, y); do j=2 to y; z=z%j; end /*j*/
!.c.x.y=z; return z /*assign memoization; return. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
gcd: procedure; parse arg x,y; x=abs(x)
do until y==0; parse value x//y y with y x; end; return x
do until y==0; parse value x//y y with y x; end; return x
/*──────────────────────────────────────────────────────────────────────────────────────*/
lcm: procedure; parse arg x,y; x=abs(x); return x*y/gcd(x,y)
lcm: procedure; parse arg x,y; x=abs(x); return x*y/gcd(x,y)
/*──────────────────────────────────────────────────────────────────────────────────────*/
perm: procedure expose !.; parse arg x,y; z=1
if !.!p.x.y\==0 then return !.!p.x.y /*permutation computed before?*/
do j=x-y+1 to x; z=z*j; end; !.!p.x.y=z; return z
perm: procedure expose !.; parse arg x,y; if !.p.x.y\==0 then return !.p.x.y
z=1; do j=x-y+1 to x; z=z*j; end; !.p.x.y=z; return z

View file

@ -1,22 +1,22 @@
func bernoulli_number{}; # must be declared before first used
func bernoulli_number{}
func bern_helper(n, k) {
binomial(n, k) * (bernoulli_number(k) / (n - k + 1));
binomial(n, k) * (bernoulli_number(k) / (n - k + 1))
}
func bern_diff(n, k, d) {
n < k ? d : bern_diff(n, k + 1, d - bern_helper(n + 1, k));
n < k ? d : bern_diff(n, k + 1, d - bern_helper(n + 1, k))
}
bernoulli_number = func(n) is cached {
n.is_one && return 1/2;
n.is_odd && return 0;
n.is_one && return 1/2
n.is_odd && return 0
n > 0 ? bern_diff(n - 1, 0, 1) : 1;
n > 0 ? bern_diff(n - 1, 0, 1) : 1
}
range(0, 60).each { |i|
var num = bernoulli_number(i) || next;
printf("B(%2d) = %44s / %s\n", i, num.parts);
for i (0..60) {
var num = bernoulli_number(i) || next
printf("B(%2d) = %44s / %s\n", i, num.nude)
}

View file

@ -1,13 +1,13 @@
func bernoulli_print {
var a = []
range(0, 60).each { |m|
a << (m+1 -> inv)
m.downto(1).each { |j|
for m (0..60) {
a.append(1/(m+1))
for j (flip(1..m)) {
(a[j-1] -= a[j]) *= j
}
a[0] || next
printf("B(%2d) = %44s / %s\n", m, a[0].parts)
printf("B(%2d) = %44s / %s\n", m, a[0].nude)
}
}
 
bernoulli_print()

View file

@ -0,0 +1,50 @@
' Bernoulli numbers - vb.net - 06/03/2017
Imports System.Numerics 'BinInteger
Module Bernoulli_numbers
Function gcd_BigInt(ByVal x As BigInteger, ByVal y As BigInteger) As BigInteger
Dim y2 As BigInteger
x = BigInteger.Abs(x)
Do
y2 = BigInteger.Remainder(x, y)
x = y
y = y2
Loop Until y = 0
Return x
End Function 'gcd_BigInt
Sub bernoul_BigInt(n As Integer, ByRef bnum As BigInteger, ByRef bden As BigInteger)
Dim j, m As Integer
Dim f As BigInteger
Dim anum(), aden() As BigInteger
ReDim anum(n + 1), aden(n + 1)
For m = 0 To n
anum(m + 1) = 1
aden(m + 1) = m + 1
For j = m To 1 Step -1
anum(j) = j * (aden(j + 1) * anum(j) - aden(j) * anum(j + 1))
aden(j) = aden(j) * aden(j + 1)
f = gcd_BigInt(BigInteger.Abs(anum(j)), BigInteger.Abs(aden(j)))
If f <> 1 Then
anum(j) = anum(j) / f
aden(j) = aden(j) / f
End If
Next
Next
bnum = anum(1) : bden = aden(1)
End Sub 'bernoul_BigInt
Sub bernoulli_BigInt()
Dim i As Integer
Dim bnum, bden As BigInteger
bnum = 0 : bden = 0
For i = 0 To 60
bernoul_BigInt(i, bnum, bden)
If bnum <> 0 Then
Console.WriteLine("B(" & i & ")=" & bnum.ToString("D") & "/" & bden.ToString("D"))
End If
Next i
End Sub 'bernoulli_BigInt
End Module 'Bernoulli_numbers

View file

@ -0,0 +1,20 @@
class Rational{ // Weenie Rational class, can handle BigInts
fcn init(_a,_b){ var a=_a, b=_b; normalize(); }
fcn toString{ "%50d / %d".fmt(a,b) }
fcn normalize{ // divide a and b by gcd
g:= a.gcd(b);
a/=g; b/=g;
if(b<0){ a=-a; b=-b; } // denominator > 0
self
}
fcn __opAdd(n){
if(Rational.isChildOf(n)) self(a*n.b + b*n.a, b*n.b); // Rat + Rat
else self(b*n + a, b); // Rat + Int
}
fcn __opSub(n){ self(a*n.b - b*n.a, b*n.b) } // Rat - Rat
fcn __opMul(n){
if(Rational.isChildOf(n)) self(a*n.a, b*n.b); // Rat * Rat
else self(a*n, b); // Rat * Int
}
fcn __opDiv(n){ self(a*n.b,b*n.a) } // Rat / Rat
}

View file

@ -0,0 +1,9 @@
var [const] BN=Import.lib("zklBigNum"); // libGMP (GNU MP Bignum Library)
fcn B(N){ // calculate Bernoulli(n)
var A=List.createLong(100,0); // aka static aka not thread safe
foreach m in (N+1){
A[m]=Rational(BN(1),BN(m+1));
foreach j in ([m..1, -1]){ A[j-1]= (A[j-1] - A[j])*j; }
}
A[0]
}

View file

@ -0,0 +1 @@
foreach b in ([0..1].chain([2..60,2])){ println("B(%2d)%s".fmt(b,B(b))) }