Skip to content

Commit 6c0febf

Browse files
authored
Merge pull request #140 from ShikharJ/SympyCompat
Additions to symengine/sympy_compat.py
2 parents 3095abc + 7d0c964 commit 6c0febf

File tree

2 files changed

+70
-3
lines changed

2 files changed

+70
-3
lines changed

symengine/sympy_compat.py

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,15 @@
33
from .compatibility import with_metaclass
44
from .lib.symengine_wrapper import (sympify, sympify as S,
55
SympifyError, sqrt, I, E, pi, Matrix, Derivative, exp,
6-
Lambdify as lambdify, symarray, diff, eye, diag, ones, zeros,
7-
expand, Subs, FunctionSymbol as AppliedUndef)
6+
nextprime, mod_inverse, primitive_root, Lambdify as lambdify,
7+
symarray, diff, eye, diag, ones, zeros, expand, Subs,
8+
FunctionSymbol as AppliedUndef)
89
from types import ModuleType
910
import sys
1011

12+
def dps_to_prec(n):
13+
"""Return the number of bits required to represent n decimals accurately."""
14+
return max(1, int(round((int(n)+1)*3.3219280948873626)))
1115

1216
class BasicMeta(type):
1317
def __instancecheck__(self, instance):
@@ -43,6 +47,34 @@ def __new__(cls, i):
4347
return symengine.Integer(i)
4448

4549

50+
class Float(Number):
51+
_classes = (symengine.RealDouble, symengine.RealMPFR)
52+
53+
def __new__(cls, num, dps=None, precision=None):
54+
if dps is not None and precision is not None:
55+
raise ValueError('Both decimal and binary precision supplied. '
56+
'Supply only one. ')
57+
if dps is None and precision is None:
58+
dps = 15
59+
if precision is None:
60+
precision = dps_to_prec(dps)
61+
62+
if symengine.have_mpfr:
63+
if precision > 53:
64+
if isinstance(num, symengine.RealMPFR) and precision == num.get_prec():
65+
return num
66+
return symengine.RealMPFR(str(num), precision)
67+
if precision > 53:
68+
raise ValueError('RealMPFR unavailable for high precision numerical values.')
69+
elif isinstance(num, symengine.RealDouble):
70+
return num
71+
else:
72+
return symengine.RealDouble(float(num))
73+
74+
75+
RealNumber = Float
76+
77+
4678
class Add(Basic):
4779
_classes = (symengine.Add,)
4880

symengine/tests/test_sympy_compat.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from symengine.sympy_compat import (Integer, Rational, S, Basic, Add, Mul,
2-
Pow, symbols, Symbol, log, sin, sech, csch, zeros, atan2, Number)
2+
Pow, symbols, Symbol, log, sin, sech, csch, zeros, atan2, Number, Float,
3+
symengine)
4+
from symengine.utilities import raises
35

46

57
def test_Integer():
@@ -24,6 +26,39 @@ def test_Rational():
2426
assert not isinstance(x, Number)
2527

2628

29+
def test_Float():
30+
A = Float("1.23", precision = 53)
31+
B = Float("1.23")
32+
C = Float(A)
33+
assert A == B == C
34+
assert isinstance(A, Float)
35+
assert isinstance(B, Float)
36+
assert isinstance(C, Float)
37+
assert isinstance(A, symengine.RealDouble)
38+
assert isinstance(B, symengine.RealDouble)
39+
assert isinstance(C, symengine.RealDouble)
40+
raises(ValueError, lambda: Float("1.23", dps = 3, precision = 10))
41+
raises(ValueError, lambda: Float(A, dps = 3, precision = 16))
42+
if symengine.have_mpfr:
43+
A = Float("1.23", dps = 16)
44+
B = Float("1.23", precision = 56)
45+
assert A == B
46+
assert isinstance(A, Float)
47+
assert isinstance(B, Float)
48+
assert isinstance(A, symengine.RealMPFR)
49+
assert isinstance(B, symengine.RealMPFR)
50+
A = Float(C, dps = 16)
51+
assert A == B
52+
assert isinstance(A, Float)
53+
assert isinstance(A, symengine.RealMPFR)
54+
A = Float(A, precision = 53)
55+
assert A == C
56+
assert isinstance(A, Float)
57+
assert isinstance(A, symengine.RealDouble)
58+
if not symengine.have_mpfr:
59+
raises(ValueError, lambda: Float("1.23", precision = 58))
60+
61+
2762
def test_Add():
2863
x, y = symbols("x y")
2964
i = Add(x, x)

0 commit comments

Comments
 (0)