A semigroup/monoid/group action of G
on P
is the combination of compatible
left and right actions, providing:
A semigroup/monoid/group action of G
on P
is the combination of compatible
left and right actions, providing:
actl(g, p)
, or g |+|> p
, such that:1. (g |+| h) |+|> p === g |+|> (h |+|> p)
for all g
, h
in G
and p
in P
.
2. id |+|> p === p
for all p
in P
(if id
is defined)
actr(p, g)
, or p <|+| g
, such that:3. p <|+| (g |+| h) === (p <|+| g) <|+| h
for all g
, h
in G
and p
in P
.
4. p <|+| id === p
for all p
in P
(if id
is defined)
In addition, if G
is a group, left and right actions are compatible:
5. g |+|> p === p <|+| g.inverse
.
EuclideanRing implements a Euclidean domain.
EuclideanRing implements a Euclidean domain.
The formal definition says that every euclidean domain A has (at least one) euclidean function f: A -> N (the natural numbers) where:
(for every x and non-zero y) x = yq + r, and r = 0 or f(r) < f(y).
This generalizes the Euclidean division of integers, where f represents a measure of length (or absolute value), and the previous equation represents finding the quotient and remainder of x and y. So:
quot(x, y) = q mod(x, y) = r
Field type class.
Field type class. While algebra already provides one, we provide one in Spire
that integrates with the commutative ring hierarchy, in particular GCDRing
and EuclideanRing
.
On a field, all nonzero elements are invertible, so the remainder of the division is always 0. The Euclidean function can take an arbitrary value on nonzero elements (it is undefined for zero); for compatibility with the degree of polynomials, we use the constant 0.
The GCD and LCM are defined up to a unit; on a field, it means that either the GCD or LCM can be fixed arbitrarily. Some conventions with consistent defaults are provided in the spire.algebra.Field companion object.
A FieldAlgebra
is a vector space that is also a Ring
.
A FieldAlgebra
is a vector space that is also a Ring
. An example is the
complex numbers.
GCDRing implements a GCD ring.
GCDRing implements a GCD ring.
For two elements x and y in a GCD ring, we can choose two elements d and m such that:
d = gcd(x, y) m = lcm(x, y)
d * m = x * y
Additionally, we require:
gcd(0, 0) = 0 lcm(x, 0) = lcm(0, x) = 0
and commutativity:
gcd(x, y) = gcd(y, x) lcm(x, y) = lcm(y, x)
A simple type class for numeric types that are a subset of the reals.
A (left) semigroup/monoid/group action of G
on P
is simply the implementation of
a method actl(g, p)
, or g |+|> p
, such that:
A (left) semigroup/monoid/group action of G
on P
is simply the implementation of
a method actl(g, p)
, or g |+|> p
, such that:
1. (g |+| h) |+|> p === g |+|> (h |+|> p)
for all g
, h
in G
and p
in P
.
2. id |+|> p === p
for all p
in P
(if id
is defined)
This type class models a metric space V
.
This type class models a metric space V
. The distance between 2 points in
V
is measured in R
, which should be real (ie. IsReal[R]
exists).
A module generalizes a vector space by requiring its scalar need only form a ring, rather than a field.
This is a type class for types with n-roots.
This is a type class for types with n-roots. The value returned by nroot
and sqrt
are only guaranteed to be approximate answers (except in the case
of Real
).
Also, generally nroot
s where n
is even are not defined for
negative numbers. The behaviour is undefined if this is attempted. It would
be nice to ensure an exception is raised, but some types may defer
computation and testing if a value is negative may not be ideal. So, do not
count on ArithmeticException
s to save you from bad arithmetic!
A normed vector space is a vector space equipped with a function
norm: V => F
.
A normed vector space is a vector space equipped with a function
norm: V => F
. The main constraint is that the norm of a vector must be
scaled linearly when the vector is scaled; that is
norm(k *: v) == k.abs * norm(v)
. Additionally, a normed vector space is
also a MetricSpace
, where distance(v, w) = norm(v - w)
, and so must
obey the triangle inequality.
An example of a normed vector space is R^n equipped with the euclidean vector length as the norm.
A (right) semigroup/monoid/group action of G
on P
is simply the implementation of
a method actr(p, g)
, or p <|+| g
, such that:
A (right) semigroup/monoid/group action of G
on P
is simply the implementation of
a method actr(p, g)
, or p <|+| g
, such that:
1. p <|+| (g |+| h) === (p <|+| g) <|+| h
for all g
, h
in G
and p
in P
.
2. p <|+| id === p
for all p
in P
(if id
is defined)
A RingAlgebra
is a module that is also a Rng
.
A RingAlgebra
is a module that is also a Rng
. An example is the Gaussian
numbers.
A simple ADT representing the Sign
of an object.
A trait for linearly ordered additive commutative monoid.
A trait for linearly ordered additive commutative monoid. The following laws holds:
(1) if a <= b
then a + c <= b + c
(linear order),
(2) signum(x) = -1
if x < 0
, signum(x) = 1
if x > 0
, signum(x) = 0
otherwise,
Negative elements only appear when scalar
is a additive abelian group, and then
(3) abs(x) = -x
if x < 0
, or x
otherwise,
Laws (1) and (2) lead to the triange inequality:
(4) abs(a + b) <= abs(a) + abs(b)
Signed should never be extended in implementations, rather the AdditiveCMonoid and AdditiveAbGroup subtraits.
We cannot use self-types to express the constraint self: AdditiveCMonoid =>
(interaction with specialization?).
A Torsor[V, R] requires an AbGroup[R] and provides Action[V, R],
plus a diff
operator, <->
in additive notation, such that:
A Torsor[V, R] requires an AbGroup[R] and provides Action[V, R],
plus a diff
operator, <->
in additive notation, such that:
1. (g <-> g) === scalar.id
for all g
in G
.
2. (g <-> h) +> h === g
for all g
, h
in G
.
3. (g <-> h) +> i === (i <-> h) +> g
for all g
, h
in G
.
4. (g <-> h) === -(h <-> g)
for all g
, h
in G
.
A vector space is a group V
that can be multiplied by scalars in F
that
lie in a field.
A vector space is a group V
that can be multiplied by scalars in F
that
lie in a field. Scalar multiplication must distribute over vector addition
(x *: (v + w) === x *: v + x *: w
) and scalar addition
((x + y) *: v === x *: v + y *: v
). Scalar multiplication by 1 in F
is an identity function (1 *: v === v
). Scalar multiplication is
"associative" (x *: y *: v === (x * y) *: v
).
Given any Ring[A]
we can construct a RingAlgebra[A, Int]
.
Given any Ring[A]
we can construct a RingAlgebra[A, Int]
. This is
possible since we can define fromInt
on Ring
generally.