Skip to content

Commit

Permalink
Merge pull request #3979 from armanbilge/topic/algebra/semifield
Browse files Browse the repository at this point in the history
Add `Semifield` and `CommutativeSemifield` to algebra
  • Loading branch information
johnynek authored Oct 1, 2021
2 parents 8e98f0b + 9c7ab12 commit 3cf10c6
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package algebra
package ring

import scala.{specialized => sp}

/**
* CommutativeSemifield is a Semifield that is commutative under multiplication.
*/
trait CommutativeSemifield[@sp(Int, Long, Float, Double) A]
extends Any
with Semifield[A]
with CommutativeRig[A]
with MultiplicativeCommutativeGroup[A]

object CommutativeSemifield
extends AdditiveMonoidFunctions[CommutativeSemifield]
with MultiplicativeGroupFunctions[CommutativeSemifield] {
@inline final def apply[A](implicit r: CommutativeSemifield[A]): CommutativeSemifield[A] = r
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package ring

import scala.{specialized => sp}

trait DivisionRing[@sp(Byte, Short, Int, Long, Float, Double) A] extends Any with Ring[A] with MultiplicativeGroup[A] {
trait DivisionRing[@sp(Byte, Short, Int, Long, Float, Double) A] extends Any with Ring[A] with Semifield[A] {
self =>

/**
Expand Down
2 changes: 1 addition & 1 deletion algebra-core/src/main/scala/algebra/ring/Field.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ trait Field[@sp(Int, Long, Float, Double) A]
extends Any
with EuclideanRing[A]
with DivisionRing[A]
with MultiplicativeCommutativeGroup[A] {
with CommutativeSemifield[A] {
self =>

// default implementations for GCD
Expand Down
18 changes: 18 additions & 0 deletions algebra-core/src/main/scala/algebra/ring/Semifield.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package algebra
package ring

import scala.{specialized => sp}

/**
* Semifield consists of:
*
* - a commutative monoid for addition (+)
* - a group for multiplication (*)
*
* Alternately, a Semifield can be thought of as a DivisionRing without an additive inverse.
*/
trait Semifield[@sp(Int, Long, Float, Double) A] extends Any with Rig[A] with MultiplicativeGroup[A]

object Semifield extends AdditiveMonoidFunctions[Semifield] with MultiplicativeGroupFunctions[Semifield] {
@inline final def apply[A](implicit ev: Semifield[A]): Semifield[A] = ev
}
18 changes: 16 additions & 2 deletions algebra-laws/shared/src/main/scala/algebra/laws/RingLaws.scala
Original file line number Diff line number Diff line change
Expand Up @@ -259,11 +259,25 @@ trait RingLaws[A] extends GroupLaws[A] { self =>
}
)

def semifield(implicit A: Semifield[A]) = new RingProperties(
name = "semifield",
al = additiveCommutativeMonoid,
ml = multiplicativeGroup,
parents = Seq(rig)
)

def commutativeSemifield(implicit A: CommutativeSemifield[A]) = new RingProperties(
name = "semifield",
al = additiveCommutativeMonoid,
ml = multiplicativeCommutativeGroup,
parents = Seq(semifield, commutativeRig)
)

def divisionRing(implicit A: DivisionRing[A]) = new RingProperties(
name = "division ring",
al = additiveCommutativeGroup,
ml = multiplicativeGroup,
parents = Seq(ring),
parents = Seq(ring, semifield),
"fromDouble" -> forAll { (n: Double) =>
if (Platform.isJvm) {
// TODO: BigDecimal(n) is busted in scalajs, so we skip this test.
Expand Down Expand Up @@ -311,7 +325,7 @@ trait RingLaws[A] extends GroupLaws[A] { self =>
name = "field",
al = additiveCommutativeGroup,
ml = multiplicativeCommutativeGroup,
parents = Seq(euclideanRing, divisionRing)
parents = Seq(euclideanRing, divisionRing, commutativeSemifield)
)

// Approximate fields such a Float or Double, even through filtered using FPFilter, do not work well with
Expand Down

0 comments on commit 3cf10c6

Please sign in to comment.