summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXavier Caruso <xavier.caruso@univ-rennes1.fr>2017-12-23 07:40:50 +0100
committerXavier Caruso <xavier.caruso@univ-rennes1.fr>2017-12-23 07:40:50 +0100
commit5ef1735186f642f81c8a335f07b3f6f05b0a2821 (patch)
treeb638da0a382689bd38b1ee9be3b582c8e20395f3
parentDoctest in padic_base_leaves.py (diff)
Doctest in padic_lattice_element.py
-rw-r--r--src/sage/rings/padics/lattice_precision.py2
-rw-r--r--src/sage/rings/padics/padic_base_leaves.py10
-rw-r--r--src/sage/rings/padics/padic_lattice_element.py691
3 files changed, 680 insertions, 23 deletions
diff --git a/src/sage/rings/padics/lattice_precision.py b/src/sage/rings/padics/lattice_precision.py
index da3c168..d4f7cd5 100644
--- a/src/sage/rings/padics/lattice_precision.py
+++ b/src/sage/rings/padics/lattice_precision.py
@@ -545,7 +545,7 @@ class PrecisionLattice(UniqueRepresentation, SageObject):
tme = walltime()
try:
index = len(self._lattice[ref]) - 1
- except IndexError:
+ except (IndexError, KeyError):
return
self._marked_for_deletion.append(index)
if self._history is not None:
diff --git a/src/sage/rings/padics/padic_base_leaves.py b/src/sage/rings/padics/padic_base_leaves.py
index 07a0de8..f57e7b1 100644
--- a/src/sage/rings/padics/padic_base_leaves.py
+++ b/src/sage/rings/padics/padic_base_leaves.py
@@ -978,12 +978,12 @@ class pAdicLatticeGeneric(pAdicGeneric):
sage: x - y
O(2^50)
"""
- # We first try the __copy__ method which is sharp on precision
+ # We first try the copy method which is sharp on precision
try:
if prec is None:
- return x.__copy__(parent=self)
+ return x.copy(parent=self)
else:
- return x.__copy__(parent=self).add_bigoh(prec)
+ return x.copy(parent=self).add_bigoh(prec)
except (TypeError, ValueError, AttributeError):
pass
return self._element_class(self, x, prec)
@@ -1072,10 +1072,10 @@ class pAdicLatticeGeneric(pAdicGeneric):
# First the elements with precision lattice
for (prec, L) in elt_by_prec.iteritems():
if prec is selfprec:
- # Here, we use the __copy__ method in order
+ # Here, we use the copy method in order
# to be sharp on precision
for x in L:
- y = x.__copy__(parent=self)
+ y = x.copy(parent=self)
for i in indices[id(x)]:
ans[i] = y
else:
diff --git a/src/sage/rings/padics/padic_lattice_element.py b/src/sage/rings/padics/padic_lattice_element.py
index 18a19f7..dd99b5a 100644
--- a/src/sage/rings/padics/padic_lattice_element.py
+++ b/src/sage/rings/padics/padic_lattice_element.py
@@ -8,8 +8,13 @@ from sage.rings.padics.generic_nodes import pAdicRingBaseGeneric
from sage.rings.padics.padic_generic_element import pAdicGenericElement
from sage.rings.padics.lattice_precision import pRational
+from sage.rings.padics.precision_error import PrecisionError
+
class pAdicLatticeElement(pAdicGenericElement):
+ """
+ Constructs new element with given parent and value.
+ """
def __init__(self, parent, x, prec=None, dx=[], dx_mode='linear_combinaison', valuation=None, check=True, reduce=True):
self._parent = parent
pAdicGenericElement.__init__(self, parent)
@@ -22,10 +27,7 @@ class pAdicLatticeElement(pAdicGenericElement):
prec = x.precision_absolute()
else:
prec = min(prec, x.precision_absolute())
- if isinstance(parent, pAdicRingBaseGeneric):
- x = ZZ(x)
- else:
- x = QQ(x)
+ x = QQ(x)
cap = parent.precision_cap()
if prec is None or prec > cap:
prec = cap
@@ -40,26 +42,146 @@ class pAdicLatticeElement(pAdicGenericElement):
self._approx_minusone = pRational(parent.prime(), -1)
def __hash__(self):
+ """
+ Return a hash of this element
+
+ TESTS::
+
+ sage: R = ZpLP(2)
+ sage: x = R(1,10)
+ sage: hash(x) # somewhat random
+ """
return id(self)
+ # This doesn't work apparently (I don't know why)
+ # Deletion is currently handled in PrecisionLattice
+ # def __del__(self):
+ # self._precision.mark_for_deletion(weakref.ref(self))
+
def _is_base_elt(self, p):
return p == self._parent.prime()
def approximation(self):
+ """
+ Return an approximation of this element at
+ its absolute precision
+
+ EXAMPLES::
+
+ sage: R = ZpLP(2, print_mode='terse')
+ sage: x = R(1234,10); x
+ 210 + O(2^10)
+ sage: x.approximation()
+ 210
+ """
prec = self.precision_absolute()
app = self._value.reduce(prec)
return app.value()
def value(self):
+ """
+ Return the actual approximation of this element
+ stored in memory.
+ In presence of diffused digits of precision, it can
+ have more precision than the absolute precision of
+ the element.
+
+ EXAMPLES::
+
+ sage: R = ZpLP(2, print_mode='terse')
+ sage: x = R(1234,10); x
+ 210 + O(2^10)
+ sage: x.approximation()
+ 210
+
+ Another example with diffused digits::
+
+ sage: x = R(2,10); y = R(7,5)
+ sage: u = x - y
+ sage: u
+ 27 + O(2^5)
+ sage: u.value()
+ 1048571
+ """
return self._value.value()
def precision_lattice(self):
+ """
+ Return the precision object (which is a lattice in a possibly
+ high-dimensional vector space) that handles the precision of
+ this element
+
+ EXAMPLES::
+
+ sage: R = ZpLP(2, label='precision')
+ sage: x = R.random_element()
+ sage: y = R.random_element()
+ sage: x.precision_lattice()
+ Precision Lattice on 2 objects (label: precision)
+
+ .. SEEALSO::
+
+ :class:`sage.rings.padics.lattice_precision.PrecisionLattice`
+ """
return self._precision
def precision_absolute(self):
+ """
+ Return the absolute precision of this element
+
+ This precision is computed by projecting the lattice precision
+ onto the coordinate defined by this element
+
+ EXAMPLES::
+
+ sage: R = ZpLP(2, print_mode='terse')
+ sage: x = R(1234,10); x
+ 210 + O(2^10)
+ sage: x.precision_absolute()
+ 10
+
+ Another example with diffused digits::
+
+ sage: x = R(1,10); y = R(1,5)
+ sage: x,y = x+y, x-y
+ sage: x.precision_absolute()
+ 5
+ sage: y.precision_absolute()
+ 5
+ sage: (x+y).precision_absolute()
+ 11
+ """
return self._precision.precision_absolute(self)
def valuation(self, secure=False):
+ """
+ Return the valuation if this element
+
+ INPUT:
+
+ - ``secure`` -- a boolean (default: ``False``); when ``True``,
+ an error is raised if the precision on the element is not
+ enough to determine for sure its valuation; otherwise the
+ absolute precision (which is the smallest possible valuation)
+ is returned
+
+ EXAMPLES::
+
+ sage: R = ZpLP(2)
+ sage: x = R(12,10); x
+ 2^2 + 2^3 + O(2^10)
+ sage: x.valuation()
+ 2
+
+ sage: y = x - x; y
+ O(2^20)
+ sage: y.valuation()
+ 20
+ sage: y.valuation(secure=True)
+ Traceback (most recent call last):
+ ...
+ PrecisionError: Not enough precision
+ """
p = self._parent.prime()
val = self._value.valuation()
prec = self.precision_absolute()
@@ -71,6 +193,34 @@ class pAdicLatticeElement(pAdicGenericElement):
return prec
def precision_relative(self, secure=False):
+ """
+ Return the relative precision of this element, that is
+ the difference between its absolute precision and its
+ valuation
+
+ INPUT:
+
+ - ``secure`` -- a boolean (default: ``False``); when ``True``,
+ an error is raised if the precision on the element is not
+ enough to determine for sure its valuation
+
+ EXAMPLES::
+
+ sage: R = ZpLP(2)
+ sage: x = R(12,10); x
+ 2^2 + 2^3 + O(2^10)
+ sage: x.precision_relative()
+ 8
+
+ sage: y = x - x; y
+ O(2^20)
+ sage: y.precision_relative()
+ 0
+ sage: y.precision_relative(secure=True)
+ Traceback (most recent call last):
+ ...
+ PrecisionError: Not enough precision
+ """
return self.precision_absolute() - self.valuation(secure=secure)
def _cmp_(self, other):
@@ -80,18 +230,77 @@ class pAdicLatticeElement(pAdicGenericElement):
return cmp(self.lift(), other.lift())
def _add_(self, other):
+ """
+ Return the sum of this element and ``other``
+
+ EXAMPLES::
+
+ sage: R = ZpLP(19,5)
+ sage: a = R(-1); a
+ 18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
+ sage: b = R(-5/2); b
+ 7 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
+ sage: a + b # indirect doctest
+ 6 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
+
+ TESTS::
+
+ sage: a = R.random_element()
+ sage: b = R.random_element()
+ sage: a + b == b + a
+ True
+ """
x = self._value + other._value
dx = [ [self, self._approx_one],
[other, self._approx_one] ]
return self.__class__(self._parent, x, self._parent.precision_cap(), dx=dx, check=False)
def _sub_(self, other):
+ """
+ Return the difference of this element and ``other``
+
+ EXAMPLES::
+
+ sage: R = ZpLP(19,5)
+ sage: a = R(-1); a
+ 18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
+ sage: b = R(-5/2); b
+ 7 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
+ sage: a - b # indirect doctest
+ 11 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
+ """
x = self._value - other._value
dx = [ [self, self._approx_one],
[other, self._approx_minusone] ]
return self.__class__(self._parent, x, self._parent.precision_cap(), dx=dx, check=False)
def _mul_(self, other):
+ """
+ Return the product of this element and ``other``
+
+ EXAMPLES::
+
+ sage: R = ZpLP(19,5)
+ sage: a = R(-1); a
+ 18 + 18*19 + 18*19^2 + 18*19^3 + 18*19^4 + O(19^5)
+ sage: b = R(-5/2); b
+ 7 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
+ sage: a * b # indirect doctest
+ 12 + 9*19 + 9*19^2 + 9*19^3 + 9*19^4 + O(19^5)
+
+ TESTS::
+
+ sage: a = R.random_element()
+ sage: b = R.random_element()
+ sage: a * b == b * a
+ True
+
+ sage: a = R.random_element()
+ sage: b = R.random_element()
+ sage: c = R.random_element()
+ sage: a * (b+c) == a*b + a*c
+ True
+ """
x_self = self._value
x_other = other._value
x = x_self * x_other
@@ -100,6 +309,38 @@ class pAdicLatticeElement(pAdicGenericElement):
return self.__class__(self._parent, x, self._parent.precision_cap(), dx=dx, check=False)
def _div_(self, other):
+ """
+ Return the quotient of this element and ``other``
+
+ NOTE::
+
+ The result of division always lives in the fraction field,
+ even if the element to be inverted is a unit.
<