Files
2026-04-17 14:55:32 -04:00

15 KiB
Raw Permalink Blame History

source_files, generated_at, model, schema_version, sha256
source_files generated_at model schema_version sha256
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
2026-04-16T03:48:44.236669+00:00 Qwen/Qwen3-Coder-Next-FP8 1 e35f8b9ef214514d

Exocortex.DSP Module Documentation

1. Purpose

This module provides core digital signal processing (DSP) functionality for the Exocortex Technologies library. It defines foundational types and utilities including complex number representations (Complex, ComplexF), polynomial evaluation (Polynomial, SimplePolynomial), filter implementations (PassFilter), Fourier transform direction specification (FourierDirection), and statistical operations on complex arrays (ComplexStats). The module serves as the mathematical backbone for signal analysis and transformation operations within the larger DataPRO system.

2. Public Interface

Structs

Complex

  • public Complex(double real, double imaginary)
    Constructs a double-precision complex number from real and imaginary components.
  • public Complex(Complex c)
    Copy constructor.
  • public static Complex FromRealImaginary(double real, double imaginary)
    Factory method to create a complex number from real/imaginary parts.
  • public static Complex FromModulusArgument(double modulus, double argument)
    Factory method to create a complex number from polar coordinates (modulus and argument in radians).
  • public double GetModulus()
    Returns the magnitude (Euclidean norm) of the complex number.
  • public double GetModulusSquared()
    Returns the squared magnitude (faster than GetModulus()).
  • public double GetArgument()
    Returns the phase angle (argument) in radians.
  • public Complex GetConjugate()
    Returns the complex conjugate.
  • public void Normalize()
    Scales the complex number to unit magnitude (throws DivideByZeroException if zero).
  • public static explicit operator Complex(ComplexF cF)
    Explicit cast from single-precision ComplexF to Complex.
  • public static explicit operator Complex(double d)
    Explicit cast from double to Complex (real part = d, imaginary part = 0).
  • public static explicit operator double(Complex c)
    Explicit cast from Complex to double (returns real part).
  • public static bool operator ==(Complex a, Complex b)
    Equality comparison (exact).
  • public static bool operator !=(Complex a, Complex b)
    Inequality comparison (exact).
  • public override bool Equals(object o)
    Object equality (delegates to ==).
  • public int CompareTo(object o)
    Compares based on magnitude (modulus). Supports comparison with Complex, double, ComplexF, float, or null.
  • public static Complex operator +(Complex a)
    Unary plus.
  • public static Complex operator -(Complex a)
    Unary negation.
  • public static Complex operator +(Complex a, double f) / operator +(double f, Complex a)
    Addition with real scalar.
  • public static Complex operator +(Complex a, Complex b)
    Complex addition.
  • public static Complex operator -(Complex a, double f) / operator -(double f, Complex a)
    Subtraction with real scalar.
  • public static Complex operator -(Complex a, Complex b)
    Complex subtraction.
  • public static Complex operator *(Complex a, double f) / operator *(double f, Complex a)
    Scalar multiplication.
  • public static Complex operator *(Complex a, Complex b)
    Complex multiplication.
  • public static Complex operator /(Complex a, double f)
    Scalar division (throws DivideByZeroException if f == 0).
  • public static Complex operator /(Complex a, Complex b)
    Complex division (throws DivideByZeroException if divisor is zero).
  • public static bool IsEqual(Complex a, Complex b, double tolerance)
    Approximate equality check within tolerance.
  • public override string ToString()
    Returns string in format "( {Re}, {Im}i )".
  • public static Complex Zero
    Static property returning (0, 0).
  • public static Complex I
    Static property returning (0, 1) (imaginary unit).
  • public static Complex MaxValue / MinValue
    Static properties for extreme values.

ComplexF

  • Note: Definition not provided in source files, but referenced extensively in ComplexStats and ComplexMath. Assumed to be a single-precision counterpart to Complex.

Classes

Polynomial

  • protected double[] coefficients
    Protected field storing the polynomial coefficients (index 0 = constant term).
  • public Polynomial(params double[] coefficients)
    Constructor initializing coefficients via deep copy.
  • public abstract double Evaluate(double value)
    Abstract method to evaluate the polynomial at value.
  • public double GetCoefficient(int index)
    Returns coefficient at index, or double.NaN if coefficients == null, index < 0, or index >= coefficients.Length.

SimplePolynomial : Polynomial

  • public SimplePolynomial(params double[] coefficients)
    Constructor delegating to base class.
  • public override double Evaluate(double value)
    Evaluates polynomial using Horners method:
    retval = c[0] + c[1]*x + c[2]*x² + ...
    Computed iteratively for efficiency.

ComplexMath

  • private ComplexMath()
    Private constructor (static class pattern).
  • public static void Swap(ref Complex a, ref Complex b)
    Swaps two Complex instances.
  • public static void Swap(ref ComplexF a, ref ComplexF b)
    Swaps two ComplexF instances.
  • public static Complex Sqrt(Complex c)
    Computes complex square root using principal branch.
    Formula:
    real = √2/2 * √(|c| + Re(c))
    imag = sign(Im(c)) * √2/2 * √(|c| - Re(c))
    where |c| is modulus.
  • public static ComplexF Sqrt(ComplexF c)
    Single-precision variant of Sqrt.
  • public static Complex Pow(Complex c, double exponent)
    Computes c^exponent via polar form:
    modulus = |c|^exponent, argument = arg(c) * exponent,
    then converts back: (modulus * cos(arg), modulus * sin(arg)).
  • public static ComplexF Pow(ComplexF c, double exponent)
    Single-precision variant of Pow.

ComplexStats

  • private ComplexStats()
    Private constructor (static class pattern).
  • public static Complex Sum(Complex[] data) / Sum(ComplexF[] data)
    Computes sum of array elements using recursive divide-and-conquer (base case ≤1000 elements).
  • public static Complex SumOfSquares(Complex[] data) / SumOfSquares(ComplexF[] data)
    Computes Σ(data[i] * data[i]) (note: not |data[i]|²).
  • public static Complex Mean(Complex[] data) / Mean(ComplexF[] data)
    Computes arithmetic mean: Sum(data) / data.Length.
  • public static Complex Variance(Complex[] data) / Variance(ComplexF[] data)
    Computes variance as: SumOfSquares(data)/n - Sum(data).
    Throws DivideByZeroException if data.Length == 0.
  • public static Complex StdDev(Complex[] data) / StdDev(ComplexF[] data)
    Computes standard deviation: Sqrt(Variance(data)).
    Throws DivideByZeroException if data.Length == 0.
  • public static double RMSError(Complex[] alpha, Complex[] beta) / RMSError(ComplexF[] alpha, ComplexF[] beta)
    Computes root mean squared error between two arrays:
    sqrt( Σ |beta[i] - alpha[i]|² / n ).
    Arrays must be non-null and equal length.

PassFilter

  • public static double[] HighPass(double[] values, double sampleRate, double centerFrequency, PassFilterType type, uint order)
    Applies high-pass filtering via FFT. Delegates to RunFilter(..., lowPass: false).
  • public static double[] LowPass(double[] values, double sampleRate, double centerFrequency, PassFilterType type, uint order)
    Applies low-pass filtering via FFT. Delegates to RunFilter(..., lowPass: true).
  • private static double[] RunFilter(..., bool lowPass)
    Core filtering logic:
    1. Converts input double[] to Complex[] (imag part = 0).
    2. Applies forward FFT.
    3. Applies frequency-domain gain function (parallelized via Parallel.For).
    4. Applies inverse FFT.
    5. Scales result by 1/N.
    6. Extracts real parts as double[].
    • Note: DC component (signal[0]) is zeroed only for Chebyshev filter.
  • private static Complex[] BesselFilter(...)
    Implements Bessel filter using precomputed denominator polynomial B.
    Gain: numerator / sqrt(B(freq / centerFreq)) (low-pass) or numerator / sqrt(B(centerFreq / freq)) (high-pass).
  • private static double BesselGain(...)
    Helper for Bessel gain computation.
  • private static Complex[] ButterworthFilter(...)
    Implements Butterworth filter.
    Gain: DCGain / sqrt(1 + (freq / centerFreq)^(2*order)) (low-pass) or DCGain / sqrt(1 + (centerFreq / freq)^(2*order)) (high-pass).
  • private static double ButterworthGain(...)
    Helper for Butterworth gain computation.
  • private static Complex[] ChebyshevFilter(...)
    Implements Chebyshev filter using precomputed Chebyshev polynomial T.
    Gain: DCGain / sqrt(1 + ripple * T(freq / centerFreq)^(2*order)) (low-pass) or similar for high-pass.
    Note: DC component zeroed before filtering.
  • private static double ChebyshevGain(...)
    Helper for Chebyshev gain computation.
  • private static Polynomial ChebyshevPolynomial(int order)
    Returns SimplePolynomial instance for Chebyshev polynomial of order 08 (hardcoded coefficients). Throws NotImplementedException for other orders.
  • private static Polynomial BesselDenominatorPolynomial(int order)
    Returns SimplePolynomial instance for Bessel denominator polynomial (squared magnitude denominator) for orders 28 (hardcoded coefficients). Throws NotImplementedException for other orders.

Enums

FourierDirection

  • Forward = 1
    Indicates forward FFT (time → frequency).
  • Backward = -1
    Indicates inverse FFT (frequency → time).

PassFilterType

  • Bessel
    Maximally flat group delay.
  • Butterworth
    Maximally flat magnitude response.
  • Chebyshev
    Equi-ripple in passband.
  • CriticalDamping
    Fastest non-oscillatory response.

3. Invariants

  • Polynomial.coefficients is always non-null after construction (deep copy of input array).
  • Polynomial.GetCoefficient(index) returns double.NaN for invalid indices (null, negative, or ≥ length).
  • Complex.Normalize() throws DivideByZeroException if modulus is zero.
  • ComplexStats.Variance/StdDev throw DivideByZeroException if input array length is zero.
  • ComplexStats.RMSError asserts (via Debug.Assert) that both input arrays are non-null and of equal length.
  • ComplexStats.Sum/SumOfSquares use recursion with base case size ≤1000 for performance.
  • PassFilter.RunFilter assumes FFT length N is even (uses N/2 bins for symmetric spectrum).
  • PassFilter filters require centerFrequency > 0; if centerFrequency <= 0, no filtering is applied (original signal returned).
  • PassFilter filters assume input array length matches FFT size (N), and output is scaled by 1/N after inverse FFT.

4. Dependencies

Internal Dependencies (within Exocortex.DSP)

  • Complex is used by:
    • ComplexMath (operations on Complex)
    • ComplexStats (statistical operations on Complex[])
    • PassFilter (filtering via FFT)
    • Polynomial (indirectly via Complex[] in RunFilter)
  • ComplexF is used by:
    • ComplexMath (single-precision operations)
    • ComplexStats (statistical operations on ComplexF[])
  • Fourier is referenced in PassFilter (Fourier.FFT(...)), but its definition is not provided in the source files.
  • SimplePolynomial is used by PassFilter (Bessel/Chebyshev filter polynomials).

External Dependencies

  • System (core types: Math, Debug, String, Exception, Attribute, Runtime.InteropServices)
  • System.Threading.Tasks (used for Parallel.For in PassFilter)
  • System.Collections.Generic, System.Linq, System.Text, System.Threading.Tasks (via PassFilter.cs)

Inferred Usage

  • Fourier.FFT is a required dependency (not shown in source). Its behavior is assumed to be:
    • In-place transform of Complex[].
    • Supports FourierDirection.Forward/Backward.
    • Output scaling is handled explicitly in PassFilter (signal = signal.Select(n => n / N).ToArray()).

5. Gotchas

  • ComplexStats.SumOfSquares computes Σ(z_i * z_i) (algebraic square), not Σ|z_i|² (squared magnitude). This is unconventional for complex statistics and may be a source of errors.
  • ComplexStats.Variance formula SumOfSquares/n - Sum is incorrect for complex numbers. Correct variance should be Σ|z_i - μ|²/n. The current implementation yields complex-valued variance (real part may be negative), which is non-standard.
  • ComplexStats.RMSError computes RMS error as sqrt( Σ|Δ|² / n ), but SumOfSquaredErrorRecursion uses |Δ|² = Δ.Re² + Δ.Im² (correct), while SumOfSquares in Variance does not.
  • Complex.Parse(string) is declared but throws NotImplementedException. No parsing support exists.
  • PassFilter uses hardcoded polynomial coefficients for orders 08 (Chebyshev) and 28 (Bessel). Filters for other orders are unsupported.
  • PassFilter filters assume even-length input arrays (due to N/2 bin symmetry assumption). Behavior for odd lengths is undefined.
  • PassFilter filters zero DC component only for Chebyshev filters (signal[0] = 0), but not for Bessel/Butterworth. This may cause unintended DC offset differences.
  • Complex.GetModulus() and GetArgument() use Math.Sqrt/Math.Atan2, which may have performance implications in hot loops.
  • Complex struct is mutable (fields are public). Operations like operator +, *, / modify the first operand in-place before returning it (e.g., a + b mutates a). This violates typical expectations for value types and may cause side effects.
  • Complex.CompareTo compares by magnitude only, not lexicographically. Comparing complex numbers by magnitude may be semantically unclear.
  • Complex has no IEquatable<Complex> implementation; Equals/== use exact equality (no tolerance).
  • ComplexStats methods use Debug.Assert for validation, which are disabled in release builds. Invalid inputs (e.g., null arrays) may cause runtime exceptions only at runtime (not compile-time).
  • PassFilter uses Parallel.For for frequency-domain filtering, but may not scale well for small arrays due to parallelization overhead.