Files
DP44/docs/ai/DataPRO/ExocortexDSP.md

127 lines
8.4 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- DataPRO/ExocortexDSP/Polynomial.cs
- DataPRO/ExocortexDSP/FourierDirection.cs
- DataPRO/ExocortexDSP/AssemblyInfo.cs
- DataPRO/ExocortexDSP/ComplexMath.cs
- DataPRO/ExocortexDSP/PassFilter.cs
- DataPRO/ExocortexDSP/ComplexStats.cs
- DataPRO/ExocortexDSP/Complex.cs
generated_at: "2026-04-17T15:48:44.861058+00:00"
model: "zai-org/GLM-5-FP8"
schema_version: 1
sha256: "df53e9f2f708d29c"
---
# Documentation: Exocortex.DSP Namespace
## 1. Purpose
The `Exocortex.DSP` namespace provides a library for Digital Signal Processing (DSP) utilities within the `DataPRO` system. It offers core data structures for representing double-precision and single-precision complex numbers, mathematical operations for complex arithmetic (roots, powers), statistical analysis tools for complex datasets, and frequency-domain filtering capabilities (Butterworth, Chebyshev, Bessel). It serves as the mathematical backbone for signal manipulation tasks, enabling transformations between time and frequency domains.
## 2. Public Interface
### Structs
**`Complex`**
A double-precision complex number representation.
* `public double Re`: The real component.
* `public double Im`: The imaginary component.
* `public Complex(double real, double imaginary)`: Constructor.
* `static public Complex FromRealImaginary(double real, double imaginary)`: Factory method.
* `static public Complex FromModulusArgument(double modulus, double argument)`: Factory method creating a complex number from polar coordinates.
* `public double GetModulus()`: Returns the magnitude $\sqrt{Re^2 + Im^2}$.
* `public double GetModulusSquared()`: Returns $Re^2 + Im^2$.
* `public double GetArgument()`: Returns the angle in radians.
* `public Complex GetConjugate()`: Returns the complex conjugate.
* `public void Normalize()`: Scales the number to a magnitude of 1.
* `static public bool IsEqual(Complex a, Complex b, double tolerance)`: Compares two numbers within a tolerance.
* `static public Complex Zero`: Represents $(0, 0)$.
* `static public Complex I`: Represents $(0, 1)$.
* Operators: `+`, `-`, `*`, `/` (supporting `Complex` and `double` operands), `==`, `!=`.
### Classes
**`ComplexMath`**
Static utility class for complex number mathematics.
* `static public void Swap(ref Complex a, ref Complex b)`: Swaps two complex numbers.
* `static public void Swap(ref ComplexF a, ref ComplexF b)`: Swaps two single-precision complex numbers.
* `static public Complex Sqrt(Complex c)`: Calculates the square root.
* `static public ComplexF Sqrt(ComplexF c)`: Calculates the square root (single-precision).
* `static public Complex Pow(Complex c, double exponent)`: Raises a complex number to a power.
* `static public ComplexF Pow(ComplexF c, double exponent)`: Raises a complex number to a power (single-precision).
**`ComplexStats`**
Static utility class for statistical operations on arrays of complex numbers.
* `static public Complex Sum(Complex[] data)`: Calculates the sum.
* `static public Complex SumOfSquares(Complex[] data)`: Calculates the sum of squares.
* `static public Complex Mean(Complex[] data)`: Calculates the mean.
* `static public Complex Variance(Complex[] data)`: Calculates the variance.
* `static public Complex StdDev(Complex[] data)`: Calculates the standard deviation.
* `static public double RMSError(Complex[] alpha, Complex[] beta)`: Calculates the Root Mean Squared Error between two datasets.
* *Note: Overloads for `ComplexF[]` exist for all the above methods.*
**`PassFilter`**
Static class for applying frequency-domain filters.
* `static public double[] HighPass(double[] values, double sampleRate, double centerFrequency, PassFilterType type, uint order)`: Applies a high-pass filter.
* `static public double[] LowPass(double[] values, double sampleRate, double centerFrequency, PassFilterType type, uint order)`: Applies a low-pass filter.
**`Polynomial` (Abstract)**
Base class for polynomial representations.
* `public Polynomial(params double[] coefficients)`: Constructor.
* `public abstract double Evaluate(double value)`: Evaluates the polynomial at a specific value.
* `public double GetCoefficient(int index)`: Retrieves a coefficient by index.
**`SimplePolynomial`**
A concrete implementation of `Polynomial`.
* `public SimplePolynomial(params double[] coefficients)`: Constructor.
* `public override double Evaluate(double value)`: Evaluates the polynomial using a loop (calculates $c_0 + c_1x + c_2x^2 + \dots$).
### Enums
**`FourierDirection`**
Specifies the direction of a Fourier Transform.
* `Forward = 1`: Time to frequency domain.
* `Backward = -1`: Frequency to time domain.
**`PassFilterType`**
Specifies the type of filter algorithm.
* `Bessel`, `Butterworth`, `Chebyshev`, `CriticalDamping`.
## 3. Invariants
* **Coefficient Storage**: In `Polynomial`, coefficients are stored in ascending order of power (index 0 is the constant term $c_0$). This is confirmed by `SimplePolynomial.Evaluate` where `coefficients[0]` is the starting value and subsequent coefficients are multiplied by increasing powers of `value`.
* **Immutability of Inputs**: `PassFilter` methods (`HighPass`, `LowPass`) do not modify the input `values` array; they clone the internal complex representation before processing.
* **FFT Scaling**: `PassFilter` methods scale the result of the inverse FFT by dividing by the signal length `N`. This is required to normalize the output of `Fourier.FFT` with `FourierDirection.Backward`.
* **Index Bounds**: `Polynomial.GetCoefficient` returns `double.NaN` if the index is out of bounds or if the coefficient array is null, rather than throwing an exception.
* **Comparison Logic**: `Complex.CompareTo` compares instances based on their `Modulus` (magnitude), not their real or imaginary components individually.
## 4. Dependencies
**Internal Dependencies (within this namespace):**
* `PassFilter` depends on `Complex`, `FourierDirection`, `Polynomial`, and `SimplePolynomial`.
* `ComplexStats` depends on `Complex`, `ComplexF`, and `ComplexMath`.
* `ComplexMath` depends on `Complex` and `ComplexF`.
**External Dependencies:**
* `System`: Basic types (`Math`, `Double`, `Array`, etc.).
* `System.Linq`: Used heavily in `PassFilter` for projection (`.Select`) and in `ComplexStats`.
* `System.Threading.Tasks`: Used in `PassFilter` for parallel processing of frequency bins (`Parallel.For`).
* `System.Runtime.InteropServices`: Used in `Complex` for `StructLayout(LayoutKind.Sequential)`.
**Missing/Inferred Dependencies:**
* `ComplexF`: Referenced in `ComplexMath` and `ComplexStats` but the definition is **not present** in the provided source files.
* `Fourier`: The static class `Fourier` is invoked in `PassFilter` (e.g., `Fourier.FFT(signal, N, FourierDirection.Forward)`), but the definition is **not present** in the provided source files.
## 5. Gotchas
* **Missing Implementation (`Complex.Parse`)**: The `Complex.Parse(string s)` method exists in the signature but throws a `NotImplementedException` if called.
* **Mutation in Math Methods**: The static methods `ComplexMath.Sqrt(Complex c)` and `ComplexMath.Pow(Complex c, double exponent)` mutate the passed-in struct `c` (modifying `c.Re` and `c.Im`) *and* return it. This is unusual for static math utilities which typically return a new instance.
* **Precision Loss in Operator**: The subtraction operator `public static Complex operator -(double f, Complex a)` casts the result components to `float` before assigning them back to the `Complex` (double) struct:
```csharp
a.Re = (float)(f - a.Re); // Precision loss here
a.Im = (float)(0 - a.Im); // Precision loss here
```
This appears to be a bug or legacy artifact, as it reduces precision for double-precision math.
* **Hardcoded Filter Parameters**: The public API for `PassFilter` does not expose ripple or DC gain parameters. `RunFilter` hardcodes `DCGain = 1D` for Butterworth/Chebyshev and `ripple = 0.005` for Chebyshev.
* **Limited Polynomial Support**: `PassFilter.ChebyshevPolynomial` and `PassFilter.BesselDenominatorPolynomial` throw `NotImplementedException` for orders greater than 8 (Chebyshev) or outside the range 2-8 (Bessel).
* **DC Offset Removal**: `PassFilter.ChebyshevFilter` explicitly sets `signal[0] = 0` (removing DC offset) inside the FFT domain. The Bessel and Butterworth implementations do **not** do this; they preserve the DC component (unless the gain function naturally attenuates it).