Octahedral symmetries
In Codac, the class OctaSym is used to represent the symmetries of the hypercube, which are elements of the hyperoctahedral group. This class provides methods to create, manipulate, and apply these symmetries to objects.
Hyperoctahedral group
The hyperoctahedral \(B_n\) group is the group of symmetries of the hypercube \([-1,1]^n\). It contains \(2^n \cdot n!\) elements.
It is a signed symmetric group of permutations. It means that each symmetry of the hypercube can be represented by a permutation of the coordinates, and a sign for each coordinate (i.e., a reflection or not).
Two main representations of the hyperoctahedral group exist:
The Cauchy’s representation: It is a two-row representation where the first row contains the indices of the coordinates, and the second row contains the new indices after the permutation, with a sign indicating whether there is a reflection or not.
The Permutation representation: It is a \(n\times n\) matrix representation where each row and column has exactly one non-zero entry, which is either +1 or -1, indicating the permutation and reflection.
For example, in dimension three the same symmetry \(\sigma\) can be written in Cauchy’s representation as:
And in permutation representation as:
If we apply the symmetry \(\sigma\) to a point \(\mathbf{x} = \begin{pmatrix} x_1 \\ x_2 \\ x_3 \end{pmatrix}\), we get:
Codac implementation
The main representation used in Codac is the Cauchy’s notation. We suppose that the first row of the cauchy’s representation is in increasing order, i.e. (1,2,…n).
Note that the indexing starts at 1 as 0 and -0 can not be distinguished.
The constructors of the OctaSym class then require a single vector reprensenting the second row of the Cauchy’s representation.
For example, the symmetry \(\sigma\) mentionned earlier can be created in Codac as follows:
sigma = OctaSym([3,-1,2])
OctaSym sigma ({3,-1,2});
sigma = OctaSym({3,-1,2});
The permutation matrix can be recovered using the method permutation_matrix(). It returns the matrix \(P_{\sigma}\) as a Matrix object
P_sigma = sigma.permutation_matrix()
Matrix P_sigma = sigma.permutation_matrix();
P_sigma = sigma.permutation_matrix();
The inverse of a symmetry can be computed using the method invert(). These symmetries can also be composed using the multiplication operator *.
sigma_inv = sigma.invert()
sigma_comp = sigma * sigma_inv # identity symmetry
OctaSym sigma_inv = sigma.invert();
OctaSym sigma_comp = sigma * sigma_inv; // identity symmetry
sigma_inv = sigma.invert();
sigma_comp = sigma * sigma_inv; % identity symmetry
To apply the symmetry to an object, the classical operator () is used. Objects which support the application of a symmetry are listed below. Objects in bold are not supported yet but will be in the future.
Vectors
Contractors and separators. see more
Analytic and sampled trajectories.
SampledTraj.Sliced tubes.
For example, with the symmetry \(\sigma\) defined earlier:
X = Vector([4,5,6])
X_s = sigma(X) # X_s is the (poncual) interval vector (6,-4,5)
x = VectorVar(3)
f = AnalyticFunction([x], sigma(2*x))
Y = f.eval(X) # Y is the (poncual) interval vector (12,-8,10)
Vector X ({4,5,6});
Vector X_s = sigma(X); // X_s is (poncual) interval the vector (6,-4,5)
VectorVar x(3);
AnalyticFunction f({x}, sigma(2*x));
auto Y = f.eval(X); // Y is the (poncual) interval vector (12,-8,10)
X = Vector({4,5,6});
X_s = sigma(X); % X_s is the (poncual) interval vector (6,-4,5)
x = VectorVar(3);
f = AnalyticFunction({x}, sigma(2*x));
Y = f.eval(X); % Y is the (poncual) interval vector (12,-8,10)