def test_generalised_signature_method(): """Check that dimension and dim of output are correct.""" # Build an array X, note that this is [n_sample, n_channels, length] shape. import esig n_channels = 3 depth = 4 X = np.random.randn(5, n_channels, 10) # Check the global dimension comes out correctly method = SignatureTransformer(depth=depth, window_name="global") assert method.fit_transform(X).shape[1] == esig.sigdim(n_channels + 1, depth) - 1 # Check dyadic dim method = SignatureTransformer(depth=depth, window_name="dyadic", window_depth=3) assert ( method.fit_transform(X).shape[1] == (esig.sigdim(n_channels + 1, depth) - 1) * 15 ) # Ensure an example X = np.array([[0, 1], [2, 3], [1, 1]]).reshape(-1, 2, 3) method = SignatureTransformer(depth=2, window_name="global") true_arr = np.array( [[1.0, 2.0, 1.0, 0.5, 1.33333333, -0.5, 0.66666667, 2.0, -1.0, 1.5, 3.0, 0.5]] ) assert np.allclose(method.fit_transform(X), true_arr)
def test_computed_size_vs_size(self): width = 2 for depth in range(2, 6): with self.subTest(depth=depth): sig = esig.stream2sig(STREAM, depth) size = esig.sigdim(width, depth) self.assertEqual(size, sig.size)
def _rescale_signature(signature, channels, depth): """Rescals the output signature by multiplying the depth-d term by d!. Ain is that every term become ~O(1). Parameters ---------- signature : np.ndarray The signature of a path. Shape [N, Sig_dim]. channels : int The number of channels of the path the signature was computed from. depth : int The depth the signature was computed to. Returns ------- np.ndarray: The signature with factorial depth scaling. """ import esig # Needed for weird esig fails if depth == 1: sigdim = channels elif channels == 1: sigdim = depth else: sigdim = esig.sigdim(channels, depth) - 1 # Verify shape if sigdim != signature.shape[-1]: raise ValueError("A path with {} channels to depth {} should yield a " "signature with {} features. Input signature has {} " "features which is inconsistent.".format( channels, depth, sigdim, signature.shape[-1])) end = 0 term_length = 1 val = 1 terms = [] for d in range(1, depth + 1): start = end term_length *= channels end = start + term_length val *= d terms.append(signature[..., start:end] * val) return np.concatenate(terms, axis=-1)