tinycwrap 0.0.0__tar.gz → 0.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {tinycwrap-0.0.0 → tinycwrap-0.0.2}/PKG-INFO +1 -1
- {tinycwrap-0.0.0 → tinycwrap-0.0.2}/pyproject.toml +1 -1
- tinycwrap-0.0.2/tests/test_examples.py +97 -0
- tinycwrap-0.0.2/tests/test_geom.py +54 -0
- tinycwrap-0.0.2/tests/test_path.py +23 -0
- {tinycwrap-0.0.0 → tinycwrap-0.0.2}/tinycwrap/__init__.py +1 -1
- tinycwrap-0.0.2/tinycwrap/cmodule.py +989 -0
- tinycwrap-0.0.2/tinycwrap/parsing.py +339 -0
- {tinycwrap-0.0.0 → tinycwrap-0.0.2}/tinycwrap.egg-info/PKG-INFO +1 -1
- {tinycwrap-0.0.0 → tinycwrap-0.0.2}/tinycwrap.egg-info/SOURCES.txt +3 -0
- tinycwrap-0.0.0/tests/test_examples.py +0 -20
- tinycwrap-0.0.0/tinycwrap/cmodule.py +0 -507
- {tinycwrap-0.0.0 → tinycwrap-0.0.2}/README.md +0 -0
- {tinycwrap-0.0.0 → tinycwrap-0.0.2}/setup.cfg +0 -0
- {tinycwrap-0.0.0 → tinycwrap-0.0.2}/tinycwrap.egg-info/dependency_links.txt +0 -0
- {tinycwrap-0.0.0 → tinycwrap-0.0.2}/tinycwrap.egg-info/requires.txt +0 -0
- {tinycwrap-0.0.0 → tinycwrap-0.0.2}/tinycwrap.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
import pytest
|
|
6
|
+
|
|
7
|
+
from tinycwrap import CModule
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@pytest.fixture(scope="module")
|
|
11
|
+
def cm():
|
|
12
|
+
c_path = Path(__file__).resolve().parent / "test_kernels.c"
|
|
13
|
+
return CModule(c_path)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def test_dot(cm):
|
|
17
|
+
x = np.arange(10, dtype=np.float64)
|
|
18
|
+
y = np.ones_like(x)
|
|
19
|
+
assert cm.dot(x, y, len_x=len(x)) == np.sum(x * y)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
def test_scale_auto_output(cm):
|
|
23
|
+
x = np.arange(10, dtype=np.float64)
|
|
24
|
+
scaled_auto = cm.scale(x, 1.1, len_x=len(x))
|
|
25
|
+
np.testing.assert_allclose(scaled_auto, x * 1.1)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def test_scale_explicit_output(cm):
|
|
29
|
+
x = np.arange(10, dtype=np.float64)
|
|
30
|
+
out = np.empty_like(x)
|
|
31
|
+
scaled_explicit = cm.scale(x, 2.0, len_x=len(x), out_x=out)
|
|
32
|
+
np.testing.assert_allclose(out, x * 2.0)
|
|
33
|
+
np.testing.assert_allclose(scaled_explicit, x * 2.0)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def test_struct_wrapper(cm):
|
|
37
|
+
cp = cm.ComplexPair(real=1.5, imag=-2.5)
|
|
38
|
+
assert repr(cp) == "ComplexPair(real=1.5, imag=-2.5)"
|
|
39
|
+
assert cp.real == 1.5
|
|
40
|
+
assert cp.imag == -2.5
|
|
41
|
+
cp.real = 3.0
|
|
42
|
+
cp.imag = 4.0
|
|
43
|
+
assert cp.real == 3.0
|
|
44
|
+
assert cp.imag == 4.0
|
|
45
|
+
np.testing.assert_equal(cp.dtype.fields.keys(), {"real", "imag"})
|
|
46
|
+
assert cp.dtype["real"] == np.dtype(np.float64)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_struct_argument(cm):
|
|
50
|
+
cp = cm.ComplexPair(real=3.0, imag=4.0)
|
|
51
|
+
mag_sq = cm.complex_magnitude(cp)
|
|
52
|
+
assert np.isclose(mag_sq, 5.0)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def test_struct_array_member(cm):
|
|
56
|
+
p = cm.Particle()
|
|
57
|
+
p.pos = [1.0, 2.0, 3.0]
|
|
58
|
+
p.vel = [0.5, 0.5, 0.5]
|
|
59
|
+
np.testing.assert_allclose(p.pos, np.array([1.0, 2.0, 3.0]))
|
|
60
|
+
np.testing.assert_allclose(p.vel, np.array([0.5, 0.5, 0.5]))
|
|
61
|
+
p.pos[:] *= 2.0
|
|
62
|
+
np.testing.assert_allclose(p.pos, np.array([2.0, 4.0, 6.0]))
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def test_struct_array_argument(cm):
|
|
66
|
+
particles = cm.Particle.zeros(2)
|
|
67
|
+
particles["pos"][0] = [0.0, 0.0, 0.0]
|
|
68
|
+
particles["vel"][0] = [1.0, 0.0, 0.0]
|
|
69
|
+
particles["pos"][1] = [0.0, 0.0, 0.0]
|
|
70
|
+
particles["vel"][1] = [0.0, 2.0, 0.0]
|
|
71
|
+
ke = cm.kinetic_energy(particles, len_p=len(particles))
|
|
72
|
+
assert np.isclose(ke, 0.5 * (1.0 + 4.0))
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def test_two_output_arrays(cm):
|
|
76
|
+
data = np.array([0, 1, 2, 3, 4, 5], dtype=np.float64)
|
|
77
|
+
out1, out2 = cm.split_vectors(data)
|
|
78
|
+
np.testing.assert_allclose(out1, np.array([0, 2, 4], dtype=np.float64))
|
|
79
|
+
np.testing.assert_allclose(out2, np.array([1, 3, 5], dtype=np.float64))
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def test_merge_sorted(cm):
|
|
83
|
+
a = np.array([1.0, 2.0, 2.0, 4.0], dtype=np.float64)
|
|
84
|
+
b = np.array([2.0, 3.0], dtype=np.float64)
|
|
85
|
+
out_len = np.zeros(1, dtype=np.int32)
|
|
86
|
+
merged, out_len_val = cm.merge_sorted(a, b, out_len=out_len)
|
|
87
|
+
np.testing.assert_allclose(merged, np.array([1.0, 2.0, 3.0, 4.0]))
|
|
88
|
+
assert out_len_val == 4
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_struct_output_array(cm):
|
|
92
|
+
n = 4
|
|
93
|
+
particles = cm.Particle.zeros(n)
|
|
94
|
+
out_particles = cm.make_particles(3.0, out_p=particles, len_p=n)
|
|
95
|
+
np.testing.assert_array_equal(out_particles, particles)
|
|
96
|
+
np.testing.assert_allclose(particles["pos"], np.ones((n, 3)))
|
|
97
|
+
np.testing.assert_allclose(particles["vel"], np.array([[3.0, 0.0, 0.0]] * n))
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from tinycwrap import CModule
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
@pytest.fixture(scope="module")
|
|
9
|
+
def cg():
|
|
10
|
+
c_path = Path(__file__).resolve().parent / "cgeom.c"
|
|
11
|
+
return CModule(c_path)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_geom2d(cg):
|
|
15
|
+
pts = cg.geom2d_circle_get_points(0.0, 0.0, 1.0)
|
|
16
|
+
assert pts.shape == (101,)
|
|
17
|
+
# first point at angle 0 -> (1,0)
|
|
18
|
+
assert pts["x"][0] == 1.0
|
|
19
|
+
assert abs(pts["y"][0]) < 1e-12
|
|
20
|
+
|
|
21
|
+
def test_geom2d_norm(cg):
|
|
22
|
+
n = cg.geom2d_norm(3.0, 4.0)
|
|
23
|
+
assert n == 5.0
|
|
24
|
+
|
|
25
|
+
def test_circle_points_length_contract(cg):
|
|
26
|
+
pts = cg.geom2d_circle_get_points(1.0, 2.0, 3.0)
|
|
27
|
+
assert pts.shape == (101,)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def test_return_struct_array_member(cg):
|
|
31
|
+
seg = cg.G2DSegment()
|
|
32
|
+
seg.type = 1
|
|
33
|
+
seg.data = [0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0]
|
|
34
|
+
assert seg.type == 1
|
|
35
|
+
np.testing.assert_allclose(seg.data, [0.0, 0.0, 1.0, 1.0, 2.0, 2.0, 3.0, 3.0])
|
|
36
|
+
|
|
37
|
+
def test_geom2d_return_strct(cg):
|
|
38
|
+
seg = cg.geom2d_line_segment_from_start_length(0.1, 0.2, 0.5, 0.4, 0.3)
|
|
39
|
+
assert seg.type == 0
|
|
40
|
+
assert seg.data[0] == 0.1
|
|
41
|
+
assert seg.data[1] == 0.2
|
|
42
|
+
assert np.isclose(seg.data[2], 0.1+0.3*0.5)
|
|
43
|
+
assert np.isclose(seg.data[3], 0.2+0.4*0.3)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_geom2d_return_strct_array_member(cg):
|
|
47
|
+
seg = cg.geom2d_rectangle_to_path(1,2)
|
|
48
|
+
assert len(seg) == 4
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def test_docstring_contains_contract(cg):
|
|
52
|
+
doc = cg.geom2d_rectangle_to_path.__doc__
|
|
53
|
+
assert "Contract: len(out_segments)=4" in doc
|
|
54
|
+
assert "Auto-wrapped C function `geom2d_rectangle_to_path`." in doc
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
import pytest
|
|
5
|
+
|
|
6
|
+
from tinycwrap import CModule
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture(scope="module")
|
|
10
|
+
def cp():
|
|
11
|
+
return CModule(Path("tests/t1/base.c"), Path("tests/t1/path.c"))
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_path_get_steps_contract(cp):
|
|
15
|
+
seg = cp.G2DSegment()
|
|
16
|
+
# line from (0,0) to (1,0)
|
|
17
|
+
seg.type = 0
|
|
18
|
+
seg.data = [0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 0.0]
|
|
19
|
+
segments = np.array([seg._data], dtype=cp.G2DSegment.dtype)
|
|
20
|
+
steps = cp.geom2d_path_get_steps(segments, ds_min=0.25)
|
|
21
|
+
expected_len = cp.geom2d_path_get_len_steps(segments, len_segments=len(segments), ds_min=0.25)
|
|
22
|
+
assert len(steps) == expected_len
|
|
23
|
+
assert np.isclose(steps[-1], cp.geom2d_path_get_length(segments, len_segments=1))
|