-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
2 changed files
with
87 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
""" | ||
A subpackage for various estimation algorithms. | ||
""" | ||
|
||
from ._snr import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
""" | ||
A module containing estimation algorithms for signal-to-noise ratio (SNR) calculations. | ||
""" | ||
|
||
from __future__ import annotations | ||
|
||
import numpy as np | ||
import numpy.typing as npt | ||
|
||
from .._conversion import db, linear | ||
from .._helper import export | ||
|
||
|
||
@export | ||
def composite_snr(snr1: npt.ArrayLike, snr2: npt.ArrayLike) -> npt.NDArray[np.float64]: | ||
r""" | ||
Calculates the signal-to-noise ratio (SNR) of the product of two signals. | ||
Arguments: | ||
snr1: The signal-to-noise ratio (SNR) of the first signal $\gamma_1$ in dB. | ||
snr2: The signal-to-noise ratio (SNR) of the second signal $\gamma_2$ in dB. | ||
Returns: | ||
The signal-to-noise ratio (SNR) of the product of the two signals $\gamma$ in dB. | ||
Notes: | ||
$$\frac{1}{\gamma} = \frac{1}{2} \left[ \frac{1}{\gamma_1} + \frac{1}{\gamma_2} + \frac{1}{\gamma_1 \cdot \gamma_2} \right]$$ | ||
References: | ||
- `Seymour Stein, Algorithms for Ambiguity Function Processing <https://ieeexplore.ieee.org/document/1163621>`_ | ||
Examples: | ||
Calculate the composite SNR of two signals with equal SNRs. Notice for positive input SNR, the composite SNR | ||
is linear with slope 1 and intercept 0 dB. For negative input SNR, the composite SNR is linear with slope 2 and | ||
offset 3 dB. | ||
.. ipython:: python | ||
snr1 = np.linspace(-60, 60, 101) | ||
@savefig sdr_composite_snr_1.png | ||
plt.figure(); \ | ||
plt.plot(snr1, sdr.composite_snr(snr1, snr1)); \ | ||
plt.xlim(-60, 60); \ | ||
plt.ylim(-60, 60); \ | ||
plt.xlabel("Input SNRs (dB), $\gamma_1$ and $\gamma_2$"); \ | ||
plt.ylabel(r"Composite SNR (dB), $\gamma$"); \ | ||
plt.title("Composite SNR of two signals with equal SNRs"); | ||
Calculate the composite SNR of two signals with different SNRs. Notice the knee of the curve is located at | ||
`max(0, snr2)`. Left of the knee, the composite SNR is linear with slope 2 and intercept `snr2 + 3` dB. | ||
Right of the knee, the composite SNR is linear with slope 0 and intercept `snr2 + 3` dB. | ||
.. ipython:: python | ||
snr1 = np.linspace(-60, 60, 101) | ||
plt.figure(); | ||
for snr2 in np.arange(-40, 40 + 10, 10): | ||
plt.plot(snr1, sdr.composite_snr(snr1, snr2), label=snr2) | ||
@savefig sdr_composite_snr_2.png | ||
plt.legend(title="SNR of signal 2 (dB), $\gamma_2$"); \ | ||
plt.xlim(-60, 60); \ | ||
plt.ylim(-60, 60); \ | ||
plt.xlabel("SNR of signal 1 (dB), $\gamma_1$"); \ | ||
plt.ylabel(r"Composite SNR (dB), $\gamma$"); \ | ||
plt.title("Composite SNR of two signals with different SNRs"); | ||
Group: | ||
estimation-snr | ||
""" | ||
snr1 = np.asarray(snr1) | ||
snr2 = np.asarray(snr2) | ||
|
||
# Convert to linear | ||
snr1 = linear(snr1) | ||
snr2 = linear(snr2) | ||
|
||
inv_snr = 0.5 * (1 / snr1 + 1 / snr2 + 1 / (snr1 * snr2)) | ||
snr = 1 / inv_snr | ||
|
||
# Convert to dB | ||
snr = db(snr) | ||
|
||
return snr |