![]() |
Symmetric Polynomials
V3.1
A C++ library for generating symmetric polynomials with relations
|
For a quick demonstration you may use the binaries found here. These are compiled from Demo.cpp using MSVC (Windows) and GCC (Linux). You can also compile these binaries yourself: For example, on Linux and from within the source
folder use:
g++ Demo.cpp -std=c++17 -O3 -fopenmp -march=native -o Lin64.out
Only the -std=c++17
flag is required; the other flags are for optimization.
Everything in this library is under the namespace symmp (short for Symmetric Polynomials). The code examples that follow will assume we are using this namespace.
So start with:
using symmp;
To specify a polynomial ring such as \(\mathbf Z[x_1,...,x_n]\), \(|x_i|=1\), we use two template parameters:
int64_t
.x_i
(when printed to an output stream) and no relations. We shall explain alternatives in the next few subsections.The zero element of \(\mathbf Z[x_1,...,x_n]\) can then be constructed by:
Poly<int, StandardVariables<>> p;
A nonzero monomial \(cx_1^{a_1}\cdots x_n^{a_n}\) is constructed by providing the exponent vector \([a_1,...,a_n]\) and the coefficient \(c\neq 0\).
For example,
p=Poly<int, StandardVariables<>>({0,1,4},7);
sets \(p=7x_2x_3^4\). Similarly,
auto t=Poly<int, StandardVariables<>>({1,1,2},-8);
sets \(t=-8x_1x_2x_3^2\).
Polynomials can be combined via the usual operators +,-,*
; they can be raised to a nonnegative integer powers by ^
.
For example:
p+=t;
sets \(p=-8x_1x_2x_3^2+7x_2x_3^4\) which can be verified by printing \(p\) to the console:
std::cout << p << "\n";
After that:
std::cout << (p+(p^2))<< "\n";
will print
$$-8x_1x_2x_3^2 + 7x_2x_3^4 + 64x_1^2x_2^2x_3^4 - 112x_1x_2^2x_3^6 + 49x_2^2x_3^8$$
which is exactly \(p+p^2\).
We can substitute StandardVariables with ElementarySymmetricVariables which specify variables with names e_i
, degrees \(|e_i|=i\) and no relations.
Example: The element \(q=-1.5e_1e_2\) of the graded ring \(\mathbf R[e_1,...,e_n], |e_i|=i\), can be defined as:
Poly<double, ElementarySymmetricVariables<>> q({ 2,3 }, -1.5);
For brevity let us use the following two typedefs:
typedef Poly<double, StandardVariables<>> x_poly_t; typedef Poly<double, ElementarySymmetricVariables<>> e_poly_t;
Now we view
\[\mathbf R[e_1,...,e_n]=\mathbf R[x_1,...,x_n]^{\Sigma_n}\]
with \(e_i=\sigma_i\) being the elementary symmetric polynomials on the \(x_i\). To convert \(q\) from \(e_i\) variables to \(x_i\) variables we use the class SymmetricBasis :
SymmetricBasis<x_poly_t, e_poly_t> SB(2);
The 2
signifies that we are using two variables \(x_1,x_2\). Then:
auto qx=SB(q); std::cout << qx;
will set the polynomial x_poly_t qx
to be q
transformed into the \(x_i\) variables (StandardVariables) and print
\[-1.5x_1^3x_2^5 -3x_1^4x_2^4 -1.5x_1^5x_2^3\]
We can perform the conversion the other way as well: given a polynomial on the \(x_i\) variables such as qx
we can use the object same SB
to transform qx
into a polynomial on the \(e_i\) variables :
auto qe=SB(qx); std::cout << qe;
which will print \(-1.5e_1e_2\).
q==qe
evaluates to 1
.We can generate
\[(\mathbf Z[x_1,...,x_n,y_1,...,y_n]/y_i^2=y_i)^{\Sigma_n}\]
by the \(\alpha_i, c_i, \gamma_{s,t}\) (see The Math).
The class TwistedChernBasis allows us to transform polynomials on \(x_i,y_i\) variables (HalfIdempotentVariables) into polynomials on the \(\alpha_i,c_i,\gamma_{s,i}\) (TwistedChernVariables).
Example:
typedef Poly<int, HalfIdempotentVariables<>> xy_poly_t; typedef Poly<int, TwistedChernVariables<>>> chern_poly_t; xy_poly_t r; r.insert({ 1,0,1,0 }, 2); r.insert({ 0,1,0,1 }, 2); TwistedChernBasis<xy_poly_t, chern_poly_t> TCB(2); std::cout << TCB(r) << "\n";
This sets r
to be \(2x_1y_1+2x_2y_2\), transforms it into \(\gamma_{s,j}\) variables and prints the result:
\[-2\gamma_{1,1}+2\alpha_1 c_1\]
And indeed:
\[2x_1y_1+2x_2y_2=-2\gamma_{1,1}+2\alpha_1 c_1\]
If we perform the transformation again we get the original polynomial:
std::cout << TCB(TCB(r)) << "\n";
prints \(2x_1y_1+2x_2y_2\).
2
in the constructor of TCB
is half the number of variables \(x_1,x_2,y_1,y_2\).To print the relations amongst \(\alpha_i,c_i,\gamma_{s,j}\) use:
print_half_idempotent_relations<xy_poly_t, chern_poly_t>(3);
The \(3\) here corresponds to the half the number of variables: \(x_1,x_2,x_3,y_1,y_2,y_3\) and can be replaced by any positive integer.
Finally, Demo.cpp contains another function, pontryagin_via_chern. This prints the expressions of the twisted Pontryagin/symplectic classes:
\[\pi_{s,t}=\kappa_{s,t}=\sum_{1\le i_1< \cdots< i_s\le n\\ 1\le j_1< \cdots< j_t\le n\\ i_u\neq j_v}x^2_{i_1}....x^2_{i_s}y_{j_1}\cdots y_{j_t}\]
in terms of the \(\alpha_i,c_i,\gamma_{s,t}\). For example, try running
pontryagin_via_chern < xy_poly_t, chern_poly_t>(5);