2.4.5. Zero-Dimensional Sublevel Set Persistence
- teaspoon.TDA.SLSP.Persistence0D(ts)[source]
- This function calculates the zero-dimensional sublevel set persistence over a closed time domain
using a recursively updated priority Q as a SortedList data structure. The algorithm is approximately O(log(n)).
- Parameters:
ts (1-D array) – time series.
- Returns:
peristence diagram with p persistence pairs.
- Return type:
[px2 array]
The following is an example implementing the zero-dimensional sublevel set persistence algorithm:
from teaspoon.TDA.SLSP import Persistence0D
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
fs, T = 100, 10
t = np.linspace(-0.2,T,fs*T+1)
A = 20
ts = A*np.sin(np.pi*t) + A*np.sin(1*t)
feature_ind_1, feature_ind_2, persistenceDgm = Persistence0D(ts)
D = persistenceDgm
print(' Persistence Diagram Pairs: ', D)
gs = gridspec.GridSpec(1,2)
plt.figure(figsize=(11,5))
ax = plt.subplot(gs[0, 0])
plt.title('Time Series')
plt.xlabel('$t$')
plt.ylabel('$x(t)$')
plt.plot(t, ts)
ax = plt.subplot(gs[0, 1])
plt.title('Persistence Diagram')
plt.xlabel('Birth')
plt.ylabel('Death')
plt.plot(D.T[0], D.T[1], 'ro')
plt.plot([min(ts), max(ts)], [min(ts), max(ts)], 'k--')
plt.show()
Where the output for this example is:
Persistence Diagram Pairs:
[[-27.87625241 0.4981549 ]
[ -0.05341814 30.33373693]
[-34.58506622 25.25230112]
[ -inf 32.58419686]]
- teaspoon.TDA.SLSP_tools.cutoff(L, n, alpha=0.001, distribution='Gaussian', signal_compensation=True, noise_param=None)[source]
This function calculates the zero-dimensional sublevel set persistence over a closed time domain.
- Parameters:
L (1-D array) – Zero-dimensional sublevel set persistence lifetimes.
n (int) – Length of time series.
alpha (Optional[float]) – Confidence level. Default is 0.1% = 0.001.
distribution (optional[string]) – Assumed distribution of additve noise. ‘Gaussian’ is default. Current options are ‘Gaussian’, , ‘Uniform’, ‘Rayleigh’, and ‘Exponential’
signal_compensation (optional[boolean]) – Signal compensation option for cutoff adjustment.
noise_param (optional[float]) – If the additive noise distribution parameter is known or estimated, it can be provided directly.
- Returns:
Cutoff for the peristence diagram. [float]: Estimated noise distribution parameter.
- Return type:
[float]
The following is an example implementing the zero-dimensional sublevel set persistence algorithm:
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.gridspec as gridspec
from teaspoon.TDA.SLSP import Persistence0D
from teaspoon.TDA.SLSP_tools import cutoff
#----------------Assume the additive noise distribution---------------
dist = 'Gaussian'
#---------------Generate a time series with additive noise------------
fs, T = 40, 10
t = np.linspace(0,T,fs*T)
A, sd = 20, 1 #signal amplitude and standard deviation
ts_0 = A*np.sin(np.pi*t) + A*np.sin(t)
noise = np.random.normal(0,sd,len(ts_0)) #gaussian distribution additive noise
ts = ts_0 + noise #add noise to time series
#--------------Run sublevel set persistence--------------------------
feature_ind_1, feature_ind_2, persistenceDgm = Persistence0D(ts)
B = np.flip(persistenceDgm.T[0], axis = 0) #get birth times
D = np.flip(persistenceDgm.T[1], axis = 0) #get death times
L = D-B #get lifetimes as difference between birth and death
I_B = np.array(feature_ind_1.astype(int)).T #indices of birth times
T_B = np.flip(t[I_B], axis = 0) #time values at birth times
#-------------get cutoff for persistence diagram---------------------
C, param = cutoff(L, alpha = 0.01, n = len(ts), distribution = dist) #get cutoff
print('Distribution parameter estimate: ', param)
print('C: ', C)
#-------------------------PLOTTING THE RESULTS-----------------------
gs = gridspec.GridSpec(2,3)
plt.figure(figsize=(17,5))
TextSize = 15
ax = plt.subplot(gs[0, 0:2])
plt.plot(t,ts, 'k')
plt.ylabel('$x(t)$', size = TextSize)
plt.xticks(size = TextSize)
plt.yticks(size = TextSize)
plt.xlim(min(t),max(t))
ax = plt.subplot(gs[1, 0:2])
plt.ylabel('$L$', size = TextSize)
plt.xlabel('$t$', size = TextSize)
plt.xticks(size = TextSize)
plt.yticks(size = TextSize)
plt.plot(T_B[L>C], L[L>C], 'bd', label = r'$L$ (signal)')
plt.plot(T_B[L<C], L[L<C], 'ko', alpha = 0.7, label = r'$L$ (noise)')
plt.plot([np.min(t),np.max(t)],[C, C],'k--', label = r'$C^*_\alpha$')
ax.fill_between([min(t), max(t)], [C, C], color = 'red', alpha = 0.15)
plt.ylim(0,)
plt.xlim(min(t),max(t))
plt.legend(loc = 'right', fontsize = TextSize-3, ncol = 2)
ax = plt.subplot(gs[0:2, 2])
plt.ylabel('$D$', size = TextSize)
plt.xlabel('$B$', size = TextSize)
plt.xticks(size = TextSize)
plt.yticks(size = TextSize)
plt.plot(B[L>C], D[L>C], 'bd', label = r'signal')
plt.plot(B[L<C], D[L<C], 'ro', alpha = 0.7, label = r'noise')
plt.plot([min(B), max(D)], [min(B), max(D)],'k')
plt.plot([min(B), max(D)], [min(B)+C, max(D)+C],'k--', label = r'$C_\alpha$')
ax.fill_between(x = [min(B), max(D)], y1 = [min(B)+C, max(D)+C], y2 = [min(B), max(D)],
color = 'red', alpha = 0.15)
plt.legend(loc = 'lower right', fontsize = TextSize-3, bbox_to_anchor = (1.02, -0.02))
plt.subplots_adjust(wspace=0.3)
plt.show()
Where the output for this example is:
Distribution parameter estimate: 1.0665900603015368
C: 7.408859563871353