Skip to content

Commit c48676c

Browse files
authored
Merge pull request #7 from seberg/mpfdtype
ENH: Add my "MPFR" example
2 parents a672b1a + 806a217 commit c48676c

File tree

19 files changed

+2440
-0
lines changed

19 files changed

+2440
-0
lines changed

mpfdtype/.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
dist/
2+
.mesonpy*.ini
3+
__pycache__

mpfdtype/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# A multi precision DType for NumPy
2+
3+
:warning: Note that while the DType is BSD license, MPFR and GMP which it
4+
must be linked with are not.
5+
6+
A very basic example::
7+
8+
import numpy as np
9+
from mpfdtype import MPFDType, MPFloat
10+
11+
# create an array with 200 bits precision:
12+
arr = np.arange(3).astype(MPFDType(200))
13+
print(repr(arr))
14+
# array(['0E+00', '1.0E+00', '2.0E+00'], dtype=MPFDType(200))
15+
16+
# Math uses the input precision (wraps almost all math functions):
17+
res = arr**2 + np.sqrt(arr)
18+
print(repr(res))
19+
# array(['0E+00', '2.0E+00',
20+
# '5.4142135623730950488016887242096980785696718753769480731766784E+00'],
21+
# dtype=MPFDType(200))
22+
23+
# cast to a different precision:
24+
arr2 = arr.astype(MPFDType(500))
25+
print(repr(arr2))
26+
# array(['0E+00', '1.0E+00', '2.0E+00'], dtype=MPFDType(500))
27+
28+
res = arr + arr2
29+
print(repr(res)) # uses the larger precision now
30+
# array(['0E+00', '2.0E+00', '4.0E+00'], dtype=MPFDType(500))
31+
32+
There also is an `mpf.MPFloat(value, prec=None)`. There is no "context"
33+
as most libraries like this (including mpfr itself) typically have.
34+
The rounding mode is always the normal one.

mpfdtype/meson.build

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
project(
2+
'mpfdtype',
3+
'c',
4+
'cpp',
5+
)
6+
7+
py_mod = import('python')
8+
py = py_mod.find_installation()
9+
10+
c = meson.get_compiler('c')
11+
mpfr = c.find_library('mpfr')
12+
13+
incdir_numpy = run_command(py,
14+
[
15+
'-c',
16+
'import numpy; print(numpy.get_include())'
17+
],
18+
check: true
19+
).stdout().strip()
20+
21+
includes = include_directories(
22+
[
23+
incdir_numpy,
24+
'mpfdtype/src',
25+
],
26+
)
27+
28+
srcs = [
29+
'mpfdtype/src/casts.cpp',
30+
'mpfdtype/src/casts.h',
31+
'mpfdtype/src/dtype.c',
32+
'mpfdtype/src/dtype.h',
33+
'mpfdtype/src/mpfdtype_main.c',
34+
'mpfdtype/src/numbers.cpp',
35+
'mpfdtype/src/numbers.h',
36+
'mpfdtype/src/ops.hpp',
37+
'mpfdtype/src/scalar.c',
38+
'mpfdtype/src/scalar.h',
39+
'mpfdtype/src/terrible_hacks.c',
40+
'mpfdtype/src/terrible_hacks.h',
41+
'mpfdtype/src/umath.cpp',
42+
'mpfdtype/src/umath.h',
43+
]
44+
45+
py.install_sources(
46+
[
47+
'mpfdtype/__init__.py',
48+
],
49+
subdir: 'mpfdtype'
50+
)
51+
52+
py.extension_module(
53+
'_mpfdtype_main',
54+
srcs,
55+
install: true,
56+
subdir: 'mpfdtype',
57+
include_directories: includes,
58+
dependencies: [mpfr],
59+
)

mpfdtype/mpfdtype/__init__.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import numpy as np
2+
3+
from ._mpfdtype_main import MPFDType, MPFloat
4+
5+
6+
7+
# Lets add some uglier hacks:
8+
9+
# NumPy uses repr as a fallback (as of writing this code), we want to
10+
# customize the printing of MPFloats though...
11+
def mystr(obj):
12+
if isinstance(obj, MPFloat):
13+
return f"'{obj}'"
14+
return repr(obj)
15+
16+
np.set_printoptions(formatter={"numpystr": mystr})

0 commit comments

Comments
 (0)