-
Notifications
You must be signed in to change notification settings - Fork 243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Don't assume NRoot[Real] is perfect #1173
Changes from 5 commits
3564bdc
8097722
74326e5
9f8f858
dcd4719
8c0260a
20edc9b
cf4c541
802c1f2
6458083
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -18,9 +18,11 @@ package math | |||||||
|
||||||||
import spire.implicits._ | ||||||||
import spire.laws.arb.{rational, real} | ||||||||
import spire.laws.gen.realFromLongs | ||||||||
|
||||||||
import ArbitrarySupport._ | ||||||||
import Ordinal._ | ||||||||
import org.scalacheck.Arbitrary | ||||||||
import org.scalacheck.Prop._ | ||||||||
|
||||||||
class RealScalaCheckSuite extends munit.ScalaCheckSuite { | ||||||||
|
@@ -112,25 +114,28 @@ class RealScalaCheckSuite extends munit.ScalaCheckSuite { | |||||||
|
||||||||
property("x.pow(3) = x * x * x") { | ||||||||
forAll { (x: Real) => | ||||||||
x.pow(2) == x * x | ||||||||
x.pow(3) == x * x * x | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
property("x.pow(k).nroot(k) = x") { | ||||||||
implicit val realArb: Arbitrary[Real] = Arbitrary(realFromLongs) | ||||||||
forAll { (x0: Real, k: Sized[Int, _1, _10]) => | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not really sure if this is any nicer, but it is a bit more explicit :)
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, this will fix the compile errors I reckon. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, this worked in 3 but not in 2 😮 -- implicit resolution must have changed in 3. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think if we explicitly pass the generator, then we can keep them in the same file. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Happy to go that route if that's standard here - I felt kind of bad writing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not entirely sure what There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm struggling to find a solution that uses I pulled in that test here because it seemed like it was susceptible to the same problem in the issue. What do you think the path forward should be? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure I understand what the Scala 2/3 issue is here, since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok so I read the compiler output again and it's not a compat issue, I'm just not sure how to provide implicit evidence properly. Sorry about the confusion. Here's the current implicit def nonZeroSpireImplicit[A: Signed: AdditiveGroup: Arbitrary]: Arbitrary[NonZero[A]] =
Arbitrary(arbitrary[A].filter(_.signum != 0).map(NonZero(_))) I want the instance of implicit def nonZeroSpireImplicit[A: Signed: AdditiveGroup](implicit arbA: Arbitrary[A]): Arbitrary[NonZero[A]] =
Arbitrary(arbA.arbitrary.filter(_.signum != 0).map(NonZero(_))) I was hoping to pass in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Aha, gotcha, no worries :) IIRC before you changed it the signature was like this: implicit def nonZeroSpireImplicit[A: Signed: AdditiveGroup: Arbitrary]: Arbitrary[NonZero[A]] You can then explicitly pass in nonZeroSpireImplicit[Real](implicitly, implicitly, Arbitrary(realFromLongs)) |
||||||||
val x = x0.abs | ||||||||
x.pow(k.num).nroot(k.num) == x | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
property("x.nroot(k).pow(k) = x") { | ||||||||
implicit val realArb: Arbitrary[Real] = Arbitrary(realFromLongs) | ||||||||
forAll { (x0: Real, k: Sized[Int, _1, _10]) => | ||||||||
val x = x0.abs | ||||||||
x.nroot(k.num).pow(k.num) == x | ||||||||
} | ||||||||
} | ||||||||
|
||||||||
property("x.nroot(-k).pow(-k) = x") { | ||||||||
implicit val realArb: Arbitrary[Real] = Arbitrary(realFromLongs) | ||||||||
forAll { (x0: NonZero[Real], k: Sized[Int, _1, _10]) => | ||||||||
val x = x0.num.abs | ||||||||
x.nroot(-k.num).pow(-k.num) == x | ||||||||
|
@@ -196,28 +201,6 @@ class RealScalaCheckSuite extends munit.ScalaCheckSuite { | |||||||
} | ||||||||
} | ||||||||
|
||||||||
// def sample1(name: String)(f: Real => Real): Unit = { | ||||||||
// property(name) { | ||||||||
// forAll { (x0: Rational, i0: Byte, j0: Byte) => | ||||||||
// val x = f(Real(x0.abs)) | ||||||||
// val i = (i0 & 0xff) % 250 + 1 | ||||||||
// val j = (j0 & 0xff) % 250 + 1 | ||||||||
// val (k1, k2) = if (i <= j) (i, j) else (j, i) | ||||||||
// val v1 = x(k1) | ||||||||
// val v2 = x(k2) | ||||||||
// val v3 = Real.roundUp(Rational(v2, SafeLong(2).pow(k2 - k1))) | ||||||||
// v1 == v3 | ||||||||
// } | ||||||||
// } | ||||||||
// } | ||||||||
|
||||||||
// sample1("sample1 id")(x => x) | ||||||||
// sample1("sample1 negate")(x => -x) | ||||||||
// sample1("sample1 +")(x => x + x) | ||||||||
// sample1("sample1 *")(x => x * x) | ||||||||
// sample1("sample1 sqrt")(_.sqrt()) | ||||||||
// sample1("sample1 pow(2)")(_.pow(2)) | ||||||||
Comment on lines
-214
to
-219
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wonder what this was. It's been commented for nearly a decade now it seems. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your guess is as good as mine. It seemed like a unused test that I couldn't really decipher. |
||||||||
|
||||||||
def arcSample(f: Rational => Rational)(g: Double => Double, h: Real => Real): String = | ||||||||
(-8 to 8).map { i => | ||||||||
val x = Real(f(Rational(i))) | ||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woops, thank you! :)