Source code for ewoksxas.fit.tests.test_data

"""Tests for the shared fit data primitives and metrics in ewoksxas.fit.data."""

from dataclasses import FrozenInstanceError

import numpy as np
import pytest

from ewoksxas.fit.data import XYData, as_1d_array, r2, rmse


[docs] def test_as_1d_array(): # flat numpy array array = as_1d_array(np.linspace(0, 1, 10)) assert isinstance(array, np.ndarray) assert array.size == 10 assert array.ndim == 1 # numpy array with shape (1, 10) array = as_1d_array(np.linspace(0, 1, 10).reshape(-1, 1)) assert isinstance(array, np.ndarray) assert array.size == 10 assert array.ndim == 1 # empty numpy array array = as_1d_array(np.empty((0,), dtype=np.float64)) assert isinstance(array, np.ndarray) assert array.size == 0 assert array.ndim == 1 # 2d numpy array with pytest.raises(ValueError, match="Array is scalar or has 2"): as_1d_array(np.ones((10, 10))) # flat list array = as_1d_array(np.linspace(0, 1, 10).tolist()) assert isinstance(array, np.ndarray) assert array.size == 10 assert array.ndim == 1 # flat tuple array = as_1d_array(tuple(np.linspace(0, 1, 10).tolist())) assert isinstance(array, np.ndarray) assert array.size == 10 assert array.ndim == 1 # scalar, strings, bytes, None with pytest.raises(TypeError, match="Expected an array"): as_1d_array(1.0) with pytest.raises(ValueError, match="Array is scalar"): as_1d_array(np.asarray(1.0)) with pytest.raises(TypeError, match="Expected an array"): as_1d_array("1.0") with pytest.raises(ValueError, match="Array is scalar"): as_1d_array(np.asarray("1.0")) with pytest.raises(TypeError, match="Expected an array"): as_1d_array(np.linspace(0, 1, 10).tobytes()) with pytest.raises(TypeError, match="Expected an array"): as_1d_array(None)
[docs] def test_xydata(): x = np.linspace(0, np.pi, 10, dtype=np.float64) y = np.sin(x) data = XYData(x=x, y=y) assert data.x.size == data.y.size == 10 assert np.allclose(data.as_dict()["y"], y) with pytest.raises(ValueError, match="Arrays don't match"): XYData(x=x, y=np.ones(5)) with pytest.raises(FrozenInstanceError, match="cannot assign to field"): data.x = np.arange(10, dtype=np.float64) with pytest.raises(TypeError, match="an instance or subtype of type"): data.z = y
[docs] def test_metrics_perfect_model(): observed = np.array([1.0, 2.0, 4.0, 8.0]) assert r2(observed, observed.copy()) == 1.0 assert rmse(observed, observed.copy()) == 0.0
[docs] def test_rmse_hand_computed(): observed = np.array([0.0, 0.0, 0.0, 0.0]) model = np.array([1.0, -1.0, 1.0, -1.0]) assert rmse(observed, model) == pytest.approx(1.0) assert rmse(observed, 2.0 * model) == pytest.approx(2.0)
[docs] def test_r2_hand_computed(): observed = np.array([0.0, 1.0, 2.0, 3.0]) # Half the residual variance of the mean model -> r2 == 0.5. mean = observed.mean() model = observed + (mean - observed) / np.sqrt(2.0) assert r2(observed, model) == pytest.approx(0.5) # The constant-mean model explains nothing. assert r2(observed, np.full_like(observed, mean)) == pytest.approx(0.0)
[docs] def test_r2_zero_variance_is_nan(): observed = np.full(5, 3.0) assert np.isnan(r2(observed, observed + 0.1))