Source code for diamondback.transforms.complex_transform
"""**Description**
A complex transform converts a three-phase real signal to a complex
signal, or converts a complex signal to a three-phase real signal, in
equivalent and reversible representations. A neutral condition is
specified.
Singleton.
.. math::
\\gamma = \\scriptsize{ \\matrix{ 1 & \\frac{-1}{2} & \\frac{-1}{2}\\cr 0 & \\frac{3^{0.5}}{2} & \\frac{-3^{0.5}}{2}\\cr 1 & 1 & 1 } }
.. math::
\\alpha = \\matrix{\\frac{1}{3}}^{0.5}\\ e^{\\ -j\\ \\frac{\\pi}{6}\\ }
Complex - Three-Phase.
.. math::
y_{n} = \\matrix{ x^{T}_{n}\\ \\gamma\\ }\\ \\scriptsize{[\\ \\matrix{ 1 & j & 0 }\\ ]^{T}}
.. math::
\\overline{\\scriptsize{Neutral}}\\ \\qquad\\longrightarrow\\qquad y_{n} = y_{n}\\ \\alpha
Three-Phase - Complex.
.. math::
\\overline{\\scriptsize{Neutral}}\\ \\qquad\\longrightarrow\\qquad x_{n} = \\frac{x_{n}}{\\alpha}
.. math::
y_{n} = \\matrix{\\ \\matrix{ \\gamma^{T}\\gamma }^{-1}\\ \\gamma^{T}\\ \\scriptsize{[\\ \\matrix{ real(\\ x_{n}\\ ) & imag(\\ x_{n}\\ ) & 0 }\\ ]^{T}}}^{T}
**Example**
.. code-block:: python
from diamondback import ComplexExponentialFilter, ComplexTransform
import numpy
x = ComplexExponentialFilter(0.0).filter(numpy.linspace(-1.0e-4, 1.0e-4, 128) + 0.1)
y = ComplexTransform.transform(x, neutral = True)
z = ComplexTransform.transform(y, neutral = True)
**License**
`BSD-3C. <https://github.com/larryturner/diamondback/blob/master/license>`_
© 2018 - 2025 Larry Turner, Schneider Electric Industries SAS. All rights reserved.
**Author**
Larry Turner, Schneider Electric, AI Hub, 2018-01-26.
"""
import math
import numpy
[docs]
class ComplexTransform(object):
"""Complex transform."""
COEFFICIENT: numpy.ndarray = (2.0 / 3.0) * numpy.array(
[[1.0, -0.5, -0.5], [0.0, 0.5 * (3.0**0.5), -0.5 * (3.0**0.5)], [1.0, 1.0, 1.0]]
)
GAIN: complex = ((1.0 / 3.0) ** 0.5) * numpy.exp(-1j * math.pi / 6.0)
[docs]
@classmethod
def transform(cls, x: list | numpy.ndarray, neutral: bool = True) -> numpy.ndarray:
"""Transforms a real three-phase or complex incident signal into a complex
or three-phase reference signal.
Arguments:
x: list | numpy.ndarray - incident signal.
neutral: bool.
Returns:
y: numpy.ndarray - reference signal.
"""
if not isinstance(x, numpy.ndarray):
x = numpy.array(list(x))
if (len(x.shape) > 2) or (len(x) == 0):
raise ValueError(f"X = {x}")
if len(x.shape) < 2:
rows, cols = 1, x.shape[0]
else:
rows, cols = x.shape
if (rows not in (1, 3)) or (cols <= 0):
raise ValueError(f"Rows = {rows} Columns = {cols} Expected Rows in (1, 3) and Columns in (0, inf)")
if rows == 1:
v = x
if not neutral:
v = x / ComplexTransform.GAIN
y = numpy.matmul(
numpy.linalg.inv(ComplexTransform.COEFFICIENT),
numpy.array([v.real, v.imag, numpy.zeros(cols)]),
)
else:
v = numpy.matmul(ComplexTransform.COEFFICIENT, x)
y = v[0, :] + 1j * v[1, :]
if not neutral:
y *= ComplexTransform.GAIN
return y