2023-12-01 01:07:48 +01:00
# Remove a common signal from your data
## Goal
We want to remove a common signal which was mixed on top a set of data channels. There are many methods to do so. We will use SVD. Implementations are for example: [scipy.linalg.svd ](https://docs.scipy.org/doc/scipy/reference/generated/scipy.linalg.svd.html ) or [torch.svd_lowrank ](https://pytorch.org/docs/stable/generated/torch.svd_lowrank.html ) (which also works on the GPU)
2023-12-01 00:49:26 +01:00
2023-12-01 01:07:48 +01:00
Questions to [David Rotermund ](mailto:davrot@uni-bremen.de )
## Creating dirty test data
```python
import numpy as np
import matplotlib.pyplot as plt
rng = np.random.default_rng()
time_series_length: int = 1000
2023-12-01 02:08:17 +01:00
number_of_channels: int = 100
t: np.ndarray = np.arange(0, time_series_length) / 1000
2023-12-01 01:07:48 +01:00
# Clean data
2023-12-01 02:08:17 +01:00
frequencies = 10 / rng.random((1, number_of_channels))
phase = 2 * np.pi * rng.random((1, number_of_channels))
2023-12-01 01:07:48 +01:00
clean_data: np.ndarray = (
2023-12-01 02:08:17 +01:00
0.5
* rng.random((1, number_of_channels))
* np.sin(t[..., np.newaxis] * 2 * np.pi * frequencies + phase)
+ np.arange(0, number_of_channels)[np.newaxis, ...]
2023-12-01 01:07:48 +01:00
)
# Perturbation
y: np.ndarray = np.sin(t * 2 * np.pi * 1)
2023-12-01 02:08:17 +01:00
mix_coefficients: np.ndarray = 1 + rng.random((number_of_channels)) * 5
2023-12-01 01:07:48 +01:00
perturbation: np.ndarray = y[..., np.newaxis] * mix_coefficients[np.newaxis, ...]
# Dirty data
dirty_data: np.ndarray = clean_data.copy()
dirty_data += perturbation
np.savez(
"data.npz", clean_data=clean_data, perturbation=perturbation, dirty_data=dirty_data
)
2023-12-01 02:08:17 +01:00
plt.plot(t, clean_data[..., 0:3])
2023-12-01 01:07:48 +01:00
plt.xlabel("Time [s]")
plt.ylabel("Clean data waveform")
plt.show()
2023-12-01 02:08:17 +01:00
plt.plot(t, perturbation[..., 0:3])
2023-12-01 01:07:48 +01:00
plt.xlabel("Time [s]")
plt.ylabel("Perturbation ")
plt.show()
2023-12-01 02:08:17 +01:00
plt.plot(t, dirty_data[..., 0:3])
2023-12-01 01:07:48 +01:00
plt.xlabel("Time [s]")
2023-12-01 02:08:17 +01:00
plt.ylabel("Dirty data ")
2023-12-01 01:07:48 +01:00
plt.show()
```
2023-12-01 01:18:01 +01:00
We get three fully random time series
![figure 1 ](image1.png )
Sine wave with random amplitudes as common perturbation
![figure 2 ](image2.png )
Both combined with random mixing coefficients
![figure 3 ](image3.png )
## Estimating the common signal