| jupytext |
|
||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|
| kernelspec |
|
:tags: [remove-cell]
import sys
sys.path.append("../code")
from init_course import *
init_notebook()
from IPython.display import HTML
from nbconvert.filters.markdown import markdown2html_pandoc
displaymd = lambda markdown: display_html(HTML(markdown2html_pandoc(markdown)))
# Markdown tables are ugly, and Mathjax doesn't support \tabular,
# therefore we use math mode + \array + add a command \T to make
# the \array rows less dense.
table_header = r"""$$
\require{color}
colordefs
\newcommand\T{\Rule{0pt}{1em}{.3em}}
\begin{array}{fmt}
\hline
body\\
\hline
\end{array}
$$"""
replacements = [
("{", "{{"),
("}", "}}"),
("colordefs", "{colordefs}"),
("fmt", "{fmt}"),
("body", "{body}"),
]
for i, j in replacements:
table_header = table_header.replace(i, j)
# Symmetry classes names and their symmetry properties
symmetry_classes = ("A", "AIII", "AI", "BDI", "D", "DIII", "AII", "CII", "C", "CI")
chiralsym = 5 * ("", "1")
phs = 3 * ("",) + 3 * ("1",) + ("",) + 3 * ("-1",)
trs = 2 * ("",) + 2 * ("1",) + ("",) + 3 * ("-1",) + ("", "1")
# Locations of non-empty entries in the periodic table
primary_seq = lambda n: np.arange(n) % 2
z_descendant = lambda n: np.arange(n) % 8
z2_descendant = lambda n: np.arange(1, n + 1) % 8
z2_descendant2 = lambda n: np.arange(2, n + 2) % 8
twoz_descendant = lambda n: np.arange(4, n + 4) % 8
line_end = "\\T\\\\\n"
sep = " & "
def make_table(n=4, show_symmetries=True, sort_order=None):
"""Create an array of entries forming the periodic table.
Parameters:
-----------
n : int
Number of dimensions to show.
show_symmetries : bool
Show symmetry information for each symmetry class.
sort_order : int array or None
Ordering to apply to the symmetry classes
(can be trivially used to discard entries).
Returns:
--------
data : np.ndarray
A string array with the entries of the periodic table.
format_string : str
An alignment string that can be used to feed the resulting
table to a Latex \array environment.
"""
dimensions = np.array([[str(i) for i in range(n)]], dtype="S100")
if dimensions.shape[1]:
dimensions[0, 0] = r"d=" + dimensions[0, 0].decode("UTF-8")
complex_entries = np.zeros((2, n), dtype="S100")
complex_entries[primary_seq(n), np.arange(n)] = r"\mathbb{Z}"
real_entries = np.zeros((8, n), dtype="S100")
real_entries[z_descendant(n), np.arange(n)] = r"\mathbb{Z}"
real_entries[z2_descendant(n), np.arange(n)] = r"\mathbb{Z}_2"
real_entries[z2_descendant2(n), np.arange(n)] = r"\mathbb{Z}_2"
real_entries[twoz_descendant(n), np.arange(n)] = r"2\mathbb{Z}"
entries = np.r_[complex_entries, real_entries]
sym_classes_rm = tuple(r"\textrm{{{}}}".format(cl) for cl in symmetry_classes)
sym = np.array(
[sym_classes_rm] + show_symmetries * [chiralsym, phs, trs], dtype="S100"
).T
sym_header = np.array(
[
[r"\textrm{class}"]
+ show_symmetries * [r"\mathcal{C}", r"\mathcal{P}", r"\mathcal{T}"]
],
dtype="S100",
)
header = np.c_[sym_header, dimensions]
table = np.c_[sym, entries]
if sort_order is not None:
table = table[sort_order]
format_string = "c|" + show_symmetries * "rrr" + n * show_symmetries * "|" + n * "c"
return np.r_[header, table], format_string
def color_table(table, color_array):
"""Apply rgb colors to table entries.
`color_array[i, j]` is the rgb color of the entry `(i, j)`.
Returns the string of color definitions required for coloring the table.
"""
apply_color = lambda text, color: r"\color{{{}}}{{{}}}".format(color, text)
colors = {}
for idx in np.indices(table.shape).reshape(2, -1).T:
idx = tuple(idx)
if not any(color_array[idx]):
pass
color = ",".join("{:1.2}".format(i) for i in color_array[idx])
val = str(abs(hash(color)))[:8]
colors[color] = val
table[idx] = apply_color(table[idx].decode("utf-8"), val)
defs = []
for color, code in list(colors.items()):
defs.append(r"\definecolor{{{}}}{{rgb}}{{{}}}".format(code, color))
return "\n".join(defs)
Shinsei Ryu from the University of Illinois will introduce the general classification of topological insulators and superconductors.
Video("cKzUuQyZjFo")
+++
Let us now look at all the possible symmetry classes in dimensions from
There are quite a few, here is the full list:
full_table, format_string = make_table(
show_symmetries=False, sort_order=np.argsort(symmetry_classes)
)
rows = [sep.join([c.decode("utf-8") for c in line]) for line in full_table]
rows[1] = r"\hline " + rows[1]
block = line_end.join(rows)
colordefs = "{}"
displaymd(table_header.format(colordefs=colordefs, fmt=format_string, body=block))
This table has a lot of logic in it, but to you it most likely looks no better than this:
np.random.seed(1)
full_table, format_string = make_table(
show_symmetries=False, sort_order=np.random.permutation(10)
)
color_array = np.round(np.random.rand(*(full_table.shape + (3,))), 2)
colordefs = color_table(full_table, color_array)
rows = [sep.join([c.decode("utf-8") for c in line]) for line in full_table]
rows[1] = r"\hline " + rows[1]
block = line_end.join(rows)
displaymd(table_header.format(colordefs=colordefs, fmt=format_string, body=block))
But don't worry, we are going to learn exactly what these tables mean.
First of all, let's review the meaning of the entries in the table. Each entry gives the topological classification of a system with a given combination of symmetries and dimensionality. In other words, it gives us the possible values that the topological invariant
An empty entry means that the system does not have a topological phase. In other words, all gapped Hamiltonians with dimension and symmetries corresponding to an empty entry can be deformed into each other, without ever closing the bulk gap and without breaking any existing symmetry.
A
A
A
Now that we have attached a meaning to each entry in the table, let's try to understand the table as a whole. The first thing to do is to understand why it has ten and only ten rows.
Each row in the table corresponds to a certain symmetry class, that is to a given combination of the presence or absence of three fundamental discrete symmetries.
You already encountered these three symmetries all the way back in week one. They are time-reversal symmetry (
Why do we consider these symmetries fundamental, and restrict the periodic table to them only?
As you may recall from week one, and as Shinsei Ryu explained in the introductory video, normal unitary symmetries of a Hamiltonian do not have particularly interesting consequences for topological classification. One may always make the Hamiltonian block-diagonal, reducing the problem to the study of a single block. This procedure can be repeated until one runs out of unitary symmetries and is left with an irreducible block of the Hamiltonian, i.e. one which cannot be block diagonalized.
Time-reversal, particle-hole and chiral symmetries act in a different way. They impose certain constraints on an irreducible Hamiltonian - for instance, by forcing it to be a real matrix, or to be block off-diagonal.
Note, however, that it is possible to extend the periodic table to study the interplay between these three discrete symmetries and other unitary symmetries. For instance, we have already touched upon crystalline symmetries in week seven, and we will return to them in week ten.
But for now, let's focus on the three fundamental discrete symmetries:
-
$\mathcal{T}$ is an anti-unitary operator which commutes with the Hamiltonian. -
$\mathcal{P}$ is an anti-unitary operator which anti-commutes with the Hamiltonian. -
$\mathcal{C}$ is a unitary operator which anti-commutes with the Hamiltonian.
Recall that an anti-unitary operator can be written as the product of a unitary operator and the complex conjugation operator
For instance, you will recall that for the time-reversal operator acting on electronic states,
We have seen the two cases
The time-reversal operator
where we have used that
This can only be upheld with
Thus, a system can behave in three ways under time-reversal symmetry
How do we arrive to having ten symmetry classes? Let's count all the possible cases carefully. By combining the three cases for
The important thing to notice now is that
This also means that if a system only has either
On the other hand, if both
Adding all the possibilities, we indeed find 10 symmetry classes:
The first term in the sum corresponds to the eight cases where there is at least one anti-unitary symmetry: either
The second term in the sum covers the two cases when there are no anti-unitary symmetries. These symmetry classes are called complex.
Let's have another look at the 10 rows in the table, this time specifying which combination of the three fundamental symmetries each row has:
np.random.seed(1)
full_table, format_string = make_table(
n=0, show_symmetries=True, sort_order=np.argsort(symmetry_classes)
)
rows = [sep.join([c.decode("utf-8") for c in line]) for line in full_table]
rows[1] = r"\hline " + rows[1]
block = line_end.join(rows)
displaymd(table_header.format(colordefs=colordefs, fmt=format_string, body=block))
The somewhat cryptic notations in the leftmost column are just the names of the different symmetry classes. (Also the 'I's appearing there are Roman cardinal numbers, so for instance BDI is 'B D one', and AIII is "A three".)
Their names come from an elegant mathematical classification of symmetric spaces worked out by Elie Cartan in 1926. While it is definitely intriguing that a group theory result from 1926 reappears in a totally different context almost 80 years later, the origin of this nomenclature is not directly relevant to most of the theory done in the field. The two complex classes are A and AIII.
question = "Which symmetry class do we get if we break Kramers degeneracy in class BDI?"
answers = ["D", "AIII", "DIII", "None, class BDI has no Kramers degeneracy"]
explanation = "Kramers degeneracy requires that time reversal squares to -1, while it squares to 1 in class BDI."
MultipleChoice(
question=question, answers=answers, correct_answer=3, explanation=explanation
)
Finally, let us make an extra observation:
While the particle-hole symmetry appears in any superconductor, it must satisfy
$\mathcal{P}^2 = -\mathcal{T}^2$ due to the way the Bogoliubov quasiparticles are related to the original electrons. This makes the symmetry classes BDI, and CII rely on a fine-tuned Hamiltonian, just like the symmetry class AIII.
To get some confidence with the table and these obscure names, it is useful to see where the topological systems that we have studied so far fit into the table.
Every red entry in the table below corresponds to something which we already know and studied in the previous weeks of the course, as you can discover by moving the mouse over it.
tooltips = {
(1, 6): "Chern insulator: no symmetries, d=2",
(9, 5): "Majorana wire: spinful particle-hole, d=1",
(4, 5): "Polyacetilene/SSH chain: sublattice symmetry, d=1",
(3, 6): "QSHE: spinful TRS, d=2",
(3, 7): "3D strong TI: spinful TRS, d=3",
(9, 6): "p-wave superconductor: PHS, d=2",
(9, 4): "Superconducting quantum dot: d=0, PHS",
(2, 4): "Quantum dot: d=0, spinless TRS",
(1, 4): "Quantum dot: d=0, no symmetries",
(3, 4): "Quantum dot: d=0, spinful TRS and Kramers degeneracy",
}
table, format_string = make_table(
show_symmetries=True, sort_order=np.argsort(symmetry_classes)
)
colors = np.zeros(shape=table.shape + (3,))
colors[1:, 4:] = [0.7, 0.7, 0.7]
for pos in tooltips:
colors[pos] = [1.0, 0.0, 0.0]
colordefs = color_table(table, colors)
for pos, val in list(tooltips.items()):
table[pos] = r"\texttip{{{}}}{{{}}}".format(table[pos].decode("utf-8"), val)
rows = [sep.join([c.decode("utf-8") for c in line]) for line in table]
rows[1] = r"\hline " + rows[1]
block = line_end.join(rows)
HTML(
markdown2html_pandoc(
table_header.format(
colordefs=("\\require{action}\n" + colordefs), fmt=format_string, body=block
)
)
)
As you can see, the Majorana wire and the
We have now explained why there are ten rows and the meaning of the symmetry classes, but the table as a whole still does not have a coherent structure. Is there a way that we can connect systems between different symmetry classes and different dimensions?
Given a gapped Bloch Hamiltonian
The basic idea is to add a new momentum
This procedure is slightly different depending on whether the initial
Let's first suppose that
Then consider the following higher-dimensional Hamiltonian:
This Hamiltonian has the same number of bands as
This expression guarantees that the gap of
What are the discrete symmetries of
If
If instead
We won't do that, but state that the result is that by removing chiral symmetry and adding one dimension, one obtains that BDI
Let's now start from a Hamiltonian without chiral symmetry. Our procedure this time involves a doubling of the number of bands of
Note that just like in our previous argument, the topological invariant of
What are the symmetries of
- if
$H_d$ has no symmetries at all, meaning that it was in class A, then$H_{d+1}$ only has chiral symmetry, meaning that it is in class AIII. So we obtain A$\to$ AIII. - if
$H_d$ has one anti-unitary symmetry, then$H_{d+1}$ must have all three discrete symmetries. Again, we will not work out the details for each case, but one obtains that AI$\to$ BDI, D$\to$ DIII, AII$\to$ CII, and C$\to$ CI.
Now that we have learned how to extend the topological classification by adding one dimension to the Hamiltonian and changing its symmetry in an appropriate way, nothing forbids us to repeat the procedure, by going two dimensions higher, three dimensions higher, etc...
So we have made the procedure of finding topological phases systematic.
If you repeat the procedure many times, you will find that it has a period, i.e. at some point you end up in the same symmetry class you started with.
This is easy to see for the two complex classes, which are just interchanged:
- A
$\to$ AIII$\to$ A.
But it is also the case for the eight real classes:
- AI
$\to$ BDI$\to$ D$\to$ DIII$\to$ AII$\to$ CII$\to$ C$\to$ CI$\to$ AI.
This property is called Bott periodicity, and it can be nicely represented in the following table, similar to a clock:
The grey entries in the table are the chiral classes, and the arrows show which classes have the same topological classification when you shift
Finally, let's see what the table looks like when we order the rows according to the Bott clock above:
np.random.seed(5)
n = 8
periodic_table, format_string = make_table(n=8, show_symmetries=True, sort_order=None)
colors = np.zeros(shape=periodic_table.shape + (3,))
colors[1:, 4:] = [0.9, 0.9, 0.9]
palette = np.linspace(0.6, 1.2, n).reshape(1, -1, 1) * np.random.rand(5, 1, 3)
palette = np.minimum(palette, 1)
colors[primary_seq(n) + 1, np.arange(n) + 4] = palette[0]
colors[z_descendant(n) + 3, np.arange(n) + 4] = palette[1]
colors[z2_descendant(n) + 3, np.arange(n) + 4] = palette[2]
colors[z2_descendant2(n) + 3, np.arange(n) + 4] = palette[3]
colors[twoz_descendant(n) + 3, np.arange(n) + 4] = palette[4]
colordefs = color_table(periodic_table, colors)
rows = [sep.join([c.decode("utf-8") for c in line]) for line in periodic_table]
rows[1] = r"\hline " + rows[1]
rows[3] = r"\hline " + rows[3]
block = line_end.join(rows)
displaymd(table_header.format(colordefs=colordefs, fmt=format_string, body=block))
Finally some order appears!
We have colored the different entries to show how all the topological invariants repeat themselves along the diagonals, as a consequence of the procedure outlined above. The table has overall a period equal to 8, meaning that for instance in
In fact, we know another way to change the dimensionality while preserving the topology. It is to go from a Hamiltonian
For example, this means that in the SSH chain, which is a
The first thing to observe is that the complex classes only have
The higher dimensional invariants are simple generalizations of these two. Their mathematical expression can be found in several papers, for instance this one.
n = 8
periodic_table, format_string = make_table(n=n, show_symmetries=True, sort_order=None)
colors = np.zeros(shape=periodic_table.shape + (3,))
colors[1:3, 4:] = [0.8, 0.8, 0.8]
colors[1, 4:] = [1, 0, 0]
colors[2, 4:] = [0, 0, 1]
colordefs = color_table(periodic_table, colors)
rows = [sep.join([c.decode("utf-8") for c in line]) for line in periodic_table]
rows[1] = r"\hline " + rows[1]
rows[3] = r"\hline " + rows[3]
block = line_end.join(rows)
displaymd(table_header.format(colordefs=colordefs, fmt=format_string, body=block))
Another useful feature of the table is that in a given column, all
np.random.seed(15)
n = 8
periodic_table, format_string = make_table(n=n, show_symmetries=True, sort_order=None)
colors = np.zeros(shape=periodic_table.shape + (3,))
colors[1:, 4:] = [0.9, 0.9, 0.9]
palette = np.random.rand(n, 3) ** 2
colors[primary_seq(n) + 1, np.arange(n) + 4] = 0.8 * palette
colors[z_descendant(n) + 3, np.arange(n) + 4] = 1 - 0.6 * (1 - palette)
colors[twoz_descendant(n) + 3, np.arange(n) + 4] = 1 - 0.6 * (1 - palette)
colordefs = color_table(periodic_table, colors)
rows = [sep.join([c.decode("utf-8") for c in line]) for line in periodic_table]
rows[1] = r"\hline " + rows[1]
rows[3] = r"\hline " + rows[3]
block = line_end.join(rows)
displaymd(table_header.format(colordefs=colordefs, fmt=format_string, body=block))
We can check this statement for some cases we know. For instance, in
An important pattern visible in the table is the descending sequence
np.random.seed(4)
n = 8
periodic_table, format_string = make_table(n=8, show_symmetries=True, sort_order=None)
colors = np.zeros(shape=periodic_table.shape + (3,))
colors[1:, 4:] = [0.9, 0.9, 0.9]
palette = np.random.rand(n, 3)
colors[z_descendant(n) + 3, np.arange(n) + 4] = 0.8 * palette
colors[z2_descendant(n - 1) + 3, np.arange(n - 1) + 4] = 1 - 0.8 * (1 - palette[1:])
colors[z2_descendant2(n - 2) + 3, np.arange(n - 2) + 4] = 1 - 0.5 * (1 - palette[2:])
colordefs = color_table(periodic_table, colors)
rows = [sep.join([c.decode("utf-8") for c in line]) for line in periodic_table]
rows[1] = r"\hline " + rows[1]
rows[3] = r"\hline " + rows[3]
block = line_end.join(rows)
displaymd(table_header.format(colordefs=colordefs, fmt=format_string, body=block))
Again, this dimensional reduction can best be understood with an example we already know. Consider the symmetry class
If you take a finite ribbon of a
You can now view this cylinder as a one-dimensional system whose ends are the two rolled-up edges, and ask: how many zero-energy Majorana modes can there be at the ends? We know the answer from last week's material: the number of zero-modes can be zero or one, depending on whether the boundary conditions are periodic or anti-periodic. The topological invariant is thus reduced to
We can proceed further with our dimensional reduction. If we take our one dimensional system and make it into a ring, we obtain a zero-dimensional system. Depending on how the two ends are coupled, the two Majorana modes can favour the even or odd fermion parity state, and this quantity cannot change without a Fermi level crossing. This is the
question = (
"What sort of topological invariant do we get if we take a 3D TI, and try to make a 4D system with strong invariant, "
"like we did when making a 3D TI out of QSHE?"
)
answers = [
"We get another $Z_2$ topological invariant",
"A 4D system with the Chern number as invariant.",
"This construction cannot be repeated anymore.",
"The topological invariant stays the same.",
]
explanation = (
"A quick check with the table shows that symmetry class AII in 4D has a $Z$ invariant, "
"and it should be the second Chern number."
)
MultipleChoice(
question=question, answers=answers, correct_answer=1, explanation=explanation
)
Video("nnzPiJ3Q3_8")