Skip to content

Commit

Permalink
Ruff linting and project workflow (devops) updates
Browse files Browse the repository at this point in the history
- pylint, pycodestyle, pydocstyle, and flake8 to start
- added pytest-cov package
- added static analysis step to ct with ruff
- added mypy typechecking step to ct
- updated the state.py module tests
- MIT license txt file added
  • Loading branch information
mahdiolfat committed Jan 31, 2024
1 parent 6ab9aea commit 9f63b7c
Show file tree
Hide file tree
Showing 17 changed files with 355 additions and 215 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ContinuousTesting.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ jobs:
python -m pip install --upgrade pip setuptools wheel
pip install -r requirements.txt
- name: Lint
- name: Static Lint
run: |
python --version
ruff check --output-format=github pyssp --verbose
- name: Test
run: |
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
__pycache__
*.egg-info
env

.env
.coverage
.vscode

20 changes: 20 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
Copyright (c) 2011-2023 GitHub Inc.

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 changes: 21 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,29 @@

Direct impelementation of statistical digital signal processing algorithms from the book by the same name by Professor Monson H. Hayes.

- Examples
- Ready-to-Implement Algorithms
- New Algorithms
The book represents algorithms as:

## Pour Moi
1. set of instructions (pseudo-code)
1. matlab code
1. described in English in the textbook body

## Chapters

1. Introduction
2. Background
3. Discrete-Time Random Processes
4. Signal Modeling
5. The Levinson Recursion
6. Lattice Filters
7. Optimum Filters
8. Spectrum Estimation
9. Adaptive Filters

### TODO

- add proper reference
- lint markdown readme
- License
- Finalize test cases for all codes
- pytest-cov?
- python documentation generator
Expand All @@ -20,3 +35,5 @@ Direct impelementation of statistical digital signal processing algorithms from
- stub files?
- VS code add-ons
- use matlab-equivalent psuedo-inverse ("X \ R") operation to match the book
- switch linting to Ruff?
- performance benchmarking would be cool
16 changes: 16 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,25 @@ build-backend = "hatchling.build"
name = "pyssp"
version = "0.0.1"
readme = "README.md"
license = "LICENSE.txt"

[tool.pytest.ini_options]
pythonpath = "."
addopts = [
"--import-mode=importlib",
"--cov=pyssp"
]

[tool.ruff]
line-length = 100
indent-width = 4

[tool.ruff.lint]
select = ["E", "F", "B", "I", "SIM", "W", "D"]
ignore = ["D213", "D401", "D211"]

[tool.ruff.format]
quote-style = "double"
indent-style = "space"
skip-magic-trailing-comma = false
line-ending = "auto"
10 changes: 10 additions & 0 deletions pyssp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
"""The import root for the book sections."""

# import system as Chapter3
# import modeling as Chapter4
# import levinson as Chapter5
# import lattice as Chapter6
# import optimal as Chapter7
# import spectrum as Chapter8
# import adaptive as Chapter9
# import state as Appendix
19 changes: 10 additions & 9 deletions pyssp/adaptive.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
"""Chapter 9 algorithm implementations."""

import numpy as np

from .state import convm


def lms(x, d, mu, nord, a0=None):
'''LMS Adaptive Filter
"""LMS Adaptive Filter.
Refernce Page 506, Figure 9.7
Suffers from gradient noise amplification
'''
"""
X = convm(x, nord)
M, N = X.shape

Expand All @@ -29,12 +31,12 @@ def lms(x, d, mu, nord, a0=None):
return A, E


def nlms(x, d, beta, nord, a0, delta=0.0001):
'''Normalized LMS Adaptive Filter
def nlms(x, d, beta, nord, a0):
"""Normalized LMS Adaptive Filter.
Refernce Page 515, Figure 9.12
'''

"""
delta = 0.0001
X = convm(x, nord)
M, N = X.shape

Expand All @@ -59,14 +61,13 @@ def nlms(x, d, beta, nord, a0, delta=0.0001):


def rls(x, d, nord, lamda=1, delta=0.001):
'''Recursive Least Squares
"""Recursive Least Squares.
Reference 545, Table 9.6
For special case of lambda == 1, this is known as growing window RLS algorithm,
For all other values of lambda <1 and >0, this is the exponentially weighted RLS algorithm.
'''

"""
X = convm(x, nord)
M, N = X.shape
P = np.eye(N) / delta
Expand Down
49 changes: 25 additions & 24 deletions pyssp/lattice.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
"""Implementation of algorithm from Chapter 6."""


import numpy as np
import scipy as sp


def fcov(x, p):
'''
Figure 6.15, Page 310.
"""Figure 6.15, Page 310.
Using the forward covariance method the reflection co-efficients of the lattice filter
are found by sequentially minimizing the sum of the squares of the forward prediction error.
'''

are found by sequentially minimizing the sum of the squares of the forward prediction error.
"""
if p >= len(x):
raise ValueError("Model order must be less than length of signal")

Expand All @@ -23,8 +25,8 @@ def fcov(x, p):
for j in range(p):
print(j)
N = N - 1
#print(f"{eplus=}, {eplus.shape=}")
#print(f"{eminus=}, {eminus.shape=}")
# print(f"{eplus=}, {eplus.shape=}")
# print(f"{eminus=}, {eminus.shape=}")
gamma[j] = (np.transpose(-eminus) @ eplus) / (np.transpose(eminus) @ eminus)
temp1 = eplus + gamma[j] * eminus
temp2 = eminus + np.conjugate(gamma[j]) * eplus
Expand All @@ -39,12 +41,10 @@ def fcov(x, p):


def burg(x, p):
'''
Sequentially minimizes the sum of the forward and backward covariance errors.
"""Sequentially minimizes the sum of the forward and backward covariance errors.
Guaranteed to be stable. All reflection coefficients will be <|1|
'''

"""
if p > len(x):
raise ValueError("Model order must be less than length of signal")

Expand All @@ -59,10 +59,10 @@ def burg(x, p):
for j in range(p):
print(j)
N = N - 1
#print(f"{eplus=}, {eplus.shape=}")
#print(f"{eminus=}, {eminus.shape=}")
eplusmag = (np.transpose(eplus) @ eplus)
eminusmag = (np.transpose(eplus) @ eplus)
# print(f"{eplus=}, {eplus.shape=}")
# print(f"{eminus=}, {eminus.shape=}")
eplusmag = np.transpose(eplus) @ eplus
eminusmag = np.transpose(eplus) @ eplus
gamma[j] = (np.transpose(-2 * eminus) @ eplus) / (eplusmag + eminusmag)
temp1 = eplus + gamma[j] * eminus
temp2 = eminus + np.conjugate(gamma[j]) * eplus
Expand All @@ -74,17 +74,18 @@ def burg(x, p):
return gamma, err


def bcov(x, p):
'''
Sequentially minimizes the backward covariance error.
'''
pass
def bcov():
"""Sequentially minimizes the backward covariance error.
Arguements: (x, p)
"""


def mcov(x, p):
'''
Modified covariance method. Unlike the forward/backward algorithms,
it *does not* minimize an error term sequentially.
'''
"""Modified covariance method. Unlike the forward/backward algorithms.
It *does not* minimize an error term sequentially.
"""
_x = np.array(x).reshape(-1, 1)
N = len(x)

Expand Down
Loading

0 comments on commit 9f63b7c

Please sign in to comment.