Skip to content
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

correction to RealRoots:-realRootIsolation #3100

Merged
merged 2 commits into from
Feb 15, 2024

Conversation

cel34-bath
Copy link
Contributor

@cel34-bath cel34-bath commented Feb 2, 2024

Fixed oversight in realRootIsolation method that fails to perform bisection if the polynomial's leadCoefficient is negative.

Lagrange bound was incorrectly implemented, failing to return a positive values whenever the lead coefficient was negative, and included the leading coefficient. This would give a larger lower bound than its upper bound, giving an interval of negative size, causing it to skip the entire bisection process.

This should now be correct (I have tested this but would appreciate another pair of eyes on this just in case).

As mentions in my issue ticket:

d0:=-2*(x1*(x1-1));
A0 := QQ(monoid[x1]);
h0:=sub(d0, A0);
d1:=-d0;
h1:=sub(d1, A0);

realRootIsolation(h0,1)
realRootIsolation(h1,1)

realRootIsolation(h1,1) correctly returns the root intervals as {{−1,0},{0,1}} but realRootIsolation(h0,1) instead returns {{2,−2}}, giving the wrong number of intervals and a lower bound larger than the upper bound.

The associated issue ticket can be found here: #3101

Fixed oversight in realRootIsolation method that fails to perform bisection if the polynomial's leadCoefficient is negative. Lagrange bound was incorrectly implemented, failing to return a positive values whenever the lead coefficient was negative, and included the leading coefficient. This should now be correct (I have tested this but would appreciate another pair of eyes on this just in case).
@d-torrance
Copy link
Member

This change broke one of the existing tests:

i2 : check(5, "RealRoots", Verbose => true)
 -- capturing check(5, "RealRoots")              -- capture failed; retrying ...
 -- running   check(5, "RealRoots")             
 ulimit -c unlimited; ulimit -t 700; ulimit -m 850000; ulimit -s 8192; ulimit -n 512;  cd /tmp/M2-898930-0/3-rundir/; GC_MAXIMUM_HEAP_SIZE=400M "/usr/bin/M2-binary" --no-randomize --no-readline --silent --stop --print-width 77 --srcdir "/home/profzoom/src/macaulay2/M2/M2" -e 'needsPackage("RealRoots",Reload=>true,FileName=>"/home/profzoom/src/macaulay2/M2/M2/Macaulay2/packages/RealRoots.m2")' <"/tmp/M2-898930-0/2.m2" >>"/tmp/M2-898930-0/2.tmp" 2>&1
/tmp/M2-898930-0/2.tmp:0:1:(3):[12]: (output file) error: Macaulay2 exited with status code 1
/tmp/M2-898930-0/2.m2:0:1: (input file)
M2: *** Error 1
 -- 0.99306 seconds elapsed
../packages/RealRoots.m2:1033:1-1038:1 error:
 -- -- -*- M2-comint -*- hash: 1082028653
 -- 
 -- i1 :  -- /home/profzoom/src/macaulay2/M2/M2/Macaulay2/packages/RealRoots.m2:1038:1: location of test code
 --      
 --          R = QQ[t];
 -- 
 -- i2 :     f = (t-1)^2*(t+3)*(t+5)*(t-6);
 -- 
 -- i3 :     assert(realRootIsolation(f,1/2) == {{-161/32, -299/64}, {-207/64, -23/8}, {23/32, 69/64}, {23/4, 391/64}});
 -- stdio:5:5:(3): error: assertion failed
 -- 
stdio:2:1:(3): error: test(s) #5 of package RealRoots failed.

Here's the new behavior:

i4 : realRootIsolation(f, 1/2)

         1281    2379      1647    183    183  549    183  3111
o4 = {{- ----, - ----}, {- ----, - ---}, {---, ---}, {---, ----}}
          256     512       512     64    256  512     32   512

o4 : List

Since the output of realRootIsolation isn't uniquely determined (I think any pair of rational numbers no more than 1/2 apart from one another that contains the roots of -5, -3, 1, and 6, should work, right?), then maybe the test should be more general. Maybe something like the following?

scan(realRootIsolation(f, 1/2), {-5, -3, 1, 6}, (I, x) -> (
      assert (last I - first I < 1/2);
      assert (x > first I);
      assert (x < last I)))

@cel34-bath
Copy link
Contributor Author

cel34-bath commented Feb 3, 2024 via email

@DanGrayson
Copy link
Member

Could you fix the error?

@DanGrayson DanGrayson changed the base branch from master to development February 12, 2024 18:41
…n interval size

Combined the Lagrange and Cauchy bounds to return the smallest. realRootIsolation no longer bisects intervals when the root is isolated and the interval is below the required size (e.g. when two roots are very close together, the interval widths with be smaller, but the interval widths do not need to be smaller for the other roots). Final list is also sorted in case bisection stops in an interval after the first.

Test also corrected (the new isolating intervals only look 'less nice' because the previous initial bounds happened to be divisible by 8).
@cel34-bath
Copy link
Contributor Author

cel34-bath commented Feb 15, 2024

I've further improved/corrected the initial bound (using the Cauchy-Langrange bound) and also dealt with cases with uneven isolating intervals, e.g. if two roots are very close, it would keep bisecting all roots until those roots were isolated and would stop after those roots were isolated. This would mean every 'non-close' root would have a much smaller isolating interval than needed and the output list might not be arranged smallest to largest. Both of these are now fixed.

The test was updated with the value reflecting this change (as mentioned, the intervals only look 'less nice' because the initial bounds previously happened to be divisible by 8, reducing the denominators by that factor)

I'm not sure if the package preamble needs updating to reflect the changes, i.e. version, date, authors(?), but let me know if they do.

@DanGrayson DanGrayson merged commit be4440a into Macaulay2:development Feb 15, 2024
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants