Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions patsy/mgcv_cubic_splines.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ def _map_cyclic(x, lbound, ubound):
)

x = np.copy(x)
if np.issubdtype(x.dtype, np.integer):
x = x.astype(float)
x[x > ubound] = lbound + (x[x > ubound] - ubound) % (ubound - lbound)
x[x < lbound] = ubound - (lbound - x[x < lbound]) % (ubound - lbound)

Expand All @@ -98,6 +100,26 @@ def test__map_cyclic_errors():
pytest.raises(ValueError, _map_cyclic, x, 4.5, 4.5)


def test__map_cyclic_integer():
x = np.arange(-1, 6)
original = x.copy()
mapped = _map_cyclic(x, 0.1, 3.4)
np.testing.assert_allclose(mapped, [2.3, 3.3, 1.0, 2.0, 3.0, 0.7, 1.7])
np.testing.assert_array_equal(x, original)


def test__map_cyclic_float_dtype():
for dtype in [np.float32, np.float64]:
x = np.arange(-1, 6, dtype=dtype)
original = x.copy()
mapped = _map_cyclic(x, 0.1, 3.4)
assert mapped.dtype == x.dtype
np.testing.assert_allclose(
mapped, [2.3, 3.3, 1.0, 2.0, 3.0, 0.7, 1.7], rtol=2 * np.finfo(dtype).eps
)
np.testing.assert_array_equal(x, original)


def _get_cyclic_f(knots):
"""Returns mapping of cyclic cubic spline values to 2nd derivatives.

Expand Down
38 changes: 38 additions & 0 deletions patsy/test_highlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -997,3 +997,41 @@ def test_NAActioon_pandas_string_index():
dm2 = dmatrix(di, data2, 0, return_type="dataframe")
assert np.allclose(dm2, [[1.0, 6.0, 4.0], [1.0, 7.0, 5.0]])
assert list(dm2.columns) == ["Intercept", "x", "z"]


@pytest.mark.parametrize(
"dtype", [np.int32, np.int64, np.uint64, np.float32, np.float64]
)
@pytest.mark.parametrize("constraints", [None, "center"])
def test_cc_integer_input(dtype, constraints):
from patsy import cc

x = np.arange(6, dtype=dtype)
original = x.copy()
kwargs = dict(
knots=[1.0, 2.0, 3.0],
lower_bound=0.1,
upper_bound=3.4,
constraints=constraints,
)
np.testing.assert_allclose(
cc(x, **kwargs), cc(x.astype(float), **kwargs), rtol=1e-6, atol=1e-6
)
formula = (
"0 + cc(x, knots=[1., 2., 3.], lower_bound=0.1, upper_bound=3.4, "
"constraints=%r)" % constraints
)
np.testing.assert_allclose(
dmatrix(formula, {"x": x}),
dmatrix(formula, {"x": x.astype(float)}),
rtol=1e-6,
atol=1e-6,
)
training = dmatrix(formula, {"x": np.array([1.0, 2.0, 3.0])})
np.testing.assert_allclose(
build_design_matrices([training.design_info], {"x": x})[0],
build_design_matrices([training.design_info], {"x": x.astype(float)})[0],
rtol=1e-6,
atol=1e-6,
)
np.testing.assert_array_equal(x, original)
Loading