Closed xcaruso closed 6 years ago
Branch: u/caruso/lattice_precision
Description changed:
---
+++
@@ -2,126 +2,141 @@
For much more details, I refer to my lecture notes http://xavier.toonywood.org/papers/publis/course-padic.pdf
-The aim of this ticket is to propose to implement these ideas in [SageMath](../wiki/SageMath).
-More precisely, I propose to create a new parent `QpLP` (LP for "lattice precision") for which the precision is tracked using lattices. This leads to some difficulties:
-- Since a lattice does not in general split properly, the precision datum is a global object which must be handled by the parent (and not by its elements). For this reason, the parent has to manage the precision itself for all its elements. In particular, he has to maintain an up-to-date list of all its elements (and should be then informed whenever one of its elements is collected by the garbage collector).
-- If f is not surjective, df_x(H) is no longer a lattice. However, dealing with general Zp-submodules (and not only lattices) is more complicated for several reasons (the first one is that they are not exact objects whereas lattices are). For this reason, we introduce a `working_precision_cap` and feel free to add to our precision lattice any multiple of `p^working_precision_cap` if needed.
+The aim of this ticket is to propose a rough implementation of these ideas.
-## About implementation
-
-The pseudo-code below gives some hints about the implementation I have in mind. Comments are welcome!
+Below is a small demo (extracted from the doctest).
-# The parent -############
-class pAdicFieldLattice(pAdicRingBaseGeneric):
+Of course, when we multiply by 3, we gain one digit of absolute +precision::
def init(self, p, working_precision_cap, print_mode):
sage: 3*x
3 + O(3^11)
def _echelonize(self):
+The lattice precision machinery sees this even if we decompose +the computation into several steps::
def _add_element(self, elt, prec):
sage: y = x+x
sage: y
2 + O(3^10)
sage: x+y
3 + O(3^11)
def _del_element(self, elt):
+The same works for the multiplication::
def precision_absolute(self, elt):
sage: z = x^2
sage: z
1 + O(3^10)
sage: x*z
1 + O(3^11)
def working_precision(self, elt):
+This comes more funny when we are working with elements given +at different precisions::
def _elementconstructor(self, x, prec):
sage: R = ZpLP(2)
sage: x = R(1,10)
sage: y = R(1,5)
sage: z = x+y; z
2 + O(2^5)
sage: t = x-y; t
0 + O(2^5)
sage: z+t # observe that z+t = 2*x
2 + O(2^11)
sage: z-t # observe that z-t = 2*y
2 + O(2^6)
-QpLP = pAdicFieldLattice
+The SOMOS sequence is the sequence defined by the recurrence::
-# The elements -############## +..MATH::
-class pAdicLatticeElement(Element):
un = \frac {u{n-1} u{n-3} + u{n-2}^2} {u_{n-4}}
def working_precision(self):
return self.parent().working_precision(self)
+It is known for its numerical instability.
+On the one hand, one can show that if the initial values are
+invertible in \mathbb{Z}_p
and known at precision O(p^N)
+then all the next terms of the SOMOS sequence will be known
+at the same precision as well.
+On the other hand, because of the division, when we unroll
+the recurrence, we loose a lot of precision. Observe::
def approximation(self):
sage: R = Zp(2, print_mode='terse')
sage: a,b,c,d = R(1,15), R(1,15), R(1,15), R(3,15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
4 + O(2^15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
13 + O(2^15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
55 + O(2^15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
21975 + O(2^15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
6639 + O(2^13)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
7186 + O(2^13)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
569 + O(2^13)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
253 + O(2^13)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
4149 + O(2^13)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
2899 + O(2^12)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
3072 + O(2^12)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
349 + O(2^12)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
619 + O(2^12)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
243 + O(2^12)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
3 + O(2^2)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
2 + O(2^2)
def precision_absolute(self):
return self.parent().precision_absolute(self) +If instead, we use the lattice precision, everything goes well::
def valuation(self, secure=False):
sage: R = ZpLP(2)
sage: a,b,c,d = R(1,15), R(1,15), R(1,15), R(3,15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
4 + O(2^15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
13 + O(2^15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
55 + O(2^15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
21975 + O(2^15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
23023 + O(2^15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
31762 + O(2^15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
16953 + O(2^15)
sage: a,b,c,d = b,c,d,(bd+cc)/a; print d
16637 + O(2^15)
def precision_relative(self, secure=False):
return self.precision_absolute() - self.valuation(secure=secure)
def repr(self):
def add(self, other):
def mul(self, other):
sage: for _ in range(100):
....: a,b,c,d = b,c,d,(bd+cc)/a
sage: a
15519 + O(2^15)
sage: b
32042 + O(2^15)
sage: c
17769 + O(2^15)
sage: d
20949 + O(2^15)
+PS: For now, the code is far from being ready for review. Any help will be of course quite appreciated.
Branch pushed to git repo; I updated commit sha1. New commits:
4b2af06 | First more-or-less working implementation |
I've worked more on my implementation and, at least, it seems now to be usable.
It still requires a lot of work (convert to Cython, write templates, write doctests, rewrite completely the class pRational
which is a hack, etc). I however post it because I think that some people might have fun playing with it and discovering what lattice precision can do. Enjoy :-)
@mezzarobba: I add your name in Cc because I think that you could be interested. If you're not, feel free to remove it.
Branch pushed to git repo; I updated commit sha1. New commits:
858492b | Second rough implementation of lattice precision |
Description changed:
---
+++
@@ -8,135 +8,297 @@
-Of course, when we multiply by 3, we gain one digit of absolute -precision::
-The lattice precision machinery sees this even if we decompose -the computation into several steps::
-The same works for the multiplication::
-This comes more funny when we are working with elements given -at different precisions::
-The SOMOS sequence is the sequence defined by the recurrence::
-..MATH::
-It is known for its numerical instability.
-On the one hand, one can show that if the initial values are
-invertible in \mathbb{Z}_p
and known at precision O(p^N)
-then all the next terms of the SOMOS sequence will be known
-at the same precision as well.
-On the other hand, because of the division, when we unroll
-the recurrence, we loose a lot of precision. Observe::
-If instead, we use the lattice precision, everything goes well::
'partial reduce': 0.0917658805847168}
-PS: For now, the code is far from being ready for review. Any help will be of course quite appreciated.
Branch pushed to git repo; I updated commit sha1. New commits:
1951205 | Fix convert_multiple |
Changed branch from u/caruso/lattice_precision to u/roed/lattice_precision
Branch pushed to git repo; I updated commit sha1. New commits:
90a79f7 | Merge branch 'u/roed/lattice_precision' of git://trac.sagemath.org/sage into t/23505/lattice_precision |
Branch pushed to git repo; I updated commit sha1. New commits:
aa8ae62 | Fix small problem in QpLP in factory |
Branch pushed to git repo; I updated commit sha1. New commits:
0bf65f1 | Merge branch 'u/roed/lattice_precision' of git://trac.sagemath.org/sage into t/23505/lattice_precision |
Changed branch from u/roed/lattice_precision to u/caruso/lattice_precision
Branch pushed to git repo; I updated commit sha1. New commits:
62c5d56 | Some doctests in lattice_precision.py |
Branch pushed to git repo; I updated commit sha1. New commits:
5ef1735 | Doctest in padic_lattice_element.py |
Changed branch from u/caruso/lattice_precision to u/roed/lattice_precision
Changed branch from u/roed/lattice_precision to u/caruso/lattice_precision
Branch pushed to git repo; I updated commit sha1. New commits:
e9bb90b | ZpLP -> ZpLC |
Branch pushed to git repo; I updated commit sha1. New commits:
087eb33 | Fix small bug |
Branch pushed to git repo; I updated commit sha1. New commits:
8d68a69 | Implementation of ZpLF |
Branch pushed to git repo; I updated commit sha1. New commits:
63eee81 | Merge branch 'develop' into lattice_precision |
Branch pushed to git repo; I updated commit sha1. New commits:
c26c01e | Fix bug in is_precision_capped |
I guess that this ticket is now more or less ready for a first review.
I would be happy to help with reviewing this. Since this is quite a lot of code, would you mind to push the code to github/gitlab where it is much easier to comment on lines of code? I can also push it to a repository there myself if you don't mind.
Do you document somewhere why this does not follow the usual linkage pattern used elsewhere in the p-adics code?
Replying to @saraedum:
Do you document somewhere why this does not follow the usual linkage pattern used elsewhere in the p-adics code?
I think the main answer is that it just hasn't been switched to the linkage pattern, but it should be. The pRational will take some work to make this happen. I'll be busy in the next few weeks working on an ANTS paper, but we can talk about this in Rennes. In the mean time, I think if you want to push the code to github/gitlab that should be fine.
In several recent papers, David Roe, Tristan Vaccon and I explain that lattices allow a sharp track of precision: if f is a function we want to evaluate and x is an input given with some uncertainty modeled by a lattice H, then the uncertainty on the output f(x) is exactly df_x(H).
For much more details, I refer to my lecture notes http://xavier.toonywood.org/papers/publis/course-padic.pdf
The aim of this ticket is to propose a rough implementation of these ideas.
You can play with the latest version of this by clicking on launch binder here.
Below is a small demo (extracted from the doctest).
CC: @roed314 @sagetrac-TristanVaccon @saraedum @mezzarobba @sagetrac-swewers
Component: padics
Keywords: sd87
Author: Xavier Caruso
Branch:
f29502e
Reviewer: David Roe, Julian Rüth
Issue created by migration from https://trac.sagemath.org/ticket/23505