Skip to content
This repository has been archived by the owner on Feb 8, 2022. It is now read-only.

Adding GCD rings and Euclidean rings, along with instances for BigInt #246

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

denisrosset
Copy link
Contributor

This aligns the commutative rings/field hierarchy with the one available in Spire.

I haven't provided instances for non-exact types such as Long, Int, etc, because their overflow behaviour doesn't work with the laws.

(Spire tests such instances by aborting the test in case of an overflow -- which is then considered undefined behaviour).

Copy link
Contributor

@johnynek johnynek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks cool!

if (EuclideanRing[A].isZero(b)) a else euclid(b, EuclideanRing[A].emod(a, b))
}

/* @tailrec final def extendedEuclid[@sp(Int, Long, Float, Double) A: Eq: EuclideanRing](a: A, b: A): (A, A, A) = {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. Or I'll implement the extended GCD algorithm.

A.isZero(r) || (A.euclideanFunction(r) < A.euclideanFunction(y))
}
},
"submultiplicative function" -> forAll { (x: A, y: A) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't see this comment in trait. Could we add it so people get more intuition for the euclideanFunction?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any law on this? Seems odd to me a division ring only has this extra method. We don't have any other division like operation?

Copy link
Contributor Author

@denisrosset denisrosset May 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Field has it too. I should have fromDouble in DivisionRing and make Field inherit DivisionRing.

Basically, if you have a type A with a function BigInt -> A and division, you have fromDouble.

(Should algebra incorporate DivisionRing, or is it too specialized? Note that DivisionRing covers the quaternions)

* quot(x, y) = q
* mod(x, y) = r
*/
trait EuclideanRing[@sp(Int, Long, Float, Double) A] extends Any with GCDRing[A] { self =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have specialized on these types can we also add the implementations?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

... Float and Double are taken charge of by Field (euclidean division is trivial).

For Byte/Short/Int/Long, the instances are not lawful as overflow is undefined behaviour territory (which was not the case for just CommutativeRing, the laws pass).

We could:

  1. Provide no instances
  2. Provide instances, but not test them
  3. Port the forAllSafe machinery from Spire that enables tests with abort-on-overflow

What do you think?

armanbilge added a commit to armanbilge/cats that referenced this pull request May 29, 2021
armanbilge added a commit to armanbilge/cats that referenced this pull request Jun 5, 2021
armanbilge added a commit to armanbilge/cats that referenced this pull request Jun 5, 2021
pikinier20 pushed a commit to pikinier20/cats that referenced this pull request Oct 25, 2021
pikinier20 pushed a commit to pikinier20/cats that referenced this pull request Oct 25, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants