or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

arma-methods.mdcorrelation-signal.mdeigenvalue-methods.mdindex.mdlinear-prediction.mdmath-tools.mdnonparametric-methods.mdparametric-ar.mdwindow-functions.md

eigenvalue-methods.mddocs/

0

# Eigenvalue Methods

1

2

High-resolution spectral estimation using eigenvalue decomposition of the data covariance matrix. These methods excel at resolving closely spaced frequency components and provide superior performance for short data records, particularly in the presence of noise.

3

4

## Capabilities

5

6

### MUSIC Method

7

8

Multiple Signal Classification (MUSIC) method provides high-resolution pseudospectrum estimation by exploiting the orthogonality between signal and noise subspaces.

9

10

```python { .api }

11

def music(X, IP, NSIG=None, NFFT=4096, threshold=None, criteria='aic', verbose=False):

12

"""

13

MUSIC pseudospectrum estimation.

14

15

Parameters:

16

- X: array-like, input time series data

17

- IP: int, total number of sinusoids + noise sources

18

- NSIG: int, number of sinusoidal sources (auto-detected if None)

19

- NFFT: int, FFT length for pseudospectrum computation

20

- threshold: float, threshold for automatic signal detection

21

- criteria: str, model order selection criteria ('aic', 'mdl')

22

- verbose: bool, enable verbose output

23

24

Returns:

25

array: MUSIC pseudospectrum values

26

"""

27

28

class pmusic(data, IP, NSIG=None, NFFT=None, sampling=1., scale_by_freq=False):

29

"""

30

MUSIC pseudospectrum class.

31

32

Parameters:

33

- data: array-like, input time series

34

- IP: int, total number of complex sinusoids + noise

35

- NSIG: int, number of complex sinusoids (auto if None)

36

- NFFT: int, FFT length for pseudospectrum computation

37

- sampling: float, sampling frequency

38

- scale_by_freq: bool, scale pseudospectrum by frequency

39

"""

40

```

41

42

### Eigenvector Method

43

44

Eigenvector method provides an alternative eigenvalue-based approach with different weighting of the noise subspace eigenvectors.

45

46

```python { .api }

47

def ev(X, IP, NSIG=None, NFFT=4096, threshold=None, criteria='aic', verbose=False):

48

"""

49

Eigenvector method pseudospectrum estimation.

50

51

Parameters:

52

- X: array-like, input time series data

53

- IP: int, total number of sinusoids + noise sources

54

- NSIG: int, number of sinusoidal sources (auto-detected if None)

55

- NFFT: int, FFT length for pseudospectrum computation

56

- threshold: float, threshold for automatic signal detection

57

- criteria: str, model order selection criteria ('aic', 'mdl')

58

- verbose: bool, enable verbose output

59

60

Returns:

61

array: Eigenvector pseudospectrum values

62

"""

63

64

class pev(data, IP, NSIG=None, NFFT=None, sampling=1., scale_by_freq=False):

65

"""

66

Eigenvector pseudospectrum class.

67

68

Parameters:

69

- data: array-like, input time series

70

- IP: int, total number of complex sinusoids + noise

71

- NSIG: int, number of complex sinusoids (auto if None)

72

- NFFT: int, FFT length for pseudospectrum computation

73

- sampling: float, sampling frequency

74

- scale_by_freq: bool, scale pseudospectrum by frequency

75

"""

76

```

77

78

### Minimum Variance Method

79

80

Minimum variance distortionless response method provides adaptive beamforming-based spectral estimation.

81

82

```python { .api }

83

def minvar(X, order, sampling=1., NFFT=4096):

84

"""

85

Minimum variance pseudospectrum estimation.

86

87

Parameters:

88

- X: array-like, input time series data

89

- order: int, order of the minimum variance filter

90

- sampling: float, sampling frequency

91

- NFFT: int, FFT length for pseudospectrum computation

92

93

Returns:

94

array: Minimum variance pseudospectrum values

95

"""

96

97

class pminvar(data, order, NFFT=None, sampling=1., scale_by_freq=False):

98

"""

99

Minimum variance pseudospectrum class.

100

101

Parameters:

102

- data: array-like, input time series

103

- order: int, order of the minimum variance filter

104

- NFFT: int, FFT length for pseudospectrum computation

105

- sampling: float, sampling frequency

106

- scale_by_freq: bool, scale pseudospectrum by frequency

107

"""

108

```

109

110

### General Eigenvalue Method

111

112

Unified interface for eigenvalue-based methods allowing selection between MUSIC and eigenvector methods.

113

114

```python { .api }

115

def eigen(X, P, NSIG=None, method='music', threshold=None, NFFT=4096, criteria='aic', verbose=False):

116

"""

117

General eigenvalue-based pseudospectrum estimation.

118

119

Parameters:

120

- X: array-like, input time series data

121

- P: int, total number of sinusoids + noise sources

122

- NSIG: int, number of sinusoidal sources (auto if None)

123

- method: str, method selection ('music', 'ev')

124

- threshold: float, threshold for signal detection

125

- NFFT: int, FFT length for pseudospectrum

126

- criteria: str, order selection criteria ('aic', 'mdl')

127

- verbose: bool, enable verbose output

128

129

Returns:

130

array: Pseudospectrum values

131

"""

132

```

133

134

### Model Order Selection

135

136

Automatic determination of signal and noise subspace dimensions using information-theoretic criteria.

137

138

```python { .api }

139

def aic_eigen(s, N):

140

"""

141

AIC criterion for eigenvalue methods.

142

143

Parameters:

144

- s: array-like, eigenvalues in descending order

145

- N: int, data length

146

147

Returns:

148

array: AIC values for different model orders

149

"""

150

151

def mdl_eigen(s, N):

152

"""

153

MDL criterion for eigenvalue methods.

154

155

Parameters:

156

- s: array-like, eigenvalues in descending order

157

- N: int, data length

158

159

Returns:

160

array: MDL values for different model orders

161

"""

162

```

163

164

## Usage Examples

165

166

### MUSIC Spectral Analysis

167

168

```python

169

import spectrum

170

import numpy as np

171

import matplotlib.pyplot as plt

172

173

# Generate signal with two closely spaced sinusoids in noise

174

N = 64

175

n = np.arange(N)

176

f1, f2 = 0.25, 0.27 # Closely spaced normalized frequencies

177

SNR_dB = 10

178

179

# Create signal

180

signal = (np.exp(1j * 2 * np.pi * f1 * n) +

181

np.exp(1j * 2 * np.pi * f2 * n))

182

noise_power = 10**(-SNR_dB/10) * np.mean(np.abs(signal)**2)

183

noise = np.sqrt(noise_power/2) * (np.random.randn(N) + 1j*np.random.randn(N))

184

noisy_signal = signal + noise

185

186

# MUSIC analysis

187

IP = 15 # Model order (number of complex exponentials + noise)

188

NSIG = 2 # Number of signal components

189

190

# Automatic signal number detection

191

p_music_auto = spectrum.pmusic(noisy_signal, IP=IP)

192

print(f"Auto-detected signals: {p_music_auto.NSIG}")

193

194

# Manual signal specification

195

p_music = spectrum.pmusic(noisy_signal, IP=IP, NSIG=NSIG)

196

197

# Compare with eigenvector method

198

p_ev = spectrum.pev(noisy_signal, IP=IP, NSIG=NSIG)

199

200

# Plot results

201

freqs = np.linspace(0, 1, len(p_music.psd))

202

plt.figure(figsize=(12, 8))

203

204

plt.subplot(2, 1, 1)

205

plt.plot(n, np.real(noisy_signal), 'b-', alpha=0.7, label='Real part')

206

plt.plot(n, np.imag(noisy_signal), 'r-', alpha=0.7, label='Imag part')

207

plt.title(f'Noisy Signal: Two Complex Sinusoids (f1={f1}, f2={f2})')

208

plt.xlabel('Sample')

209

plt.ylabel('Amplitude')

210

plt.legend()

211

plt.grid(True)

212

213

plt.subplot(2, 1, 2)

214

plt.plot(freqs, 10*np.log10(p_music.psd), 'b-', linewidth=2, label='MUSIC')

215

plt.plot(freqs, 10*np.log10(p_ev.psd), 'r--', linewidth=2, label='Eigenvector')

216

plt.axvline(f1, color='k', linestyle=':', alpha=0.7, label='True f1')

217

plt.axvline(f2, color='k', linestyle=':', alpha=0.7, label='True f2')

218

plt.xlabel('Normalized Frequency')

219

plt.ylabel('Pseudospectrum (dB)')

220

plt.title('MUSIC vs Eigenvector Method')

221

plt.legend()

222

plt.grid(True)

223

plt.xlim(0.2, 0.3)

224

225

plt.tight_layout()

226

plt.show()

227

```

228

229

### Model Order Selection

230

231

```python

232

import spectrum

233

import numpy as np

234

import matplotlib.pyplot as plt

235

236

# Generate test signal with known number of components

237

N = 100

238

n = np.arange(N)

239

frequencies = [0.1, 0.15, 0.3] # Three sinusoids

240

amplitudes = [1.0, 0.8, 0.6]

241

242

signal = sum(A * np.exp(1j * 2 * np.pi * f * n)

243

for A, f in zip(amplitudes, frequencies))

244

noise = 0.1 * (np.random.randn(N) + 1j * np.random.randn(N))

245

noisy_signal = signal + noise

246

247

# Test different model orders

248

orders = range(5, 20)

249

aic_values = []

250

mdl_values = []

251

252

for order in orders:

253

# Compute correlation matrix

254

R = spectrum.corrmtx(noisy_signal, order-1, method='autocorrelation')

255

eigenvals = np.linalg.eigvals(R)

256

eigenvals = np.sort(eigenvals)[::-1] # Descending order

257

258

# Compute criteria

259

aic_vals = spectrum.aic_eigen(eigenvals, N)

260

mdl_vals = spectrum.mdl_eigen(eigenvals, N)

261

262

aic_values.append(np.min(aic_vals))

263

mdl_values.append(np.min(mdl_vals))

264

265

# Plot model order selection

266

plt.figure(figsize=(10, 6))

267

plt.subplot(1, 2, 1)

268

plt.plot(orders, aic_values, 'bo-', label='AIC')

269

plt.xlabel('Model Order')

270

plt.ylabel('AIC Value')

271

plt.title('AIC Model Order Selection')

272

plt.grid(True)

273

optimal_aic = orders[np.argmin(aic_values)]

274

plt.axvline(optimal_aic, color='r', linestyle='--',

275

label=f'Optimal: {optimal_aic}')

276

plt.legend()

277

278

plt.subplot(1, 2, 2)

279

plt.plot(orders, mdl_values, 'ro-', label='MDL')

280

plt.xlabel('Model Order')

281

plt.ylabel('MDL Value')

282

plt.title('MDL Model Order Selection')

283

plt.grid(True)

284

optimal_mdl = orders[np.argmin(mdl_values)]

285

plt.axvline(optimal_mdl, color='b', linestyle='--',

286

label=f'Optimal: {optimal_mdl}')

287

plt.legend()

288

289

plt.tight_layout()

290

plt.show()

291

292

print(f"True number of signals: {len(frequencies)}")

293

print(f"AIC optimal order: {optimal_aic}")

294

print(f"MDL optimal order: {optimal_mdl}")

295

```

296

297

### Minimum Variance Spectral Analysis

298

299

```python

300

import spectrum

301

import numpy as np

302

import matplotlib.pyplot as plt

303

304

# Generate signal with multiple frequency components

305

N = 128

306

t = np.arange(N)

307

fs = 1.0 # Sampling frequency

308

309

# Multiple sinusoids with different amplitudes

310

signal = (2.0 * np.sin(2*np.pi*0.1*t) + # Strong component

311

1.0 * np.sin(2*np.pi*0.25*t) + # Medium component

312

0.5 * np.sin(2*np.pi*0.4*t)) # Weak component

313

noise = 0.2 * np.random.randn(N)

314

noisy_signal = signal + noise

315

316

# Compare different eigenvalue methods

317

orders = [10, 15, 20]

318

methods = ['MUSIC', 'Eigenvector', 'Minimum Variance']

319

320

plt.figure(figsize=(15, 10))

321

322

for i, order in enumerate(orders):

323

plt.subplot(len(orders), 3, 3*i + 1)

324

# MUSIC

325

p_music = spectrum.pmusic(noisy_signal, IP=order, NSIG=3)

326

freqs = np.linspace(0, fs/2, len(p_music.psd))

327

plt.semilogy(freqs, p_music.psd)

328

plt.title(f'MUSIC (Order={order})')

329

plt.ylabel('Pseudospectrum')

330

if i == len(orders)-1:

331

plt.xlabel('Frequency')

332

plt.grid(True)

333

334

plt.subplot(len(orders), 3, 3*i + 2)

335

# Eigenvector

336

p_ev = spectrum.pev(noisy_signal, IP=order, NSIG=3)

337

plt.semilogy(freqs, p_ev.psd)

338

plt.title(f'Eigenvector (Order={order})')

339

if i == len(orders)-1:

340

plt.xlabel('Frequency')

341

plt.grid(True)

342

343

plt.subplot(len(orders), 3, 3*i + 3)

344

# Minimum Variance

345

p_minvar = spectrum.pminvar(noisy_signal, order=order)

346

plt.semilogy(freqs, p_minvar.psd)

347

plt.title(f'Min Variance (Order={order})')

348

if i == len(orders)-1:

349

plt.xlabel('Frequency')

350

plt.grid(True)

351

352

plt.tight_layout()

353

plt.show()

354

```