Benchmarking

[1]:
import numpy as np
import jax
import jax.numpy as jnp
import time
import WDM

We will time some of the dwt methods on a time series of length \(N=2^{16}=32768\).

[2]:
wdm = WDM.WDM.WDM_transform(dt=1.,
                            Nf=2**8,
                            N=2**15)

x = np.random.normal(size=wdm.N) # white noise
[3]:
t0 = time.time()
w = wdm.forward_transform_exact(x).block_until_ready()
t1 = time.time()

print(f"Time taken: {(t1-t0)*1000:.2f} milliseconds")
Time taken: 1369.47 milliseconds
[4]:
t0 = time.time()
w = wdm.forward_transform_short_fft(x).block_until_ready()
t1 = time.time()

print(f"Time taken: {(t1-t0)*1000:.2f} milliseconds")
Time taken: 94.96 milliseconds
[5]:
t0 = time.time()
w = wdm.forward_transform_fft(x).block_until_ready()
t1 = time.time()

print(f"Time taken: {(t1-t0)*1000:.2f} milliseconds")
Time taken: 44.54 milliseconds

Compilation means subsequent calls can be much faster.

[6]:
t0 = time.time()
w = wdm.dwt(x).block_until_ready()
t1 = time.time()

print(f"Time taken: {(t1-t0)*1000:.2f} milliseconds")

t0 = time.time()
w = wdm.dwt(x).block_until_ready()
t1 = time.time()

print(f"Time taken: {(t1-t0)*1000:.2f} milliseconds")
Time taken: 21.80 milliseconds
Time taken: 0.92 milliseconds

Vectorisation means that batched transforms can also be much faster.

[7]:
x = np.random.normal(size=(20, wdm.N)) # white noise

t0 = time.time()
w = wdm.dwt(x).block_until_ready()
t1 = time.time()

print(f"Time taken: {(t1-t0)*1000:.2f} milliseconds")

t0 = time.time()
w = wdm.dwt(x).block_until_ready()
t1 = time.time()

print(f"Time taken: {(t1-t0)*1000:.2f} milliseconds")
Time taken: 66.06 milliseconds
Time taken: 8.31 milliseconds

Let’s compare this with the cost of an FFT on the same set of time series.

[8]:
t0 = time.time()
w = jnp.fft.fft(x).block_until_ready()
t1 = time.time()

print(f"Time taken: {(t1-t0)*1000:.2f} milliseconds")

t0 = time.time()
w = jnp.fft.fft(x).block_until_ready()
t1 = time.time()

print(f"Time taken: {(t1-t0)*1000:.2f} milliseconds")
Time taken: 41.41 milliseconds
Time taken: 11.78 milliseconds

Let’s also time the inverse transform.

[9]:
x = np.random.normal(size=wdm.N) # white noise

w = wdm.dwt(x)

t0 = time.time()
x_recovered = wdm.idwt(w).block_until_ready()
t1 = time.time()

print(f"Time taken: {(t1-t0)*1000:.2f} milliseconds")
Time taken: 1057.09 milliseconds

The inverse transforms are also vectorised.

[10]:
x = np.random.normal(size=(20, wdm.N)) # white noise

w = wdm.dwt(x)

t0 = time.time()
x_recovered = wdm.idwt(w).block_until_ready()
t1 = time.time()

print(f"Time taken: {(t1-t0)*1000:.2f} milliseconds")
Time taken: 5842.13 milliseconds
[ ]: