or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

coefficient-utils.mdcontinuous-dwt.mdindex.mdmulti-level-dwt.mdmultiresolution-analysis.mdsingle-level-dwt.mdstationary-dwt.mdthresholding.mdwavelet-packets.mdwavelets.md

multi-level-dwt.mddocs/

0

# Multi-Level Discrete Wavelet Transform

1

2

Multi-level wavelet decomposition and reconstruction providing hierarchical analysis with automatic or specified decomposition levels for comprehensive signal and image analysis.

3

4

## Capabilities

5

6

### 1D Multi-Level DWT

7

8

Hierarchical decomposition and reconstruction for one-dimensional signals.

9

10

```python { .api }

11

def wavedec(data, wavelet, mode: str = 'symmetric', level: int = None, axis: int = -1):

12

"""

13

Multi-level 1D discrete wavelet decomposition.

14

15

Parameters:

16

- data: Input 1D array or multi-dimensional array

17

- wavelet: Wavelet specification (string name, Wavelet object, or filter bank)

18

- mode: Signal extension mode for boundary handling

19

- level: Decomposition level (default: maximum possible level)

20

- axis: Axis along which to perform decomposition (default: -1, last axis)

21

22

Returns:

23

List [cAn, cDn, cDn-1, ..., cD1] where:

24

- cAn: Approximation coefficients at level n

25

- cDi: Detail coefficients at level i (from finest to coarsest)

26

"""

27

28

def waverec(coeffs, wavelet, mode: str = 'symmetric', axis: int = -1):

29

"""

30

Multi-level 1D discrete wavelet reconstruction.

31

32

Parameters:

33

- coeffs: Coefficient list from wavedec [cAn, cDn, ..., cD1]

34

- wavelet: Wavelet specification matching decomposition

35

- mode: Signal extension mode matching decomposition

36

- axis: Axis along which to perform reconstruction

37

38

Returns:

39

Reconstructed 1D signal

40

"""

41

```

42

43

#### Usage Examples

44

45

```python

46

import pywt

47

import numpy as np

48

import matplotlib.pyplot as plt

49

50

# Create test signal with multiple frequency components

51

t = np.linspace(0, 2, 2048)

52

signal = (np.sin(2 * np.pi * 1 * t) + # Low frequency

53

0.5 * np.sin(2 * np.pi * 10 * t) + # Medium frequency

54

0.3 * np.sin(2 * np.pi * 100 * t)) # High frequency

55

noise = 0.1 * np.random.randn(len(signal))

56

noisy_signal = signal + noise

57

58

# Multi-level decomposition

59

coeffs = pywt.wavedec(noisy_signal, 'db8', level=6)

60

print(f"Number of coefficient arrays: {len(coeffs)}")

61

print(f"Coefficient array lengths: {[len(c) for c in coeffs]}")

62

63

# Access approximation and detail coefficients

64

cA6 = coeffs[0] # Approximation at level 6 (coarsest)

65

cD6 = coeffs[1] # Detail at level 6 (coarsest detail)

66

cD5 = coeffs[2] # Detail at level 5

67

cD4 = coeffs[3] # Detail at level 4

68

cD3 = coeffs[4] # Detail at level 3

69

cD2 = coeffs[5] # Detail at level 2

70

cD1 = coeffs[6] # Detail at level 1 (finest detail)

71

72

# Perfect reconstruction

73

reconstructed = pywt.waverec(coeffs, 'db8')

74

print(f"Reconstruction error: {np.max(np.abs(noisy_signal - reconstructed))}")

75

76

# Selective reconstruction - remove high-frequency noise (cD1, cD2)

77

denoised_coeffs = coeffs.copy()

78

denoised_coeffs[-1][:] = 0 # Zero out cD1 (finest details)

79

denoised_coeffs[-2][:] = 0 # Zero out cD2 (second finest details)

80

denoised_signal = pywt.waverec(denoised_coeffs, 'db8')

81

82

# Visualization

83

fig, axes = plt.subplots(4, 2, figsize=(15, 12))

84

85

# Original signals

86

axes[0, 0].plot(t, signal, 'b-', label='Clean')

87

axes[0, 0].plot(t, noisy_signal, 'r-', alpha=0.7, label='Noisy')

88

axes[0, 0].set_title('Original Signals')

89

axes[0, 0].legend()

90

91

axes[0, 1].plot(t, denoised_signal, 'g-', label='Denoised')

92

axes[0, 1].plot(t, signal, 'b--', alpha=0.7, label='True Signal')

93

axes[0, 1].set_title('Denoising Result')

94

axes[0, 1].legend()

95

96

# Plot coefficients at different levels

97

for i, (coeff, title) in enumerate(zip(coeffs[1:],

98

['cD6 (Coarsest Detail)', 'cD5', 'cD4',

99

'cD3', 'cD2', 'cD1 (Finest Detail)'])):

100

row = (i // 2) + 1

101

col = i % 2

102

if row < 4:

103

axes[row, col].plot(coeff)

104

axes[row, col].set_title(title)

105

106

plt.tight_layout()

107

plt.show()

108

109

# Automatic vs manual level selection

110

max_level = pywt.dwt_max_level(len(noisy_signal), pywt.Wavelet('db8').dec_len)

111

print(f"Maximum possible decomposition level: {max_level}")

112

113

# Decompose with automatic level

114

coeffs_auto = pywt.wavedec(noisy_signal, 'db8')

115

print(f"Automatic decomposition levels: {len(coeffs_auto) - 1}")

116

```

117

118

### 2D Multi-Level DWT

119

120

Hierarchical decomposition and reconstruction for two-dimensional data such as images.

121

122

```python { .api }

123

def wavedec2(data, wavelet, mode: str = 'symmetric', level: int = None, axes=(-2, -1)):

124

"""

125

Multi-level 2D discrete wavelet decomposition.

126

127

Parameters:

128

- data: Input 2D array or multi-dimensional array

129

- wavelet: Wavelet specification

130

- mode: Signal extension mode for boundary handling

131

- level: Decomposition level (default: maximum possible level)

132

- axes: Pair of axes along which to perform 2D DWT (default: last two axes)

133

134

Returns:

135

List [cAn, (cHn, cVn, cDn), (cHn-1, cVn-1, cDn-1), ..., (cH1, cV1, cD1)] where:

136

- cAn: Approximation coefficients at level n

137

- (cHi, cVi, cDi): Horizontal, vertical, diagonal detail coefficients at level i

138

"""

139

140

def waverec2(coeffs, wavelet, mode: str = 'symmetric', axes=(-2, -1)):

141

"""

142

Multi-level 2D discrete wavelet reconstruction.

143

144

Parameters:

145

- coeffs: Coefficient list from wavedec2

146

- wavelet: Wavelet specification matching decomposition

147

- mode: Signal extension mode matching decomposition

148

- axes: Pair of axes along which to perform 2D IDWT

149

150

Returns:

151

Reconstructed 2D array

152

"""

153

```

154

155

#### Usage Examples

156

157

```python

158

import pywt

159

import numpy as np

160

import matplotlib.pyplot as plt

161

162

# Create test image with different frequency content

163

x, y = np.mgrid[0:256, 0:256]

164

image = (np.sin(2 * np.pi * x / 64) * np.cos(2 * np.pi * y / 64) + # Low frequency

165

0.5 * np.sin(2 * np.pi * x / 16) * np.cos(2 * np.pi * y / 16) + # Medium frequency

166

0.3 * np.sin(2 * np.pi * x / 4) * np.cos(2 * np.pi * y / 4)) # High frequency

167

168

# Add noise

169

noisy_image = image + 0.2 * np.random.randn(*image.shape)

170

171

# Multi-level 2D decomposition

172

coeffs = pywt.wavedec2(noisy_image, 'db4', level=4)

173

print(f"Number of decomposition levels: {len(coeffs) - 1}")

174

print(f"Approximation shape: {coeffs[0].shape}")

175

for i, (cH, cV, cD) in enumerate(coeffs[1:], 1):

176

print(f"Level {len(coeffs)-i} detail shapes: {cH.shape}, {cV.shape}, {cD.shape}")

177

178

# Perfect reconstruction

179

reconstructed = pywt.waverec2(coeffs, 'db4')

180

print(f"2D Reconstruction error: {np.max(np.abs(noisy_image - reconstructed))}")

181

182

# Image denoising by coefficient thresholding

183

def threshold_coeffs(coeffs, threshold):

184

"""Apply soft thresholding to detail coefficients."""

185

coeffs_thresh = [coeffs[0]] # Keep approximation unchanged

186

for cH, cV, cD in coeffs[1:]:

187

cH_thresh = pywt.threshold(cH, threshold, mode='soft')

188

cV_thresh = pywt.threshold(cV, threshold, mode='soft')

189

cD_thresh = pywt.threshold(cD, threshold, mode='soft')

190

coeffs_thresh.append((cH_thresh, cV_thresh, cD_thresh))

191

return coeffs_thresh

192

193

# Apply thresholding and reconstruct

194

threshold_value = 0.1

195

coeffs_thresh = threshold_coeffs(coeffs, threshold_value)

196

denoised_image = pywt.waverec2(coeffs_thresh, 'db4')

197

198

# Visualization

199

fig, axes = plt.subplots(2, 3, figsize=(15, 10))

200

201

axes[0, 0].imshow(image, cmap='gray')

202

axes[0, 0].set_title('Original Clean Image')

203

axes[0, 0].axis('off')

204

205

axes[0, 1].imshow(noisy_image, cmap='gray')

206

axes[0, 1].set_title('Noisy Image')

207

axes[0, 1].axis('off')

208

209

axes[0, 2].imshow(denoised_image, cmap='gray')

210

axes[0, 2].set_title('Denoised Image')

211

axes[0, 2].axis('off')

212

213

# Show approximation at coarsest level

214

axes[1, 0].imshow(coeffs[0], cmap='gray')

215

axes[1, 0].set_title(f'Approximation Level {len(coeffs)-1}')

216

axes[1, 0].axis('off')

217

218

# Show details at finest level

219

cH1, cV1, cD1 = coeffs[-1]

220

axes[1, 1].imshow(np.abs(cH1), cmap='gray')

221

axes[1, 1].set_title('Horizontal Details (Level 1)')

222

axes[1, 1].axis('off')

223

224

axes[1, 2].imshow(np.abs(cD1), cmap='gray')

225

axes[1, 2].set_title('Diagonal Details (Level 1)')

226

axes[1, 2].axis('off')

227

228

plt.tight_layout()

229

plt.show()

230

231

# Progressive reconstruction - build up from coarse to fine

232

progressive_images = []

233

for level in range(len(coeffs)):

234

# Reconstruct using only levels 0 to level

235

partial_coeffs = coeffs[:level+1]

236

if level < len(coeffs) - 1:

237

# Add zero details for missing levels

238

zero_shape = coeffs[level+1][0].shape

239

for missing_level in range(level+1, len(coeffs)):

240

zero_details = (np.zeros(zero_shape), np.zeros(zero_shape), np.zeros(zero_shape))

241

partial_coeffs.append(zero_details)

242

zero_shape = (zero_shape[0] * 2, zero_shape[1] * 2)

243

244

progressive_image = pywt.waverec2(partial_coeffs, 'db4')

245

progressive_images.append(progressive_image)

246

247

# Show progressive reconstruction

248

fig, axes = plt.subplots(1, len(progressive_images), figsize=(20, 4))

249

for i, (ax, img) in enumerate(zip(axes, progressive_images)):

250

ax.imshow(img, cmap='gray')

251

ax.set_title(f'Up to Level {i}')

252

ax.axis('off')

253

plt.tight_layout()

254

plt.show()

255

```

256

257

### nD Multi-Level DWT

258

259

Hierarchical decomposition and reconstruction for n-dimensional data.

260

261

```python { .api }

262

def wavedecn(data, wavelet, mode: str = 'symmetric', level: int = None, axes=None):

263

"""

264

Multi-level nD discrete wavelet decomposition.

265

266

Parameters:

267

- data: Input nD array

268

- wavelet: Wavelet specification

269

- mode: Signal extension mode for boundary handling

270

- level: Decomposition level (default: maximum possible level)

271

- axes: Axes along which to perform DWT (default: all axes)

272

273

Returns:

274

List [cAn, {details_level_n}, {details_level_n-1}, ..., {details_level_1}] where:

275

- cAn: Approximation coefficients at level n

276

- {details_level_i}: Dictionary of detail coefficients at level i

277

"""

278

279

def waverecn(coeffs, wavelet, mode: str = 'symmetric', axes=None):

280

"""

281

Multi-level nD discrete wavelet reconstruction.

282

283

Parameters:

284

- coeffs: Coefficient list from wavedecn

285

- wavelet: Wavelet specification matching decomposition

286

- mode: Signal extension mode matching decomposition

287

- axes: Axes along which to perform IDWT (should match decomposition)

288

289

Returns:

290

Reconstructed nD array

291

"""

292

```

293

294

#### Usage Examples

295

296

```python

297

import pywt

298

import numpy as np

299

300

# 3D volume example

301

volume = np.random.randn(64, 64, 64)

302

print(f"Original volume shape: {volume.shape}")

303

304

# 3D multi-level decomposition

305

coeffs_3d = pywt.wavedecn(volume, 'db2', level=3)

306

print(f"Number of decomposition levels: {len(coeffs_3d) - 1}")

307

print(f"Approximation shape: {coeffs_3d[0].shape}")

308

309

# Each level has 2^n - 1 detail coefficient arrays (n = number of dimensions)

310

for level, details in enumerate(coeffs_3d[1:], 1):

311

print(f"Level {len(coeffs_3d) - level} details:")

312

for key, coeff in details.items():

313

print(f" '{key}': {coeff.shape}")

314

315

# Perfect reconstruction

316

reconstructed_3d = pywt.waverecn(coeffs_3d, 'db2')

317

print(f"3D reconstruction error: {np.max(np.abs(volume - reconstructed_3d))}")

318

319

# 4D example - 3D spatial + 1D temporal

320

data_4d = np.random.randn(32, 32, 32, 100)

321

coeffs_4d = pywt.wavedecn(data_4d, 'haar', level=2)

322

print(f"4D data shape: {data_4d.shape}")

323

print(f"4D approximation shape: {coeffs_4d[0].shape}")

324

print(f"Number of detail types at each level: {len(coeffs_4d[1])}") # 2^4 - 1 = 15

325

326

# Show some detail coefficient keys for 4D

327

print("4D detail coefficient keys (level 1):")

328

for key in sorted(coeffs_4d[-1].keys()):

329

print(f" '{key}': {coeffs_4d[-1][key].shape}")

330

```

331

332

### Coefficient Utility Functions

333

334

Helper functions for working with multi-level decomposition coefficients and data analysis.

335

336

```python { .api }

337

def downcoef(part: str, data, wavelet, mode: str = 'symmetric', level: int = 1):

338

"""

339

Partial DWT - compute only approximation or detail coefficients.

340

341

Parameters:

342

- part: 'a' for approximation, 'd' for detail coefficients

343

- data: Input signal

344

- wavelet: Wavelet specification

345

- mode: Signal extension mode

346

- level: Decomposition level

347

348

Returns:

349

Requested coefficient type at specified level

350

"""

351

352

def upcoef(part: str, coeffs, wavelet, level: int = 1, take: int = 0):

353

"""

354

Direct reconstruction from single coefficient type.

355

356

Parameters:

357

- part: 'a' for approximation, 'd' for detail coefficients

358

- coeffs: Input coefficients

359

- wavelet: Wavelet specification

360

- level: Number of reconstruction levels

361

- take: Number of coefficients to take (0 = all)

362

363

Returns:

364

Reconstructed signal from specified coefficient type only

365

"""

366

```

367

368

#### Usage Examples

369

370

```python

371

import pywt

372

import numpy as np

373

import matplotlib.pyplot as plt

374

375

# Generate test signal

376

t = np.linspace(0, 1, 1024)

377

signal = np.sin(2 * np.pi * 5 * t) + 0.5 * np.sin(2 * np.pi * 50 * t)

378

379

# Extract only approximation at level 3

380

approx_level3 = pywt.downcoef('a', signal, 'db4', level=3)

381

print(f"Approximation at level 3 shape: {approx_level3.shape}")

382

383

# Extract only detail at level 2

384

detail_level2 = pywt.downcoef('d', signal, 'db4', level=2)

385

print(f"Detail at level 2 shape: {detail_level2.shape}")

386

387

# Reconstruct signal from approximation only

388

reconstructed_approx = pywt.upcoef('a', approx_level3, 'db4', level=3)

389

print(f"Reconstructed from approximation shape: {reconstructed_approx.shape}")

390

391

# Reconstruct signal from detail only

392

reconstructed_detail = pywt.upcoef('d', detail_level2, 'db4', level=2)

393

print(f"Reconstructed from detail shape: {reconstructed_detail.shape}")

394

395

# Visualization

396

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

397

398

plt.subplot(2, 2, 1)

399

plt.plot(t, signal)

400

plt.title('Original Signal')

401

402

plt.subplot(2, 2, 2)

403

plt.plot(reconstructed_approx[:len(signal)])

404

plt.title('Reconstructed from Approximation (Level 3)')

405

406

plt.subplot(2, 2, 3)

407

plt.plot(reconstructed_detail[:len(signal)])

408

plt.title('Reconstructed from Detail (Level 2)')

409

410

plt.subplot(2, 2, 4)

411

plt.plot(t, signal, 'b-', label='Original')

412

plt.plot(reconstructed_approx[:len(signal)] + reconstructed_detail[:len(signal)],

413

'r--', label='Approx + Detail')

414

plt.title('Partial Reconstruction Sum')

415

plt.legend()

416

417

plt.tight_layout()

418

plt.show()

419

420

# Taking partial coefficients

421

partial_approx = pywt.upcoef('a', approx_level3[:len(approx_level3)//2], 'db4', level=3)

422

print(f"Reconstruction from half coefficients: {partial_approx.shape}")

423

```

424

425

### Fully Separable Wavelet Transform

426

427

Advanced transform providing axis-specific decomposition levels for flexible multi-dimensional analysis.

428

429

```python { .api }

430

def fswavedecn(data, wavelet, mode: str = 'symmetric', levels=None, axes=None):

431

"""

432

Fully separable wavelet decomposition.

433

434

Parameters:

435

- data: Input nD array

436

- wavelet: Wavelet specification or list of wavelets for each axis

437

- mode: Signal extension mode or list of modes for each axis

438

- levels: Decomposition levels as int or list of ints for each axis

439

- axes: Axes along which to perform transform (default: all axes)

440

441

Returns:

442

FswavedecnResult object with coefficient access and reconstruction methods

443

"""

444

445

def fswaverecn(fswavedecn_result):

446

"""

447

Inverse fully separable wavelet transform.

448

449

Parameters:

450

- fswavedecn_result: FswavedecnResult object from fswavedecn

451

452

Returns:

453

Reconstructed nD array

454

"""

455

456

class FswavedecnResult:

457

"""Container for fully separable decomposition results."""

458

459

# Properties

460

coeffs: np.ndarray # Coefficient array

461

coeff_slices: list # Coefficient slice information

462

axes: tuple # Transform axes

463

wavelets: list # Wavelets used for each axis

464

modes: list # Extension modes for each axis

465

levels: list # Decomposition levels for each axis

466

approx: np.ndarray # Approximation coefficients

467

468

def __getitem__(self, levels):

469

"""Access coefficients at specified levels."""

470

471

def __setitem__(self, levels, x):

472

"""Set coefficients at specified levels."""

473

474

def detail_keys(self):

475

"""List all detail coefficient keys."""

476

```

477

478

## Types

479

480

```python { .api }

481

# Multi-level coefficient formats

482

MultiLevelCoeffs1D = List[np.ndarray] # [cAn, cDn, cDn-1, ..., cD1]

483

484

MultiLevelCoeffs2D = List[

485

Union[

486

np.ndarray, # Approximation coefficients (first element)

487

Tuple[np.ndarray, np.ndarray, np.ndarray] # (cH, cV, cD) detail tuples

488

]

489

]

490

491

MultiLevelCoeffsND = List[

492

Union[

493

np.ndarray, # Approximation coefficients (first element)

494

Dict[str, np.ndarray] # Detail coefficient dictionaries

495

]

496

]

497

498

# Coefficient part specifications

499

CoeffPart = Literal['a', 'd'] # 'a' for approximation, 'd' for detail

500

```