diff --git a/build.sbt b/build.sbt index 19aad7695..ab90fcf35 100644 --- a/build.sbt +++ b/build.sbt @@ -20,7 +20,7 @@ lazy val scalaCheckVersion = "1.15.4" lazy val munit = "0.7.29" lazy val munitDiscipline = "1.0.9" -lazy val algebraVersion = "2.2.3" +lazy val algebraVersion = "2.7.0" lazy val apfloatVersion = "1.10.1" lazy val jscienceVersion = "4.3.1" diff --git a/core/src/main/scala-2/spire/macros/Auto.scala b/core/src/main/scala-2/spire/macros/Auto.scala index 569130e12..74d91e2b7 100644 --- a/core/src/main/scala-2/spire/macros/Auto.scala +++ b/core/src/main/scala-2/spire/macros/Auto.scala @@ -162,12 +162,12 @@ abstract class AutoAlgebra extends AutoOps { ops => def EuclideanRing[A: c.WeakTypeTag](z: c.Expr[A], o: c.Expr[A])(ev: c.Expr[Eq[A]]): c.Expr[EuclideanRing[A]] = { c.universe.reify { new EuclideanRing[A] { self => - // default implementations from EuclideanRing.WithEuclideanAlgorithm + // default implementations from EuclideanRing @tailrec final def euclid(a: A, b: A)(implicit ev: Eq[A]): A = if (isZero(b)) a else euclid(b, emod(a, b)) - def gcd(a: A, b: A)(implicit ev: Eq[A]): A = + override def gcd(a: A, b: A)(implicit ev: Eq[A]): A = euclid(a, b)(ev) - def lcm(a: A, b: A)(implicit ev: Eq[A]): A = + override def lcm(a: A, b: A)(implicit ev: Eq[A]): A = if (isZero(a) || isZero(b)) zero else times(equot(a, gcd(a, b)), b) def zero: A = z.splice @@ -186,7 +186,7 @@ abstract class AutoAlgebra extends AutoOps { ops => def Field[A: c.WeakTypeTag](z: c.Expr[A], o: c.Expr[A])(ev: c.Expr[Eq[A]]): c.Expr[Field[A]] = { c.universe.reify { new Field[A] { - // default implementations from Field.WithDefaultGCD + // default implementations from Field override def gcd(a: A, b: A)(implicit eqA: Eq[A]): A = if (isZero(a) && isZero(b)) zero else one override def lcm(a: A, b: A)(implicit eqA: Eq[A]): A = times(a, b) diff --git a/core/src/main/scala-3/spire/syntax/Ops.scala b/core/src/main/scala-3/spire/syntax/Ops.scala index 2d353dcd3..4a2e14c6e 100644 --- a/core/src/main/scala-3/spire/syntax/Ops.scala +++ b/core/src/main/scala-3/spire/syntax/Ops.scala @@ -83,7 +83,7 @@ final class SignedOps[A](a: A)(using s: Signed[A]): def isSignNonNegative: Boolean = s.isSignNonNegative(a) final class TruncatedDivisionOps[A](lhs: A)(using ev: TruncatedDivision[A]): - def toBigIntOpt: Opt[BigInt] = ev.toBigIntOpt(lhs) + // def toBigIntOpt: Opt[BigInt] = ev.toBigIntOpt(lhs) // TODO port to algebra? def tquot(rhs: A): A = ev.tquot(lhs, rhs) def tmod(rhs: A): A = ev.tmod(lhs, rhs) def tquotmod(rhs: A): (A, A) = ev.tquotmod(lhs, rhs) diff --git a/core/src/main/scala/spire/algebra/Action.scala b/core/src/main/scala/spire/algebra/Action.scala index de3ba0440..95a6f83dc 100644 --- a/core/src/main/scala/spire/algebra/Action.scala +++ b/core/src/main/scala/spire/algebra/Action.scala @@ -100,3 +100,15 @@ trait MultiplicativeAction[@sp(Int) P, G] extends Any { self => def gtimesl(g: G, p: P): P def gtimesr(p: P, g: G): P } + +object MultiplicativeAction { + implicit def SignAction[A](implicit A: AdditiveGroup[A]): MultiplicativeAction[A, Sign] = + new MultiplicativeAction[A, Sign] { + def gtimesl(s: Sign, a: A): A = s match { + case Signed.Positive => a + case Signed.Negative => A.negate(a) + case Signed.Zero => A.zero + } + def gtimesr(a: A, s: Sign): A = gtimesl(s, a) + } +} diff --git a/core/src/main/scala/spire/algebra/DivisionRing.scala b/core/src/main/scala/spire/algebra/DivisionRing.scala deleted file mode 100644 index b711cd14e..000000000 --- a/core/src/main/scala/spire/algebra/DivisionRing.scala +++ /dev/null @@ -1,30 +0,0 @@ -/* - * **********************************************************************\ - * * Project ** - * * ______ ______ __ ______ ____ ** - * * / ____/ / __ / / / / __ / / __/ (c) 2011-2021 ** - * * / /__ / /_/ / / / / /_/ / / /_ ** - * * /___ / / ____/ / / / __ / / __/ Erik Osheim, Tom Switzer ** - * * ____/ / / / / / / / | | / /__ ** - * * /_____/ /_/ /_/ /_/ |_| /____/ All rights reserved. ** - * * ** - * * Redistribution and use permitted under the MIT license. ** - * * ** - * \*********************************************************************** - */ - -package spire -package algebra - -trait DivisionRing[@sp(Byte, Short, Int, Long, Float, Double) A] extends Any with Ring[A] with MultiplicativeGroup[A] { - self => - - def fromDouble(a: Double): A = Ring.defaultFromDouble[A](a)(self, self) - -} - -object DivisionRing { - - @inline final def apply[A](implicit f: DivisionRing[A]): DivisionRing[A] = f - -} diff --git a/core/src/main/scala/spire/algebra/EuclideanRing.scala b/core/src/main/scala/spire/algebra/EuclideanRing.scala deleted file mode 100644 index 5dc2a54fc..000000000 --- a/core/src/main/scala/spire/algebra/EuclideanRing.scala +++ /dev/null @@ -1,68 +0,0 @@ -/* - * **********************************************************************\ - * * Project ** - * * ______ ______ __ ______ ____ ** - * * / ____/ / __ / / / / __ / / __/ (c) 2011-2021 ** - * * / /__ / /_/ / / / / /_/ / / /_ ** - * * /___ / / ____/ / / / __ / / __/ Erik Osheim, Tom Switzer ** - * * ____/ / / / / / / / | | / /__ ** - * * /_____/ /_/ /_/ /_/ |_| /____/ All rights reserved. ** - * * ** - * * Redistribution and use permitted under the MIT license. ** - * * ** - * \*********************************************************************** - */ - -package spire -package algebra - -/** - * 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 - * }}} - */ -trait EuclideanRing[@sp(Int, Long, Float, Double) A] extends Any with GCDRing[A] { - def euclideanFunction(a: A): BigInt - def equot(a: A, b: A): A - def emod(a: A, b: A): A - def equotmod(a: A, b: A): (A, A) = (equot(a, b), emod(a, b)) -} - -trait EuclideanRingFunctions[R[T] <: EuclideanRing[T]] extends GCDRingFunctions[R] { - def euclideanFunction[@sp(Int, Long, Float, Double) A](a: A)(implicit ev: R[A]): BigInt = - ev.euclideanFunction(a) - def equot[@sp(Int, Long, Float, Double) A](a: A, b: A)(implicit ev: R[A]): A = - ev.equot(a, b) - def emod[@sp(Int, Long, Float, Double) A](a: A, b: A)(implicit ev: R[A]): A = - ev.emod(a, b) - def equotmod[@sp(Int, Long, Float, Double) A](a: A, b: A)(implicit ev: R[A]): (A, A) = - ev.equotmod(a, b) -} - -object EuclideanRing extends EuclideanRingFunctions[EuclideanRing] { - - @inline final def apply[A](implicit e: EuclideanRing[A]): EuclideanRing[A] = e - - @tailrec final def euclid[@sp(Int, Long, Float, Double) A: Eq: EuclideanRing](a: A, b: A): A = { - if (EuclideanRing[A].isZero(b)) a else euclid(b, EuclideanRing[A].emod(a, b)) - } - - trait WithEuclideanAlgorithm[@sp(Int, Long, Float, Double) A] extends Any with EuclideanRing[A] { self => - def gcd(a: A, b: A)(implicit ev: Eq[A]): A = - EuclideanRing.euclid(a, b)(ev, self) - def lcm(a: A, b: A)(implicit ev: Eq[A]): A = - if (isZero(a) || isZero(b)) zero else times(equot(a, gcd(a, b)), b) - } - -} diff --git a/core/src/main/scala/spire/algebra/Field.scala b/core/src/main/scala/spire/algebra/Field.scala deleted file mode 100644 index 5ef652950..000000000 --- a/core/src/main/scala/spire/algebra/Field.scala +++ /dev/null @@ -1,81 +0,0 @@ -/* - * **********************************************************************\ - * * Project ** - * * ______ ______ __ ______ ____ ** - * * / ____/ / __ / / / / __ / / __/ (c) 2011-2021 ** - * * / /__ / /_/ / / / / /_/ / / /_ ** - * * /___ / / ____/ / / / __ / / __/ Erik Osheim, Tom Switzer ** - * * ____/ / / / / / / / | | / /__ ** - * * /_____/ /_/ /_/ /_/ |_| /____/ All rights reserved. ** - * * ** - * * Redistribution and use permitted under the MIT license. ** - * * ** - * \*********************************************************************** - */ - -package spire -package algebra - -/** - * 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. - */ -trait Field[@sp(Int, Long, Float, Double) A] extends Any with AlgebraField[A] with EuclideanRing[A] { - def euclideanFunction(a: A): BigInt = BigInt(0) - def equot(a: A, b: A): A = div(a, b) - def emod(a: A, b: A): A = zero - override def equotmod(a: A, b: A): (A, A) = (div(a, b), zero) -} - -object Field extends _root_.algebra.ring.FieldFunctions[Field] with EuclideanRingFunctions[Field] { - - @inline def apply[A](implicit ev: Field[A]): Field[A] = ev - - /** - * Field with simple default GCD/LCM implementations: - * {{{ - * gcd(a, b) = 1 (except gcd(0, 0) = 0) while lcm(a, b) = a * b. - * }}} - */ - trait WithDefaultGCD[@sp(Int, Long, Float, Double) A] extends Any with Field[A] { - override def gcd(a: A, b: A)(implicit eqA: Eq[A]): A = - if (isZero(a) && isZero(b)) zero else one - override def lcm(a: A, b: A)(implicit eqA: Eq[A]): A = times(a, b) - } - - /** - * Field defined as a field of fractions with a default implementation of GCD/LCM such that - * {{{ - * - gcd(a/b, c/d) = gcd(a, c) / lcm(b, d) - * - lcm(a/b, c/d) = lcm(a, c) / gcd(b, d) - * }}} - * which corresponds to the convention of the GCD domains of SageMath; on rational numbers, it "yields the unique - * extension of gcd from integers to rationals presuming the natural extension of the divisibility relation from - * integers to rationals", see http://math.stackexchange.com/a/151431 - */ - trait FieldOfFractionsGCD[A, R] extends Any with Field[A] { - implicit def ringR: GCDRing[R] - implicit def eqR: Eq[R] - def numerator(a: A): R - def denominator(a: A): R - def fraction(num: R, den: R): A - override def gcd(x: A, y: A)(implicit ev: Eq[A]): A = { - val num = ringR.gcd(numerator(x), numerator(y)) - val den = ringR.lcm(denominator(x), denominator(y)) - fraction(num, den) - } - override def lcm(x: A, y: A)(implicit ev: Eq[A]): A = { - val num = ringR.lcm(numerator(x), numerator(y)) - val den = ringR.gcd(denominator(x), denominator(y)) - fraction(num, den) - } - } - -} diff --git a/core/src/main/scala/spire/algebra/GCDRing.scala b/core/src/main/scala/spire/algebra/GCDRing.scala deleted file mode 100644 index a64a232d5..000000000 --- a/core/src/main/scala/spire/algebra/GCDRing.scala +++ /dev/null @@ -1,59 +0,0 @@ -/* - * **********************************************************************\ - * * Project ** - * * ______ ______ __ ______ ____ ** - * * / ____/ / __ / / / / __ / / __/ (c) 2011-2021 ** - * * / /__ / /_/ / / / / /_/ / / /_ ** - * * /___ / / ____/ / / / __ / / __/ Erik Osheim, Tom Switzer ** - * * ____/ / / / / / / / | | / /__ ** - * * /_____/ /_/ /_/ /_/ |_| /____/ All rights reserved. ** - * * ** - * * Redistribution and use permitted under the MIT license. ** - * * ** - * \*********************************************************************** - */ - -package spire.algebra - -import scala.{specialized => sp} - -/** - * 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) - * }}} - */ -trait GCDRing[@sp(Int, Long, Float, Double) A] extends Any with CRing[A] { - def gcd(a: A, b: A)(implicit ev: Eq[A]): A - def lcm(a: A, b: A)(implicit ev: Eq[A]): A -} - -trait GCDRingFunctions[R[T] <: GCDRing[T]] extends _root_.algebra.ring.RingFunctions[R] { - def gcd[@sp(Int, Long, Float, Double) A](a: A, b: A)(implicit ev: R[A], eqA: Eq[A]): A = - ev.gcd(a, b)(eqA) - def lcm[@sp(Int, Long, Float, Double) A](a: A, b: A)(implicit ev: R[A], eqA: Eq[A]): A = - ev.lcm(a, b)(eqA) -} - -object GCDRing extends GCDRingFunctions[GCDRing] { - @inline final def apply[A](implicit ev: GCDRing[A]): GCDRing[A] = ev -} diff --git a/core/src/main/scala/spire/algebra/IsReal.scala b/core/src/main/scala/spire/algebra/IsReal.scala index f2ecb628a..d2a327516 100644 --- a/core/src/main/scala/spire/algebra/IsReal.scala +++ b/core/src/main/scala/spire/algebra/IsReal.scala @@ -21,7 +21,7 @@ import spire.math.{Algebraic, Rational, Real} /** * A simple type class for numeric types that are a subset of the reals. */ -trait IsReal[@sp A] extends Any with Signed[A] { +trait IsReal[@sp A] extends Any with Order[A] with Signed[A] { /** * Rounds `a` the nearest integer that is greater than or equal to `a`. diff --git a/core/src/main/scala/spire/algebra/Sign.scala b/core/src/main/scala/spire/algebra/Sign.scala deleted file mode 100644 index e5fafcdff..000000000 --- a/core/src/main/scala/spire/algebra/Sign.scala +++ /dev/null @@ -1,69 +0,0 @@ -/* - * **********************************************************************\ - * * Project ** - * * ______ ______ __ ______ ____ ** - * * / ____/ / __ / / / / __ / / __/ (c) 2011-2021 ** - * * / /__ / /_/ / / / / /_/ / / /_ ** - * * /___ / / ____/ / / / __ / / __/ Erik Osheim, Tom Switzer ** - * * ____/ / / / / / / / | | / /__ ** - * * /_____/ /_/ /_/ /_/ |_| /____/ All rights reserved. ** - * * ** - * * Redistribution and use permitted under the MIT license. ** - * * ** - * \*********************************************************************** - */ - -package spire -package algebra - -/** - * A simple ADT representing the `Sign` of an object. - */ -sealed abstract class Sign(val toInt: Int) { - import Sign._ - - def unary_- : Sign = this match { - case Positive => Negative - case Negative => Positive - case Zero => Zero - } - - def *(that: Sign): Sign = Sign(this.toInt * that.toInt) - - def **(that: Int): Sign = Sign(spire.math.pow(this.toInt, that).toInt) -} - -object Sign { - case object Zero extends Sign(0) - case object Positive extends Sign(1) - case object Negative extends Sign(-1) - - implicit def sign2int(s: Sign): Int = s.toInt - implicit def apply(i: Int): Sign = - if (i == 0) Zero else if (i > 0) Positive else Negative - - class SignAlgebra extends CMonoid[Sign] with Signed[Sign] { - def empty: Sign = Positive - def combine(a: Sign, b: Sign): Sign = a * b - // the Signum instance is slightly abusive, as Sign doesn't provide an additive monoid - override def sign(a: Sign): Sign = a - def signum(a: Sign): Int = a.toInt - def abs(a: Sign): Sign = if (a == Negative) Positive else a - def compare(x: Sign, y: Sign): Int = java.lang.Integer.signum(x.toInt - y.toInt) - } - - implicit final val SignAlgebra: CMonoid[Sign] with Signed[Sign] = new SignAlgebra - - implicit final val SignMultiplicativeGroup: MultiplicativeCMonoid[Sign] = - Multiplicative(SignAlgebra) - - implicit def SignAction[A](implicit A: AdditiveGroup[A]): MultiplicativeAction[A, Sign] = - new MultiplicativeAction[A, Sign] { - def gtimesl(s: Sign, a: A): A = s match { - case Positive => a - case Negative => A.negate(a) - case Zero => A.zero - } - def gtimesr(a: A, s: Sign): A = gtimesl(s, a) - } -} diff --git a/core/src/main/scala/spire/algebra/Signed.scala b/core/src/main/scala/spire/algebra/Signed.scala deleted file mode 100644 index 0abc87baf..000000000 --- a/core/src/main/scala/spire/algebra/Signed.scala +++ /dev/null @@ -1,92 +0,0 @@ -/* - * **********************************************************************\ - * * Project ** - * * ______ ______ __ ______ ____ ** - * * / ____/ / __ / / / / __ / / __/ (c) 2011-2021 ** - * * / /__ / /_/ / / / / /_/ / / /_ ** - * * /___ / / ____/ / / / __ / / __/ Erik Osheim, Tom Switzer ** - * * ____/ / / / / / / / | | / /__ ** - * * /_____/ /_/ /_/ /_/ |_| /____/ All rights reserved. ** - * * ** - * * Redistribution and use permitted under the MIT license. ** - * * ** - * \*********************************************************************** - */ - -package spire -package algebra - -/** - * 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?). - */ -trait Signed[@sp(Byte, Short, Int, Long, Float, Double) A] extends Any with Order[A] { - - /** - * Returns Zero if `a` is 0, Positive if `a` is positive, and Negative is `a` is negative. - */ - def sign(a: A): Sign = Sign(signum(a)) - - /** - * Returns 0 if `a` is 0, 1 if `a` is positive, and -1 is `a` is negative. - */ - def signum(a: A): Int - - /** - * An idempotent function that ensures an object has a non-negative sign. - */ - def abs(a: A): A - - def isSignZero(a: A): Boolean = signum(a) == 0 - def isSignPositive(a: A): Boolean = signum(a) > 0 - def isSignNegative(a: A): Boolean = signum(a) < 0 - - def isSignNonZero(a: A): Boolean = signum(a) != 0 - def isSignNonPositive(a: A): Boolean = signum(a) <= 0 - def isSignNonNegative(a: A): Boolean = signum(a) >= 0 -} - -trait SignedAdditiveCMonoid[@sp(Byte, Short, Int, Long, Float, Double) A] - extends Any - with Signed[A] - with AdditiveCMonoid[A] { - - /** - * Returns 0 if `a` is 0, 1 if `a` is positive, and -1 is `a` is negative. - */ - def signum(a: A): Int = { - val c = compare(a, zero) - if (c < 0) -1 - else if (c > 0) 1 - else 0 - } -} - -trait SignedAdditiveAbGroup[@sp(Byte, Short, Int, Long, Float, Double) A] - extends Any - with SignedAdditiveCMonoid[A] - with AdditiveAbGroup[A] { - def abs(a: A): A = if (compare(a, zero) < 0) negate(a) else a -} - -object Signed { - def apply[A](implicit s: Signed[A]): Signed[A] = s -} diff --git a/core/src/main/scala/spire/algebra/TruncatedDivision.scala b/core/src/main/scala/spire/algebra/TruncatedDivision.scala deleted file mode 100644 index 6256bad6b..000000000 --- a/core/src/main/scala/spire/algebra/TruncatedDivision.scala +++ /dev/null @@ -1,101 +0,0 @@ -/* - * **********************************************************************\ - * * Project ** - * * ______ ______ __ ______ ____ ** - * * / ____/ / __ / / / / __ / / __/ (c) 2011-2021 ** - * * / /__ / /_/ / / / / /_/ / / /_ ** - * * /___ / / ____/ / / / __ / / __/ Erik Osheim, Tom Switzer ** - * * ____/ / / / / / / / | | / /__ ** - * * /_____/ /_/ /_/ /_/ |_| /____/ All rights reserved. ** - * * ** - * * Redistribution and use permitted under the MIT license. ** - * * ** - * \*********************************************************************** - */ - -package spire -package algebra - -import spire.util.Opt - -/** - * Division and modulus for computer scientists taken from - * https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/divmodnote-letter.pdf - * - * For two numbers x (dividend) and y (divisor) on an ordered ring with y != 0, there exists a pair of numbers q - * (quotient) and r (remainder) such that these laws are satisfied: - * - * {{{ - * (1) q is an integer - * (2) x = y * q + r (division rule) - * (3) |r| < |y| - * (4t) r = 0 or sign(r) = sign(x) - * (4f) r = 0 or sign(r) = sign(y). - * }}} - * - * where sign is the sign function, and the absolute value function |x| is defined as |x| = x if x >=0, and |x| = -x - * otherwise. - * - * We define functions tmod and tquot such that: - * {{{ - * q = tquot(x, y) and r = tmod(x, y) obey rule (4t), - * (whichtruncates effectively towards zero) and functions fmod and fquot such that: - * q = fquot(x, y) and r = fmod(x, y) obey rule (4f) - * (which floors the quotient and effectively rounds towards negative infinity). - * }}} - * - * Law (4t) corresponds to ISO C99 and Haskell's quot/rem. - * - * Law (4f) is described by Knuth and used by Haskell, and fmod corresponds to the REM function of the IEEE - * floating-point standard. - */ -trait TruncatedDivision[@sp(Byte, Short, Int, Long, Float, Double) A] extends Any with Signed[A] { - - /** - * Returns the integer `a` such that `x = a * one`, if it exists. - */ - def toBigIntOpt(x: A): Opt[BigInt] - - def tquot(x: A, y: A): A - def tmod(x: A, y: A): A - def tquotmod(x: A, y: A): (A, A) = (tquot(x, y), tmod(x, y)) - - def fquot(x: A, y: A): A - def fmod(x: A, y: A): A - def fquotmod(x: A, y: A): (A, A) = (fquot(x, y), fmod(x, y)) -} - -trait TruncatedDivisionCRing[@sp(Byte, Short, Int, Long, Float, Double) A] - extends Any - with TruncatedDivision[A] - with CRing[A] { self => - - def fmod(x: A, y: A): A = { - val tm = tmod(x, y) - if (signum(tm) == -signum(y)) plus(tm, y) else tm - } - - def fquot(x: A, y: A): A = { - val (tq, tm) = tquotmod(x, y) - if (signum(tm) == -signum(y)) minus(tq, one) else tq - } - - override def fquotmod(x: A, y: A): (A, A) = { - val (tq, tm) = tquotmod(x, y) - TruncatedDivision.fquotmodFromTquotmod(x, y, tq, tm)(self, self) - } - -} - -object TruncatedDivision { - - def fquotmodFromTquotmod[A: CRing: Signed](x: A, y: A, tquot: A, tmod: A): (A, A) = { - val signsDiffer = Signed[A].signum(tmod) == -Signed[A].signum(y) - val fquot = if (signsDiffer) CRing[A].minus(tquot, CRing[A].one) else tquot - val fmod = if (signsDiffer) CRing[A].plus(tmod, y) else tmod - (fquot, fmod) - } - - def apply[A](implicit ev: TruncatedDivision[A]): TruncatedDivision[A] = ev - -} diff --git a/core/src/main/scala/spire/algebra/UniqueFactorizationDomain.scala b/core/src/main/scala/spire/algebra/UniqueFactorizationDomain.scala index d19301d29..6f71ca5d6 100644 --- a/core/src/main/scala/spire/algebra/UniqueFactorizationDomain.scala +++ b/core/src/main/scala/spire/algebra/UniqueFactorizationDomain.scala @@ -52,9 +52,9 @@ object UniqueFactorizationDomain { case class WrapDecomposition[A: CRing](safeLongFactors: spire.math.prime.Factors) extends Decomposition[A] { def unit: A = safeLongFactors.sign match { - case Sign.Negative => CRing[A].negate(CRing[A].one) - case Sign.Positive => CRing[A].one - case _ => throw new ArithmeticException("Factorization of zero is undefined.") + case Signed.Negative => CRing[A].negate(CRing[A].one) + case Signed.Positive => CRing[A].one + case _ => throw new ArithmeticException("Factorization of zero is undefined.") } override def elements: Map[A, Int] = safeLongFactors.elements.map { case (f, exp) => ((CRing[A].fromBigInt(f.toBigInt), exp)) diff --git a/core/src/main/scala/spire/algebra/package.scala b/core/src/main/scala/spire/algebra/package.scala index 43eb2e23d..3df0f7989 100644 --- a/core/src/main/scala/spire/algebra/package.scala +++ b/core/src/main/scala/spire/algebra/package.scala @@ -172,8 +172,31 @@ package object algebra { type CRing[A] = _root_.algebra.ring.CommutativeRing[A] val CRing = _root_.algebra.ring.CommutativeRing - type AlgebraField[A] = _root_.algebra.ring.Field[A] - val AlgebraField = _root_.algebra.ring.Field + type GCDRing[A] = _root_.algebra.ring.GCDRing[A] + val GCDRing = _root_.algebra.ring.GCDRing + + type EuclideanRing[A] = _root_.algebra.ring.EuclideanRing[A] + val EuclideanRing = _root_.algebra.ring.EuclideanRing + + type Sign = _root_.algebra.ring.Signed.Sign + val Sign = _root_.algebra.ring.Signed.Sign + + type Signed[A] = _root_.algebra.ring.Signed[A] + val Signed = _root_.algebra.ring.Signed + + type SignedAdditiveCMonoid[A] = _root_.algebra.ring.Signed.forAdditiveCommutativeMonoid[A] + type SignedAdditiveAbGroup[A] = _root_.algebra.ring.Signed.forAdditiveCommutativeGroup[A] + + type TruncatedDivision[A] = _root_.algebra.ring.TruncatedDivision[A] + val TruncatedDivision = _root_.algebra.ring.TruncatedDivision + + type TruncatedDivisionCRing[A] = _root_.algebra.ring.TruncatedDivision.forCommutativeRing[A] + + type DivisionRing[A] = _root_.algebra.ring.DivisionRing[A] + val DivisionRing = _root_.algebra.ring.DivisionRing + + type Field[A] = _root_.algebra.ring.Field[A] + val Field = _root_.algebra.ring.Field type Bool[A] = _root_.algebra.lattice.Bool[A] val Bool = _root_.algebra.lattice.Bool diff --git a/core/src/main/scala/spire/math/Algebraic.scala b/core/src/main/scala/spire/math/Algebraic.scala index 8ca490701..7804f8317 100644 --- a/core/src/main/scala/spire/math/Algebraic.scala +++ b/core/src/main/scala/spire/math/Algebraic.scala @@ -23,7 +23,7 @@ import java.util.concurrent.atomic.AtomicReference import scala.math.{ScalaNumber, ScalaNumericConversions} import spire.Platform -import spire.algebra.{Eq, Field, IsAlgebraic, NRoot, Sign, TruncatedDivisionCRing} +import spire.algebra.{Eq, Field, IsAlgebraic, NRoot, Order, Sign, TruncatedDivisionCRing} import spire.macros.Checked.checked import spire.math.poly.{BigDecimalRootRefinement, RootFinder, Roots, Term} import spire.std.bigInt._ @@ -1549,16 +1549,15 @@ object Algebraic extends AlgebraicInstances { } trait AlgebraicInstances { - implicit final val AlgebraicAlgebra: Field.WithDefaultGCD[Algebraic] - with NRoot[Algebraic] - with IsAlgebraic[Algebraic] - with TruncatedDivisionCRing[Algebraic] = new AlgebraicAlgebra + implicit final val AlgebraicAlgebra + : Field[Algebraic] with NRoot[Algebraic] with IsAlgebraic[Algebraic] with TruncatedDivisionCRing[Algebraic] = + new AlgebraicAlgebra import NumberTag._ implicit final val AlgebraicTag: NumberTag[Algebraic] = new LargeTag[Algebraic](Exact, Algebraic(0)) } -private[math] trait AlgebraicIsField extends Field.WithDefaultGCD[Algebraic] { +private[math] trait AlgebraicIsField extends Field[Algebraic] { def zero: Algebraic = Algebraic.Zero def one: Algebraic = Algebraic.One def plus(a: Algebraic, b: Algebraic): Algebraic = a + b @@ -1579,7 +1578,11 @@ private[math] trait AlgebraicIsField extends Field.WithDefaultGCD[Algebraic] { private[math] trait AlgebraicIsNRoot extends NRoot[Algebraic] -private[math] trait AlgebraicIsReal extends IsAlgebraic[Algebraic] with TruncatedDivisionCRing[Algebraic] { +private[math] trait AlgebraicIsReal + extends IsAlgebraic[Algebraic] + with TruncatedDivisionCRing[Algebraic] + with Order[Algebraic] { + def order = this def toDouble(x: Algebraic): Double = x.toDouble def toAlgebraic(x: Algebraic): Algebraic = x def ceil(a: Algebraic): Algebraic = Algebraic(a.toBigDecimal(0, RoundingMode.CEILING)) diff --git a/core/src/main/scala/spire/math/Complex.scala b/core/src/main/scala/spire/math/Complex.scala index eac427247..ffa3302b5 100644 --- a/core/src/main/scala/spire/math/Complex.scala +++ b/core/src/main/scala/spire/math/Complex.scala @@ -117,22 +117,22 @@ final case class Complex[@sp(Float, Double) T](real: T, imag: T) * * `sgn(z) = z / abs(z) = abs(z) / z` */ - def complexSignum(implicit f: Field[T], n: NRoot[T], s: Signed[T]): Complex[T] = + def complexSignum(implicit f: Field[T], n: NRoot[T], o: Order[T], s: Signed[T]): Complex[T] = if (isZero) this else this / abs - def abs(implicit f: Field[T], n: NRoot[T], s: Signed[T]): T = hypot(real, imag) + def abs(implicit f: Field[T], n: NRoot[T], o: Order[T], s: Signed[T]): T = hypot(real, imag) def absSquare(implicit r: CRing[T]): T = real * real + imag * imag def arg(implicit f: Field[T], s: Signed[T], t: Trig[T]): T = if (isZero) f.zero else t.atan2(imag, real) - def norm(implicit f: Field[T], n: NRoot[T], s: Signed[T]): T = hypot(real, imag) + def norm(implicit f: Field[T], n: NRoot[T], o: Order[T], s: Signed[T]): T = hypot(real, imag) def conjugate(implicit f: CRing[T]): Complex[T] = new Complex(real, -imag) def asTuple: (T, T) = (real, imag) - def asPolarTuple(implicit f: Field[T], n: NRoot[T], s: Signed[T], t: Trig[T]): (T, T) = (abs, arg) + def asPolarTuple(implicit f: Field[T], n: NRoot[T], o: Order[T], s: Signed[T], t: Trig[T]): (T, T) = (abs, arg) def isZero(implicit s: Signed[T]): Boolean = real.isSignZero && imag.isSignZero def isImaginary(implicit s: Signed[T]): Boolean = real.isSignZero @@ -159,8 +159,8 @@ final case class Complex[@sp(Float, Double) T](real: T, imag: T) } */ - def **(e: T)(implicit f: Field[T], n: NRoot[T], s: Signed[T], t: Trig[T]): Complex[T] = this.pow(e) - def pow(e: T)(implicit f: Field[T], n: NRoot[T], s: Signed[T], t: Trig[T]): Complex[T] = + def **(e: T)(implicit f: Field[T], n: NRoot[T], o: Order[T], s: Signed[T], t: Trig[T]): Complex[T] = this.pow(e) + def pow(e: T)(implicit f: Field[T], n: NRoot[T], o: Order[T], s: Signed[T], t: Trig[T]): Complex[T] = if (e.isSignZero) { Complex.one[T] } else if (this.isZero) { @@ -180,7 +180,7 @@ final case class Complex[@sp(Float, Double) T](real: T, imag: T) def *(b: Complex[T])(implicit r: CRing[T]): Complex[T] = new Complex(real * b.real - imag * b.imag, imag * b.real + real * b.imag) - def /(b: Complex[T])(implicit f: Field[T], s: Signed[T]): Complex[T] = { + def /(b: Complex[T])(implicit f: Field[T], o: Order[T], s: Signed[T]): Complex[T] = { val abs_breal = b.real.abs val abs_bimag = b.imag.abs @@ -212,17 +212,17 @@ final case class Complex[@sp(Float, Double) T](real: T, imag: T) } */ - def **(b: Int)(implicit f: Field[T], n: NRoot[T], s: Signed[T], t: Trig[T]): Complex[T] = pow(b) + def **(b: Int)(implicit f: Field[T], n: NRoot[T], o: Order[T], s: Signed[T], t: Trig[T]): Complex[T] = pow(b) - def nroot(k: Int)(implicit f: Field[T], n: NRoot[T], s: Signed[T], t: Trig[T]): Complex[T] = + def nroot(k: Int)(implicit f: Field[T], n: NRoot[T], o: Order[T], s: Signed[T], t: Trig[T]): Complex[T] = if (isZero) Complex.zero else pow(Complex(f.fromInt(k).reciprocal, f.zero)) - def pow(b: Int)(implicit f: Field[T], n: NRoot[T], s: Signed[T], t: Trig[T]): Complex[T] = + def pow(b: Int)(implicit f: Field[T], n: NRoot[T], o: Order[T], s: Signed[T], t: Trig[T]): Complex[T] = if (isZero) Complex.zero else Complex.polar(abs.pow(b), arg * b) - def **(b: Complex[T])(implicit f: Field[T], n: NRoot[T], s: Signed[T], t: Trig[T]): Complex[T] = pow(b) + def **(b: Complex[T])(implicit f: Field[T], n: NRoot[T], o: Order[T], s: Signed[T], t: Trig[T]): Complex[T] = pow(b) - def pow(b: Complex[T])(implicit f: Field[T], n: NRoot[T], s: Signed[T], t: Trig[T]): Complex[T] = + def pow(b: Complex[T])(implicit f: Field[T], n: NRoot[T], o: Order[T], s: Signed[T], t: Trig[T]): Complex[T] = if (b.isZero) { Complex.one[T] } else if (this.isZero) { @@ -238,13 +238,13 @@ final case class Complex[@sp(Float, Double) T](real: T, imag: T) } // we are going with the "principal value" definition of Log. - def log(implicit f: Field[T], n: NRoot[T], t: Trig[T], s: Signed[T]): Complex[T] = { + def log(implicit f: Field[T], n: NRoot[T], o: Order[T], t: Trig[T], s: Signed[T]): Complex[T] = { if (isZero) throw new IllegalArgumentException("log(0) undefined") new Complex(t.log(abs), arg) } // returns the root with angle in (-pi/2, pi/2] - def sqrt(implicit f: Field[T], n0: NRoot[T], s: Signed[T]): Complex[T] = { + def sqrt(implicit f: Field[T], n0: NRoot[T], o: Order[T], s: Signed[T]): Complex[T] = { if (isZero) { this } else if (imag.isSignZero) { @@ -270,7 +270,7 @@ final case class Complex[@sp(Float, Double) T](real: T, imag: T) def round(implicit o: IsReal[T]): Complex[T] = new Complex(real.round, imag.round) // acos(z) = -i*(log(z + i*(sqrt(1 - z*z)))) - def acos(implicit f: Field[T], n: NRoot[T], t: Trig[T], s0: Signed[T]): Complex[T] = { + def acos(implicit f: Field[T], n: NRoot[T], o: Order[T], t: Trig[T], s0: Signed[T]): Complex[T] = { val z2 = this * this val s = new Complex(f.one - z2.real, -z2.imag).sqrt val l = new Complex(real + s.imag, imag + s.real).log @@ -278,7 +278,7 @@ final case class Complex[@sp(Float, Double) T](real: T, imag: T) } // asin(z) = -i*(log(sqrt(1 - z*z) + i*z)) - def asin(implicit f: Field[T], n: NRoot[T], t: Trig[T], s0: Signed[T]): Complex[T] = { + def asin(implicit f: Field[T], n: NRoot[T], o: Order[T], t: Trig[T], s0: Signed[T]): Complex[T] = { val z2 = this * this val s = new Complex(f.one - z2.real, -z2.imag).sqrt val l = new Complex(s.real + -imag, s.imag + real).log @@ -286,7 +286,7 @@ final case class Complex[@sp(Float, Double) T](real: T, imag: T) } // atan(z) = (i/2) log((i + z)/(i - z)) - def atan(implicit f: Field[T], r: NRoot[T], t: Trig[T], s0: Signed[T]): Complex[T] = { + def atan(implicit f: Field[T], o: Order[T], r: NRoot[T], s: Signed[T], t: Trig[T]): Complex[T] = { val n = new Complex(real, imag + f.one) val d = new Complex(-real, f.one - imag) val l = (n / d).log @@ -376,11 +376,11 @@ trait ComplexInstances0 { } trait ComplexInstances1 extends ComplexInstances0 { - implicit def ComplexOnField[A: Field: Signed]: ComplexOnField[A] = new ComplexOnFieldImpl[A] + implicit def ComplexOnField[A: Field: Order: Signed]: ComplexOnField[A] = new ComplexOnFieldImpl[A] } trait ComplexInstances extends ComplexInstances1 { - implicit def ComplexOnTrig[@sp(Float, Double) A: Fractional: Trig: Signed]: ComplexOnTrigImpl[A] = + implicit def ComplexOnTrig[@sp(Float, Double) A: Fractional: Order: Trig: Signed]: ComplexOnTrigImpl[A] = new ComplexOnTrigImpl[A] implicit def ComplexEq[A: Eq]: Eq[Complex[A]] = new ComplexEq[A] @@ -406,11 +406,12 @@ private[math] trait ComplexOnCRing[@sp(Float, Double) A] private[math] trait ComplexOnField[@sp(Float, Double) A] extends ComplexOnCRing[A] - with Field.WithDefaultGCD[Complex[A]] + with Field[Complex[A]] with FieldAssociativeAlgebra[Complex[A], A] { implicit def scalar: Field[A] implicit def signed: Signed[A] + implicit def order: Order[A] override def fromDouble(n: Double): Complex[A] = Complex(scalar.fromDouble(n)) def div(a: Complex[A], b: Complex[A]): Complex[A] = a / b @@ -419,6 +420,7 @@ private[math] trait ComplexOnField[@sp(Float, Double) A] private[math] trait ComplexOnTrig[@sp(Float, Double) A] extends Trig[Complex[A]] { implicit def scalar: Field[A] implicit def nroot: NRoot[A] + implicit def order: Order[A] implicit def trig: Trig[A] implicit def signed: Signed[A] @@ -451,6 +453,7 @@ private[math] trait ComplexOnTrig[@sp(Float, Double) A] extends Trig[Complex[A]] private[math] trait ComplexIsNRoot[A] extends NRoot[Complex[A]] { implicit def scalar: Field[A] implicit def nroot: NRoot[A] + implicit def order: Order[A] implicit def trig: Trig[A] implicit def signed: Signed[A] @@ -471,14 +474,18 @@ final private[math] class ComplexOnCRingImpl[@sp(Float, Double) A](implicit val with Serializable @SerialVersionUID(1L) -final private[math] class ComplexOnFieldImpl[@sp(Float, Double) A](implicit val scalar: Field[A], val signed: Signed[A]) - extends ComplexOnField[A] +final private[math] class ComplexOnFieldImpl[@sp(Float, Double) A](implicit + val scalar: Field[A], + val order: Order[A], + val signed: Signed[A] +) extends ComplexOnField[A] with Serializable @SerialVersionUID(1L) private[math] class ComplexOnTrigImpl[@sp(Float, Double) A](implicit val scalar: Field[A], val nroot: NRoot[A], + val order: Order[A], val trig: Trig[A], val signed: Signed[A] ) extends ComplexOnField[A] diff --git a/core/src/main/scala/spire/math/Fractional.scala b/core/src/main/scala/spire/math/Fractional.scala index b2f526a8a..ac422e7c1 100644 --- a/core/src/main/scala/spire/math/Fractional.scala +++ b/core/src/main/scala/spire/math/Fractional.scala @@ -16,10 +16,10 @@ package spire package math -import spire.algebra.{Field, NRoot} +import spire.algebra.{Field, NRoot, Order} import spire.std._ -trait Fractional[@sp(Float, Double) A] extends Any with Field[A] with NRoot[A] with Integral[A] +trait Fractional[@sp(Float, Double) A] extends Any with Field[A] with NRoot[A] with Integral[A] with Order[A] object Fractional { implicit final val FloatIsFractional: Fractional[Float] = new FloatIsFractional diff --git a/core/src/main/scala/spire/math/Integral.scala b/core/src/main/scala/spire/math/Integral.scala index 850fecfcf..ec448a0b9 100644 --- a/core/src/main/scala/spire/math/Integral.scala +++ b/core/src/main/scala/spire/math/Integral.scala @@ -16,7 +16,7 @@ package spire package math -import spire.algebra.{EuclideanRing, IsReal} +import spire.algebra.{EuclideanRing, IsReal, Order} import spire.std._ /** @@ -28,6 +28,7 @@ trait Integral[@sp(Int, Long) A] with ConvertableFrom[A] with ConvertableTo[A] with IsReal[A] + with Order[A] object Integral { implicit final val ByteIsIntegral: Integral[Byte] = new ByteIsIntegral diff --git a/core/src/main/scala/spire/math/Jet.scala b/core/src/main/scala/spire/math/Jet.scala index 9909d24fe..1593d48b1 100644 --- a/core/src/main/scala/spire/math/Jet.scala +++ b/core/src/main/scala/spire/math/Jet.scala @@ -281,13 +281,22 @@ final case class Jet[@sp(Float, Double) T](real: T, infinitesimal: Array[T]) def **(b: Int)(implicit f: Field[T], v: VectorSpace[Array[T], T]): Jet[T] = pow(b) - def nroot(k: Int)(implicit f: Field[T], s: Signed[T], t: Trig[T], v: VectorSpace[Array[T], T]): Jet[T] = { + def nroot( + k: Int + )(implicit f: Field[T], o: Order[T], s: Signed[T], t: Trig[T], v: VectorSpace[Array[T], T]): Jet[T] = { pow(f.fromInt(k).reciprocal) } def **( b: Jet[T] - )(implicit c: ClassTag[T], f: Field[T], s: Signed[T], t: Trig[T], v: VectorSpace[Array[T], T]): Jet[T] = { + )(implicit + c: ClassTag[T], + f: Field[T], + o: Order[T], + s: Signed[T], + t: Trig[T], + v: VectorSpace[Array[T], T] + ): Jet[T] = { pow(b) } @@ -309,13 +318,13 @@ final case class Jet[@sp(Float, Double) T](real: T, infinitesimal: Array[T]) /** * abs(x + du) ~= x + du or -(x + du) */ - def abs(implicit f: Field[T], s: Signed[T], v: VectorSpace[Array[T], T]): Jet[T] = { + def abs(implicit f: Field[T], o: Order[T], s: Signed[T], v: VectorSpace[Array[T], T]): Jet[T] = { if (real < f.zero) new Jet(-real, -infinitesimal) else this } // spire.math. does not define this pow generically, so there it is - private def powScalarToScalar(b: T, e: T)(implicit f: Field[T], s: Signed[T], t: Trig[T]): T = { + private def powScalarToScalar(b: T, e: T)(implicit f: Field[T], o: Order[T], s: Signed[T], t: Trig[T]): T = { if (e === f.zero) { f.one } else if (b === f.zero) { @@ -330,7 +339,7 @@ final case class Jet[@sp(Float, Double) T](real: T, infinitesimal: Array[T]) // b^(p + du) ~= b^p + b^p * log(b) du def powScalarToJet( a: T - )(implicit c: ClassTag[T], f: Field[T], m: CModule[Array[T], T], s: Signed[T], t: Trig[T]): Jet[T] = { + )(implicit c: ClassTag[T], f: Field[T], m: CModule[Array[T], T], o: Order[T], s: Signed[T], t: Trig[T]): Jet[T] = { if (isZero) { Jet.one[T] } else { @@ -345,7 +354,7 @@ final case class Jet[@sp(Float, Double) T](real: T, infinitesimal: Array[T]) * pow(a + du, p) ~= pow(a, p) + p * pow(a, p-1) du * }}} */ - def pow(p: T)(implicit f: Field[T], s: Signed[T], t: Trig[T], v: VectorSpace[Array[T], T]): Jet[T] = { + def pow(p: T)(implicit f: Field[T], o: Order[T], s: Signed[T], t: Trig[T], v: VectorSpace[Array[T], T]): Jet[T] = { val tmp: T = p * powScalarToScalar(real, p - f.one) new Jet(powScalarToScalar(real, p), tmp *: infinitesimal) } @@ -364,7 +373,7 @@ final case class Jet[@sp(Float, Double) T](real: T, infinitesimal: Array[T]) */ def pow( b: Jet[T] - )(implicit c: ClassTag[T], f: Field[T], m: CModule[Array[T], T], s: Signed[T], t: Trig[T]): Jet[T] = { + )(implicit c: ClassTag[T], f: Field[T], m: CModule[Array[T], T], o: Order[T], s: Signed[T], t: Trig[T]): Jet[T] = { if (b.isZero) { Jet.one[T] } else { @@ -520,6 +529,7 @@ trait JetInstances { d: JetDim, f: Field[T], n: NRoot[T], + o: Order[T], s: Signed[T], t: Trig[T] ): JetAlgebra[T] = { @@ -570,7 +580,7 @@ private[math] trait JetIsEuclideanRing[@sp(Float, Double) T] extends JetIsGCDRin } /* TODO: Jet[T] is probably not a genuine Field */ -private[math] trait JetIsField[@sp(Float, Double) T] extends JetIsEuclideanRing[T] with Field.WithDefaultGCD[Jet[T]] { +private[math] trait JetIsField[@sp(Float, Double) T] extends JetIsEuclideanRing[T] with Field[Jet[T]] { /* TODO: what are exactly the laws of Jet with respect to EuclideanRing ? */ // duplicating methods because super[..].call does not work on 2.10 and 2.11 override def fromDouble(n: Double): Jet[T] = Jet(f.fromDouble(n)) @@ -614,6 +624,7 @@ private[math] trait JetIsTrig[@sp(Float, Double) T] extends Trig[Jet[T]] { private[math] trait JetIsNRoot[T] extends NRoot[Jet[T]] { implicit def f: Field[T] implicit def n: NRoot[T] + implicit def o: Order[T] implicit def t: Trig[T] implicit def s: Signed[T] implicit def c: ClassTag[T] @@ -651,6 +662,7 @@ private[math] class JetAlgebra[@sp(Float, Double) T](implicit val eq: Eq[T], val f: Field[T], val n: NRoot[T], + val o: Order[T], val t: Trig[T], val s: Signed[T], val v: VectorSpace[Array[T], T] diff --git a/core/src/main/scala/spire/math/Natural.scala b/core/src/main/scala/spire/math/Natural.scala index 7687bd719..79fa512d9 100644 --- a/core/src/main/scala/spire/math/Natural.scala +++ b/core/src/main/scala/spire/math/Natural.scala @@ -760,6 +760,7 @@ private[math] trait NaturalOrder extends Order[Natural] { } private[math] trait NaturalSigned extends NaturalOrder with SignedAdditiveCMonoid[Natural] { + def order = this def abs(x: Natural): Natural = x } diff --git a/core/src/main/scala/spire/math/Number.scala b/core/src/main/scala/spire/math/Number.scala index 8e4e9bffb..f1a6f58f2 100644 --- a/core/src/main/scala/spire/math/Number.scala +++ b/core/src/main/scala/spire/math/Number.scala @@ -624,7 +624,7 @@ private[math] case class RationalNumber(n: Rational) extends Number { lhs => } trait NumberInstances { - implicit final val NumberAlgebra: Field.WithDefaultGCD[Number] + implicit final val NumberAlgebra: Field[Number] with CRing[Number] with NRoot[Number] with Trig[Number] @@ -653,7 +653,7 @@ private[math] trait NumberIsGCDRing extends GCDRing[Number] with NumberIsCRing { } */ -private[math] trait NumberIsField extends Field.WithDefaultGCD[Number] with NumberIsCRing { +private[math] trait NumberIsField extends Field[Number] with NumberIsCRing { def div(a: Number, b: Number): Number = a / b override def fromDouble(a: Double): Number = Number(a) } @@ -701,6 +701,7 @@ private[math] trait NumberOrder extends Order[Number] { } private[math] trait NumberSigned extends Signed[Number] with NumberOrder { + def order = this override def signum(a: Number): Int = a.signum override def abs(a: Number): Number = a.abs } diff --git a/core/src/main/scala/spire/math/Polynomial.scala b/core/src/main/scala/spire/math/Polynomial.scala index 4b88bdc1f..e27c981e0 100644 --- a/core/src/main/scala/spire/math/Polynomial.scala +++ b/core/src/main/scala/spire/math/Polynomial.scala @@ -380,12 +380,12 @@ trait Polynomial[@sp(Double) C] { lhs => * Returns the number of sign variations in the coefficients of this polynomial. Given 2 consecutive terms (ignoring 0 * terms), a sign variation is indicated when the terms have differing signs. */ - def signVariations(implicit ring: Semiring[C], signed: Signed[C]): Int = { - var prevSign: Sign = Sign.Zero + def signVariations(implicit ring: Semiring[C], order: Order[C], signed: Signed[C]): Int = { + var prevSign: Sign = Signed.Zero var variations = 0 foreachNonZero { (_, c) => val sign = signed.sign(c) - if (Sign.Zero != prevSign && sign != prevSign) { + if (Signed.Zero != prevSign && sign != prevSign) { variations += 1 } prevSign = sign @@ -553,7 +553,7 @@ trait PolynomialOverCRing[@sp(Double) C] trait PolynomialOverField[@sp(Double) C] extends PolynomialOverRing[C] - with EuclideanRing.WithEuclideanAlgorithm[Polynomial[C]] + with EuclideanRing[Polynomial[C]] with VectorSpace[Polynomial[C], C] with FieldAssociativeAlgebra[Polynomial[C], C] { self => implicit override val scalar: Field[C] diff --git a/core/src/main/scala/spire/math/Quaternion.scala b/core/src/main/scala/spire/math/Quaternion.scala index cee1ee416..fc980d444 100644 --- a/core/src/main/scala/spire/math/Quaternion.scala +++ b/core/src/main/scala/spire/math/Quaternion.scala @@ -224,7 +224,7 @@ final case class Quaternion[@sp(Float, Double) A](r: A, i: A, j: A, k: A) Quaternion(f.zero, r.abs.sqrt, f.zero, f.zero) } - def nroot(m: Int)(implicit f: Field[A], nr: NRoot[A], si: Signed[A], tr: Trig[A]): Quaternion[A] = + def nroot(m: Int)(implicit f: Field[A], nr: NRoot[A], or: Order[A], si: Signed[A], tr: Trig[A]): Quaternion[A] = if (m <= 0) { throw new IllegalArgumentException(s"illegal root: $m") } else if (m == 1) { @@ -295,7 +295,7 @@ final case class Quaternion[@sp(Float, Double) A](r: A, i: A, j: A, k: A) def **(k: Int)(implicit s: CRing[A]): Quaternion[A] = pow(k) - def fpow(k0: A)(implicit f: Field[A], nr: NRoot[A], si: Signed[A], tr: Trig[A]): Quaternion[A] = + def fpow(k0: A)(implicit f: Field[A], nr: NRoot[A], or: Order[A], si: Signed[A], tr: Trig[A]): Quaternion[A] = if (k0.signum < 0) { Quaternion.zero } else if (k0 == f.zero) { diff --git a/core/src/main/scala/spire/math/Rational.scala b/core/src/main/scala/spire/math/Rational.scala index 953111dfe..2e4dac22b 100644 --- a/core/src/main/scala/spire/math/Rational.scala +++ b/core/src/main/scala/spire/math/Rational.scala @@ -20,8 +20,8 @@ import scala.math.{ScalaNumber, ScalaNumericConversions} import java.math.{BigDecimal => JBigDecimal, BigInteger, MathContext, RoundingMode} -import spire.algebra.{Eq, Field, IsRational, NRoot, Sign, TruncatedDivisionCRing} -import spire.algebra.Sign.{Negative, Positive, Zero} +import spire.algebra.{Eq, Field, IsRational, NRoot, Order, Sign, TruncatedDivisionCRing} +import spire.algebra.Signed.{Negative, Positive, Zero} import spire.macros.Checked import spire.std.long.LongAlgebra import spire.std.double._ @@ -895,7 +895,8 @@ object Rational extends RationalInstances { } trait RationalInstances { - implicit final val RationalAlgebra: Field[Rational] with IsRational[Rational] with TruncatedDivisionCRing[Rational] = + implicit final val RationalAlgebra + : Field[Rational] with IsRational[Rational] with TruncatedDivisionCRing[Rational] with Order[Rational] = new RationalAlgebra import NumberTag._ implicit final val RationalTag: NumberTag[Rational] = new LargeTag[Rational](Exact, Rational.zero) @@ -930,7 +931,11 @@ private[math] trait RationalIsField extends Field[Rational] { def div(a: Rational, b: Rational): Rational = a / b } -private[math] trait RationalIsReal extends IsRational[Rational] with TruncatedDivisionCRing[Rational] { +private[math] trait RationalIsReal + extends IsRational[Rational] + with Order[Rational] + with TruncatedDivisionCRing[Rational] { + def order = this override def eqv(x: Rational, y: Rational): Boolean = x == y override def neqv(x: Rational, y: Rational): Boolean = x != y override def gt(x: Rational, y: Rational): Boolean = x > y diff --git a/core/src/main/scala/spire/math/Real.scala b/core/src/main/scala/spire/math/Real.scala index 1005a60ab..1240cf130 100644 --- a/core/src/main/scala/spire/math/Real.scala +++ b/core/src/main/scala/spire/math/Real.scala @@ -20,7 +20,7 @@ import scala.math.{ScalaNumber, ScalaNumericConversions} import scala.collection.immutable.LazyList import scala.collection.immutable.LazyList.#:: -import spire.algebra.{Field, Trig, TruncatedDivisionCRing} +import spire.algebra.{Field, Order, Trig, TruncatedDivisionCRing} import spire.syntax.nroot._ import spire.util.Opt import scala.annotation.nowarn @@ -591,7 +591,7 @@ object Real extends RealInstances { trait RealInstances { implicit final val algebra - : Fractional[Real] with TruncatedDivisionCRing[Real] with Trig[Real] with Field.WithDefaultGCD[Real] = + : Fractional[Real] with TruncatedDivisionCRing[Real] with Trig[Real] with Field[Real] with Order[Real] = new RealAlgebra import NumberTag._ implicit final val RealTag: NumberTag[Real] = new LargeTag[Real](Exact, Real.zero) @@ -604,7 +604,10 @@ trait RealIsFractional extends Fractional[Real] with TruncatedDivisionCRing[Real] with Trig[Real] - with Field.WithDefaultGCD[Real] { + with Field[Real] + with Order[Real] { + def order = this + override def abs(x: Real): Real = x.abs override def signum(x: Real): Int = x.signum diff --git a/core/src/main/scala/spire/math/SafeLong.scala b/core/src/main/scala/spire/math/SafeLong.scala index 9eda3100a..56a85a9bb 100644 --- a/core/src/main/scala/spire/math/SafeLong.scala +++ b/core/src/main/scala/spire/math/SafeLong.scala @@ -704,6 +704,8 @@ private[math] trait SafeLongOrder extends Order[SafeLong] { } private[math] trait SafeLongSigned extends Signed[SafeLong] with SafeLongOrder { + def order = this + def additiveCommutativeMonoid = SafeLong.SafeLongAlgebra override def signum(a: SafeLong): Int = a.signum override def abs(a: SafeLong): SafeLong = a.abs } diff --git a/core/src/main/scala/spire/math/UByte.scala b/core/src/main/scala/spire/math/UByte.scala index 7db00344c..f06ac489b 100644 --- a/core/src/main/scala/spire/math/UByte.scala +++ b/core/src/main/scala/spire/math/UByte.scala @@ -16,7 +16,7 @@ package spire package math -import spire.algebra.{CRig, IsIntegral, SignedAdditiveCMonoid, TruncatedDivision} +import spire.algebra.{CRig, IsIntegral, Order, SignedAdditiveCMonoid, TruncatedDivision} import spire.util.Opt object UByte extends UByteInstances { @@ -87,8 +87,11 @@ class UByte(val signed: Byte) extends AnyVal with scala.math.ScalaNumericAnyConv } trait UByteInstances { - implicit final val UByteAlgebra - : CRig[UByte] with IsIntegral[UByte] with TruncatedDivision[UByte] with SignedAdditiveCMonoid[UByte] = + implicit final val UByteAlgebra: CRig[UByte] + with IsIntegral[UByte] + with TruncatedDivision[UByte] + with SignedAdditiveCMonoid[UByte] + with Order[UByte] = new UByteAlgebra implicit final val UByteBitString: BitString[UByte] = new UByteBitString import spire.math.NumberTag._ @@ -107,7 +110,8 @@ private[math] trait UByteIsCRig extends CRig[UByte] { def zero: UByte = UByte(0) } -private[math] trait UByteSigned extends SignedAdditiveCMonoid[UByte] { +private[math] trait UByteSigned extends Order[UByte] with SignedAdditiveCMonoid[UByte] { + def order = this override def eqv(x: UByte, y: UByte): Boolean = x == y override def neqv(x: UByte, y: UByte): Boolean = x != y override def gt(x: UByte, y: UByte): Boolean = x > y diff --git a/core/src/main/scala/spire/math/UInt.scala b/core/src/main/scala/spire/math/UInt.scala index b77514534..fc56fc2a8 100644 --- a/core/src/main/scala/spire/math/UInt.scala +++ b/core/src/main/scala/spire/math/UInt.scala @@ -16,7 +16,7 @@ package spire package math -import spire.algebra.{CRig, IsIntegral, SignedAdditiveCMonoid, TruncatedDivision} +import spire.algebra.{CRig, IsIntegral, Order, SignedAdditiveCMonoid, TruncatedDivision} import spire.util.Opt object UInt extends UIntInstances { @@ -78,7 +78,8 @@ class UInt(val signed: Int) extends AnyVal { trait UIntInstances { implicit final val UIntAlgebra - : CRig[UInt] with IsIntegral[UInt] with TruncatedDivision[UInt] with SignedAdditiveCMonoid[UInt] = new UIntAlgebra + : CRig[UInt] with IsIntegral[UInt] with TruncatedDivision[UInt] with SignedAdditiveCMonoid[UInt] with Order[UInt] = + new UIntAlgebra implicit final val UIntBitString: BitString[UInt] = new UIntBitString import spire.math.NumberTag._ implicit final val UIntTag: NumberTag[UInt] = new UnsignedIntTag[UInt](UInt.MinValue, UInt.MaxValue) @@ -96,7 +97,8 @@ private[math] trait UIntIsCRig extends CRig[UInt] { def zero: UInt = UInt(0) } -private[math] trait UIntSigned extends SignedAdditiveCMonoid[UInt] { +private[math] trait UIntSigned extends Order[UInt] with SignedAdditiveCMonoid[UInt] { + def order = this override def eqv(x: UInt, y: UInt): Boolean = x == y override def neqv(x: UInt, y: UInt): Boolean = x != y override def gt(x: UInt, y: UInt): Boolean = x > y diff --git a/core/src/main/scala/spire/math/ULong.scala b/core/src/main/scala/spire/math/ULong.scala index 13d69f904..8f55b7027 100644 --- a/core/src/main/scala/spire/math/ULong.scala +++ b/core/src/main/scala/spire/math/ULong.scala @@ -16,7 +16,7 @@ package spire package math -import spire.algebra.{CRig, IsIntegral, SignedAdditiveCMonoid, TruncatedDivision} +import spire.algebra.{CRig, IsIntegral, Order, SignedAdditiveCMonoid, TruncatedDivision} import spire.util.Opt object ULong extends ULongInstances { @@ -147,8 +147,11 @@ class ULong(val signed: Long) extends AnyVal { } trait ULongInstances { - implicit final val ULongAlgebra - : CRig[ULong] with IsIntegral[ULong] with TruncatedDivision[ULong] with SignedAdditiveCMonoid[ULong] = + implicit final val ULongAlgebra: CRig[ULong] + with IsIntegral[ULong] + with TruncatedDivision[ULong] + with SignedAdditiveCMonoid[ULong] + with Order[ULong] = new ULongAlgebra implicit final val ULongBitString: BitString[ULong] = new ULongBitString import spire.math.NumberTag._ @@ -167,7 +170,8 @@ private[math] trait ULongIsCRig extends CRig[ULong] { def zero: ULong = ULong(0) } -private[math] trait ULongSigned extends SignedAdditiveCMonoid[ULong] { +private[math] trait ULongSigned extends Order[ULong] with SignedAdditiveCMonoid[ULong] { + def order = this override def eqv(x: ULong, y: ULong): Boolean = x == y override def neqv(x: ULong, y: ULong): Boolean = x != y override def gt(x: ULong, y: ULong): Boolean = x > y diff --git a/core/src/main/scala/spire/math/UShort.scala b/core/src/main/scala/spire/math/UShort.scala index 4f4010232..29b24eda9 100644 --- a/core/src/main/scala/spire/math/UShort.scala +++ b/core/src/main/scala/spire/math/UShort.scala @@ -16,7 +16,7 @@ package spire package math -import spire.algebra.{CRig, IsIntegral, SignedAdditiveCMonoid, TruncatedDivision} +import spire.algebra.{CRig, IsIntegral, Order, SignedAdditiveCMonoid, TruncatedDivision} import spire.util.Opt object UShort extends UShortInstances { @@ -78,8 +78,11 @@ class UShort(val signed: Char) extends AnyVal { } trait UShortInstances { - implicit final val UShortAlgebra - : CRig[UShort] with IsIntegral[UShort] with TruncatedDivision[UShort] with SignedAdditiveCMonoid[UShort] = + implicit final val UShortAlgebra: CRig[UShort] + with IsIntegral[UShort] + with TruncatedDivision[UShort] + with SignedAdditiveCMonoid[UShort] + with Order[UShort] = new UShortAlgebra implicit final val UShortBitString: BitString[UShort] = new UShortBitString import spire.math.NumberTag._ @@ -98,7 +101,8 @@ private[math] trait UShortIsCRig extends CRig[UShort] { def zero: UShort = UShort(0) } -private[math] trait UShortSigned extends SignedAdditiveCMonoid[UShort] { +private[math] trait UShortSigned extends Order[UShort] with SignedAdditiveCMonoid[UShort] { + def order = this override def eqv(x: UShort, y: UShort): Boolean = x == y override def neqv(x: UShort, y: UShort): Boolean = x != y override def gt(x: UShort, y: UShort): Boolean = x > y diff --git a/core/src/main/scala/spire/math/package.scala b/core/src/main/scala/spire/math/package.scala index 3ed12a968..c26cc8ffe 100644 --- a/core/src/main/scala/spire/math/package.scala +++ b/core/src/main/scala/spire/math/package.scala @@ -538,7 +538,7 @@ package object math { final def ulp(x: Double): Double = Math.ulp(x) final def ulp(x: Float): Double = Math.ulp(x) - final def hypot[@sp(Float, Double) A](x: A, y: A)(implicit f: Field[A], n: NRoot[A], s: Signed[A]): A = { + final def hypot[@sp(Float, Double) A](x: A, y: A)(implicit f: Field[A], n: NRoot[A], o: Order[A], s: Signed[A]): A = { import spire.implicits._ def abs(n: A): A = if (n < f.zero) -n else n val ax = abs(x) diff --git a/core/src/main/scala/spire/math/poly/BigDecimalRootRefinement.scala b/core/src/main/scala/spire/math/poly/BigDecimalRootRefinement.scala index 6d6cda15e..2237fbd39 100644 --- a/core/src/main/scala/spire/math/poly/BigDecimalRootRefinement.scala +++ b/core/src/main/scala/spire/math/poly/BigDecimalRootRefinement.scala @@ -102,7 +102,9 @@ object BigDecimalRootRefinement { ): BigDecimalRootRefinement = apply(poly, lowerBound, upperBound).refine(mc) - implicit private val JBigDecimalOrder: Signed[JBigDecimal] = new SignedAdditiveAbGroup[JBigDecimal] { + implicit private val JBigDecimalOrder: Order[JBigDecimal] with Signed[JBigDecimal] = new Order[JBigDecimal] + with SignedAdditiveAbGroup[JBigDecimal] { + def order = this def negate(x: JBigDecimal) = x.negate def zero = JBigDecimal.ZERO def plus(x: JBigDecimal, y: JBigDecimal) = x.add(y) diff --git a/core/src/main/scala/spire/math/prime/Factors.scala b/core/src/main/scala/spire/math/prime/Factors.scala index 3d4883e80..1b05d4e25 100644 --- a/core/src/main/scala/spire/math/prime/Factors.scala +++ b/core/src/main/scala/spire/math/prime/Factors.scala @@ -17,7 +17,7 @@ package spire package math.prime import spire.algebra.{Sign, UniqueFactorizationDomain} -import spire.algebra.Sign.{Negative, Positive, Zero} +import spire.algebra.Signed.{Negative, Positive, Zero} import spire.math.SafeLong import spire.std.int._ import spire.std.map._ @@ -131,7 +131,7 @@ case class Factors(elements: Map[SafeLong, Int], sign: Sign) def /(rhs: Factors): Factors = { val (sign, nn, dd, cc) = qm(rhs) - if (dd.isEmpty) Factors(nn, sign) else Factors((prod(nn) * sign) / prod(dd)) + if (dd.isEmpty) Factors(nn, Sign(sign)) else Factors((prod(nn) * sign) / prod(dd)) } def /(rhs: SafeLong): Factors = @@ -157,7 +157,7 @@ case class Factors(elements: Map[SafeLong, Int], sign: Sign) def /%(rhs: Factors): (Factors, Factors) = { val (sign, nn, dd, cc) = qm(rhs) if (dd.isEmpty) { - (Factors(nn, sign), Factors.zero) + (Factors(nn, Sign(sign)), Factors.zero) } else { val (q, m) = prod(nn) /% prod(dd) (Factors(q) * sign, Factors(m * prod(cc)) * lhs.signum) diff --git a/core/src/main/scala/spire/math/prime/package.scala b/core/src/main/scala/spire/math/prime/package.scala index a7af7df6d..b12ae78c2 100644 --- a/core/src/main/scala/spire/math/prime/package.scala +++ b/core/src/main/scala/spire/math/prime/package.scala @@ -17,7 +17,7 @@ package spire package math import spire.algebra.Sign -import spire.algebra.Sign.Positive +import spire.algebra.Signed.Positive import spire.std.double._ import spire.syntax.cfor._ import spire.syntax.nroot._ diff --git a/core/src/main/scala/spire/std/bigDecimal.scala b/core/src/main/scala/spire/std/bigDecimal.scala index 5d44563de..9f72c8158 100644 --- a/core/src/main/scala/spire/std/bigDecimal.scala +++ b/core/src/main/scala/spire/std/bigDecimal.scala @@ -25,7 +25,7 @@ import spire.algebra.{Field, IsRational, NRoot, Order, Signed, Trig, TruncatedDi import spire.math.Rational import spire.util.Opt -trait BigDecimalIsField extends Field.WithDefaultGCD[BigDecimal] { +trait BigDecimalIsField extends Field[BigDecimal] { override def minus(a: BigDecimal, b: BigDecimal): BigDecimal = a - b def negate(a: BigDecimal): BigDecimal = -a val one: BigDecimal = BigDecimal(1.0) @@ -182,6 +182,7 @@ trait BigDecimalOrder extends Order[BigDecimal] { } trait BigDecimalSigned extends Signed[BigDecimal] with BigDecimalOrder { + def order = this override def signum(a: BigDecimal): Int = a.signum override def abs(a: BigDecimal): BigDecimal = a.abs } @@ -208,7 +209,7 @@ class BigDecimalAlgebra extends BigDecimalIsField with BigDecimalIsNRoot with Bi trait BigDecimalInstances { import BigDecimal.defaultMathContext - implicit final val BigDecimalAlgebra: Field.WithDefaultGCD[BigDecimal] + implicit final val BigDecimalAlgebra: Field[BigDecimal] with NRoot[BigDecimal] with IsRational[BigDecimal] with TruncatedDivisionCRing[BigDecimal] diff --git a/core/src/main/scala/spire/std/bigInt.scala b/core/src/main/scala/spire/std/bigInt.scala index 5d3a75717..21f187b95 100644 --- a/core/src/main/scala/spire/std/bigInt.scala +++ b/core/src/main/scala/spire/std/bigInt.scala @@ -78,6 +78,7 @@ trait BigIntOrder extends Order[BigInt] { } trait BigIntSigned extends Signed[BigInt] with BigIntOrder { + def order = this override def signum(a: BigInt): Int = a.signum override def abs(a: BigInt): BigInt = a.abs } diff --git a/core/src/main/scala/spire/std/bigInteger.scala b/core/src/main/scala/spire/std/bigInteger.scala index 42d2660aa..752853fc3 100644 --- a/core/src/main/scala/spire/std/bigInteger.scala +++ b/core/src/main/scala/spire/std/bigInteger.scala @@ -36,8 +36,8 @@ trait BigIntegerIsEuclideanRing extends EuclideanRing[BigInteger] { override def equotmod(a: BigInteger, b: BigInteger): (BigInteger, BigInteger) = spire.math.equotmod(a, b) def equot(a: BigInteger, b: BigInteger): BigInteger = spire.math.equot(a, b) def emod(a: BigInteger, b: BigInteger): BigInteger = spire.math.emod(a, b) - def gcd(a: BigInteger, b: BigInteger)(implicit ev: Eq[BigInteger]): BigInteger = a.gcd(b) - def lcm(a: BigInteger, b: BigInteger)(implicit ev: Eq[BigInteger]): BigInteger = + override def gcd(a: BigInteger, b: BigInteger)(implicit ev: Eq[BigInteger]): BigInteger = a.gcd(b) + override def lcm(a: BigInteger, b: BigInteger)(implicit ev: Eq[BigInteger]): BigInteger = if (a.signum == 0 || b.signum == 0) zero else a.divide(a.gcd(b)).multiply(b) } @@ -92,6 +92,7 @@ trait BigIntegerOrder extends Order[BigInteger] { } trait BigIntegerSigned extends Signed[BigInteger] with BigIntegerOrder { + def order = this override def signum(a: BigInteger): Int = a.signum override def abs(a: BigInteger): BigInteger = a.abs } diff --git a/core/src/main/scala/spire/std/byte.scala b/core/src/main/scala/spire/std/byte.scala index 6136b44c1..461295764 100644 --- a/core/src/main/scala/spire/std/byte.scala +++ b/core/src/main/scala/spire/std/byte.scala @@ -35,8 +35,8 @@ trait ByteIsEuclideanRing extends EuclideanRing[Byte] { override def equotmod(a: Byte, b: Byte): (Byte, Byte) = spire.math.equotmod(a, b) def equot(a: Byte, b: Byte): Byte = spire.math.equot(a, b) def emod(a: Byte, b: Byte): Byte = spire.math.emod(a, b) - def gcd(a: Byte, b: Byte)(implicit ev: Eq[Byte]): Byte = spire.math.gcd(a, b).toByte - def lcm(a: Byte, b: Byte)(implicit ev: Eq[Byte]): Byte = spire.math.lcm(a, b).toByte + override def gcd(a: Byte, b: Byte)(implicit ev: Eq[Byte]): Byte = spire.math.gcd(a, b).toByte + override def lcm(a: Byte, b: Byte)(implicit ev: Eq[Byte]): Byte = spire.math.lcm(a, b).toByte } // Not included in Instances trait. @@ -73,6 +73,7 @@ trait ByteOrder extends Order[Byte] { } trait ByteSigned extends Signed[Byte] with ByteOrder { + def order = this override def signum(a: Byte): Int = java.lang.Integer.signum(a) override def abs(a: Byte): Byte = if (a < 0) (-a).toByte else a } diff --git a/core/src/main/scala/spire/std/double.scala b/core/src/main/scala/spire/std/double.scala index ed0fa3c60..20d53479f 100644 --- a/core/src/main/scala/spire/std/double.scala +++ b/core/src/main/scala/spire/std/double.scala @@ -22,7 +22,7 @@ import spire.util.Opt import java.lang.Math -trait DoubleIsField extends Field.WithDefaultGCD[Double] { +trait DoubleIsField extends Field[Double] { override def minus(a: Double, b: Double): Double = a - b def negate(a: Double): Double = -a def one: Double = 1.0 @@ -127,6 +127,7 @@ trait DoubleOrder extends Order[Double] { } trait DoubleSigned extends Signed[Double] with DoubleOrder { + def order = this override def signum(a: Double): Int = Math.signum(a).toInt override def abs(a: Double): Double = if (a < 0.0) -a else a } @@ -150,7 +151,7 @@ trait DoubleIsReal extends IsRational[Double] with DoubleTruncatedDivision { class DoubleAlgebra extends DoubleIsField with DoubleIsNRoot with DoubleIsTrig with DoubleIsReal with Serializable trait DoubleInstances { - implicit final val DoubleAlgebra: Field.WithDefaultGCD[Double] + implicit final val DoubleAlgebra: Field[Double] with NRoot[Double] with Trig[Double] with IsRational[Double] diff --git a/core/src/main/scala/spire/std/float.scala b/core/src/main/scala/spire/std/float.scala index 9a915110c..8fd10a044 100644 --- a/core/src/main/scala/spire/std/float.scala +++ b/core/src/main/scala/spire/std/float.scala @@ -22,7 +22,7 @@ import spire.util.Opt import java.lang.Math -trait FloatIsField extends Field.WithDefaultGCD[Float] { +trait FloatIsField extends Field[Float] { override def minus(a: Float, b: Float): Float = a - b def negate(a: Float): Float = -a def one: Float = 1.0f @@ -136,6 +136,7 @@ trait FloatSigned extends Signed[Float] with FloatOrder { } trait FloatTruncatedDivision extends TruncatedDivisionCRing[Float] with FloatSigned { + def order = this def toBigIntOpt(a: Float): Opt[BigInt] = if (a.isWhole) Opt(BigDecimal(a.toDouble).toBigInt) else Opt.empty[BigInt] def tquot(a: Float, b: Float): Float = (a - (a % b)) / b def tmod(a: Float, b: Float): Float = a % b @@ -155,7 +156,8 @@ class FloatAlgebra extends FloatIsField with FloatIsNRoot with FloatIsTrig with trait FloatInstances { implicit final val FloatAlgebra - : Field.WithDefaultGCD[Float] with NRoot[Float] with Trig[Float] with IsRational[Float] = new FloatAlgebra + : Field[Float] with NRoot[Float] with Trig[Float] with IsRational[Float] with Order[Float] = + new FloatAlgebra import Float._ import spire.math.NumberTag import spire.math.NumberTag._ diff --git a/core/src/main/scala/spire/std/int.scala b/core/src/main/scala/spire/std/int.scala index 66eb048e8..949843c50 100644 --- a/core/src/main/scala/spire/std/int.scala +++ b/core/src/main/scala/spire/std/int.scala @@ -38,8 +38,8 @@ trait IntIsEuclideanRing extends EuclideanRing[Int] { override def equotmod(a: Int, b: Int): (Int, Int) = spire.math.equotmod(a, b) def equot(a: Int, b: Int): Int = spire.math.equot(a, b) def emod(a: Int, b: Int): Int = spire.math.emod(a, b) - def gcd(a: Int, b: Int)(implicit ev: Eq[Int]): Int = spire.math.gcd(a, b).toInt - def lcm(a: Int, b: Int)(implicit ev: Eq[Int]): Int = spire.math.lcm(a, b).toInt + override def gcd(a: Int, b: Int)(implicit ev: Eq[Int]): Int = spire.math.gcd(a, b).toInt + override def lcm(a: Int, b: Int)(implicit ev: Eq[Int]): Int = spire.math.lcm(a, b).toInt } // Not included in Instances trait. @@ -87,6 +87,7 @@ trait IntTruncatedDivision extends TruncatedDivisionCRing[Int] with IntSigned { } trait IntIsReal extends IsIntegral[Int] with IntTruncatedDivision { + def order = this def toDouble(n: Int): Double = n.toDouble def toBigInt(n: Int): BigInt = BigInt(n) } diff --git a/core/src/main/scala/spire/std/long.scala b/core/src/main/scala/spire/std/long.scala index e6e56db24..9d195042c 100644 --- a/core/src/main/scala/spire/std/long.scala +++ b/core/src/main/scala/spire/std/long.scala @@ -37,8 +37,8 @@ trait LongIsEuclideanRing extends EuclideanRing[Long] { override def equotmod(a: Long, b: Long): (Long, Long) = spire.math.equotmod(a, b) def equot(a: Long, b: Long): Long = spire.math.equot(a, b) def emod(a: Long, b: Long): Long = spire.math.emod(a, b) - def gcd(a: Long, b: Long)(implicit ev: Eq[Long]): Long = spire.math.gcd(a, b) - def lcm(a: Long, b: Long)(implicit ev: Eq[Long]): Long = spire.math.lcm(a, b) + override def gcd(a: Long, b: Long)(implicit ev: Eq[Long]): Long = spire.math.gcd(a, b) + override def lcm(a: Long, b: Long)(implicit ev: Eq[Long]): Long = spire.math.lcm(a, b) } // Not included in Instances trait! @@ -76,6 +76,7 @@ trait LongOrder extends Order[Long] { } trait LongSigned extends Signed[Long] with LongOrder { + def order = this override def signum(a: Long): Int = java.lang.Long.signum(a) override def abs(a: Long): Long = if (a < 0L) -a else a } diff --git a/core/src/main/scala/spire/std/short.scala b/core/src/main/scala/spire/std/short.scala index 3a1eea110..9c16de2c1 100644 --- a/core/src/main/scala/spire/std/short.scala +++ b/core/src/main/scala/spire/std/short.scala @@ -35,8 +35,8 @@ trait ShortIsEuclideanRing extends EuclideanRing[Short] { override def equotmod(a: Short, b: Short): (Short, Short) = spire.math.equotmod(a, b) def equot(a: Short, b: Short): Short = spire.math.equot(a, b) def emod(a: Short, b: Short): Short = spire.math.emod(a, b) - def gcd(a: Short, b: Short)(implicit ev: Eq[Short]): Short = spire.math.gcd(a, b).toShort - def lcm(a: Short, b: Short)(implicit ev: Eq[Short]): Short = spire.math.lcm(a, b).toShort + override def gcd(a: Short, b: Short)(implicit ev: Eq[Short]): Short = spire.math.gcd(a, b).toShort + override def lcm(a: Short, b: Short)(implicit ev: Eq[Short]): Short = spire.math.lcm(a, b).toShort } // Not included in Instances trait. @@ -73,6 +73,7 @@ trait ShortOrder extends Order[Short] { } trait ShortSigned extends Signed[Short] with ShortOrder { + def order = this override def signum(a: Short): Int = java.lang.Integer.signum(a) override def abs(a: Short): Short = if (a < 0) (-a).toShort else a.toShort } diff --git a/extras/src/main/scala/spire/math/FixedPoint.scala b/extras/src/main/scala/spire/math/FixedPoint.scala index 97837d27b..2001077f1 100644 --- a/extras/src/main/scala/spire/math/FixedPoint.scala +++ b/extras/src/main/scala/spire/math/FixedPoint.scala @@ -22,7 +22,7 @@ import spire.syntax.euclideanRing._ import spire.syntax.convertableFrom._ import java.math.MathContext -import spire.algebra.{Field, TruncatedDivisionCRing} +import spire.algebra.{Field, Order, TruncatedDivisionCRing} import spire.util.Opt class FixedPointOverflow(n: Long) extends Exception(n.toString) @@ -316,8 +316,13 @@ object FixedPoint extends FixedPointInstances { trait FixedPointInstances { - implicit def algebra(implicit scale: FixedScale): Fractional[FixedPoint] with TruncatedDivisionCRing[FixedPoint] = - new Fractional[FixedPoint] with TruncatedDivisionCRing[FixedPoint] with Field.WithDefaultGCD[FixedPoint] { self => + implicit def algebra(implicit + scale: FixedScale + ): Fractional[FixedPoint] with Order[FixedPoint] with TruncatedDivisionCRing[FixedPoint] = + new Fractional[FixedPoint] with TruncatedDivisionCRing[FixedPoint] with Field[FixedPoint] with Order[FixedPoint] { + self => + def order = this + override def abs(x: FixedPoint): FixedPoint = x.abs override def signum(x: FixedPoint): Int = x.signum diff --git a/laws/src/main/scala/spire/laws/BaseLaws.scala b/laws/src/main/scala/spire/laws/BaseLaws.scala index ab025987c..a569fd385 100644 --- a/laws/src/main/scala/spire/laws/BaseLaws.scala +++ b/laws/src/main/scala/spire/laws/BaseLaws.scala @@ -43,12 +43,12 @@ trait BaseLaws[A] extends Laws { def metricSpace[R](implicit MSA: MetricSpace[A, R], SR: Signed[R], OR: Order[R], ASR: AdditiveSemigroup[R]) = new SimpleRuleSet( name = "metricSpace", - "non-negative" -> forAllSafe((a1: A, a2: A) => MSA.distance(a1, a2).sign != Sign.Negative), - "identity" -> forAllSafe((a: A) => MSA.distance(a, a).sign == Sign.Zero), + "non-negative" -> forAllSafe((a1: A, a2: A) => MSA.distance(a1, a2).sign != Signed.Negative), + "identity" -> forAllSafe((a: A) => MSA.distance(a, a).sign == Signed.Zero), "equality" -> forAllSafe((a1: A, a2: A) => // generating equal values is hard, and Scalacheck will give up if it can't // hence, not using `==>` here - a1 =!= a2 || MSA.distance(a1, a2).sign == Sign.Zero + a1 =!= a2 || MSA.distance(a1, a2).sign == Signed.Zero ), "symmetry" -> forAllSafe((a1: A, a2: A) => MSA.distance(a1, a2) === MSA.distance(a2, a1)), "triangleInequality" -> forAllSafe((a1: A, a2: A, a3: A) => diff --git a/laws/src/main/scala/spire/laws/CombinationLaws.scala b/laws/src/main/scala/spire/laws/CombinationLaws.scala index e2d79bb0a..c6ccf0cc2 100644 --- a/laws/src/main/scala/spire/laws/CombinationLaws.scala +++ b/laws/src/main/scala/spire/laws/CombinationLaws.scala @@ -23,6 +23,7 @@ import org.scalacheck.Prop._ import InvalidTestException._ import org.typelevel.discipline.Laws +@deprecated("0.18.0", "These laws are now provided by algebra") object CombinationLaws { def apply[A: Eq: Arbitrary] = new CombinationLaws[A] { def Equ = Eq[A] @@ -33,34 +34,37 @@ object CombinationLaws { /** * Contains laws that are obeying by combination of types, for example various kinds of signed rings. */ +@deprecated("0.18.0", "These laws are now provided by algebra") trait CombinationLaws[A] extends Laws { implicit def Equ: Eq[A] implicit def Arb: Arbitrary[A] - def signedAdditiveCMonoid(implicit signedA: Signed[A], additiveCMonoidA: AdditiveCMonoid[A]) = new DefaultRuleSet( - name = "signedAdditiveCMonoid", - parent = None, - "ordered group" -> forAllSafe { (x: A, y: A, z: A) => - !(x <= y) || (x + z <= y + z) // replaces (x <= y) ==> (x + z <= y + z) - }, - "triangle inequality" -> forAllSafe { (x: A, y: A) => - (x + y).abs <= x.abs + y.abs - } - ) + def signedAdditiveCMonoid(implicit orderA: Order[A], signedA: Signed[A], additiveCMonoidA: AdditiveCMonoid[A]) = + new DefaultRuleSet( + name = "signedAdditiveCMonoid", + parent = None, + "ordered group" -> forAllSafe { (x: A, y: A, z: A) => + !(x <= y) || (x + z <= y + z) // replaces (x <= y) ==> (x + z <= y + z) + }, + "triangle inequality" -> forAllSafe { (x: A, y: A) => + (x + y).abs <= x.abs + y.abs + } + ) - def signedAdditiveAbGroup(implicit signedA: Signed[A], additiveAbGroupA: AdditiveAbGroup[A]) = new DefaultRuleSet( - name = "signedAdditiveAbGroup", - parent = Some(signedAdditiveCMonoid), - "abs(x) equals abs(-x)" -> forAllSafe { (x: A) => - x.abs === (-x).abs - } - ) + def signedAdditiveAbGroup(implicit orderA: Order[A], signedA: Signed[A], additiveAbGroupA: AdditiveAbGroup[A]) = + new DefaultRuleSet( + name = "signedAdditiveAbGroup", + parent = Some(signedAdditiveCMonoid), + "abs(x) equals abs(-x)" -> forAllSafe { (x: A) => + x.abs === (-x).abs + } + ) // more a convention: as GCD is defined up to a unit, so up to a sign, // on an ordered GCD ring we require gcd(x, y) >= 0, which is the common // behavior of computer algebra systems - def signedGCDRing(implicit signedA: Signed[A], gcdRingA: GCDRing[A]) = new DefaultRuleSet( + def signedGCDRing(implicit orderA: Order[A], signedA: Signed[A], gcdRingA: GCDRing[A]) = new DefaultRuleSet( name = "signedGCDRing", parent = Some(signedAdditiveAbGroup), "gcd(x, y) >= 0" -> forAllSafe { (x: A, y: A) => diff --git a/laws/src/main/scala/spire/laws/OrderLaws.scala b/laws/src/main/scala/spire/laws/OrderLaws.scala index 5cfae0273..51c506432 100644 --- a/laws/src/main/scala/spire/laws/OrderLaws.scala +++ b/laws/src/main/scala/spire/laws/OrderLaws.scala @@ -57,78 +57,80 @@ trait OrderLaws[A] extends Laws { def signed(implicit A: Signed[A]) = new OrderProperties( name = "signed", - parent = Some(order), - "abs non-negative" -> forAllSafe((x: A) => x.abs.sign != Sign.Negative), + parent = Some(order(A.order)), + "abs non-negative" -> forAllSafe((x: A) => x.abs.sign != Signed.Negative), "signum returns -1/0/1" -> forAllSafe((x: A) => x.signum.abs <= 1), "signum is sign.toInt" -> forAllSafe((x: A) => x.signum == x.sign.toInt) ) - def truncatedDivision(implicit cRigA: CRig[A], truncatedDivisionA: TruncatedDivision[A]) = new DefaultRuleSet( - name = "truncatedDivision", - parent = Some(signed), - "division rule (tquotmod)" -> forAllSafe { (x: A, y: A) => - y.isZero || { - val (q, r) = x.tquotmod(y) - x === y * q + r + def truncatedDivision(implicit cRigA: CRig[A], orderA: Order[A], truncatedDivisionA: TruncatedDivision[A]) = + new DefaultRuleSet( + name = "truncatedDivision", + parent = Some(signed), + "division rule (tquotmod)" -> forAllSafe { (x: A, y: A) => + y.isZero || { + val (q, r) = x.tquotmod(y) + x === y * q + r + } + }, + "division rule (fquotmod)" -> forAllSafe { (x: A, y: A) => + y.isZero || { + val (q, r) = x.fquotmod(y) + x == y * q + r + } + }, + // toBigIntOpt is not in algebra + // "quotient is integer (tquot)" -> forAllSafe { (x: A, y: A) => + // y.isZero || x.tquot(y).toBigIntOpt.nonEmpty + // }, + // "quotient is integer (fquot)" -> forAllSafe { (x: A, y: A) => + // y.isZero || x.fquot(y).toBigIntOpt.nonEmpty + // }, + "|r| < |y| (tmod)" -> forAllSafe { (x: A, y: A) => + y.isZero || { + val r = x.tmod(y) + r.abs < y.abs + } + }, + "|r| < |y| (fmod)" -> forAllSafe { (x: A, y: A) => + y.isZero || { + val r = x.fmod(y) + r.abs < y.abs + } + }, + "r = 0 or sign(r) = sign(x) (tmod)" -> forAllSafe { (x: A, y: A) => + y.isZero || { + val r = x.tmod(y) + r.isZero || (r.sign === x.sign) + } + }, + "r = 0 or sign(r) = sign(y) (fmod)" -> forAllSafe { (x: A, y: A) => + y.isZero || { + val r = x.fmod(y) + r.isZero || (r.sign === y.sign) + } + }, + "tquot" -> forAllSafe { (x: A, y: A) => + y.isZero || { + x.tquotmod(y)._1 === (x.tquot(y)) + } + }, + "tmod" -> forAllSafe { (x: A, y: A) => + y.isZero || { + x.tquotmod(y)._2 === (x.tmod(y)) + } + }, + "fquot" -> forAllSafe { (x: A, y: A) => + y.isZero || { + x.fquotmod(y)._1 === (x.fquot(y)) + } + }, + "fmod" -> forAllSafe { (x: A, y: A) => + y.isZero || { + x.fquotmod(y)._2 === (x.fmod(y)) + } } - }, - "division rule (fquotmod)" -> forAllSafe { (x: A, y: A) => - y.isZero || { - val (q, r) = x.fquotmod(y) - x == y * q + r - } - }, - "quotient is integer (tquot)" -> forAllSafe { (x: A, y: A) => - y.isZero || x.tquot(y).toBigIntOpt.nonEmpty - }, - "quotient is integer (fquot)" -> forAllSafe { (x: A, y: A) => - y.isZero || x.fquot(y).toBigIntOpt.nonEmpty - }, - "|r| < |y| (tmod)" -> forAllSafe { (x: A, y: A) => - y.isZero || { - val r = x.tmod(y) - r.abs < y.abs - } - }, - "|r| < |y| (fmod)" -> forAllSafe { (x: A, y: A) => - y.isZero || { - val r = x.fmod(y) - r.abs < y.abs - } - }, - "r = 0 or sign(r) = sign(x) (tmod)" -> forAllSafe { (x: A, y: A) => - y.isZero || { - val r = x.tmod(y) - r.isZero || (r.sign === x.sign) - } - }, - "r = 0 or sign(r) = sign(y) (fmod)" -> forAllSafe { (x: A, y: A) => - y.isZero || { - val r = x.fmod(y) - r.isZero || (r.sign === y.sign) - } - }, - "tquot" -> forAllSafe { (x: A, y: A) => - y.isZero || { - x.tquotmod(y)._1 === (x.tquot(y)) - } - }, - "tmod" -> forAllSafe { (x: A, y: A) => - y.isZero || { - x.tquotmod(y)._2 === (x.tmod(y)) - } - }, - "fquot" -> forAllSafe { (x: A, y: A) => - y.isZero || { - x.fquotmod(y)._1 === (x.fquot(y)) - } - }, - "fmod" -> forAllSafe { (x: A, y: A) => - y.isZero || { - x.fquotmod(y)._2 === (x.fmod(y)) - } - } - ) + ) class OrderProperties( name: String, diff --git a/laws/src/main/scala/spire/laws/gen.scala b/laws/src/main/scala/spire/laws/gen.scala index 0d4bf39a6..56c947a97 100644 --- a/laws/src/main/scala/spire/laws/gen.scala +++ b/laws/src/main/scala/spire/laws/gen.scala @@ -107,7 +107,7 @@ object gen { rational.map(Real(_)) lazy val sign: Gen[Sign] = - Gen.oneOf(Sign.Positive, Sign.Zero, Sign.Negative) + Gen.oneOf(Signed.Positive, Signed.Zero, Signed.Negative) def term[A: Arbitrary]: Gen[poly.Term[A]] = for { diff --git a/laws/src/main/scala/spire/laws/shadows/Shadow.scala b/laws/src/main/scala/spire/laws/shadows/Shadow.scala index 6d59920d5..319e46225 100644 --- a/laws/src/main/scala/spire/laws/shadows/Shadow.scala +++ b/laws/src/main/scala/spire/laws/shadows/Shadow.scala @@ -121,11 +121,15 @@ abstract class ShadowInstances3 extends ShadowInstances2 { def eqS = implicitly } - implicit def signed[A: Signed, S: Signed](implicit ev: Shadowing[A, S]): Signed[Shadow[A, S]] = + implicit def signed[A: AdditiveCMonoid: Order: Signed, S: AdditiveCMonoid: Order: Signed](implicit + ev: Shadowing[A, S] + ): Signed[Shadow[A, S]] = new ShadowSigned[A, S] { val shadowing = ev def A = implicitly def S = implicitly + def order = implicitly + def additiveCommutativeMonoid = implicitly } } @@ -149,13 +153,17 @@ abstract class ShadowInstances4 extends ShadowInstances3 { def eqS = implicitly } - implicit def truncatedDivision[A: TruncatedDivision, S: TruncatedDivision](implicit + implicit def truncatedDivision[A: AdditiveCMonoid: Order: TruncatedDivision, + S: AdditiveCMonoid: Order: TruncatedDivision + ](implicit ev: Shadowing[A, S] ): TruncatedDivision[Shadow[A, S]] = new ShadowTruncatedDivision[A, S] { val shadowing = ev def A = implicitly def S = implicitly + def order = implicitly + def additiveCommutativeMonoid = implicitly } } diff --git a/laws/src/main/scala/spire/laws/shadows/ShadowGCDRing.scala b/laws/src/main/scala/spire/laws/shadows/ShadowGCDRing.scala index 98377643c..dfde58543 100644 --- a/laws/src/main/scala/spire/laws/shadows/ShadowGCDRing.scala +++ b/laws/src/main/scala/spire/laws/shadows/ShadowGCDRing.scala @@ -22,9 +22,9 @@ trait ShadowGCDRing[A, S] extends GCDRing[Shadow[A, S]] with ShadowCRing[A, S] { implicit def A: GCDRing[A] implicit def S: GCDRing[S] - def gcd(x: Shadow[A, S], y: Shadow[A, S])(implicit ev: Eq[Shadow[A, S]]): Shadow[A, S] = + override def gcd(x: Shadow[A, S], y: Shadow[A, S])(implicit ev: Eq[Shadow[A, S]]): Shadow[A, S] = Shadow(A.gcd(x.a, y.a), checked(S.gcd(x.s, y.s))) - def lcm(x: Shadow[A, S], y: Shadow[A, S])(implicit ev: Eq[Shadow[A, S]]): Shadow[A, S] = + override def lcm(x: Shadow[A, S], y: Shadow[A, S])(implicit ev: Eq[Shadow[A, S]]): Shadow[A, S] = Shadow(A.lcm(x.a, y.a), checked(S.lcm(x.s, y.s))) } diff --git a/laws/src/main/scala/spire/laws/shadows/ShadowSigned.scala b/laws/src/main/scala/spire/laws/shadows/ShadowSigned.scala index 89b380ae7..1284bf04a 100644 --- a/laws/src/main/scala/spire/laws/shadows/ShadowSigned.scala +++ b/laws/src/main/scala/spire/laws/shadows/ShadowSigned.scala @@ -17,7 +17,7 @@ package spire.laws.shadows import spire.algebra.{Sign, Signed} -trait ShadowSigned[A, S] extends ShadowOrder[A, S] with Signed[Shadow[A, S]] { +trait ShadowSigned[A, S] extends Signed[Shadow[A, S]] { implicit val shadowing: Shadowing[A, S] import shadowing._ implicit def A: Signed[A] diff --git a/laws/src/main/scala/spire/laws/shadows/ShadowTruncatedDivision.scala b/laws/src/main/scala/spire/laws/shadows/ShadowTruncatedDivision.scala index a0b6f655b..27b4840e2 100644 --- a/laws/src/main/scala/spire/laws/shadows/ShadowTruncatedDivision.scala +++ b/laws/src/main/scala/spire/laws/shadows/ShadowTruncatedDivision.scala @@ -27,7 +27,7 @@ trait ShadowTruncatedDivision[A, S] extends TruncatedDivision[Shadow[A, S]] with /** * Returns the integer `a` such that `x = a * one`, if it exists. */ - def toBigIntOpt(x: Shadow[A, S]): Opt[BigInt] = A.toBigIntOpt(x.a) + // def toBigIntOpt(x: Shadow[A, S]): Opt[BigInt] = A.toBigIntOpt(x.a) def tquot(x: Shadow[A, S], y: Shadow[A, S]): Shadow[A, S] = Shadow(A.tquot(x.a, y.a), checked(S.tquot(x.s, y.s))) diff --git a/tests/shared/src/test/scala-2/scala/spire/math/fpf/FpFilterSuite.scala b/tests/shared/src/test/scala-2/scala/spire/math/fpf/FpFilterSuite.scala index ff3750114..8941211f4 100644 --- a/tests/shared/src/test/scala-2/scala/spire/math/fpf/FpFilterSuite.scala +++ b/tests/shared/src/test/scala-2/scala/spire/math/fpf/FpFilterSuite.scala @@ -37,6 +37,8 @@ class FpFilterSuite extends munit.ScalaCheckSuite { // the exact case, since it'll fail with an Evaluated excetion. sealed trait Bad implicit object BadField extends Field[Bad] with IsReal[Bad] with NRoot[Bad] { + def order = this + def additiveCommutativeMonoid = this def zero: Bad = evaluated def one: Bad = evaluated def negate(a: Bad): Bad = evaluated diff --git a/tests/shared/src/test/scala/spire/SyntaxScalaCheckSuite.scala b/tests/shared/src/test/scala/spire/SyntaxScalaCheckSuite.scala index d7a42b9b3..d09f5b7f2 100644 --- a/tests/shared/src/test/scala/spire/SyntaxScalaCheckSuite.scala +++ b/tests/shared/src/test/scala/spire/SyntaxScalaCheckSuite.scala @@ -52,7 +52,7 @@ class SyntaxScalaCheckSuite extends munit.ScalaCheckSuite with BaseSyntaxSuite { .map { a => if (a === Ring[A].zero) Ring[A].one else a.abs } - .filter(_.sign == Sign.Positive) + .filter(_.sign == Signed.Positive) .map(Positive(_)) ) } @@ -158,10 +158,10 @@ trait BaseSyntaxSuite { (a.isSignNonNegative == Signed[A].isSignNonNegative(a)) } - def testTruncatedDivisionSyntax[A: TruncatedDivision](a: A, b: A) = { + def testTruncatedDivisionSyntax[A: TruncatedDivision: Eq](a: A, b: A) = { import spire.syntax.truncatedDivision._ import spire.std.tuples._ - (a.toBigIntOpt === TruncatedDivision[A].toBigIntOpt(a)) && + // (a.toBigIntOpt === TruncatedDivision[A].toBigIntOpt(a)) && ((a.tquot(b)) === TruncatedDivision[A].tquot(a, b)) && ((a.tmod(b)) === TruncatedDivision[A].tmod(a, b)) && ((a.tquotmod(b)) === TruncatedDivision[A].tquotmod(a, b)) && diff --git a/tests/shared/src/test/scala/spire/algebra/SignedSuite.scala b/tests/shared/src/test/scala/spire/algebra/SignedSuite.scala index 8deb2bf0c..995574651 100644 --- a/tests/shared/src/test/scala/spire/algebra/SignedSuite.scala +++ b/tests/shared/src/test/scala/spire/algebra/SignedSuite.scala @@ -37,9 +37,9 @@ class SignedSuite extends munit.FunSuite { runTest("-neg.abs === pos")(assertEquals(neg.abs, pos)) runTest("pos.abs === pos")(assertEquals(pos.abs, pos)) - runTest("neg.sign == Negative")(assertEquals(neg.sign, Sign.Negative)) - runTest("pos.sign == Positive")(assertEquals(pos.sign, Sign.Positive)) - runTest("zero.sign == Zero")(assertEquals(zero.sign, Sign.Zero)) + runTest("neg.sign == Negative")(assertEquals(neg.sign, Signed.Negative)) + runTest("pos.sign == Positive")(assertEquals(pos.sign, Signed.Positive)) + runTest("zero.sign == Zero")(assertEquals(zero.sign, Signed.Zero)) runTest("neg.signum < 0")(assert(neg.signum < 0)) runTest("pos.signum > 0")(assert(pos.signum > 0)) runTest("zero.signum == 0")(assertEquals(zero.signum, 0)) diff --git a/tests/shared/src/test/scala/spire/laws/LawSuite.scala b/tests/shared/src/test/scala/spire/laws/LawSuite.scala index 24a7b7a88..fbe1257d2 100644 --- a/tests/shared/src/test/scala/spire/laws/LawSuite.scala +++ b/tests/shared/src/test/scala/spire/laws/LawSuite.scala @@ -52,19 +52,31 @@ class LawSuite extends munit.DisciplineSuite { implicit val shadowingLong: Shadowing[Long, BigInt] = Shadowing.bigInt[Long](s => s.toLong) checkAll("UByte", RingLaws[UByte].cRig) - checkAll("UByte", OrderLaws[Shadow[UByte, BigInt]].truncatedDivision(Shadow.cRig, Shadow.truncatedDivision)) + checkAll( + "UByte", + OrderLaws[Shadow[UByte, BigInt]].truncatedDivision(Shadow.cRig, Shadow.orderInstance, Shadow.truncatedDivision) + ) checkAll("UByte", CombinationLaws[Shadow[UByte, BigInt]].signedAdditiveCMonoid) checkAll("UShort", RingLaws[UShort].cRig) - checkAll("UShort", OrderLaws[Shadow[UShort, BigInt]].truncatedDivision(Shadow.cRig, Shadow.truncatedDivision)) + checkAll( + "UShort", + OrderLaws[Shadow[UShort, BigInt]].truncatedDivision(Shadow.cRig, Shadow.orderInstance, Shadow.truncatedDivision) + ) checkAll("UShort", CombinationLaws[Shadow[UShort, BigInt]].signedAdditiveCMonoid) checkAll("UInt", RingLaws[UInt].cRig) - checkAll("UInt", OrderLaws[Shadow[UInt, BigInt]].truncatedDivision(Shadow.cRig, Shadow.truncatedDivision)) + checkAll( + "UInt", + OrderLaws[Shadow[UInt, BigInt]].truncatedDivision(Shadow.cRig, Shadow.orderInstance, Shadow.truncatedDivision) + ) checkAll("UInt", CombinationLaws[Shadow[UInt, BigInt]].signedAdditiveCMonoid) checkAll("ULong", RingLaws[ULong].cRig) - checkAll("ULong", OrderLaws[Shadow[ULong, BigInt]].truncatedDivision(Shadow.cRig, Shadow.truncatedDivision)) + checkAll( + "ULong", + OrderLaws[Shadow[ULong, BigInt]].truncatedDivision(Shadow.cRig, Shadow.orderInstance, Shadow.truncatedDivision) + ) checkAll("ULong", CombinationLaws[Shadow[ULong, BigInt]].signedAdditiveCMonoid) checkAll("Natural", RingLaws[Natural].cRig) @@ -75,25 +87,36 @@ class LawSuite extends munit.DisciplineSuite { checkAll("Byte", RingLaws[Byte].cRing) checkAll("Byte", RingLaws[Shadow[Byte, BigInt]].integerEuclideanRing(Shadow.euclideanRing, Shadow.signed)) checkAll("Byte", CombinationLaws[Shadow[Byte, BigInt]].signedAdditiveCMonoid) - checkAll("Byte", OrderLaws[Shadow[Byte, BigInt]].truncatedDivision(Shadow.cRig, Shadow.truncatedDivision)) + checkAll( + "Byte", + OrderLaws[Shadow[Byte, BigInt]].truncatedDivision(Shadow.cRig, Shadow.orderInstance, Shadow.truncatedDivision) + ) checkAll("Byte", BaseLaws[Byte].uniqueFactorizationDomain) checkAll("Short", RingLaws[Short].cRing) checkAll("Short", RingLaws[Shadow[Short, BigInt]].integerEuclideanRing(Shadow.euclideanRing, Shadow.signed)) checkAll("Short", CombinationLaws[Shadow[Short, BigInt]].signedAdditiveCMonoid) - checkAll("Short", OrderLaws[Shadow[Short, BigInt]].truncatedDivision(Shadow.cRig, Shadow.truncatedDivision)) + checkAll( + "Short", + OrderLaws[Shadow[Short, BigInt]].truncatedDivision(Shadow.cRig, Shadow.orderInstance, Shadow.truncatedDivision) + ) checkAll("Short", BaseLaws[Short].uniqueFactorizationDomain) checkAll("Int", RingLaws[Int].cRing) checkAll("Int", RingLaws[Shadow[Int, BigInt]].integerEuclideanRing(Shadow.euclideanRing, Shadow.signed)) checkAll("Int", BaseLaws[Int].uniqueFactorizationDomain) - checkAll("Int", OrderLaws[Shadow[Int, BigInt]].truncatedDivision(Shadow.cRig, Shadow.truncatedDivision)) + checkAll("Int", + OrderLaws[Shadow[Int, BigInt]].truncatedDivision(Shadow.cRig, Shadow.orderInstance, Shadow.truncatedDivision) + ) checkAll("Int", CombinationLaws[Shadow[Int, BigInt]].signedAdditiveCMonoid) checkAll("Long", RingLaws[Long].cRing) checkAll("Long", RingLaws[Shadow[Long, BigInt]].integerEuclideanRing(Shadow.euclideanRing, Shadow.signed)) checkAll("Long", BaseLaws[Long].uniqueFactorizationDomain) - checkAll("Long", OrderLaws[Shadow[Long, BigInt]].truncatedDivision(Shadow.cRig, Shadow.truncatedDivision)) + checkAll( + "Long", + OrderLaws[Shadow[Long, BigInt]].truncatedDivision(Shadow.cRig, Shadow.orderInstance, Shadow.truncatedDivision) + ) checkAll("Long", CombinationLaws[Shadow[Long, BigInt]].signedAdditiveCMonoid) // to test ShadowInvolution diff --git a/tests/shared/src/test/scala/spire/math/AlgebraicScalaCheckSuite.scala b/tests/shared/src/test/scala/spire/math/AlgebraicScalaCheckSuite.scala index 52d8dc30d..aabe0b06f 100644 --- a/tests/shared/src/test/scala/spire/math/AlgebraicScalaCheckSuite.scala +++ b/tests/shared/src/test/scala/spire/math/AlgebraicScalaCheckSuite.scala @@ -16,7 +16,7 @@ package spire package math -import spire.algebra.Sign +import spire.algebra.Signed import org.scalacheck.{Arbitrary, Gen} import org.scalacheck.Arbitrary.arbitrary @@ -136,7 +136,7 @@ class AlgebraicScalaCheckSuite extends munit.ScalaCheckSuite { // This is just a simpler special case of the property test above. test("sign of tricky zero is Zero") { - assertEquals(trickyZero.sign, Sign.Zero) + assertEquals(trickyZero.sign, Signed.Zero) } test("relative approximation of zero is zero") {