Numeric Programming with Spire
Lars Hupel
September 14th, 2018
Slide 2
Slide 2 text
Numeric Programming with
Cats Kernel, Algebra & Spire
Lars Hupel
September 14th, 2018
Slide 3
Slide 3 text
What is Spire?
“ Spire is a numeric library for Scala which is intended to
be generic, fast, and precise.
”
3
Slide 4
Slide 4 text
What is Spire?
“ Spire is a numeric library for Scala which is intended to
be generic, fast, and precise.
”
▶ one of the “oldest” Typelevel libraries
▶ initial work by Eiríkr Åsheim & Tom Switzer
▶ 60 contributors
▶ started out in 2011 as a SIP for improving numerics
3
“Algebra”
“ Algebra is the study of mathematical symbols and the
rules for manipulating these symbols.
”
7
Slide 10
Slide 10 text
“Algebra”
“ Algebra is the study of mathematical symbols and the
rules for manipulating these symbols.
”
Mathematicians study algebra to discover common properties of
various concrete structures.
7
Slide 11
Slide 11 text
“Algebra”
“ Algebra is the study of mathematical symbols and the
rules for manipulating these symbols.
”
Mathematicians study algebra to discover common properties of
various concrete structures.
Examples
▶ numbers, addition, multiplication
▶ matrices, vector spaces, linear algebra
▶ lattices, boolean algebra
7
Slide 12
Slide 12 text
“Algebra”
“ Algebra is the study of mathematical symbols and the
rules for manipulating these symbols.
”
Mathematicians study algebra to discover common properties of
various concrete structures.
Examples
▶ numbers, addition, multiplication
▶ matrices, vector spaces, linear algebra
▶ lattices, boolean algebra
7
Slide 13
Slide 13 text
“Algebra”
“ Algebra is the study of mathematical symbols and the
rules for manipulating these symbols.
”
Mathematicians study algebra to discover common properties of
various concrete structures.
Examples
▶ numbers, addition, multiplication
▶ matrices, vector spaces, linear algebra
▶ lattices, boolean algebra
7
Slide 14
Slide 14 text
Semigroup
trait Semigroup[A] {
def append(x: A, y: A): A
}
8
Monoids
trait Monoid[A] extends Semigroup[A] {
def append(x: A, y: A): A // Semigroup
def zero: A
}
Law: Neutral element
append(x, zero) == x
9
Slide 17
Slide 17 text
Monoidal structures
Lots of things are monoids.
10
Slide 18
Slide 18 text
Trains are monoids
11
Slide 19
Slide 19 text
Trains are monoids
11
Slide 20
Slide 20 text
Monoidal structures
Lots of things are monoids.
▶ (Train, no train, couple)
▶ (Int, 0, +)
▶ (List[T], Nil, concat)
▶ (Map[K, V], Map.empty, merge)
12
Slide 21
Slide 21 text
Demo
Slide 22
Slide 22 text
Monoidal structures
Lots of things are monoids.
▶ (Train, no train, couple)
▶ (Int, 0, +)
▶ (List[T], Nil, concat)
▶ (Map[K, V], Map.empty, merge)
But some are not!
▶ (Float, 0, +)
14
Law Checking
// Float and Double fail these tests
checkAll(”Int”, RingLaws[Int].euclideanRing)
checkAll(”Long”, RingLaws[Long].euclideanRing)
checkAll(”BigInt”, RingLaws[BigInt].euclideanRing)
checkAll(”Rational”, RingLaws[Rational].field)
checkAll(”Real”, RingLaws[Real].field)
16
Slide 29
Slide 29 text
Demo
Slide 30
Slide 30 text
Numbers
▶ machine floats are fast, but imprecise
▶ good tradeoff for many purposes, but not all!
▶ there is no “one size fits all” number type
18
Slide 31
Slide 31 text
Rational numbers
n
d
∈ Q where n, d ∈ Z
Properties
▶ closed under addition, multiplication, ...
▶ decidable comparison
19
Slide 32
Slide 32 text
Rational numbers
n
d
∈ Q where n, d ∈ Z
Properties
▶ closed under addition, multiplication, ...
▶ decidable comparison
▶ may grow large
19
Slide 33
Slide 33 text
Demo
Slide 34
Slide 34 text
Real numbers
We can’t represent all real numbers on a computer ...
21
Slide 35
Slide 35 text
Real numbers
We can’t represent all real numbers on a computer ...
... but we can get arbitrarily close
21
Slide 36
Slide 36 text
Real numbers
We can’t represent all real numbers on a computer ...
... but we can get arbitrarily close
21
Slide 37
Slide 37 text
Real numbers, approximated
trait Real {
def approximate(precision: Int): Rational
}
22
Slide 38
Slide 38 text
Real numbers, approximated
trait Real { self =>
def approximate(precision: Int): Rational
def +(that: Real): Real = new Real {
def approximate(precision: Int) = {
val r1 = self.approximate(precision + 2)
val r2 = that.approximate(precision + 2)
r1 + r2
}
}
}
22
Slide 39
Slide 39 text
Real numbers, approximated
trait Real {
def approximate(precision: Int): Rational
def +(that: Real): Real = new Real {
// ...
}
}
object Real {
def apply(f: Int => Rational) = // ...
def fromRational(rat: Rational) =
apply(_ => rat)
}
22
Slide 40
Slide 40 text
Irrational numbers
val pi: Real =
Real(16) * atan(Real(Rational(1, 5))) -
Real(4) * atan(Real(Rational(1, 239)))
23
Slide 41
Slide 41 text
Demo
Slide 42
Slide 42 text
Error bounds
▶ often, inputs are not accurate
▶ e.g. measurements (temperature, work, time, ...)
▶ What to do with error bounds?
25
Slide 43
Slide 43 text
Interval arithmetic
case class Interval[A](lower: A, upper: A)
26
Slide 44
Slide 44 text
Interval arithmetic
case class Interval[A](lower: A, upper: A) {
def +(that: Interval[A]) =
Interval(this.lower + that.lower,
this.upper + that.upper)
}
26
Slide 45
Slide 45 text
Interval arithmetic
case class Interval[A](lower: A, upper: A) {
def +(that: Interval[A]) =
Interval(this.lower + that.lower,
this.upper + that.upper)
}
Spire generalizes this even further:
▶ open/closed intervals
▶ bounded/unbounded intervals
26
Slide 46
Slide 46 text
Demo
Slide 47
Slide 47 text
What else?
Spire is full of tools you didn’t know you needed.
28
Slide 48
Slide 48 text
What else?
Spire is full of tools you didn’t know you needed.
▶ SafeLong: like BigInt, but faster
28
Slide 49
Slide 49 text
What else?
Spire is full of tools you didn’t know you needed.
▶ SafeLong: like BigInt, but faster
▶ Trilean: tri-state boolean value
28
Slide 50
Slide 50 text
What else?
Spire is full of tools you didn’t know you needed.
▶ SafeLong: like BigInt, but faster
▶ Trilean: tri-state boolean value
▶ UByte, UShort, UInt, ULong: unsigned machine words
28
Slide 51
Slide 51 text
What else?
Spire is full of tools you didn’t know you needed.
▶ SafeLong: like BigInt, but faster
▶ Trilean: tri-state boolean value
▶ UByte, UShort, UInt, ULong: unsigned machine words
▶ Natural: non-negative, arbitrary-sized integers
28
Slide 52
Slide 52 text
Appreciate your maintainers!
+54 contributors
29
Slide 53
Slide 53 text
Q & A
larsrh larsr_h
Slide 54
Slide 54 text
Image sources
▶ Rubik’s Cube:
https://en.wikipedia.org/wiki/File:Rubik%27s_Cube_variants.jpg,
Hellbus
▶ Knots: https://en.wikipedia.org/wiki/File:
Tabela_de_n%C3%B3s_matem%C3%A1ticos_01,_crop.jpg, Rodrigo.Argenton
▶ Intervals:
https://commons.wikimedia.org/wiki/File:Confidenceinterval.png,
Audrius Meskauskas
▶ Number venn diagram:
http://www.science4all.org/article/numbers-and-constructibility/,
Lê Nguyên Hoang
▶ Ponte Vecchio: https://commons.wikimedia.org/wiki/File:
Panorama_of_the_Ponte_Vecchio_in_Florence,_Italy.jpg, Jan Drewes
▶ Drawings: Yifan Xing
31