The Realification module transforms complex‑valued multivariate polynomials into equivalent real‑valued polynomials. This is useful when complex normal coordinates appear in dynamical systems or reduced‑order models, but the final equations must be expressed in real variables. The module also provides general linear composition of polynomials, which can be used for coordinate changes and as an alternative realification method.
What does it do?
realify(poly, conj_map)Takes a polynomial in complex variables (which may be conjugate pairs or real) and a conjugation map, and returns a polynomial in real variables $x_i$, $y_i$ (for each conjugate pair) and $w_i$ (for each real variable). Example: if $z$ and $\bar z$ are a conjugate pair, they are replaced by $x+iy$ and $x-iy$.compose_linear(poly, M, p)Replaces each original variable $x_i$ by a linear combination $\sum_{j=1}^p M_{ij} y_j$ of new variables $y_1,\dots,y_p$. The matrix $M$ is $n \times p$, where $n$ is the number of variables inpoly.realify_via_linear(poly, conj_map)An alternative implementation that builds the linear map $z = x+iy$, $\bar z = x-iy$ and usescompose_linear. Mathematically equivalent torealify.
All functions preserve the concrete polynomial type (SparsePolynomial or DensePolynomial) of the input and work with both scalar‑ and array‑valued coefficients (e.g., vectors or tuples).
What is the maths?
Given variables in the canonical order $z_1,\dots,z_n,\bar z_1,\dots,\bar z_n,w_1,\dots,w_m$, each monomial
$
z1^{\alpha1}\cdots zn^{\alphan}\;\bar z1^{\beta1}\cdots\bar zn^{\betan}\;w1^{\gamma1}\cdots wm^{\gammam} $
is expanded using the binomial theorem for each pair $z_k, \bar z_k$ as follows:
$
zk^{\alphak}\bar zk^{\betak} = \sum{mk=0}^{\alphak}\sum{nk=0}^{\betak} \binom{\alphak}{mk}\binom{\betak}{nk} i^{\,mk-nk}\, xk^{\alphak+\betak-mk-nk}\, yk^{mk+nk}. $
Multiplying over all $k$ yields a sum of real monomials $x^{\gamma_x}y^{\gamma_y}w^{\gamma_w}$. Coefficients are accumulated over all $\mathbf{m},\mathbf{n}$ satisfying $\gamma_x = \alpha+\beta-\mathbf m-\mathbf n$ and $\gamma_y = \mathbf m+\mathbf n$.
The module also handles unpaired real variables directly. The conjugation map conj_map (length = number of original variables) encodes:
conj_map[i] = jmeans variable $i$ is the conjugate of variable $j$;conj_map[i] = imeans variable $i$ is real.
Variables are internally reordered to the canonical order $z, \bar z, w$ for efficient processing.
How does one use the module?
1. Setup
Load the module. It re‑exports the needed polynomial types and basic functions from an underlying Polynomials module.
using Realification # brings in realify, compose_linear, etc.2. Create a polynomial
Use either SparsePolynomial or DensePolynomial. Coefficients can be numbers, tuples, vectors, etc. The polynomial’s variables are implicitly the columns of the exponent matrix.
# Dense example: 3 variables, max degree 2
miset = all_multiindices_up_to(3, 2) # uses Grlex order
poly = zero(DensePolynomial{Tuple{2,ComplexF64}}, miset) # 2‑component coefficients3. Realify
Define a conjugation map of length equal to the number of variables. For a system with variables $z_1$, $z_2$, $z_3$ where $z_2$ is the conjugate of $z_1$ and $z_3$ is real:
conj_map = [2, 1, 3] # conj(z1)=z2, conj(z2)=z1, conj(z3)=z3
real_poly = realify(poly, conj_map)The new polynomial has variables $x_1, y_1, w_1$ (since $n=1$, $m=1$). Evaluation now expects real numbers:
x = real(z1); y = imag(z1); w = real(z3)
val = evaluate(real_poly, [x, y, w])4. Compose with a linear map
If you have a polynomial in variables $x_1,\dots,x_n$ and want to express it in new variables $y_1,\dots,y_p$ via $x_i = \sum_j M_{ij} y_j$ —
M = [1 1; 1 -1] # 2×2 matrix
p = 2
new_poly = compose_linear(poly, M, p) # result in y1,y25. Extract a single component
If coefficients are array‑valued (e.g., tuples for vector fields), you can extract one component as a scalar polynomial:
comp1_poly = extract_component(poly, 1) # polynomial for the first component6. Evaluate
evaluate works with the full coefficient array or a specific component:
full = evaluate(poly, [z1,z2,z3]) # returns the tuple
comp = evaluate(poly, [z1,z2,z3], 1) # returns first component
scalar = evaluate(comp1_poly, [z1,z2,z3]) # returns a numberImportant notes
- All functions preserve the polynomial type (
Sparse/Dense) and work with arbitrary coefficient types (numbers, vectors, tuples). - The module does not simplify powers of
imbeyond normal arithmetic; the final coefficients may still containimbut multiplied by real‑valued numbers, which is acceptable because the polynomial is complex‑valued but expressed in real variables. - The canonical variable ordering after
realifyis always $x_1,\dots,x_n, y_1,\dots,y_n, w_1,\dots,w_m$. This order is used in the exponent vectors of the returned polynomial. - The internal functions
_reorder_canonical,_realify_term,_multinomial,_compositionsare for module use only; the public API is what is exported.
For a complete working example, see the demo file that accompanies the module.