1"""Scalar wrapper and elementary operations exposed by the native backend."""
3from pyhyperiso.phyperiso.pyhyperiso
import math
as ma
4from typing
import Union
8 """Python wrapper for the C++ scalar_t class.
10 scalar_t is an enhanced complex number type that supports real projection,
11 full arithmetic, and compatibility with Python's numeric types.
14 def __init__(self, re: float = 0.0, im: float = 0.0):
15 """Initializes a Scalar from real and imaginary parts.
18 re (float): Real part. Defaults to 0.0.
19 im (float): Imaginary part. Defaults to 0.0.
25 """Creates a Scalar from a complex number.
28 z (complex): A Python complex.
31 Scalar: A wrapped scalar_t.
34 instance._cpp_obj = ma.scalar_t(z)
37 def real(self) -> float:
38 """Returns the real part.
40 ``Scalar.from_cpp`` can receive either a bound ``scalar_t`` object or a
41 native Python ``complex`` depending on the pybind overload that produced
42 the value. The C++ object exposes ``real()`` as a method, while Python
43 complex exposes ``real`` as a float attribute; both forms are supported.
46 float: Real component.
48 real_attr = getattr(self.
_cpp_obj,
"real")
49 return float(real_attr()
if callable(real_attr)
else real_attr)
51 def imag(self) -> float:
52 """Returns the imaginary part.
54 Supports both bound ``scalar_t.imag()`` and Python ``complex.imag``.
57 float: Imaginary component.
59 imag_attr = getattr(self.
_cpp_obj,
"imag")
60 return float(imag_attr()
if callable(imag_attr)
else imag_attr)
63 """Casts to float using the real part.
65 Bound ``scalar_t`` still uses its native ``to_double()`` implementation.
66 Native Python numbers/complex values use ``real()``.
71 to_double = getattr(self.
_cpp_obj,
"to_double",
None)
72 if callable(to_double):
77 """Casts to float, calling to_double.
85 """Casts to Python complex.
88 complex: Native Python complex value.
90 return complex(self.
real(), self.
imag())
92 def __add__(self, other:
"Scalar") ->
"Scalar":
94 result._cpp_obj = self.
_cpp_obj + other._cpp_obj
97 def __sub__(self, other:
"Scalar") ->
"Scalar":
99 result._cpp_obj = self.
_cpp_obj - other._cpp_obj
102 def __mul__(self, other:
"Scalar") ->
"Scalar":
104 result._cpp_obj = self.
_cpp_obj * other._cpp_obj
109 result._cpp_obj = self.
_cpp_obj / other._cpp_obj
118 if not isinstance(other, Scalar):
120 return self.
real() == other.real()
and self.
imag() == other.imag()
124 """Wraps an existing C++ scalar_t object."""
126 instance._cpp_obj = cpp_obj
130 return f
"Scalar({self.real()}, {self.imag()})"
133def _to_scalar(value: Union[float, complex, Scalar]) -> Scalar:
134 """Helper to convert float/complex to Scalar."""
135 if isinstance(value, Scalar):
137 elif isinstance(value, (float, int)):
139 elif isinstance(value, complex):
140 return Scalar.from_complex(value)
142 raise TypeError(f
"Expected float, complex or Scalar, got {type(value)}")
149 def wrapped(x: Scalar) -> Scalar:
151 result._cpp_obj = cpp_func(x._cpp_obj)
175def pow_scalar(base: Scalar, exponent: Union[Scalar, float, int]) -> Scalar:
176 """Raises a Scalar to a scalar/int/float exponent.
179 base (Scalar): The base.
180 exponent (Union[Scalar, float, int]): The exponent.
183 Scalar: Result of exponentiation.
185 if isinstance(exponent, Scalar):
186 cpp = ma.pow(base._cpp_obj, exponent._cpp_obj)
187 elif isinstance(exponent, (float, int)):
188 cpp = ma.pow(base._cpp_obj, float(exponent))
190 raise TypeError(
"Exponent must be Scalar, float, or int")
192 result._cpp_obj = cpp
__init__(self, float re=0.0, float im=0.0)
"Scalar" __sub__(self, "Scalar" other)
bool __eq__(self, object other)
"Scalar" __add__(self, "Scalar" other)
"Scalar" from_cpp(cls, cpp_obj)
"Scalar" from_complex(cls, complex z)
"Scalar" __mul__(self, "Scalar" other)
"Scalar" __truediv__(self, "Scalar" other)
complex __complex__(self)
Scalar pow_scalar(Scalar base, Union[Scalar, float, int] exponent)
_wrap_math_func(cpp_func)