spyrit.misc.walsh_hadamard.fwalsh_S

spyrit.misc.walsh_hadamard.fwalsh_S(x, ind=True)[source]

Fast Walsh S-transform of x

Args:

x (np.ndarray): n-by-1 signal. n+1 should be a power of two.

ind (bool, optional): True for sequency (default)

ind (list, optional): permutation indices. This is faster than True

when repeating the sequency-ordered transform multilple times.

Returns:

np.ndarray: n-by-1 S-transformed signal

Example 1:

Walsh-ordered S-transform of a signal of length 7

>>> import spyrit.misc.walsh_hadamard as wh
>>> import numpy as np
>>> x = np.array([1, 3, 0, -1, 7, 5, 1])
>>> s = wh.fwalsh_S(x)
>>> print(s)
[12.  9.  9. 16.  4.  5.  9.]
Example 2:

Permuted fast S-transform

>>> import numpy as np
>>> import spyrit.misc.walsh_hadamard as wh
>>> x = np.array([1, 3, 0, -1, 7, 5, 1])
>>> ind = [1, 0, 3, 2, 7, 4, 5, 6]
>>> y = wh.fwalsh_S(x, ind)
>>> print(y)
[ 0. 16.  9.  4. 12.  5.  9.]
Example 3:

Repeating the Walsh-ordered S-transform using input indices is faster

>>> import timeit
>>> x = np.random.rand(2**12-1,1)
>>> t = timeit.timeit(lambda: wh.fwalsh_S(x), number=100)
>>> print(f"No indices as inputs (10x): {t:.3f} seconds")
No indices as inputs (10x): ... seconds
>>> ind = wh.sequency_perm_ind(x.shape[-1]+1)
>>> t = timeit.timeit(lambda: wh.fwalsh_S(x,ind), number=100)
>>> print(f"With indices as inputs (10x): {t:.3f} seconds")
With indices as inputs (10x): ... seconds
Example 4:

Comparison with S-transform via matrix-vector product

>>> import numpy as np
>>> import spyrit.misc.walsh_hadamard as wh
>>> x = np.array([3, 0, -1, 7, 5, 1, -2])
>>> y1 = wh.fwalsh_S(x)
>>> y2 = wh.walsh_S(x)
>>> print(f"Diff = {np.linalg.norm(y1-y2)}")
Diff = 0.0
Example 5:

Computation times for a signal of length 2**12-1

>>> import timeit
>>> import numpy as np
>>> import spyrit.misc.walsh_hadamard as wh
>>> x = np.random.rand(2**14-1,1)
>>> t = timeit.timeit(lambda: wh.fwalsh_S(x), number=100)
>>> print(f"Fast transform, no ind (10x): {t:.3f} seconds")
Fast transform, no ind (10x): ... seconds
>>> ind = wh.sequency_perm_ind(x.shape[-1]+1)
>>> t = timeit.timeit(lambda: wh.fwalsh_S(x,ind), number=100)
>>> print(f"Fast transform, with ind (10x): {t:.3f} seconds")
Fast transform, with ind (10x): ... seconds
>>> S = wh.walsh_S_matrix(x.shape[-1])
>>> t = timeit.timeit(lambda: wh.walsh_S(x,S), number=100)
>>> print(f"Naive transform (10x): {t:.3f} seconds")
Naive transform (10x): ... seconds