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

single-level-dwt.mddocs/

0

# Single-Level Discrete Wavelet Transform

1

2

Single-level forward and inverse discrete wavelet transforms for 1D, 2D, and nD data providing complete coefficient decomposition into approximation and detail components.

3

4

## Capabilities

5

6

### 1D Discrete Wavelet Transform

7

8

Single-level analysis and synthesis for one-dimensional signals.

9

10

```python { .api }

11

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

12

"""

13

Single-level 1D discrete wavelet transform.

14

15

Parameters:

16

- data: Input 1D array or array with axis specified

17

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

18

- mode: Signal extension mode for boundary handling

19

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

20

21

Returns:

22

(cA, cD) - approximation and detail coefficients as tuple

23

"""

24

25

def idwt(cA, cD, wavelet, mode: str = 'symmetric', axis: int = -1):

26

"""

27

Single-level 1D inverse discrete wavelet transform.

28

29

Parameters:

30

- cA: Approximation coefficients (can be None)

31

- cD: Detail coefficients (can be None)

32

- wavelet: Wavelet specification matching forward transform

33

- mode: Signal extension mode matching forward transform

34

- axis: Axis along which to perform IDWT

35

36

Returns:

37

Reconstructed 1D signal

38

"""

39

```

40

41

#### Usage Examples

42

43

```python

44

import pywt

45

import numpy as np

46

import matplotlib.pyplot as plt

47

48

# Create test signal with noise

49

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

50

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

51

noisy_signal = signal + 0.3 * np.random.randn(len(signal))

52

53

# Single-level DWT

54

cA, cD = pywt.dwt(noisy_signal, 'db4')

55

print(f"Original signal length: {len(noisy_signal)}")

56

print(f"Approximation coefficients: {len(cA)}")

57

print(f"Detail coefficients: {len(cD)}")

58

59

# Perfect reconstruction

60

reconstructed = pywt.idwt(cA, cD, 'db4')

61

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

62

63

# Denoising by thresholding detail coefficients

64

threshold = 0.1 * np.max(np.abs(cD))

65

cD_thresh = np.where(np.abs(cD) > threshold, cD, 0)

66

denoised = pywt.idwt(cA, cD_thresh, 'db4')

67

68

# Plotting

69

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

70

plt.subplot(2, 2, 1)

71

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

72

plt.plot(t, noisy_signal, 'r-', alpha=0.7, label='Noisy')

73

plt.title('Original vs Noisy Signal')

74

plt.legend()

75

76

plt.subplot(2, 2, 2)

77

plt.plot(cA, 'g-', label='Approximation')

78

plt.title('Approximation Coefficients')

79

plt.legend()

80

81

plt.subplot(2, 2, 3)

82

plt.plot(cD, 'r-', label='Detail')

83

plt.plot(cD_thresh, 'k-', label='Thresholded')

84

plt.title('Detail Coefficients')

85

plt.legend()

86

87

plt.subplot(2, 2, 4)

88

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

89

plt.plot(t, denoised, 'g-', label='Denoised')

90

plt.title('Original vs Denoised')

91

plt.legend()

92

plt.tight_layout()

93

plt.show()

94

95

# Multi-dimensional data along specific axis

96

data_2d = np.random.randn(50, 1000)

97

cA_2d, cD_2d = pywt.dwt(data_2d, 'haar', axis=1) # Transform along columns

98

print(f"2D data shape: {data_2d.shape}")

99

print(f"2D coefficients shape: {cA_2d.shape}, {cD_2d.shape}")

100

```

101

102

### 2D Discrete Wavelet Transform

103

104

Single-level analysis and synthesis for two-dimensional data such as images.

105

106

```python { .api }

107

def dwt2(data, wavelet, mode: str = 'symmetric', axes=(-2, -1)):

108

"""

109

Single-level 2D discrete wavelet transform.

110

111

Parameters:

112

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

113

- wavelet: Wavelet specification

114

- mode: Signal extension mode for boundary handling

115

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

116

117

Returns:

118

(cA, (cH, cV, cD)) - approximation and horizontal/vertical/diagonal detail coefficients

119

"""

120

121

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

122

"""

123

Single-level 2D inverse discrete wavelet transform.

124

125

Parameters:

126

- coeffs: Coefficient tuple (cA, (cH, cV, cD)) from dwt2

127

- wavelet: Wavelet specification matching forward transform

128

- mode: Signal extension mode matching forward transform

129

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

130

131

Returns:

132

Reconstructed 2D array

133

"""

134

```

135

136

#### Usage Examples

137

138

```python

139

import pywt

140

import numpy as np

141

import matplotlib.pyplot as plt

142

143

# Create test image

144

image = np.zeros((128, 128))

145

image[30:98, 30:98] = 1 # Square in center

146

image[40:88, 40:88] = 0.5 # Smaller square inside

147

# Add some texture

148

image += 0.1 * np.random.randn(128, 128)

149

150

# 2D DWT

151

coeffs = pywt.dwt2(image, 'db2')

152

cA, (cH, cV, cD) = coeffs

153

154

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

155

print(f"Approximation shape: {cA.shape}")

156

print(f"Detail shapes: {cH.shape}, {cV.shape}, {cD.shape}")

157

158

# Perfect reconstruction

159

reconstructed = pywt.idwt2(coeffs, 'db2')

160

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

161

162

# Visualize decomposition

163

fig, axes = plt.subplots(2, 3, figsize=(12, 8))

164

165

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

166

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

167

168

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

169

axes[0, 1].set_title('Approximation (cA)')

170

171

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

172

axes[0, 2].set_title('Reconstructed')

173

174

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

175

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

176

177

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

178

axes[1, 1].set_title('Vertical Details (cV)')

179

180

axes[1, 2].imshow(cD, cmap='gray')

181

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

182

183

for ax in axes.flat:

184

ax.axis('off')

185

186

plt.tight_layout()

187

plt.show()

188

189

# Image compression by coefficient thresholding

190

threshold = 0.1

191

cA_thresh = cA # Keep all approximation coefficients

192

cH_thresh = np.where(np.abs(cH) > threshold, cH, 0)

193

cV_thresh = np.where(np.abs(cV) > threshold, cV, 0)

194

cD_thresh = np.where(np.abs(cD) > threshold, cD, 0)

195

196

compressed_coeffs = (cA_thresh, (cH_thresh, cV_thresh, cD_thresh))

197

compressed_image = pywt.idwt2(compressed_coeffs, 'db2')

198

199

# Calculate compression ratio

200

original_nonzero = np.count_nonzero(image)

201

compressed_nonzero = (np.count_nonzero(cA_thresh) +

202

np.count_nonzero(cH_thresh) +

203

np.count_nonzero(cV_thresh) +

204

np.count_nonzero(cD_thresh))

205

compression_ratio = original_nonzero / compressed_nonzero

206

207

print(f"Compression ratio: {compression_ratio:.2f}")

208

```

209

210

### nD Discrete Wavelet Transform

211

212

Single-level analysis and synthesis for n-dimensional data with arbitrary number of dimensions.

213

214

```python { .api }

215

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

216

"""

217

Single-level nD discrete wavelet transform.

218

219

Parameters:

220

- data: Input nD array

221

- wavelet: Wavelet specification

222

- mode: Signal extension mode for boundary handling

223

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

224

225

Returns:

226

Dictionary of coefficients with string keys indicating coefficient type.

227

For 2D: {'aa': cA, 'ad': cH, 'da': cV, 'dd': cD}

228

For 3D: {'aaa': cAAA, 'aad': cAAD, 'ada': cADA, ...} (8 coefficients)

229

"""

230

231

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

232

"""

233

Single-level nD inverse discrete wavelet transform.

234

235

Parameters:

236

- coeffs: Dictionary of coefficients from dwtn

237

- wavelet: Wavelet specification matching forward transform

238

- mode: Signal extension mode matching forward transform

239

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

240

241

Returns:

242

Reconstructed nD array

243

"""

244

```

245

246

#### Usage Examples

247

248

```python

249

import pywt

250

import numpy as np

251

252

# 3D volume data example

253

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

254

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

255

256

# 3D DWT

257

coeffs_3d = pywt.dwtn(volume, 'db2')

258

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

259

print(f"Coefficient keys: {list(coeffs_3d.keys())}")

260

261

# Each coefficient array is 1/8 the size in 3D

262

for key, coeff in coeffs_3d.items():

263

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

264

265

# Perfect reconstruction

266

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

267

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

268

269

# 2D example using dwtn (equivalent to dwt2)

270

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

271

coeffs_2d = pywt.dwtn(image_2d, 'haar')

272

print(f"2D coefficient keys: {list(coeffs_2d.keys())}")

273

print(f"Approximation 'aa' shape: {coeffs_2d['aa'].shape}")

274

275

# Compare with dwt2

276

coeffs_dwt2 = pywt.dwt2(image_2d, 'haar')

277

cA, (cH, cV, cD) = coeffs_dwt2

278

279

# Verify equivalence

280

print(f"dwtn 'aa' equals dwt2 cA: {np.allclose(coeffs_2d['aa'], cA)}")

281

print(f"dwtn 'ad' equals dwt2 cH: {np.allclose(coeffs_2d['ad'], cH)}")

282

print(f"dwtn 'da' equals dwt2 cV: {np.allclose(coeffs_2d['da'], cV)}")

283

print(f"dwtn 'dd' equals dwt2 cD: {np.allclose(coeffs_2d['dd'], cD)}")

284

285

# Partial transforms along specific axes

286

data_4d = np.random.randn(16, 16, 16, 100) # 3D spatial + 1D time

287

coeffs_partial = pywt.dwtn(data_4d, 'db1', axes=(0, 1, 2)) # Transform only spatial dimensions

288

print(f"Partial transform result shape for 'aaa': {coeffs_partial['aaa'].shape}")

289

```

290

291

### Utility Functions

292

293

Helper functions for working with DWT parameters and coefficients.

294

295

```python { .api }

296

def dwt_max_level(data_len: int, filter_len: int) -> int:

297

"""

298

Compute maximum useful decomposition level for 1D DWT.

299

300

Parameters:

301

- data_len: Length of input data

302

- filter_len: Length of wavelet filter

303

304

Returns:

305

Maximum decomposition level

306

"""

307

308

def dwt_coeff_len(data_len: int, filter_len: int, mode: str) -> int:

309

"""

310

Compute length of DWT coefficient arrays.

311

312

Parameters:

313

- data_len: Length of input data

314

- filter_len: Length of wavelet filter

315

- mode: Signal extension mode

316

317

Returns:

318

Length of coefficient arrays

319

"""

320

321

def dwtn_max_level(shape: tuple, wavelet, axes=None) -> int:

322

"""

323

Compute maximum decomposition level for nD data.

324

325

Parameters:

326

- shape: Shape of input data

327

- wavelet: Wavelet specification

328

- axes: Axes for transform (default: all axes)

329

330

Returns:

331

Maximum decomposition level

332

"""

333

334

def pad(x, pad_widths, mode: str):

335

"""

336

Extend signal using PyWavelets extension modes.

337

338

Parameters:

339

- x: Input array

340

- pad_widths: Padding widths for each axis

341

- mode: PyWavelets extension mode

342

343

Returns:

344

Padded array

345

"""

346

347

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

348

"""

349

Partial discrete wavelet transform decomposition.

350

351

Parameters:

352

- part: Coefficients type ('a' for approximation, 'd' for details)

353

- data: Input signal array

354

- wavelet: Wavelet specification

355

- mode: Signal extension mode

356

- level: Decomposition level (default: 1)

357

358

Returns:

359

1D array of requested coefficients

360

"""

361

362

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

363

"""

364

Direct reconstruction from wavelet coefficients.

365

366

Parameters:

367

- part: Coefficients type ('a' for approximation, 'd' for details)

368

- coeffs: Coefficient array to reconstruct from

369

- wavelet: Wavelet specification

370

- level: Multilevel reconstruction level (default: 1)

371

- take: Take central part of specified length (0 for full length)

372

373

Returns:

374

1D array with reconstructed signal

375

"""

376

```

377

378

#### Usage Examples

379

380

```python

381

import pywt

382

import numpy as np

383

384

# Calculate maximum decomposition levels

385

data_1d = np.random.randn(1000)

386

wavelet = 'db4'

387

filter_len = pywt.Wavelet(wavelet).dec_len

388

389

max_level_1d = pywt.dwt_max_level(len(data_1d), filter_len)

390

print(f"Max level for 1D data (length {len(data_1d)}): {max_level_1d}")

391

392

# Calculate coefficient lengths for different modes

393

coeff_len_sym = pywt.dwt_coeff_len(len(data_1d), filter_len, 'symmetric')

394

coeff_len_per = pywt.dwt_coeff_len(len(data_1d), filter_len, 'periodization')

395

print(f"Coefficient length (symmetric): {coeff_len_sym}")

396

print(f"Coefficient length (periodization): {coeff_len_per}")

397

398

# nD maximum levels

399

image_2d = np.random.randn(256, 256)

400

max_level_2d = pywt.dwtn_max_level(image_2d.shape, wavelet)

401

print(f"Max level for 2D image {image_2d.shape}: {max_level_2d}")

402

403

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

404

max_level_3d = pywt.dwtn_max_level(volume_3d.shape, wavelet)

405

print(f"Max level for 3D volume {volume_3d.shape}: {max_level_3d}")

406

407

# Signal padding examples

408

signal = np.array([1, 2, 3, 4, 5])

409

pad_widths = [(2, 2)] # Pad 2 elements on each side

410

411

padded_zero = pywt.pad(signal, pad_widths, 'zero')

412

padded_symmetric = pywt.pad(signal, pad_widths, 'symmetric')

413

padded_periodic = pywt.pad(signal, pad_widths, 'periodic')

414

415

print(f"Original: {signal}")

416

print(f"Zero padding: {padded_zero}")

417

print(f"Symmetric padding: {padded_symmetric}")

418

print(f"Periodic padding: {padded_periodic}")

419

420

# Partial decomposition with downcoef

421

test_signal = np.sin(2 * np.pi * np.linspace(0, 1, 256))

422

423

# Get only approximation coefficients at level 2

424

approx_only = pywt.downcoef('a', test_signal, 'db4', level=2)

425

print(f"Approximation coefficients shape: {approx_only.shape}")

426

427

# Get only detail coefficients at level 1

428

detail_only = pywt.downcoef('d', test_signal, 'db4', level=1)

429

print(f"Detail coefficients shape: {detail_only.shape}")

430

431

# Compare with full DWT

432

coeffs_full = pywt.wavedec(test_signal, 'db4', level=2)

433

cA2, cD2, cD1 = coeffs_full

434

print(f"Full decomposition - cA2: {cA2.shape}, matches downcoef: {np.allclose(cA2, approx_only)}")

435

436

# Direct reconstruction with upcoef

437

# Reconstruct signal from approximation coefficients only

438

reconstructed_approx = pywt.upcoef('a', approx_only, 'db4', level=2)

439

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

440

441

# Reconstruct signal from detail coefficients only

442

reconstructed_detail = pywt.upcoef('d', detail_only, 'db4', level=1)

443

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

444

445

# Visualization of partial reconstruction

446

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

447

plt.subplot(2, 2, 1)

448

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

449

plt.title('Original Signal')

450

plt.legend()

451

452

plt.subplot(2, 2, 2)

453

plt.plot(reconstructed_approx[:len(test_signal)], 'g-', label='From Approximation')

454

plt.title('Reconstructed from Approximation Only')

455

plt.legend()

456

457

plt.subplot(2, 2, 3)

458

plt.plot(reconstructed_detail[:len(test_signal)], 'r-', label='From Details')

459

plt.title('Reconstructed from Details Only')

460

plt.legend()

461

462

plt.subplot(2, 2, 4)

463

combined = reconstructed_approx[:len(test_signal)] + reconstructed_detail[:len(test_signal)]

464

plt.plot(test_signal, 'b-', alpha=0.7, label='Original')

465

plt.plot(combined, 'k--', label='Approx + Detail')

466

plt.title('Combined Reconstruction')

467

plt.legend()

468

plt.tight_layout()

469

plt.show()

470

```

471

472

## Types

473

474

```python { .api }

475

# Single-level coefficient formats

476

Coeffs1D = Tuple[np.ndarray, np.ndarray] # (cA, cD)

477

Coeffs2D = Tuple[np.ndarray, Tuple[np.ndarray, np.ndarray, np.ndarray]] # (cA, (cH, cV, cD))

478

CoeffsND = Dict[str, np.ndarray] # String keys like 'aa', 'ad', 'da', 'dd' for 2D

479

480

# Input data types

481

ArrayLike = Union[np.ndarray, list, tuple]

482

483

# Extension modes

484

Mode = Literal[

485

'zero', 'constant', 'symmetric', 'periodic',

486

'smooth', 'periodization', 'reflect',

487

'antisymmetric', 'antireflect'

488

]

489

```