|
|
import numpy as np |
|
|
from scipy.fft import rfft, rfftfreq |
|
|
from scipy.signal import hilbert |
|
|
from typing import Dict, Tuple |
|
|
|
|
|
def analyze_cognitive_signal( |
|
|
state_deltas: np.ndarray, |
|
|
sampling_rate: float = 1.0 |
|
|
) -> Dict[str, float]: |
|
|
""" |
|
|
Führt eine fortgeschrittene Signalverarbeitungs-Analyse auf der Zeitreihe der |
|
|
State Deltas durch, um den "kognitiven Frequenz-Fingerabdruck" zu extrahieren. |
|
|
""" |
|
|
if len(state_deltas) < 2: |
|
|
return {} |
|
|
|
|
|
|
|
|
n = len(state_deltas) |
|
|
yf = rfft(state_deltas - np.mean(state_deltas)) |
|
|
xf = rfftfreq(n, 1 / sampling_rate) |
|
|
|
|
|
power_spectrum = np.abs(yf)**2 |
|
|
|
|
|
|
|
|
if len(power_spectrum) > 1: |
|
|
|
|
|
dominant_freq_index = np.argmax(power_spectrum[1:]) + 1 |
|
|
dominant_frequency = xf[dominant_freq_index] |
|
|
|
|
|
|
|
|
prob_dist = power_spectrum / np.sum(power_spectrum) |
|
|
prob_dist = prob_dist[prob_dist > 0] |
|
|
spectral_entropy = -np.sum(prob_dist * np.log2(prob_dist)) |
|
|
else: |
|
|
dominant_frequency = 0.0 |
|
|
spectral_entropy = 0.0 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return { |
|
|
"dominant_frequency": float(dominant_frequency), |
|
|
"spectral_entropy": float(spectral_entropy), |
|
|
} |
|
|
|
|
|
def get_power_spectrum_for_plotting(state_deltas: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: |
|
|
""" |
|
|
Berechnet das Leistungsspektrum speziell für die Visualisierung. |
|
|
""" |
|
|
if len(state_deltas) < 2: |
|
|
return np.array([]), np.array([]) |
|
|
|
|
|
n = len(state_deltas) |
|
|
yf = rfft(state_deltas - np.mean(state_deltas)) |
|
|
xf = rfftfreq(n, 1.0) |
|
|
|
|
|
power_spectrum = np.abs(yf)**2 |
|
|
return xf, power_spectrum |