-
Notifications
You must be signed in to change notification settings - Fork 236
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
Update random(QQ) to use standard uniform distribution #3481
base: development
Are you sure you want to change the base?
Conversation
23db5d8
to
2dcfd43
Compare
Have it call rawSetRandomQQ to de-duplicate code
This gives us the closest rational number to a given real number with bounded denominator. It's available at top level using the unexported rawFareyApproximation.
2dcfd43
to
c976fa1
Compare
I think the build failures are coming from examples that use In particular, I was able to reproduce both of these pretty quickly using Macaulay2 1.24.05 on Debian unstable, i.e., before the proposed changes: i1 : needsPackage "CoincidentRootLoci";
i2 : realrank randomBinaryForm(6, 4, 4)
o2 = 4
i3 : realrank randomBinaryForm(6, 4, 4)
o3 = 4
i4 : realrank randomBinaryForm(6, 4, 4)
stdio:4:10:(3):[1]: error: the ideal is not apolar
i5 : realrank randomBinaryForm(6, 4, 4)
o5 = 4
i6 : realrank randomBinaryForm(6, 4, 4)
o6 = 4
i7 : realrank randomBinaryForm(6, 4, 4)
o7 = 4
i8 : realrank randomBinaryForm(6, 4, 4)
/bin/sh: 1: qepcad: not found
stdio:8:1:(3): error: error occurred while executing QEPCAD. Please make sure that it is installed and configured correctly. i1 : needsPackage "GraphicalModelsMLE";
-- storing configuration for package Graphs in /root/.Macaulay2/init-Graphs.m2
-- storing configuration for package NumericalAlgebraicGeometry in /root/.Macaulay2/init-NumericalAlgebraicGeometry.m2
-- storing configuration for package Bertini in /root/.Macaulay2/init-Bertini.m2
i2 : G = mixedGraph(digraph {{1,2},{1,3},{2,3},{3,4}},bigraph {{3,4}});
i3 : U = matrix{{6.2849049, 10.292875, 1.038475, 1.1845757}, {3.1938475, 3.2573, 1.13847, 1}, {4/5, 3/2, 9/8, 3/10}, {10/7, 2/3,1, 8/3}};
4 4
o3 : Matrix RR <-- RR
53 53
i4 : solverMLE(G,U,RealPrecision=>10)
o4 = (1.83311, | 4.52904 7.81123 -.0250185 .309951 |, 2)
| 7.81123 14.3732 -.0382332 .473665 |
| -.0250185 -.0382332 .00337164 -.0418254 |
| .309951 .473665 -.0418254 .742627 |
o4 : Sequence
i5 : solverMLE(G,U,RealPrecision=>10)
stdio:5:1:(3): error: atttempt to divide by zero I'm thinking of replacing the failing examples with canned ones for the time being and also opening issues for both of these examples. Does that sound reasonable? |
Instead of canning the examples, try setting the random seed to something that prevents failure. |
d454379
to
6d494b3
Compare
For now, I've just added a Maybe at some point we should add some way of setting the random seed for a particular example (or test)? |
This kind of situation is fairly rare, so I think it's fine. Also, I think it's helpful for users to see that they can produce the results identical to the documentation. |
I'm happy with this PR, but given that it's changing the behavior of |
Yes, I agree! |
While we're here, could you also add something like random QQ := QQ => opts -> x -> x * random(QQ, opts) A problem with this method is that the height is then skewed (e.g. |
I pushed a commit adding i1 : apply(20, i -> random(10/1))
19 11 59 25 7 5 17 89 4 8 33 31 31 11 53 17 64 31 53
o1 = {--, --, --, --, -, -, --, --, -, -, --, --, --, --, --, 4, --, --, --, --}
10 5 6 8 6 2 3 10 7 5 4 10 4 3 9 6 7 6 6
o1 : List |
95e64e3
to
3265493
Compare
I went ahead and added more For the complex numbers, if we give it i1 : random(1, pi)
o1 = 1.47764022754653
o1 : RR (of precision 53)
i2 : random(1/2, ii)
o2 = .398515040066406+.230213567526911*ii
o2 : CC (of precision 53) |
I don't like the "pair of numbers" methods and would even advocate for deprecating |
Fair enough -- I'll remove them. It was redundant with |
I'm wondering if maybe the support of |
2f2ee70
to
428b1ea
Compare
Yeah, maybe. Height of a rational number a/b is usually defined as max(a,b) so you're right that that would make more sense. I guess I'm just annoyed that Height has different effects for ZZ and QQ and seemingly no effect for RR or CC. Can we make these consistent somehow and document them all in the same page? Also, should |
We then round the result to the nearest rational number with denominator bounded by the Height option using Farey approximation
It's defined in the interpreter, which we don't link against here, and we need it for rawSetRandomQQ.
Previously misspelled the word "attempt". We use the same message as the same error in the interpreter.
For consistency w/ rawRandomRRNormal
This way, calling GF(p^n) 100 times won't give us 100 different GaloisField objects. This fixes a strange example in the "random(Ring)" docs where we called "tally for i to 100 list random GF 11" and got a Tally object with 100 different key-value pairs.
428b1ea
to
25efd13
Compare
Otherwise, we end up calling QEPCAD, which will fail if it's not available (e.g., on the macOS GitHub builds).
I've updated the support so that So for |
Just pushed another commit fixing a bug I found working on this: Beforei1 : random(QQ, Height => 0)
Floating point exception (core dumped) Afteri1 : random(QQ, Height => 0)
stdio:1:6:(3): error: expected a positive height |
@@ -66,8 +66,7 @@ export rawFareyApproximation(e:Expr):Expr := ( | |||
setupfun("rawFareyApproximation", rawFareyApproximation); | |||
export rawRandomQQ(e:Expr):Expr := ( | |||
when e | |||
is Nothing do toExpr(Ccode(QQ, "rawRandomQQ(", "0)")) | |||
is ht:ZZcell do toExpr(Ccode(QQ, "rawRandomQQ(", ht.v, ")")) | |||
is ht:ZZcell do toExpr(Ccode(QQorNull, "rawRandomQQ(", ht.v, ")")) |
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.
I think it might be simpler to just assert that Height is positive in the top-level, no?
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.
My concern was that we also want to catch this when making random matrices, which is a different call to the engine that isn't specific to the coefficient ring. Is height always positive for all the various meanings of height we might want for random
? Or could it be zero/negative in other contexts?
I keep re-thinking what the support of Considering that the height of a rational number is the max of the absolute values of its numerator and denominator, and the proposed behavior would allow larger numerators, then maybe the current behavior is basically correct, or at least has the correct support. But instead maybe we should have a uniform distribution on that support, rather than the current distribution where 1 is more likely than anything else. So in other words, instead of the distribution being So
|
So where did we land on the support? [0, 1] or [0, height]? |
I think new option random QQ := o -> r -> random(QQ, o, Support => [0,r]) |
If it makes sense to you, I think we should merge this and work on the optional arguments in follow ups. |
I'm not sure if the current proposed behavior is what we want, though, since the numerator can exceed the height. |
This is split off from #3478. I think it makes sense to keep them separate since that deals with the Probability package and this deals with how rationals are randomly generated in the engine. The big change to the commits that were removed from that PR is the proposed probability distribution (no longer normal).
Rather than using the quotient of two discrete random variables with the uniform distribution on {1, ..., h}, we use the continuous uniform distribution on [0, 1], but rounded to the nearest rational number with denominator bounded by the number given by the
Height
option (default 10). For example: