![]() |
Mackey
V3.3
A C++ library for computing RO(G) graded homology
|
The code examples here can be compiled from the .cpp file in the demo folder.
Many parts of the library can be individually included. To keep things simple, we provide a single header file Mackey.hpp that includes the entire library (and Eigen)
MACKEY_USE_OPENMP
before including Mackey.hpp and enable openMP in your compiler (on Clang and GCC this is done by the flag -fopenmp
)With that in mind, we start with:
#include "Mackey.hpp"
Everything in this library is under the namespace mackey. For the following code examples we use:
using namespace mackey;
The three template parameters that need to be set are the ambient group \(G\), the coefficient ring \(R\) and the \(G\)-space \(X\). For these examples let us use \(X=*\) which supports all of the library's features.
From the get-go the library provides support for:
int64_t
so there's no need to define a wrapper around it (64bit accuracy is more than enough for these computations, and you can use an overflow sanitizer to protect against it).For example C2Power<5,Z_mod<3>>
is the type corresponding to group \(C_{2^5}\) and coefficients \(\mathbf Z/3\).
Another example: C2Power<1,int64_t>
corresponds to group \(C_2\) and coefficients \(\mathbf Z\) with 64bit range.
For the following examples we shall use the configuration:
typedef C4<int64_t> group_t;
which means \(\mathbf Z\) coefficients and group \(C_4\).
The class AdditiveStructure computes the homology of all spheres in a given range as Mackey functors.
Example:
AdditiveStructure<group_t> A({-3,-4},{5,6});
computes the homology of all spheres \(S^{n\sigma+m\lambda}\) with \(-3\leq n\leq 5, -4\leq m\leq 6\).
{n,m}
. More generally for \(C_{2^n}\) the sphere \(S^{t_1\sigma+\sum_it_i\lambda_i}\) is represented by {t_1,...,t_n}
. This is specified in C2n.hpp.To print all Mackey functors \(H_{\star}\) in the universal notation (see "Universal" Mackey functor notation) and for \(\star\) in the aforementioned range, use:
std::cout << A << "\n";
The answer is of the form
The k=-9 homology of the -1,-4 sphere is 112#01
which means
\[H_{-9}(S^{-\sigma-4\lambda})= 112\#01\]
in our "universal notation".
You can survey the identified Mackey functors by:
std::cout << "The identified Mackey functors are: " << A.identified() << "\n\n\n\n";
(this will print one Mackey functor from each each equivalence class)
The class Factorization computes the multiplication graph (see the page Factorization) given the "basic irreducibles".
In this case let us use \(a_{\sigma},u_{2\sigma},a_{\lambda},u_{\lambda}\) as our irreducibles:
std::vector<std::vector<int>> basic_irr = { {0, 1, 0}, {2, 2, 0}, {0, 0, 1}, {2, 0, 1} }; std::vector<std::string> basic_irr_names = {"asigma", "u2sigma", "alambda", "ulambda"};
{k,t1,...,tn}
where {t1,...,tn}
represents \(S^V\).To compute the multiplication graph in the range \(S^{n\sigma+m\lambda}\), $-5\leq n,m\leq 5$, use:
auto F = Factorization<group_t>(2, {-5, -5}, {5, 5}, basic_irr, basic_irr_names);
The 2
here signifies that we work on the top level of \(C_4\).
Then
F.compute_with_sources({{0, 0, 0}}, {"1"});
computes the factorizations by connecting every node in the multiplication graph to \(1\) (if possible). To print the generator at degree \([3,1,0]\) use:
std::cout << "The generator(s) at degree 3,1,0 is (are): " << F.getname({ -2,-2,0 }) << "\n\n";
F
. This can be done using degreewithinrangeTo print the names of all generators use:
std::cout << F << "\n\n";
The answer will be of the form
At degree -4,-2,-1 we have: 1*4/(u2sigma*ulambda)
or of the form:
At degree -7,-4,-4 we have: ???
The ???
means that the generator could not be obtained by multiplying/dividing the basic irreducibles with 1
. This means that additional sources may be needed. To include the generator of \(H_{-3}S^{-2\lambda}\) as our source we use:
F.compute_with_sources({{0,0,0},{-3,0,-2}}, {"1","s"});
where now both \(1\) and \(s\) are used as sources. With that extra source, the code
std::cout << F << "\n\n";
won't produce any ???
.
To print the multiplication graph to a file and in the dot format use
std::ofstream file; file.open("multgraph.dot"); file << F.graph; file.close();
You can also print the shortest path tree to a file, which will be much simpler than the entire multiplication graph
file.open("shortestpaths.dot"); file << F.shortest_paths; file.close();
The .dot files can be rendered to .svg files using Graphviz.
The class Factorization works by multiplying all generators of \(H_\star\) in a given range.
To multiply two specific generators together we use the function ROGreen. Example:
auto linear_combination = ROGreen<group_t>(2, {-4, -2, -1}, {2, 0, 1});
performs the operation
\[ H_0^{C_4}(S^{2\sigma-2\lambda}) \otimes H_{-4}^{C_4}(S^{-2\sigma-\lambda}) \to H_{-2}^{C_4}(S^{-2\sigma}) \\ a\otimes b\mapsto ab\]
where \(a,b\) are generators of the respective homology groups. Here:
linear_combination
is a row vector \([t_0,...,t_k]\) of integer entries representing that: \[ab=\sum_it_ig_i\]
where \(g_i\) are the generators of the homology group the product lives in.In our case \(H_{-2}^{C_4}(S^{-2\sigma}) \) is cyclic so linear_combination
has length \(1\).
Using the Factorization object F
from the previous examples, we can actually print the names of the generators being multiplied and the name of the generator in the degree of the product:
std::cout << F.getname({ -4,-2,-1 }) << " * " << F.getname({ 2,0,1 }) << " = "; std::cout << linear_combination[0] << " * " << F.getname({ -2,-2,0 });
which will print out that:
\[\frac{4}{u_{2\sigma}u_{\lambda}}\cdot u_{\lambda}= 2\cdot \frac{2}{u_{2\sigma}}\]
int
arguments in RO::Green. For example, providing \(1,2\) selects the second and third generators \(a,b\) of the noncyclic groups respectively.The method ROMassey computes (triple) Massey products in the Green functor \(H_{\star}\). Example:
auto Mass= mackey::ROMassey<group_t>(2,{0,1,0},{-3,-3,0},{2,2,0});
computes the Massey product \(\langle a_{\sigma},w_3,u_{2\sigma}\rangle \) and its indeterminacy.
As with the multiplicative structure, the Massey product is expressed in terms of a linear combination of the basis in the homology of the box product. But there's also indeterminacy to worry about. In this case,
std::cout << Mass.indeterminacy;
prints out 1, so there is no indeterminacy, and we can print out the answer by:
std::cout << "<" << F.getname({ 0, 0, 3 }) << " , " << F.getname({ -3, 0, -2 }) << " , "; std::cout << F.getname({ 2, 0, 1 }) << "> = " << Mass.basis[0] << " * " << F.getname({ 0,0,2 });
since the homology at degree {0,0,2}
is cyclic (otherwise Mass.basis
is a vector of size >1).
int
arguments at the end for selections, analogous to what we did in Multiplying generators (see Massey for more details).For groups beyond \(C_4\) it's possible for various identifications to fail. So let us set
typedef C8<int64_t> group2_t;
for \(C_8\) with \(\mathbf Z\) coefficients.
Then the code
AdditiveStructure<group2_t> A2({ -3, -3,-3 }, { 3, 3,3 }); std::cout << A2 << "\n\n";
can also produce output like:
The k=3 homology of the 3,1,-1 sphere is unknown 5
This means that the program couldn't write \(H_{3}(S^{3\sigma+\lambda_0-\lambda_1})\) in the "universal notation" and instead named it unknown Mackey functor with id 5. To print out the Mackey functor structure, us:
std::cout << "The unknown 5 is =\n" << A2.unknown()[5].print()<< "\n\n";
As for factorization, let us use the following basic irreducibles and sources over \(C_8\):
typedef std::vector<std::vector<int>> vv; typedef std::vector<std::string> vs; vv basic_irr2 = { {0,1,0,0},{0,0,1,0},{0,0,0,1},{2,2,0,0},{2,0,1,0},{2,0,0,1} }; vs basic_names2 = { "a2","a4","a8","u2","u4","u8" }; vv sources2 = { {0,0,0,0}, {-3,0,0,-2} }; vs source_names2 = { "1", "s"};
Then
auto F2 = Factorization<group2_t>(3, {-5,-5,-5 }, { 5, 5, 5 }, basic_irr2, basic_names2); F2.compute_with_sources(sources2, source_names2); std::cout << F2.disconnected_degrees().size() << "\n\n";
will print out 49, which is the number of generators that couldn't be connected to \(1\) or \(s\). There are two reasons that caused this:
The solution to the first problem is to increase the range of the spheres being used. To solve the second problem, we use triple products (see A caveat) via:
F2.pass_unidentified();
Once we do that,
std::cout << F2.disconnected_degrees().size() << "\n\n";
will print out 5.
Finally, if only the connectivity of the multiplication graph is desired, there is a specialized MultConnectivity class for that exact purpose.
For example,
auto MC = MultConnectivity<group2_t>(F2); MC.compute_with_sources(sources2); std::cout << MC.disconnected_degrees.size() << "\n";
will print \(0\), which means that all generators are connected to \(1,s\).
In many cases it is desirable to save computational results in cold storage and then load them back as needed.
This library achieves serialization by calling the cereal library, which you'll need to include in your path. The serialization methods are found in the header Cerealizer.hpp so start with:
#include Serialization/Cerealizer.hpp
For example, say we have a Factorization object F
that we want to save to a binary file. We can do that by:
save(F,"filename");
This actually saves the parent class MultTableData as opposed to the factorization object, since the fundamental data are in that class. As such, to load it use:
MultTableData<group_t> M; load(M,"filename");
group_t
must match with the template parameter of the saved object.We can then construct F
from M
by:
Factorization<group_t> Fnew(std::move(M),basic_irr_names);
(the names of the basic irreducibles are not part of the data that was serialized). Then Fnew
and F
will be identical.