Math Library
The definitions provided by this library operate on numbers or streams of numbers providing statistics or other mathematical evaluations.
Functions
Many of the functions here are implemented in Perl. The definitions are examples of how some of these might be implemented in Dallycot.
abs
(x: Numeric) → Numeric
Returns the absolute value of a numeric datum.
Examples
abs(-1) = 1
abs(0) = 0
abs(1) = 1
Implementation
This is implemented natively.
(x) :> (
(x < 0) : -x
( ) : x
)
arc-tan
(y: Numeric, x: Numeric, units -> “degrees”, accuracy -> 40) → Numeric
Implementation
This is implemented natively.
binomial
(n: Numeric, k: Numeric) → Numeric
Returns the binomial coefficient n over k. The binomial coefficient can be used to generate Pascal’s Triangle.
Examples
Boundary conditions
When the second argument is zero or when both arguments are the same value,
the binomial
is one.
binomial(n, 0) = 1
binomial(n, n) = 1
Fourth row of Pascal’s Triangle
The first five rows of the triangle are:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
The fourth row (starting at zero) is then:
binomial(4, 0) = 1
binomial(4, 1) = 4
binomial(4, 2) = 6
binomial(4, 3) = 4
binomial(4, 4) = 1
Implementation
This is implemented natively.
(n, k) :> factorial(n) div ( factorial(k) * factorial(n - k) )
ceil
(x: Numeric) → Numeric
Returns the smallest integer greater than or equal to the given number.
Examples
ceil(1.23) = 2
ceil(-1.23) = -1
ceil(1) = 1
ceil(-1) = -1
Implementation
This is implemented natively.
cos
(angle: Numeric, units -> “degrees”, accuracy -> 40) → Numeric
Calculates the cosine of an angle. The units
may be degrees
, radians
, or gradians
. The calculation will be done to accuracy
digits.
Examples
cos(90) = 0
cos(60) = 1/2
cos(0) = 1
cos(89, accuracy -> 3) = 7/400
cos(89, accuracy -> 3, units -> "radians") = 841/1000
Implementation
This is implemented natively.
count-and-sum
(s: [Numeric]) → [<Numeric, Numeric>]
Returns a stream of duples (count and sum) produced by counting and summing each element in the input stream.
Examples
count-and-sum(1..) = [ <1,1>, <2,3>, <3,6>, <4,10>, <5,15>, <6,21>, ... ]
count-and-sum(primes) = [ <1,1>, <2,3>, <3,6>, <4,11>, <5,18>, ... ]
Implementation
foldl(
<0,0>,
(
(pad, element) :> <pad[1] + 1, pad[2] + element>
),
_
)
differences
(s: [Numeric]) → [Numeric]
Returns a stream of numbers representing the difference between successive elements in the input numeric stream.
Examples
differences(1..) = [ -1, -1, -1, ... ]
differences(primes) = [ -1, -1, -2, -2, -4, -2, ... ]
Implementation
(
diff := y-combinator(
(self, sh, st) :> (
(?sh and ?st) : [ sh - st', self(self, st', st...) ]
(?sh ) : [ sh ]
( ) : [ ]
)
);
{ diff(#', #...) }
)
divisible-by?
(n: Numeric, d: Numeric) → Boolean
Returns true
if the numerator (n) is divisible by the denominator (d).
Examples
divisible-by?(10, 3) = false
divisible-by?(123, 3) = true
divisible-by?(3, 1) = true
divisible-by?(1, 3) = false
Implementation
This is implemented natively.
(n, d) :> n mod d = 0
even?
(x: Numeric) → Boolean
Returns true
if the given number is even.
Examples
even? @ 1.. = [ false, true, false, true, false, true, ... ]
even?(123) = false
even?(0) = true
even?(1.23) = false
Implementation
This is implemented natively.
divisible-by?(_, 2)
factorial
(n: Numeric) → Numeric
Calculates the factorial (n!) of a number.
Examples
factorial(1) = 1
factorial(3) = 6
factorial @ 1.. = [ 1, 2, 6, 24, 120, 720, ... ]
Implementation
This is implemented natively.
(n) :> (
(n > 1) : last(product(2..n))
(n = 1) : 1
( ) : 0
)
fibonacci
(n: Numeric) → Numeric
Implementation
(n) :> fibonacci-sequence[n]
floor
(x: Numeric) → Numeric
Returns the largest integer less than or equal to the given number.
Examples
floor(1.23) = 1
floor(1) = 1
floor(-1) = -1
floor(-1.23) = -2
Implementation
This is implemented natively.
gcd
(*x: Numeric) → Numeric
Calculates the greatest common divisor shared by two or more numbers.
Examples
gcd(63, 42) = 21
gcd(64, 42) = 2
gcd(65, 42) = 1
Implementation
This is implemented natively.
For two arguments, this is equivalent to the following:
y-combinator(
(self, a, b) :> (
(a = 0) : b
(b = 0) : a
(a > b) : self(self, a mod b, b)
( ) : self(self, a, b mod a)
)
)
golden-ration
(accuracy: Numeric = 40) → Numeric
Provides a numerical approximation of phi, the golden ration, to the desired accuracy. Defaults to 40 digits.
Examples
golden-ratio(1) = 2
golden-ratio(2) = 8/5
golden-ratio(3) = 81/50
golden-ratio(9) = 161803399/100000000
Implementation
This is implemented natively.
(accuracy) :>
(1 + sqrt(5, accuracy -> accuracy)) / 2
lcm
(*x: Numeric) → Numeric
Calculates the least common multiple of two or more numbers.
Examples
lcm(63, 42) = 126
lcm(64, 42) = 1344
lcm(65, 42) = 2730
Implementation
This is implemented natively.
For two arguments, this is equivalent to:
(x, y) :> x * y div gcd(x,y)
leonardo
Implementation
(n) :> leonardo-sequence[n]
make-evens
() → [ 2, 4, 6, … ]
Creates a new stream consisting of the positive, non-zero even integers.
This is useful when you need a stream of even numbers and want to garbage collect the stream after using it.
Examples
make-evens() = [ 2, 4, 6, ... ]
Implementation
() :> ({ # * 2 } @ 1..)
make-odds
() → [ 1, 3, 5, … ]
Creates a new stream consisting of the positive, non-zero even integers.
This is useful when you need a stream of odd numbers and want to garbage collect the stream after using it.
Examples
make-odds() = [ 1, 3, 5, ... ]
Implementation
() :> ({ # * 2 + 1} @ 0..)
max
(s: [Numeric]) → [Numeric]
Given a stream of numbers, max
returns a new stream representing the maximum
number seen up to that point in the input stream.
Examples
max(primes) = primes
max(1..) = 1..
max([1,3,5,3,1]) = [ 1, 3, 5, 5, 5 ]
Implementation
foldl1({(
(#1 > #2) : #1
( ) : #2
)}/2, _)
mean
(s: [Numeric]) → [Numeric]
Given a stream of numbers, mean
returns a new stream representing the mean of
the numbers seen up to that point in the input stream.
Examples
mean([1, 3, 5, 3, 1]) = [ 1, 2, 3, 3, 13/5 ]
mean(1..) = [ 1, 3/2, 2, 5/2, 3, ... ]
Implementation
{ #[2] div #[1] } @ count-and-sum
min
(s: [Numeric]) → [Numeric]
Given a stream of numbers, min
returns a new stream representing the minimum
number seen up to that point in the input stream.
Examples
min(primes) = [ 1, 1, 1, ... ]
min(1..) = [ 1, 1, 1, ... ]
min([1,3,5,3,1]) = [ 1, 1, 1, 1, 1 ]
min([-1, -3, -5, -3, -1]) = [ -1, -3, -5, -5, -5 ]
Implementation
foldl1({(
(#1 < #2) : #1
( ) : #2
)}/2, _)
odd?
(x: Numeric) → Boolean
Returns true
if the given number is odd.
Examples
odd? @ 1.. = [ true, false, true, false, true, false, ... ]
odd?(123) = true
odd?(0) = false
odd?(1.23) = false
Implementation
This is implemented natively.
~even?
pi
(accuracy: Numeric = 40) → Numeric
Provides a numerical approximation of PI to the desired accuracy. Defaults to 40 digits.
Examples
pi(1) = 3
pi(2) = 31/10
pi(3) = 157/50
pi(9) = 62831853/20000000
Implementation
This is implemented natively.
prime
(n: Numeric) → Numeric
Implementation
(n) :> primes[n]
product
(s: [Numeric]) → [Numeric]
Transforms a stream of numbers into a stream of cumulative products.
Examples
product(1..) = [ 1, 2, 6, 24, 120, ... ]
product(primes) = [ 1, 2, 6, 30, 180, ... ]
product([1, 3, 5, 3, 1]) = [ 1, 3, 15, 45, 135, 135 ]
Implementation
foldl(1, { #1 * #2 }/2, _)
random
(spec: Numeric|<Numeric,Numeric>) → Numeric
Creates a pseudo-random integer up to the number given or in the range given by a vector of numbers. The upper bound must be greater than zero.
Examples
0 <= random(10) <= 10
20 <= random(<20,40>) <= 40
Implementation
This is implemented natively.
sin
(angle: Numeric, units -> “degrees”, accuracy -> 40) :> Numeric
Calculates the sine of an angle. The units
may be degrees
, radians
, or gradians
. The calculation will be done to accuracy
digits.
Examples
sin(0) = 0
sin(30) = 1/2
sin(90) = 1
sin(1, accuracy -> 3) = 7/400
sin(1, accuracy -> 3, units -> "radians") = 841/1000
Implementation
This is implemented natively.
sum
(s: [Numeric]) → [Numeric]
Transforms a stream of numbers into a stream of cumulative sums.
Examples
sum(1..) = [ 1, 3, 6, 10, 15, ... ]
sum(primes) = [ 1, 3, 6, 11, 18, ... ]
sum([1, 3, 5, 3, 1]) = [ 1, 4, 9, 12, 13 ]
Implementation
foldl(0, { #1 + #2 }/2, _)
tan
(angle: Numeric, units -> “degrees”, accuracy -> 40) :> Numeric
Calculates the tangent of an angle. The units
may be degrees
, radians
, or gradians
. The calculation will be done to accuracy
digits.
Examples
sin(0) = 0
sin(30) = 1/2
sin(90) = 1
sin(1, accuracy -> 3) = 7/400
sin(1, accuracy -> 3, units -> "radians") = 841/1000
Implementation
(angle, units -> "degrees", accuracy -> 40) :> (
sin(angle, units -> units, accuracy -> accuracy) div
cos(angle, units -> units, accuracy -> accuracy)
)
weighted-count-and-sum
(s: [<Numeric, Numeric>]) → [<Numeric, Numeric>]
Transforms a stream of duples (weight and number) into a stream of duples containing the sum of weights and sum of weighted numbers.
Examples
Assuming we have a gradebook with the following grade distribution:
A (4 pts) | 4 |
B (3 pts) | 9 |
C (2 pts) | 15 |
D (1 pts) | 8 |
F (0 pts) | 2 |
then we can calculate the class average:
mean @ weighted-count-and-sum([<4, 4>, <9, 3>, <15, 2>, <8, 1>, <2, 0>])
= mean @ [ <4, 16>, <13, 43>, <28, 73>, <36, 81>, <38, 81> ]
= [ 4, 43/13, 73/28, 9/4, 81/38 ]
Dallycot uses rationals for all numbers, so the final average for the class is around 2.131 (the sequence in floating point numbers: [ 4, 3.307, 2.607, 2.250, 2.131] ).
Implementation
foldl(
<0,0>,
((pad, element) :>
<pad[1] + element[1], pad[2] + element[1] * element[2]>
),
_
)
Streams
evens
Implementation
make-evens()
factorials
Implementation
factorial @ 1..
fibonacci-sequence
Implementation
[ 1,
1,
y-combinator(
(self, a, b) :>
[ a + b, self(self, b, a + b) ]
)(1, 1)
]
leonardo-sequence
Implementation
[ 1,
1,
y-combinator(
(self, a, b) :>
[ a + b + 1, self(self, b, a + b + 1) ]
)(1, 1)
]
odds
Implementation
make-odds()
primes
Implementation
[ 1,
2,
y-combinator(
(self, s) :>
[ s', self(self, ~divisible-by?(_, s') % s...) ]
)(make-odds()...)
]
twin-primes
Implementation
{ #[2] - #[1] = 2 } % (primes Z primes...)