A picture is worth a thousand words (sorry for the shoddy work):
If the solution is preserving the value and the slope at both ends it is better. If, in addition, the position and sharpness of the transition can be adjusted it is perfect.
But I have not found any solution yet…
Thank you very much for your help
Here is a piece of code to get started:
JavaScript
x
43
43
1
import matplotlib.pyplot as plt
2
from scipy.signal import savgol_filter
3
import numpy as np
4
5
def round_up_to_odd(f):
6
return np.int(np.ceil(f / 2.) * 2 + 1)
7
8
def generateRandomSignal(n=1000, seed=None):
9
"""
10
Parameters
11
----------
12
n : integer, optional
13
Number of points in the signal. The default is 1000.
14
15
Returns
16
-------
17
sig : numpy array
18
19
"""
20
np.random.seed(seed)
21
print("Seed was:", seed)
22
steps = np.random.choice(a=[-1, 0, 1], size=(n-1))
23
roughSig = np.concatenate([np.array([0]), steps]).cumsum(0)
24
sig = savgol_filter(roughSig, round_up_to_odd(n/20), 6)
25
return sig
26
27
n = 1000
28
t = np.linspace(0,10,n)
29
seed = np.random.randint(0,high=100000)
30
#seed = 45136
31
sig = generateRandomSignal(seed=seed)
32
33
###############################
34
# ????
35
# sigFilt = adaptiveFilter(sig)
36
###############################
37
38
# Plot
39
plt.figure()
40
plt.plot(t, sig, label="Signal")
41
# plt.plot(t, sigFilt, label="Signal filtered")
42
plt.legend()
43
Advertisement
Answer
Simple convolution does smoothing. However, as mentioned below, here we need strong smoothing first and no smoothing towards the end. I used the moving average approach with the dynamic size of the window. In the example below, the window size changes linearly.
JavaScript
1
13
13
1
def dynamic_smoothing(x, start_window_length=(len(x)//2), end_window_length=1):
2
d_sum = np.cumsum(a, dtype=float)
3
smoothed = list()
4
for i in range(len(x)):
5
# compute window length
6
a = i / len(x)
7
w = int(np.round(a * start_window_length + (1.0-a) * end_window_length))
8
# get the window
9
w0 = max(0, i - w) # the window must stay inside the array
10
w1 = min(len(x), i + w)
11
smoothed.append(sum(x[w0:w1])/(w1+w0))
12
return np.array(smoothed)
13