shifting issue in padic _set_from_list functions
Closed this issue · 23 comments
Using version 9.1 of sage, the function _set_from_list_both(), implemented in: /sage/src/sage/rings/padics/padic_ZZ_pX_element.pyx, crashes or returns wrong results for some inputs.
Example for wrong results:
sage: T.<a> = Qp(5).extension(x^2-5)
sage: W.<w> = Qp(5).extension(x^2-5)
sage: W(a^-41)
O(w^-1)
Example for a crash (full output is availabale in the attached file):
sage: T.<a> = Qp(5).extension(x^2-5)
sage: T([5^-2], absprec=-1)
------------------------------------------------------------------------
/home/noa/workspace/padic_project/sage/local/lib/python3.7/site-packages/cysignals/signals.cpython-37m-x86_64-linux-gnu.so(+0x828b)[0x7f250e49428b]
/home/noa/workspace/padic_project/sage/local/lib/python3.7/site-packages/cysignals/signals.cpython-37m-x86_64-linux-gnu.so(+0x8348)[0x7f250e494348]
/home/noa/workspace/padic_project/sage/local/lib/python3.7/site-packages/cysignals/signals.cpython-37m-x86_64-linux-gnu.so(+0xb323)[0x7f250e497323]
/lib/x86_64-linux-gnu/libc.so.6(+0x3ef20)[0x7f251cc46f20]
/home/noa/workspace/padic_project/sage/local/lib/python3.7/site-packages/sage/rings/padics/padic_ZZ_pX_CR_element.cpython-37m-x86_64-linux-gnu.so(+0x34d62)[0x7f2455837d62]
/home/noa/workspace/padic_project/sage/local/lib/python3.7/site-packages/sage/rings/padics/padic_ZZ_pX_element.cpython-37m-x86_64-linux-gnu.so(+0x1f27d)[0x7f2455c9027d]
/home/noa/workspace/padic_project/sage/local/lib/python3.7/site-packages/sage/rings/padics/padic_ZZ_pX_CR_element.cpython-37m-x86_64-linux-gnu.so(+0x2fee9)[0x7f2455832ee9]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(+0x105972)[0x7f251d0fe972]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(PyObject_Call+0x68)[0x7f251d096538]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalFrameDefault+0x4fc5)[0x7f251d067d65]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalCodeWithName+0xa81)[0x7f251d181af1]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyFunction_FastCallDict+0x14a)[0x7f251d093cda]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyObject_Call_Prepend+0xcc)[0x7f251d094ecc]
/home/noa/workspace/padic_project/sage/local/lib/python3.7/site-packages/sage/structure/coerce_maps.cpython-37m-x86_64-linux-gnu.so(+0x7c7c)[0x7f25074c2c7c]
/home/noa/workspace/padic_project/sage/local/lib/python3.7/site-packages/sage/structure/coerce_maps.cpython-37m-x86_64-linux-gnu.so(+0x13bec)[0x7f25074cebec]
/home/noa/workspace/padic_project/sage/local/lib/python3.7/site-packages/sage/structure/parent.cpython-37m-x86_64-linux-gnu.so(+0x1dfa9)[0x7f250d533fa9]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyObject_FastCallKeywords+0xc3)[0x7f251d094503]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalFrameDefault+0x5132)[0x7f251d067ed2]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalCodeWithName+0xa81)[0x7f251d181af1]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(PyEval_EvalCodeEx+0x3e)[0x7f251d181bde]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(PyEval_EvalCode+0x1b)[0x7f251d181c0b]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(+0x185e4d)[0x7f251d17ee4d]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyMethodDef_RawFastCallKeywords+0x23d)[0x7f251d09433d]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyCFunction_FastCallKeywords+0x25)[0x7f251d094425]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalFrameDefault+0x8ffe)[0x7f251d06bd9e]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalCodeWithName+0xa81)[0x7f251d181af1]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyFunction_FastCallKeywords+0x8f)[0x7f251d093eef]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalFrameDefault+0x7219)[0x7f251d069fb9]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalCodeWithName+0xa81)[0x7f251d181af1]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyFunction_FastCallKeywords+0x8f)[0x7f251d093eef]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalFrameDefault+0x6cae)[0x7f251d069a4e]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalCodeWithName+0xa81)[0x7f251d181af1]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyFunction_FastCallKeywords+0x8f)[0x7f251d093eef]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalFrameDefault+0x6cae)[0x7f251d069a4e]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalCodeWithName+0xa81)[0x7f251d181af1]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyFunction_FastCallKeywords+0x8f)[0x7f251d093eef]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalFrameDefault+0x7219)[0x7f251d069fb9]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalCodeWithName+0xa81)[0x7f251d181af1]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyFunction_FastCallKeywords+0x8f)[0x7f251d093eef]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalFrameDefault+0x7219)[0x7f251d069fb9]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(+0x68c8f)[0x7f251d061c8f]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalFrameDefault+0x7219)[0x7f251d069fb9]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_PyEval_EvalCodeWithName+0xa81)[0x7f251d181af1]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(PyEval_EvalCodeEx+0x3e)[0x7f251d181bde]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(PyEval_EvalCode+0x1b)[0x7f251d181c0b]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(PyRun_FileExFlags+0xaa)[0x7f251d1b6f3a]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(PyRun_SimpleFileExFlags+0xfd)[0x7f251d1b70ad]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(+0x1e25e0)[0x7f251d1db5e0]
/home/noa/workspace/padic_project/sage/local/lib/libpython3.7m.so.1.0(_Py_UnixMain+0x49)[0x7f251d1db859]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7f251cc29b97]
/home/noa/workspace/padic_project/sage/local/bin/python3(_start+0x2a)[0x558e97ef478a]
------------------------------------------------------------------------
The bug occurs because the element is set to the desirable absolute precision before it is shifted by pmin_val.
To fix this, I subtracted (min_val * ramification-index) from the absolute precision to which the element is set, so that after shifting it will hopefully reach the desirable precision.
However, this does not completely solve the problem, because in case p is not a power of the uniformizer, shifting doesn't necessarily increase the absolute precision by exactly (min_val * ramification-index). So perhaps it would be best to set the absolute precision to the desirable value, only after the shifting (I didn't figure out how to do this correctly).
However, if it isn't necessary to have the exact desirable precision, the above solution could be enough.
The issue of shifting after setting the precision, is also relevant to _set_from_list_abs(), which I changed similarly.
Note: The first example given in this ticket requires fixing not only this bug, but also tickets #29925, #29926. After those bugs are all fixed, we get the result: w-41 + O(w-2).
Component: padics
Keywords: precision, set_from_list, shifting
Author: Noa Viner
Branch/Commit: a97b2a6
Reviewer: Julian Rüth
Issue created by migration from https://trac.sagemath.org/ticket/29927
Attachment: set_from_list_both_crash_log.gz
Description changed:
---
+++
@@ -1,4 +1,4 @@
-Using version 9.1 of sage, the function _set_from_list_both(), which is written in the file: /sage/src/sage/rings/padics/padic_ZZ_pX_element.pyx, crashes or returns wrong results for some inputs.
+Using version 9.1 of sage, the function _set_from_list_both(), implemented in: /sage/src/sage/rings/padics/padic_ZZ_pX_element.pyx, crashes or returns wrong results for some inputs.
Example for wrong results:
@@ -8,7 +8,7 @@
sage: W(a^-41)
O(w^-1)
```
-Example for a crash (see full output in attached file):
+Example for a crash (full output is availabale in the attached file):
```
sage: T.<a> = Qp(5).extension(x^2-5)
@@ -72,8 +72,10 @@
To fix this, I subtracted (min_val * ramification-index) from the absolute precision to which the element is set, so that **after** shifting it will hopefully reach the desirable precision.
-However, this does not completely solve the problem, because in case p is not a power of the uniformizer, it's not necessary that shifting increases the absolute precision in exactly (min_val * ramification-index). So perhaps it would be best to set the absolute precision to the desirable value, only **after** the shifting (I didn't figure out how to do this correctly).
+However, this does not completely solve the problem, because in case p is not a power of the uniformizer, shifting doesn't necessarily increase the absolute precision by exactly (min_val * ramification-index). So perhaps it would be best to set the absolute precision to the desirable value, only **after** the shifting (I didn't figure out how to do this correctly).
However, if it isn't necessary to have the exact desirable precision, the above solution could be enough.
-Note: The issue of shifting after setting the precision, is also relevant for _set_from_list_abs(), which I changed similarly.
+The issue of shifting after setting the precision, is also relevant to _set_from_list_abs(), which I changed similarly.
+
+Note: The first example given in this ticket requires fixing not only this bug, but also tickets #29925, #29926. After those bugs are all fixed, we get the result: w<sup>-41</sup> + O(w<sup>-2</sup>).this looks simple enough, but needs people that know the padics code
gh-n-vi: I don't know a better way of contacting you. So, we're meeting every Thursday 3pm US/Eastern = 9pm CEST on Zulip (and then maybe in Zoom.) Feel free to join us if you want to discuss p-adics :)
https://zulip.sagemath.org/#narrow/stream/15-padics
Replying to @saraedum:
gh-n-vi: I don't know a better way of contacting you. So, we're meeting every Thursday 3pm US/Eastern = 9pm CEST on Zulip (and then maybe in Zoom.) Feel free to join us if you want to discuss p-adics :)
https://zulip.sagemath.org/#narrow/stream/15-padics
Thanks saraedum, I would be glad to join the discussion!
Would you mind adding the first example to the doctests as well? (I read that it did not work originally, but it should now, right?)
Reviewer: Julian Rüth
However, this does not completely solve the problem, because in case p is not a power of the uniformizer, shifting doesn't necessarily increase the absolute precision by exactly (min_val * ramification-index).
True. It's been a while since I looked at this. But isn't it at most off by one?
Is this correct when min_val is positive?
self._set_from_ZZ_pX_abs(&(<ntl_ZZ_pX>ntl_ZZ_pX(L, ctx)).x, ctx, absprec - (min_val * self.parent().e()))
When min_val is large, wouldn't x be 0 modulo the precision then?
It seems to me that you have to do the shift (probably depending on the sign of min_val) and then reduce the precision to absprec explicitly again for this to be really correct. Is that what you tried originally? Feel free to ask on Zulip if you are not sure how to do this.
Branch pushed to git repo; I updated commit sha1. New commits:
41856e4 | Add first doctest |
Hi Julian, thank you for the review!
- I have added the first example as you suggested.
- Regarding the question of the increase in the absolute-precision when shifting by pmin_val :
Rethinking about the subject, it seems to me that perhaps the absolute-precision is actually increased by exactly (min_val * ramification-index).
Here is a proof (if anything in the process is wrong, I will appreciate any corrections!):
Denote the original number by x, the uniformizer by u, the ramification index by e, and min_val by n.
- The valuation of p always equals e. Therefore the valuation of pn is en.
Denote: pn = a0(uen) + a1(uen+1) + a2(ue*n+2) +... - xpn = (xa0*(uen)) + (xa1*(uen+1)) + (xa2*(ue*n+2)) +...
- The absolute-precision of x*pn equals the absolute-precision of the element which has the lowest absolute-precision among those in the sum.
- For each i>=0, (xai(uen+i)).absolute_precision() = x.absolute_precision() + en+i.
-
- and 4. imply that: (xpn).absolute_precision() = (xa0*(uen)).absolute_precision() = x.absolute_precision() + en.
Therefore, the absolute-precision has indeed been increased by exactly e*n.
- and 4. imply that: (xpn).absolute_precision() = (xa0*(uen)).absolute_precision() = x.absolute_precision() + en.
-
Correctness in case min_val is positive:
Denote the valuation of x by v, and: x = a0*(uv) + a1*(uv+1) + ...
If the i-th element in this sum is truncated when setting the precision of x to (absprec - (min_val * e)), it means that i >= (absprec - (min_val * e)).
Now, I claim that this element would also be truncated if we set the precision after the shifting. Let's assume for simplicity that p is a power of the uniformizer: p=ue, which implies that: pmin_val=umin_vale.
We need to shift x by pmin_val and then truncate its precision to absprec.
So the i-th element is shifted by min_vale entries, and now equals: ai*(uv+i+min_vale).
Now we set the result (xpmin_val) to precision absprec. We assumed that i >= (absprec - (min_val * e)). Therefore i+min_vale >= absprec, which implies that this element (ai(uv+i+min_val*e)) is truncated.
Therefore I think that if min_val is large enough so that x is 0 modolu (absprec - (min_val * e)), it is O.K because x would be truncated either way. Am I right in this deduction? -
The problem I had with changing the precision after the shifting, is that I don't know how to increase precision of elements (the only method I found to be relevant is lift_to_precision, but it does not guarantee that the new entries that are added to the element are zero-entries). So if I wanted to do this, I would have to make sure that the precision needs to be decreased rather than increased.
Sage development has entered the release candidate phase for 9.3. Setting a new milestone for this ticket based on a cursory review of ticket status, priority, and last modification date.
Therefore I think that if min_val is large enough so that x is 0 modolu (absprec - (min_val * e)), it is O.K because x would be truncated either way. Am I right in this deduction?
It was my understanding that this code also used for capped-relative p-adics? In that case I don't think that this is correct.
Setting a new milestone for this ticket based on a cursory review.
Replying to @saraedum:
It was my understanding that this code also used for capped-relative p-adics? In that case I don't think that this is correct.
Hi Julian!
Sorry about the very-long-delay in answering your comment.
Can you please explain, or give an example, why there should be a problem with the capped-relative case? I tried to think about it but didn't manage to figure out myself.
Thank you!
I made some minor modifications to the documentation. If these look good to you, feel free to set this to positive review.
Sorry, for getting you wrong the first time and delaying this forever in doing so. The relprec in the docstring confused me when it should have been absprec.
New commits:
c76d35e | Merge remote-tracking branch 'trac/develop' into HEAD |
4203fd1 | Merge remote-tracking branch 'trac/develop' into HEAD |
a97b2a6 | Improve set_from_list documentation |
This is great, thank you Julian! The documentation was indeed misleading here...
Changed branch from u/saraedum/shifting_issue_in_padic__set_from_list_functions to a97b2a6