forked from typelevel/cats
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d54ae94
commit a652b61
Showing
7 changed files
with
242 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
22 changes: 22 additions & 0 deletions
22
algebra-core/src/main/scala/algebra/ring/DivisionRing.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package algebra | ||
package ring | ||
|
||
import scala.{specialized => sp} | ||
|
||
trait DivisionRing[@sp(Byte, Short, Int, Long, Float, Double) A] extends Any with Ring[A] with MultiplicativeGroup[A] { | ||
self => | ||
|
||
def fromDouble(a: Double): A = Field.defaultFromDouble[A](a)(self, self) | ||
|
||
} | ||
|
||
trait DivisionRingFunctions[F[T] <: DivisionRing[T]] extends RingFunctions[F] with MultiplicativeGroupFunctions[F] { | ||
def fromDouble[@sp(Int, Long, Float, Double) A](n: Double)(implicit ev: F[A]): A = | ||
ev.fromDouble(n) | ||
} | ||
|
||
object DivisionRing extends DivisionRingFunctions[DivisionRing] { | ||
|
||
@inline final def apply[A](implicit f: DivisionRing[A]): DivisionRing[A] = f | ||
|
||
} |
55 changes: 55 additions & 0 deletions
55
algebra-core/src/main/scala/algebra/ring/EuclideanRing.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package algebra | ||
package ring | ||
|
||
import scala.annotation.tailrec | ||
import scala.{specialized => sp} | ||
|
||
/** | ||
* 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] { self => | ||
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)) | ||
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) | ||
} | ||
|
||
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 | ||
|
||
/** | ||
* Simple implementation of Euclid's algorithm for gcd | ||
*/ | ||
@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)) | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package algebra | ||
package ring | ||
|
||
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 CommutativeRing[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 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 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters