How to find generators in simplicial cohomology? For example, for $S^1$ and $S^2\dots$ Is there a way to find generators in cohomology groups? Any algorithm or even philosophical remark would be highly appreciated.
For example, I have $S^1\cong K$ represented by $1$-dimensional simplicial complex $K$ in the form of a triangle. Let its vertices be $1,2,3$. I want to find a generator of $H^1(K,\mathbb{Z})\cong \mathbb{Z}$. After some time thinking I decided to check whether cochain dual to edge $\{1,2\}$ (i.e. cochain $\{1,2\}$ taking value $1$ on the edge $\{1,2\}$ and value $0$ on other two edges) is a generator of $H^1(K,\mathbb{Z})$ and was able to prove it directly, that is, I can prove that any element $a\{12\}^*+b\{23\}^*+c\{31\}^*\in H^1(K,\mathbb{Z})$ can be written as $x\{3,1\}^*+d(y)$ by explicitly finding $y\in C^0(K,\mathbb{Z})$ and $x\in \mathbb{Z}$. However, at first I only guessed that $\{1,2\}^*$ is a generator. Is there a way how I could understand it without guessing?
Also, if I have, for example, $S^2\cong L$, where $L$ is a scary looking simplicial complex (imagine boundary of $3$-dimensional polyhedron with triangle faces scary enough to not have a name), then I have no idea what a candidate for generator of $H^2(L,\mathbb{Z})$ looks like. How could I see it in this case? I mean, as dimension increases, difficulty of guessing and direct proof must increase too.
Thank you.
 A: Ok! Well, this was more long-winded than I intended, haha. There's a LOT to cover here, so don't feel bad if it takes a while to sink in! Everything will come with time. For now, though, let's get started!
How do we compute simplicial cohomology? Moreover, when we compute it, what are the generators physically?
The first question won't be too hard to answer -- one of the big draws of cohomology (and part of its great success) is its effectiveness. We really can compute the hell out of these things, and there are computer programs (such as sage) that will happily compute the cohomology of your favorite complex. Indeed, in sage, the following works:
# Let's use a premade complex for simplicity
# you could build your own if you wanted to, though!
T = simplicial_complexes.Torus() 

T.cohomology()

# the above outputs: {0: 0, 1: Z x Z, 2: Z}
# this is the reduced cohomology! 

# If you want the unreduced cohomology, then run
T.cohomology(reduced=False)

# which outputs {0: Z, 1: Z x Z, 2: Z}
# (as expected)


A lot of ink has been spilled (see here and here for instance) about what cohomology is intuitively. I think there is a good answer for manifolds (De Rham Cohomology) but things are less clear for simplicial cohomology.
Here's my take:
Let's look at a simple graph -- say

then 0-cochains are (basically) functions on the vertices. Similarly, 1-cochains are (basically) functions on the edges.
Now a 1-cochain is a coboundary exactly when we can "integrate" along the cochain. That is, exactly when we can find a function on the vertices which is compatible with the edges. Let's see two examples in action:

If we want to "integrate" this, we want to assign integers to $v_0$, $v_1$, and $v_2$ so that the difference along each edge agrees with our function. Of course, it's obvious how we can do this:

*

*$v_0$ can get whatever value it likes ($C$, say)

*which forces $v_1$ and $v_2$ to get $C+5$

*Luckily, then the difference along $e_{12}$ is $0$. Which is what we needed!


Let's see another example where we're less lucky.

In this case we can try the same procedure. You can convince yourself that no function on the vertices can possibly be compatible with this edge-function.
This element, then, survives to the cohomology. It is a cocycle (since it lives in dimension 1 and there are no simplices of dimension 2 for it to map to) but it is not a coboundary (since there is no vertex function which induces it).
A generator of the cohomology group is some edge-function (or family of edge functions, more generally) with the property that every non-integrable edge function is a linear combination of the generators.

You can see that "locally" we can always solve this problem. Along any given edge it's easy to find a function on the vertices which works with that one edge.
The issue comes from trying to glue these "local" solutions together. It's possible that there is no way to choose the choices in a way that's globally compatible.
As we saw in the above example, we could solve the problem for $e_{02}$ and for $e_{01}$, but this forced us into a corner where $e_{12}$ was unsatisfiable. Notice this issue occurred because of the cycle. It is in this (slightly roundabout) way that cohomology "detects holes".
This is what cohomology does. It measures the ways that "gluing" together locally easy decisions might fail. So then generators for our cohomology group encapsulate all the ways (up to a natural notion of "equivalence", which you should work out!)
an edge-function might fail to be solvable. That is, the generators are "basic" obstructions from which all other unsolvable edge-functions spawn.
Now I'll wave my hands and say the higher dimensional case is analogous. An element of $H^2$ is a function defined on triangles which can't be "integrated" to a function on the edges bounding those triangles, etc.
It's at this point that things begin to get hard to visualize, thankfully the computation remains easy. Let's see why!

For concreteness we'll work with real valued functions. Then we have a vector space of such functions and everything is nice. You can imagine functions valued in an arbitrary ring will work too, at the cost of doing module theory instead of linear algebra (though for nice rings like $\mathbb{Z}$, things are still extremely tractable).
Now let $K$ be a simplicial complex.

*

*Build the chain complex
$$
\cdots \to C_{n+1} \to C_n \to C_{n-1} \to \cdots
$$
where each $C_n$ is free abelian, generated by the $n$-simplices in $K$.

Notice our boundary map $\partial : C_{n+1} \to C_n$ is given by a matrix.
We know what $\partial \sigma$ is for each individual $n+1$-simplex $\sigma$, but since the $\sigma$ form a basis for the space, that's all we need. For the triangle example we've been working with, can you compute $\partial$?
It should be a $3 \times 3$ matrix mapping
$\mathbb{Z}(e_{01}, e_{12}, e_{02}) \to \mathbb{Z}(v_0, v_1, v_2)$.


*Dualize, by looking at functions from each of these groups to $\mathbb{R}$.
This gives us a new complex
$$
\cdots \leftarrow 
\text{Hom}(C_{n+1}, \mathbb{R}) \leftarrow
\text{Hom}(C_n, \mathbb{R}) \leftarrow
\text{Hom}(C_{n-1}, \mathbb{R}) \leftarrow \cdots
$$
Note, by free-abelian-ness, each $C^n = \text{Hom}(C_n, \mathbb{R})$ is basically the same as looking at functions from individual $n$-simplices to $\mathbb{R}$ (like we were doing in the previous section). You should convince yourself that the coboundary operator for this complex is exactly $\partial^{T}$ (the transpose of the matrix from step 1).


*Compute homology of this sequence. That is, look at
$$
\frac{\text{ker}(\partial^T : C^n \to C^{n+1})}{\text{im}(\partial^T : C^{n-1} \to C^{n})}
$$
Of course, computing the kernel of a matrix is easy. Then after we have our two kernels, computing the quotient of two vector spaces is also easy (though regrettably much less frequently taught... See here for a quick description).
But now we're done! The linear algebra that we just did endowed us with a basis for the cohomology group. If you like, you can simply look at the size of the basis and carry on with your life. But as a (fun?) exercise, do you see how to answer your own question from here? The basis elements actually correspond to functions on $n$-simplices! Do you see how?

I hope this helps ^_^
