Skip to content

Commit 2c12f33

Browse files
committed
Add PrecisionManager to flint context
This allows temporarily changing the working precision using python context managers. Related: #5
1 parent 7b2c76d commit 2c12f33

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

doc/source/general.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,28 @@ The special method ``ctx.cleanup()`` frees up internal caches
5555
used by MPFR, FLINT and Arb. The user does normally not have to
5656
worry about this.
5757

58+
The context object ``flint.ctx`` can be controlled locally to increase the
59+
working precision using python context managers::
60+
61+
>>> arb(2).sqrt()
62+
[1.41421356237309 +/- 5.15e-15]
63+
>>> with ctx.extraprec(15):
64+
... arb(2).sqrt()
65+
...
66+
[1.414213562373095049 +/- 2.10e-19]
67+
68+
In the same manner, it is possible to exactly set the working precision,
69+
or to update it in terms of digits::
70+
71+
>>> with ctx.extradps(15):
72+
... arb(2).sqrt()
73+
...
74+
[1.41421356237309504880168872421 +/- 6.27e-31]
75+
>>> with ctx.workprec(15):
76+
... arb(2).sqrt()
77+
...
78+
[1.414 +/- 2.46e-4]
79+
5880
Types and methods
5981
-----------------
6082

src/flint/flint_base/flint_context.pyx

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,18 @@ cdef class FlintContext:
5757
assert num >= 1 and num <= 64
5858
flint_set_num_threads(num)
5959

60+
def extraprec(self, n):
61+
return self.workprec(n + self.prec)
62+
63+
def extradps(self, n):
64+
return self.workdps(n + self.dps)
65+
66+
def workprec(self, n):
67+
return PrecisionManager(self, eprec=n)
68+
69+
def workdps(self, n):
70+
return PrecisionManager(self, edps=n)
71+
6072
def __repr__(self):
6173
return "pretty = %-8s # pretty-print repr() output\n" \
6274
"unicode = %-8s # use unicode characters in output\n" \
@@ -69,4 +81,28 @@ cdef class FlintContext:
6981
def cleanup(self):
7082
flint_cleanup()
7183

84+
85+
class PrecisionManager:
86+
def __init__(self, ctx, eprec=None, edps=None):
87+
if eprec is not None and edps is not None:
88+
raise ValueError("two different precisions requested")
89+
90+
self.ctx = ctx
91+
92+
self.eprec = eprec
93+
self.edps = edps
94+
95+
def __enter__(self):
96+
self._oldprec = self.ctx.prec
97+
98+
if self.eprec is not None:
99+
self.ctx.prec = self.eprec
100+
101+
if self.edps is not None:
102+
self.ctx.dps = self.edps
103+
104+
def __exit__(self, type, value, traceback):
105+
self.ctx.prec = self._oldprec
106+
107+
72108
cdef FlintContext thectx = FlintContext()

0 commit comments

Comments
 (0)