From 02b5f22d9241327de1af5aaad96d6dd8a7706cc9 Mon Sep 17 00:00:00 2001 From: Sam Morley <41870650+inakleinbottle@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:18:01 +0000 Subject: [PATCH] Fix bug signature domain (#188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add unit test for linear signature computation This test validates the computed linear signature against expected values, covering levels 0 to 3. It includes an explanation for the adjusted divisor in level 3 due to symmetry considerations, ensuring numerical accuracy. * Add resolution parameter to signature method in test Updated the `signature` method call to include a `resolution` parameter in the test case for `LieIncrementStream`. This change ensures consistency with the expected method signature and enhances test clarity. * Adjust resolution to honor refined query interval Ensure the resolution is updated if it’s lower than the refined query's second value. This prevents inconsistencies and ensures proper handling in `log_signature_impl`. * Remove unnecessary resolution update in stream.cpp The conditional update of the resolution variable was redundant and has been removed. This simplifies the code and ensures that `log_signature_impl` is called with the correct parameters without modifying resolution prematurely. * Remove unused 'resolution' parameter in test signature call The 'resolution' parameter in the 'signature' method call was redundant and has been removed for clarity. This ensures the test reflects the current API usage and avoids potential confusion. --- tests/streams/test_lie_increment_path.py | 32 +++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/tests/streams/test_lie_increment_path.py b/tests/streams/test_lie_increment_path.py index efd7fbf28..af25fe799 100644 --- a/tests/streams/test_lie_increment_path.py +++ b/tests/streams/test_lie_increment_path.py @@ -468,4 +468,34 @@ def test_equivariance_esig_treelike3(): tree_like = np.array([[0.0, 0], [1, 1], [3, 1], [2, 1], [1, 1], [2, 0]], dtype=np.float64) pruned = np.array([[0., 0.], [1. ,1.], [2., 0]], dtype=np.float64) - assert_array_almost_equal(esig_stream2sig(tree_like, 2), esig_stream2sig(pruned, 2)) \ No newline at end of file + assert_array_almost_equal(esig_stream2sig(tree_like, 2), esig_stream2sig(pruned, 2)) + + +def test_linear_signature(): + ctx = rp.get_context(width=3, depth=3, coeffs=rp.DPReal) + + start = np.array([0., 0., 0.], dtype=np.float64) + end = np.array([1., 9., -6], dtype=np.float64) + + increment = end - start + + indices = np.array([0.0], dtype=np.float64) + + stream = LieIncrementStream.from_increments(np.array([increment]), indices=indices, ctx=ctx) + + sig = stream.signature(rp.RealInterval(0., 1.)) + + level0 = np.array([1.]) + level1 = increment + level2 = np.einsum("i,j -> ij", level1, level1) / 2 + + + # The divisor here should be 3!, but for some reason, that results in numerical values that are + # half as large as they should be in the level 3 terms. I think it is because we're missing one + # half of the calculations, because of the symmetry. + level3 = np.einsum("ij,k -> ijk", level2, level1) / 3 + + expected = np.hstack([level0, level1, level2.flatten(), level3.flatten()]) + + assert_array_almost_equal(sig, expected) +