From 0630211734747af04046da581238c4fcd128de06 Mon Sep 17 00:00:00 2001
From: Anton Akhmerov
Date: Wed, 1 Aug 2018 15:54:51 +0200
Subject: [PATCH 1/5] convert notebooks to markdown

.gitlabci.yml  7 +
scripts/activate_filters.sh  1 
scripts/config_filter_clean.py  4 
scripts/config_filter_smudge.py  2 
scripts/converter.py  1 
scripts/converter_pelican.py  33 +
scripts/nb_filter_clean.sh  2 
scripts/nbconvert.sh  5 
scripts/preprocessors.py  22 
syllabus.ipynb  221 
syllabus.md  147 ++++
w0_background/intro.ipynb  324 
w0_background/intro.md  182 +++++
w10_extensions/gapless.ipynb  566 
w10_extensions/gapless.md  379 +++++++++++
w10_extensions/mechanics.ipynb  752 
w10_extensions/mechanics.md  396 +++++++++++
w10_extensions/w10_assignments.ipynb  160 
w10_extensions/w10_assignments.md  72 ++
w11_extensions2/cti.ipynb  374 
w11_extensions2/cti.md  213 ++++++
w11_extensions2/floquet.ipynb  630 
w11_extensions2/floquet.md  417 ++++++++++++
w11_extensions2/w11_assignments.ipynb  142 
w11_extensions2/w11_assignments.md  59 ++
w12_manybody/fqhe.ipynb  315 
w12_manybody/fqhe.md  167 +++++
w12_manybody/topoorder.ipynb  205 
w12_manybody/topoorder.md  105 +++
w12_manybody/w12_assignments.ipynb  98 
w12_manybody/w12_assignments.md  35 +
w1_topointro/0d.ipynb  863 
w1_topointro/0d.md  581 ++++++++++++++++
w1_topointro/1D.ipynb  658 
w1_topointro/1D.md  449 +++++++++++++
w1_topointro/w1_assignments.ipynb  199 
w1_topointro/w1_assignments.md  104 +++
w2_majorana/Peierls.ipynb  54 
w2_majorana/Peierls.md  14 +
w2_majorana/braiding.ipynb  328 
w2_majorana/braiding.md  230 +++++++
w2_majorana/nanowire.ipynb  604 
w2_majorana/nanowire.md  396 +++++++++++
w2_majorana/signatures.ipynb  654 
w2_majorana/signatures.md  440 ++++++++++++
w2_majorana/w2_assignments.ipynb  179 
w2_majorana/w2_assignments.md  93 +++
w3_pump_QHE/Laughlinargument.ipynb  756 
w3_pump_QHE/Laughlinargument.md  569 ++++++++++++++++
w3_pump_QHE/QHEedgestates.ipynb  588 
w3_pump_QHE/QHEedgestates.md  412 ++++++++++++
w3_pump_QHE/pumps.ipynb  684 
w3_pump_QHE/pumps.md  450 +++++++++++++
w3_pump_QHE/w3_assignments.ipynb  175 
w3_pump_QHE/w3_assignments.md  80 +++
w4_haldane/ComputingChern.ipynb  103 
w4_haldane/ComputingChern.md  51 ++
w4_haldane/QHE_lattice.ipynb  398 
w4_haldane/QHE_lattice.md  233 +++++++
w4_haldane/haldane_model.ipynb  748 
w4_haldane/haldane_model.md  477 +++++++++++++
w4_haldane/w4_assignments.ipynb  144 
w4_haldane/w4_assignments.md  66 ++
w5_qshe/fermion_parity_pump.ipynb  934 
w5_qshe/fermion_parity_pump.md  615 +++++++++++++++++
w5_qshe/qshe_experiments.ipynb  576 
w5_qshe/qshe_experiments.md  344 ++++++++++
w5_qshe/w5_assignments.ipynb  156 
w5_qshe/w5_assignments.md  66 ++
w6_3dti/3dti_signatures.ipynb  593 
w6_3dti/3dti_signatures.md  365 ++++++++++
w6_3dti/bhz.ipynb  552 
w6_3dti/bhz.md  344 ++++++++++
w6_3dti/w6_assignments.ipynb  143 
w6_3dti/w6_assignments.md  65 ++
w7_defects/crystalline_defects.ipynb  622 
w7_defects/crystalline_defects.md  452 +++++++++++++
w7_defects/ti_majoranas.ipynb  714 
w7_defects/ti_majoranas.md  478 +++++++++++++
w7_defects/w7_assignments.ipynb  166 
w7_defects/w7_assignments.md  74 ++
w8_general/classification.ipynb  790 
w8_general/classification.md  530 +++++++++++++++
w8_general/invariants.ipynb  597 
w8_general/invariants.md  399 +++++++++++
w8_general/w8_assignments.ipynb  180 
w8_general/w8_assignments.md  75 +++
w9_disorder/scaling.ipynb  403 
w9_disorder/scaling.md  216 ++++++
w9_disorder/topoflow.ipynb  525 
w9_disorder/topoflow.md  339 ++++++++++
w9_disorder/w9_assignments.ipynb  205 
w9_disorder/w9_assignments.md  88 +++
93 files changed, 11290 insertions(+), 18132 deletions()
delete mode 100644 scripts/activate_filters.sh
delete mode 100644 scripts/config_filter_clean.py
delete mode 100644 scripts/config_filter_smudge.py
delete mode 100755 scripts/nb_filter_clean.sh
delete mode 100755 scripts/nbconvert.sh
delete mode 100644 scripts/preprocessors.py
delete mode 100644 syllabus.ipynb
create mode 100644 syllabus.md
delete mode 100644 w0_background/intro.ipynb
create mode 100644 w0_background/intro.md
delete mode 100644 w10_extensions/gapless.ipynb
create mode 100644 w10_extensions/gapless.md
delete mode 100644 w10_extensions/mechanics.ipynb
create mode 100644 w10_extensions/mechanics.md
delete mode 100644 w10_extensions/w10_assignments.ipynb
create mode 100644 w10_extensions/w10_assignments.md
delete mode 100644 w11_extensions2/cti.ipynb
create mode 100644 w11_extensions2/cti.md
delete mode 100644 w11_extensions2/floquet.ipynb
create mode 100644 w11_extensions2/floquet.md
delete mode 100644 w11_extensions2/w11_assignments.ipynb
create mode 100644 w11_extensions2/w11_assignments.md
delete mode 100644 w12_manybody/fqhe.ipynb
create mode 100644 w12_manybody/fqhe.md
delete mode 100644 w12_manybody/topoorder.ipynb
create mode 100644 w12_manybody/topoorder.md
delete mode 100644 w12_manybody/w12_assignments.ipynb
create mode 100644 w12_manybody/w12_assignments.md
delete mode 100644 w1_topointro/0d.ipynb
create mode 100644 w1_topointro/0d.md
delete mode 100644 w1_topointro/1D.ipynb
create mode 100644 w1_topointro/1D.md
delete mode 100644 w1_topointro/w1_assignments.ipynb
create mode 100644 w1_topointro/w1_assignments.md
delete mode 100644 w2_majorana/Peierls.ipynb
create mode 100644 w2_majorana/Peierls.md
delete mode 100644 w2_majorana/braiding.ipynb
create mode 100644 w2_majorana/braiding.md
delete mode 100644 w2_majorana/nanowire.ipynb
create mode 100644 w2_majorana/nanowire.md
delete mode 100644 w2_majorana/signatures.ipynb
create mode 100644 w2_majorana/signatures.md
delete mode 100644 w2_majorana/w2_assignments.ipynb
create mode 100644 w2_majorana/w2_assignments.md
delete mode 100644 w3_pump_QHE/Laughlinargument.ipynb
create mode 100644 w3_pump_QHE/Laughlinargument.md
delete mode 100644 w3_pump_QHE/QHEedgestates.ipynb
create mode 100644 w3_pump_QHE/QHEedgestates.md
delete mode 100644 w3_pump_QHE/pumps.ipynb
create mode 100644 w3_pump_QHE/pumps.md
delete mode 100644 w3_pump_QHE/w3_assignments.ipynb
create mode 100644 w3_pump_QHE/w3_assignments.md
delete mode 100644 w4_haldane/ComputingChern.ipynb
create mode 100644 w4_haldane/ComputingChern.md
delete mode 100644 w4_haldane/QHE_lattice.ipynb
create mode 100644 w4_haldane/QHE_lattice.md
delete mode 100644 w4_haldane/haldane_model.ipynb
create mode 100644 w4_haldane/haldane_model.md
delete mode 100644 w4_haldane/w4_assignments.ipynb
create mode 100644 w4_haldane/w4_assignments.md
delete mode 100644 w5_qshe/fermion_parity_pump.ipynb
create mode 100644 w5_qshe/fermion_parity_pump.md
delete mode 100644 w5_qshe/qshe_experiments.ipynb
create mode 100644 w5_qshe/qshe_experiments.md
delete mode 100644 w5_qshe/w5_assignments.ipynb
create mode 100644 w5_qshe/w5_assignments.md
delete mode 100644 w6_3dti/3dti_signatures.ipynb
create mode 100644 w6_3dti/3dti_signatures.md
delete mode 100644 w6_3dti/bhz.ipynb
create mode 100644 w6_3dti/bhz.md
delete mode 100644 w6_3dti/w6_assignments.ipynb
create mode 100644 w6_3dti/w6_assignments.md
delete mode 100644 w7_defects/crystalline_defects.ipynb
create mode 100644 w7_defects/crystalline_defects.md
delete mode 100644 w7_defects/ti_majoranas.ipynb
create mode 100644 w7_defects/ti_majoranas.md
delete mode 100644 w7_defects/w7_assignments.ipynb
create mode 100644 w7_defects/w7_assignments.md
delete mode 100644 w8_general/classification.ipynb
create mode 100644 w8_general/classification.md
delete mode 100644 w8_general/invariants.ipynb
create mode 100644 w8_general/invariants.md
delete mode 100644 w8_general/w8_assignments.ipynb
create mode 100644 w8_general/w8_assignments.md
delete mode 100644 w9_disorder/scaling.ipynb
create mode 100644 w9_disorder/scaling.md
delete mode 100644 w9_disorder/topoflow.ipynb
create mode 100644 w9_disorder/topoflow.md
delete mode 100644 w9_disorder/w9_assignments.ipynb
create mode 100644 w9_disorder/w9_assignments.md
diff git a/.gitlabci.yml b/.gitlabci.yml
index 9e35ea5..211e35e 100644
 a/.gitlabci.yml
+++ b/.gitlabci.yml
@@ 7,16 +7,17 @@ stages:
execute_ipynbs:
stage: execute
+ before_script:
+  pip install notedown
script:
 export PYTHONPATH=$PYTHONPATH:${PWD}/code
 export OPENBLAS_NUM_THREADS=1 OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 MKL_DYNAMIC=FALSE
 export DEST=generated/with_output
 mkdir p $DEST
  cp syllabus.ipynb $DEST
+  cp syllabus.md $DEST
 cp r data $DEST
 cp r w[!e]*_* $DEST
  jupyter nbconvert to notebook inplace config scripts/config_filter_smudge.py $DEST/syllabus.ipynb
  find $DEST/w* name '*.ipynb'  parallel delay 3 jobs 32 scripts/nbconvert.sh
+  find $DEST name '*.md'  parallel delay 3 jobs 32 notedown o run timeout 1 match fenced
 rm rf $DEST/data
artifacts:
paths:
diff git a/scripts/activate_filters.sh b/scripts/activate_filters.sh
deleted file mode 100644
index 9e09670..0000000
 a/scripts/activate_filters.sh
+++ /dev/null
@@ 1 +0,0 @@
git config filter.nbfilters.clean "./scripts/nb_filter_clean.sh"
diff git a/scripts/config_filter_clean.py b/scripts/config_filter_clean.py
deleted file mode 100644
index 2e78a2a..0000000
 a/scripts/config_filter_clean.py
+++ /dev/null
@@ 1,4 +0,0 @@
c.Exporter.preprocessors = ['scripts.preprocessors.RemoveVersionPreprocessor',
 'scripts.preprocessors.SetNamePreprocessor']
c.ClearOutputPreprocessor['enabled'] = True
c.RemoveVersionPreprocessor['enabled'] = True
diff git a/scripts/config_filter_smudge.py b/scripts/config_filter_smudge.py
deleted file mode 100644
index be840a9..0000000
 a/scripts/config_filter_smudge.py
+++ /dev/null
@@ 1,2 +0,0 @@
c.Exporter.preprocessors = ['scripts.preprocessors.TrustPreprocessor']
c.TrustPreprocessor['enabled'] = True
diff git a/scripts/converter.py b/scripts/converter.py
index eee7ed0..251812a 100755
 a/scripts/converter.py
+++ b/scripts/converter.py
@@ 43,7 +43,6 @@ response = urllib.request.urlopen(url)
js = response.read().decode('utf8')
IFRAME_TEMPLATE = r"""

diff git a/scripts/converter_pelican.py b/scripts/converter_pelican.py
index 5a7344c..0dfb5dc 100644
 a/scripts/converter_pelican.py
+++ b/scripts/converter_pelican.py
@@ 4,20 +4,21 @@ import os
import glob
import json
import shutil
import nbformat
import datetime
+from itertools import dropwhile
+import re
+
+import nbformat
def remove_first_cell(nb_name):
 """Remove the cells until a cell starts with `# `."""
 nb = nbformat.read(nb_name, as_version=4)
 cells = nb.cells[1:] # Always skip the first cell
 for i, cell in enumerate(cells):
 if cell['source'].startswith('# '):
 break
 cells = cells[i:]
 return nbformat.v4.new_notebook(cells=cells,
 metadata={'name': cells[0].source[2:]})
+def notebook_title(nb: nbformat.NotebookNode):
+ first_text_cell = next(
+ cell for cell in nb.cells if cell.cell_type == 'markdown'
+ )
+ try:
+ return re.search('# (.*)', first_text_cell.source).group(1)
+ except AttributeError as e:
+ raise RuntimeError('Notebook has no title') from e
meta_file = """Title: {title}
@@ 33,8 +34,12 @@ figures = glob.glob('generated/with_output/w*/figures/*')
# Copy ipynbs and create meta data files
for ipynb in ipynbs:
 nb = remove_first_cell(ipynb)
 title = nb.cells[0].source[2:]
+ nb = nbformat.read(ipynb, as_version=4)
+ nb.metadata['name'] = title = notebook_title(nb)
+
+ # Remove initialization cells
+ nb.cells = list(dropwhile((lambda cell: cell.type == 'code'), nb.cells))
+
new_fname = ipynb.replace('generated/with_output',
'generated/pelican_content')
os.makedirs(os.path.dirname(new_fname), exist_ok=True)
@@ 54,7 +59,7 @@ for figure in figures:
# Copy syllabus
nb = remove_first_cell('syllabus.ipynb')
+nb = nbformat.read('generated/with_output/syllabus.ipynb', as_version=4)
with open('generated/pelican_content/syllabus.ipynb', 'w') as f:
json.dump(nb, f)
with open('generated/pelican_content/syllabus.ipynbmeta', 'w',
diff git a/scripts/nb_filter_clean.sh b/scripts/nb_filter_clean.sh
deleted file mode 100755
index 885ca49..0000000
 a/scripts/nb_filter_clean.sh
+++ /dev/null
@@ 1,2 +0,0 @@
#!/bin/bash
python3 m nbconvert to notebook config scripts/config_filter_clean.py stdin stdout
diff git a/scripts/nbconvert.sh b/scripts/nbconvert.sh
deleted file mode 100755
index 69853cc..0000000
 a/scripts/nbconvert.sh
+++ /dev/null
@@ 1,5 +0,0 @@
#!/bin/bash
export MPLCONFIGDIR=$(mktemp d)
export IPYTHONDIR=$(mktemp d)
echo "c.HistoryManager.enabled = False" > $IPYTHONDIR/ipython_config.py
jupyter nbconvert to notebook ExecutePreprocessor.timeout=3000 execute inplace config scripts/config_filter_smudge.py $1
diff git a/scripts/preprocessors.py b/scripts/preprocessors.py
deleted file mode 100644
index 67ed59d..0000000
 a/scripts/preprocessors.py
+++ /dev/null
@@ 1,22 +0,0 @@
from nbconvert.preprocessors import Preprocessor
from nbformat.sign import NotebookNotary


class TrustPreprocessor(Preprocessor):
 def preprocess(self, nb, resources):
 NotebookNotary().sign(nb)
 return nb, resources


class RemoveVersionPreprocessor(Preprocessor):
 def preprocess(self, nb, resources):
 if 'version' in nb.metadata['language_info']:
 del nb.metadata['language_info']['version']
 return nb, resources


class SetNamePreprocessor(Preprocessor):
 def preprocess(self, nb, resources):
 nb.metadata['kernelspec']['display_name'] = "Python 3"
 nb.metadata['kernelspec']['name'] = "python3"
 return nb, resources
diff git a/syllabus.ipynb b/syllabus.ipynb
deleted file mode 100644
index d55e0f0..0000000
 a/syllabus.ipynb
+++ /dev/null
@@ 1,221 +0,0 @@
{
 "cells": [
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**This is general information about the EdX course on [topology in condensed matter](http://tiny.cc/topocm)**\n",
 "\n",
 "The IPython notebooks contains some auxiliary information, like code, that is hidden on EdX."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Syllabus"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "* **Before you begin**\n",
 " \n",
 " * [About this course](w0_background/intro.ipynb)\n",
 " * Starting survey\n",
 "\n",
 "* **Topology in toy models**\n",
 "\n",
 " * [Hamiltonians, topology, and symmetry](w1_topointro/0d.ipynb) \n",
 " * [Bulkedge correspondence in the Kitaev chain](w1_topointro/1D.ipynb) \n",
 " * [Assignments](w1_topointro/w1_assignments.ipynb)\n",
 "\n",
 "* **Majoranas I**\n",
 "\n",
 " * [From Kitaev chain to a nanowire](w2_majorana/nanowire.ipynb) \n",
 " * [Majorana signatures: 4πperiodic Josephson effect, Andreev conductance quantization](w2_majorana/signatures.ipynb) \n",
 " * [Why Majoranas are cool: braiding and quantum computation](w2_majorana/braiding.ipynb) \n",
 " * [Assignments](w2_majorana/w2_assignments.ipynb)\n",
 "\n",
 "* **More parameters: charge pumping**\n",
 "\n",
 " * [Thouless pumps and winding invariant](w3_pump_QHE/pumps.ipynb) \n",
 " * [Quantum Hall effect: pumping electrons in Landau levels](w3_pump_QHE/Laughlinargument.ipynb) \n",
 " * [Quantum Hall effect: edge states](w3_pump_QHE/QHEedgestates.ipynb) \n",
 " * [Assignments](w3_pump_QHE/w3_assignments.ipynb)\n",
 "\n",
 "* **Chern insulators**\n",
 "\n",
 " * [Quantum Hall Effect on the lattice and Dirac Hamiltonian](w4_haldane/QHE_lattice.ipynb) \n",
 " * [Haldane model, Berry curvature, and Chern number](w4_haldane/haldane_model.ipynb) \n",
 " * [Assignments](w4_haldane/w4_assignments.ipynb)\n",
 "\n",
 "* **Quantum spin Hall effect**\n",
 "\n",
 " * [Timereversal symmetry and fermion parity pumps](w5_qshe/fermion_parity_pump.ipynb) \n",
 " * [Experimental progress and candidate materials](w5_qshe/qshe_experiments.ipynb) \n",
 " * [Assignments](w5_qshe/w5_assignments.ipynb)\n",
 "\n",
 "* **Threedimensional topological insulators**\n",
 "\n",
 " * [Dirac equation of the surface states, 3D BernevigHughesZhang model](w6_3dti/bhz.ipynb) \n",
 " * [Experimental progress and candidate materials](w6_3dti/3dti_signatures.ipynb) \n",
 " * [Assignments](w6_3dti/w6_assignments.ipynb)\n",
 "\n",
 "* **Topological defects**\n",
 "\n",
 " * [Majoranas in topological insulators and superconductors](w7_defects/ti_majoranas.ipynb) \n",
 " * [Crystalline defects in weak topological insulators](w7_defects/crystalline_defects.ipynb) \n",
 " * [Assignments](w7_defects/w7_assignments.ipynb)\n",
 "\n",
 "* **General approach to topological classification**\n",
 "\n",
 " * [10 symmetry classes and the periodic table of topological insulators](w8_general/classification.ipynb) \n",
 " * [Different approaches to topological invariants](w8_general/invariants.ipynb) \n",
 " * [Assignments](w8_general/w8_assignments.ipynb)\n",
 "\n",
 "* **Anderson localization and topology**\n",
 "\n",
 " * [Disorder and the scaling theory of localization](w9_disorder/scaling.ipynb) \n",
 " * [Flow diagram of topological insulators](w9_disorder/topoflow.ipynb) \n",
 " * [Assignments](w9_disorder/w9_assignments.ipynb)\n",
 "\n",
 "* **Extensions of classification I**\n",
 "\n",
 " * [Topology in gapless systems](w10_extensions/gapless.ipynb) \n",
 " * [Topological mechanics](w10_extensions/mechanics.ipynb) \n",
 " * [Assignments](w10_extensions/w10_assignments.ipynb)\n",
 "\n",
 "* **Extensions of classification II**\n",
 " * [Floquet topological insulators](w11_extensions2/floquet.ipynb) \n",
 " * [Crystalline topological insulators](w11_extensions2/cti.ipynb) \n",
 " * [Assignments](w11_extensions2/w11_assignments.ipynb)\n",
 " \n",
 "* **Beyond singleparticle physics**\n",
 "\n",
 " * [Fractional quantum Hall effect and topological particles](w12_manybody/fqhe.ipynb) \n",
 " * [Topological order and the toric code](w12_manybody/topoorder.ipynb) \n",
 " * [Assignments](w12_manybody/w12_assignments.ipynb)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Course structure\n",
 "\n",
 "* Each section consists of several relatively selfcontained topics, each introduced and summarized by an expert.\n",
 "* If you have questions about the material, ask them using the discussion right after the final video of each topic.\n",
 "* The assignments are a combination of numerical simulations, where you evaluate your success on your own (but do share your results), and a review of a paper out of a selection of papers. The reviews are then crossevaluated by other participants.\n",
 "* In order to keep everyone on the same page, we set a one week deadline for the assignments (plus an extra week for crossevaluation of the paper reviews). The questions in the course materials have no deadline."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Current course team\n",
 "\n",
 "**Anton Akhmerov** is an assistant professor in Kavli Institute of Nanoscience of Delft University of Technology and QuTech.\n",
 "\n",
 "**Jay Sau** is an assistant professor in the area of theoretical Condensed matter physics at the University of Maryland, College Park, USA.\n",
 "\n",
 "**Bernard van Heck** is a postdoc at Yale University.\n",
 "\n",
 "**Bas Nijholt, Irfan Muhammad, Tómas Örn Rosdahl** are PhD students working in Kavli Institute for Nanoscience at TU Delft supervised by Anton Akhmerov.\n",
 "\n",
 "## Other course developers\n",
 "\n",
 "The initial verison of the course was created by: \n",
 "Anton Akhmerov \n",
 "Jay Sau \n",
 "Bernard van Heck \n",
 "Sebastian Rubbert \n",
 "Rafał Skolasiński."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Acknowledgements\n",
 "\n",
 "When working on the course, we greatly benefitted from support of\n",
 "\n",
 "* [Delft University of Technology](http://tudelft.nl) and its Extension School\n",
 "* [QuTech](http://qutech.nl)\n",
 "* [Casimir Research School](http://casimir.researchschool.nl) and the [NanoFront](http://casimir.researchschool.nl/nanofront) program\n",
 "* [University of Maryland](http://umd.edu) and its Physics Department\n",
 "* [Joint Quantum Institute](http://jqi.umd.edu)\n",
 "\n",
 "We thank [M. Wimmer](http://michaelwimmer.org/) and [C. Groth](http://inac.cea.fr/Pisp/christoph.groth/) for letting us use their code in some of the course materials.\n",
 "\n",
 "For the support with implementing the technical aspects of the course we thank\n",
 "\n",
 "* The [Jupyter project](https://jupyter.org) and its developer team, especially Min RaganKelley.\n",
 "* [SageMathCloud](https://cloud.sagemath.org) and its creator W. Stein.\n",
 "* The [Holoviews](https://holoviews.org) team: JeanLuc Stevens and Philipp Rudiger.\n",
 "\n",
 "Finally, we thank all the external speakers for contributing the videos for the course."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## License\n",
 "\n",
 "Unless otherwise specified the **Course Materials** of TU\n",
 "Delft TOPOCMx are Copyright [Delft University of Technology](http://www.tudelft.nl/en/) and are licensed under\n",
 "a [Creative Commons AttributionShareAlike 4.0\n",
 "International License](http://creativecommons.org/licenses/bysa/4.0/)\n",
 "[![](https://i.creativecommons.org/l/bysa/4.0/88x31.png)](http://creativecommons.org/licenses/bysa/4.0/)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The **source code** can also be used under conditions of the 3clause BSD licence: \n",
 "\n",
 " Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\n",
 "\n",
 "1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\n",
 "\n",
 "2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\n",
 "\n",
 "3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\n",
 "\n",
 "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Videos contributed by external experts** are copyright of their creators, and are also available under Creative Commons Attribution 3.0 Unported License."
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
diff git a/syllabus.md b/syllabus.md
new file mode 100644
index 0000000..a3f03fe
 /dev/null
+++ b/syllabus.md
@@ 0,0 +1,147 @@
+# Syllabus
+
+* **Before you begin**
+
+ * [About this course](w0_background/intro.ipynb)
+ * Starting survey
+
+* **Topology in toy models**
+
+ * [Hamiltonians, topology, and symmetry](w1_topointro/0d.ipynb)
+ * [Bulkedge correspondence in the Kitaev chain](w1_topointro/1D.ipynb)
+ * [Assignments](w1_topointro/w1_assignments.ipynb)
+
+* **Majoranas I**
+
+ * [From Kitaev chain to a nanowire](w2_majorana/nanowire.ipynb)
+ * [Majorana signatures: 4πperiodic Josephson effect, Andreev conductance quantization](w2_majorana/signatures.ipynb)
+ * [Why Majoranas are cool: braiding and quantum computation](w2_majorana/braiding.ipynb)
+ * [Assignments](w2_majorana/w2_assignments.ipynb)
+
+* **More parameters: charge pumping**
+
+ * [Thouless pumps and winding invariant](w3_pump_QHE/pumps.ipynb)
+ * [Quantum Hall effect: pumping electrons in Landau levels](w3_pump_QHE/Laughlinargument.ipynb)
+ * [Quantum Hall effect: edge states](w3_pump_QHE/QHEedgestates.ipynb)
+ * [Assignments](w3_pump_QHE/w3_assignments.ipynb)
+
+* **Chern insulators**
+
+ * [Quantum Hall Effect on the lattice and Dirac Hamiltonian](w4_haldane/QHE_lattice.ipynb)
+ * [Haldane model, Berry curvature, and Chern number](w4_haldane/haldane_model.ipynb)
+ * [Assignments](w4_haldane/w4_assignments.ipynb)
+
+* **Quantum spin Hall effect**
+
+ * [Timereversal symmetry and fermion parity pumps](w5_qshe/fermion_parity_pump.ipynb)
+ * [Experimental progress and candidate materials](w5_qshe/qshe_experiments.ipynb)
+ * [Assignments](w5_qshe/w5_assignments.ipynb)
+
+* **Threedimensional topological insulators**
+
+ * [Dirac equation of the surface states, 3D BernevigHughesZhang model](w6_3dti/bhz.ipynb)
+ * [Experimental progress and candidate materials](w6_3dti/3dti_signatures.ipynb)
+ * [Assignments](w6_3dti/w6_assignments.ipynb)
+
+* **Topological defects**
+
+ * [Majoranas in topological insulators and superconductors](w7_defects/ti_majoranas.ipynb)
+ * [Crystalline defects in weak topological insulators](w7_defects/crystalline_defects.ipynb)
+ * [Assignments](w7_defects/w7_assignments.ipynb)
+
+* **General approach to topological classification**
+
+ * [10 symmetry classes and the periodic table of topological insulators](w8_general/classification.ipynb)
+ * [Different approaches to topological invariants](w8_general/invariants.ipynb)
+ * [Assignments](w8_general/w8_assignments.ipynb)
+
+* **Anderson localization and topology**
+
+ * [Disorder and the scaling theory of localization](w9_disorder/scaling.ipynb)
+ * [Flow diagram of topological insulators](w9_disorder/topoflow.ipynb)
+ * [Assignments](w9_disorder/w9_assignments.ipynb)
+
+* **Extensions of classification I**
+
+ * [Topology in gapless systems](w10_extensions/gapless.ipynb)
+ * [Topological mechanics](w10_extensions/mechanics.ipynb)
+ * [Assignments](w10_extensions/w10_assignments.ipynb)
+
+* **Extensions of classification II**
+ * [Floquet topological insulators](w11_extensions2/floquet.ipynb)
+ * [Crystalline topological insulators](w11_extensions2/cti.ipynb)
+ * [Assignments](w11_extensions2/w11_assignments.ipynb)
+
+* **Beyond singleparticle physics**
+
+ * [Fractional quantum Hall effect and topological particles](w12_manybody/fqhe.ipynb)
+ * [Topological order and the toric code](w12_manybody/topoorder.ipynb)
+ * [Assignments](w12_manybody/w12_assignments.ipynb)
+
+## Course structure
+
+* Each section consists of several relatively selfcontained topics, each introduced and summarized by an expert.
+* If you have questions about the material, ask them using the discussion right after the final video of each topic.
+* The assignments are a combination of numerical simulations, where you evaluate your success on your own (but do share your results), and a review of a paper out of a selection of papers. The reviews are then crossevaluated by other participants.
+* In order to keep everyone on the same page, we set a one week deadline for the assignments (plus an extra week for crossevaluation of the paper reviews). The questions in the course materials have no deadline.
+
+## Current course team
+
+**Anton Akhmerov** is an assistant professor in Kavli Institute of Nanoscience of Delft University of Technology and QuTech.
+
+**Jay Sau** is an assistant professor in the area of theoretical Condensed matter physics at the University of Maryland, College Park, USA.
+
+**Bernard van Heck** is a postdoc at Yale University.
+
+**Bas Nijholt, Irfan Muhammad, Tómas Örn Rosdahl** are PhD students working in Kavli Institute for Nanoscience at TU Delft supervised by Anton Akhmerov.
+
+## Other course developers
+
+The initial verison of the course was created by:
+Anton Akhmerov
+Jay Sau
+Bernard van Heck
+Sebastian Rubbert
+Rafał Skolasiński.
+
+## Acknowledgements
+
+When working on the course, we greatly benefitted from support of
+
+* [Delft University of Technology](http://tudelft.nl) and its Extension School
+* [QuTech](http://qutech.nl)
+* [Casimir Research School](http://casimir.researchschool.nl) and the [NanoFront](http://casimir.researchschool.nl/nanofront) program
+* [University of Maryland](http://umd.edu) and its Physics Department
+* [Joint Quantum Institute](http://jqi.umd.edu)
+
+We thank [M. Wimmer](http://michaelwimmer.org/) and [C. Groth](http://inac.cea.fr/Pisp/christoph.groth/) for letting us use their code in some of the course materials.
+
+For the support with implementing the technical aspects of the course we thank
+
+* The [Jupyter project](https://jupyter.org) and its developer team, especially Min RaganKelley.
+* [SageMathCloud](https://cloud.sagemath.org) and its creator W. Stein.
+* The [Holoviews](https://holoviews.org) team: JeanLuc Stevens and Philipp Rudiger.
+
+Finally, we thank all the external speakers for contributing the videos for the course.
+
+## License
+
+Unless otherwise specified the **Course Materials** of TU
+Delft TOPOCMx are Copyright [Delft University of Technology](http://www.tudelft.nl/en/) and are licensed under
+a [Creative Commons AttributionShareAlike 4.0
+International License](http://creativecommons.org/licenses/bysa/4.0/)
+[![](https://i.creativecommons.org/l/bysa/4.0/88x31.png)](http://creativecommons.org/licenses/bysa/4.0/)
+
+The **source code** can also be used under conditions of the 3clause BSD licence:
+
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+**Videos contributed by external experts** are copyright of their creators, and are also available under Creative Commons Attribution 3.0 Unported License.
diff git a/w0_background/intro.ipynb b/w0_background/intro.ipynb
deleted file mode 100644
index e1a8b61..0000000
 a/w0_background/intro.ipynb
+++ /dev/null
@@ 1,324 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "# This cell is present in all the notebooks.\n",
 "# It makes the necessary packages available and adjusts various settings.\n",
 "# You should execute this cell at the start.\n",
 "\n",
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "\n",
 "from IPython.display import HTML"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# A welcome word"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "First of all, greetings from the TOPOCMx team! We are very happy that you chose to follow our course.\n",
 "\n",
 "Through TOPOCMx we want to provide an introduction to the new topics on topology in condensed matter.\n",
 "We want it to be simple, and we want it to be useful for people with very different background and motivation.\n",
 "\n",
 "We want the course to be useful to you if you are a **master student**, and you want to get an understanding of what topology is all about.\n",
 "\n",
 "Or you could be a **PhD student or a postdoc** doing experiments, and you want to get a better theoretical understanding of what you should expect in your investigations.\n",
 "\n",
 "You could even be a **theorist working in topology** and be extremely familiar with topological invariants and vector bundles, but you would like to get a better understanding of how the mathematical ideas apply in physical systems.\n",
 "\n",
 "Finally, we also want this course to be equally useful if you are, say, a **professor working in condensed matter** and you want to apply the ideas introduced by topology in your domain, so that you just need a quick overview of what research activity is there.\n",
 "\n",
 "But even despite your different backgrounds, we want our course to feel like this:\n",
 "\n",
 "\n",
 "\n",
 "rather than this:\n",
 "\n",
 "\n",
 "\n",
 "*(Images by Bruno Touschek, © 1981 [CERN](http://cds.cern.ch/record/135949) CCBY3.0)*"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### What you get"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let us explain what you can expect from the course, and what is special about it.\n",
 "The first thing which you need to understand is that the course is hard.\n",
 "We don't mean advanced and involved math (we took care to skip all the parts that don't help understanding).\n",
 "Instead, since topology has impact on many different physical phenomena, the course will touch a lot of different concepts in condensed matter physics.\n",
 "\n",
 "First of all, we will provide you with a description of the most **important facts and discoveries in topology** in the most simple and concise manner that we can find.\n",
 "\n",
 "This will still be hard to some of you, since the required background in condensed matter physics is still broad.\n",
 "If you see that it is the case, you will need to search for advice in the course **discussions**, so you'll also use the course as an expert community."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "If you are experienced already, you may find the lectures straightforward.\n",
 "However, even though active research on topological insulators began less than ten years ago,\n",
 "the field is already incredibly broad.\n",
 "\n",
 "This is why we want our course to also fulfill a role of a **journal club**:\n",
 "every week we'll ask you to read one of several suggested papers, observe how the concepts that you learn\n",
 "appear in a new context, and summarize it for the other participants.\n",
 "That way you will learn to analyze research papers and get an **overview of the field**."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Most of the numerical simulations that are used in our research are actually amazingly easy if you know how to do them.\n",
 "While teaching how to do computer simulations is not our main aim, we provide already set up simulations for the systems we describe in the lectures.\n",
 "\n",
 "Using these **computer simulations** you can see for yourself how various models behave, discover new parameter regimes that we don't cover in the lectures, or even extend the simulations and see how adding new terms to the models changes the results."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### How you can help us"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "MOOCs like this one are not a usual way for providing graduatelevel materials, and even less so materials that are a topic of active research.\n",
 "\n",
 "We believe that it is a very useful and promising way of knowledge dissemination, that has advantages over a book, a university course, or a review.\n",
 "\n",
 "This is why it is extremely important for us to know what is your background and your motivation to take the course.\n",
 "We want you to share what you found difficult, what you found easy, and where you think the course can be improved."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Moreover, we publish the **source code** for every single bit of this course in this [Github repository](https://github.com/topocm/topocm_content).\n",
 "So whenever you see a typo, or you would like to suggest an improvement, you can open a new issue, (or even make a pull request if you know how to use Github)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Software you will need"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "If you don't want to be bothered trying out the numerical simulations, you are all set if you have an EdX account and you are signed up for the course.\n",
 "\n",
 "However we strongly recommend to not skip the numerical simulations part. Following it will help you to develop intuition about how the topological systems behave. The numerical simulations can also serve as an extremely useful tool helping both in experiments and theory."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "To get going with the simulations, you will need to get the computational software.\n",
 "Specifically you need:\n",
 "\n",
 "* Python 3.5 or 3.6\n",
 "* Python scientific stack (SciPy, NumPy, Matplotlib, Jupyter notebook)\n",
 "* Holoviews 1.7, a Python library for plotting data.\n",
 "* [Kwant](http://kwantproject.org) 1.3, a package for quantum transport simulations.\n",
 "\n",
 "The installation should be straightforward.\n",
 "Installation of most of the requirements is described [here](http://kwantproject.org/install).\n",
 "\n",
 "If you are using Windows, you are all set after following the above instructions.\n",
 "\n",
 "The easiest way to install `kwant` when you are using Linux or OS X is with `conda` which comes with Miniconda, a Python distribution.\n",
 "\n",
 "1. Open a terminal and download [Miniconda](http://conda.pydata.org/miniconda.html>)\n",
 " (or [Anaconda](https://www.continuum.io/downloads)) by running:\n",
 "\n",
 " wget https://repo.continuum.io/miniconda/Miniconda3latestMacOSXx86_64.sh\n",
 "\n",
 "2. Install Miniconda with:\n",
 "\n",
 " bash Miniconda3latestMacOSXx86_64.sh\n",
 "\n",
 " and follow its instructions. Make sure that ``conda`` is in your PATH, which you \n",
 " can do by adding ``export PATH=\"$HOME/miniconda3/bin:$PATH\"`` to your ``.bashrc``\n",
 " or ``.bash_profile``.\n",
 "\n",
 "3. Add the [condaforge](https://condaforge.github.io/) channel and install \n",
 " Kwant and its dependencies with:\n",
 "\n",
 " conda config add channels condaforge\n",
 " conda install kwant holoviews notebook feedparser"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Jupyter notebooks"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "A separate mention of the software we use goes to Jupyter notebooks.\n",
 "\n",
 "Every document that you see in our course (including the one that you are reading right now) was prepared as a Jupyter notebook.\n",
 "\n",
 "These notebooks are extremely handy, they allow:\n",
 "\n",
 "* To use an interactive computing environment where you can see what your simulation does right as you are creating it. \n",
 "* To combine nicely formatted text (with Latex equations and images) together with code in any language and the output of that code.\n",
 "* To easily share that same code: here, take a look at the source of [the notebook](http://nbviewer.ipython.org/github/topocm/topocm_content/blob/master/w0_background/intro.ipynb) that you are currently reading.\n",
 "* To convert it to a presentation, blog post, or an EdX course.\n",
 "\n",
 "The combination of the above nice properties with many more and with Jupyter being free software lead to the notebooks being [highlighted](http://www.nature.com/news/interactivenotebookssharingthecode1.16261) in Nature.\n",
 "\n",
 "For a short presentation of Jupyter notebooks just use `Help > User Interface Tour` inside the notebook."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Sharing notebooks"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Showing the results of your work is very easy.\n",
 "\n",
 "If you are using Sage Cloud, you can just click the \"share the notebook\" button when you have it opened, and copy the URL.\n",
 "\n",
 "Otherwise you can make the notebook visible online (for example by putting it in your Dropbox public folder or something similar), copy link, and paste it into [http://nbviewer.ipython.org](http://nbviewer.ipython.org)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Kwant, Python, and Python scientific software"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "For most of the simulations of condensed matter systems we are going to use the Kwant package. You can learn Kwant in more detail by following the [tutorial](http://kwantproject.org/doc/1.0/tutorial/), however we aim that for most of the exercises you will be able to learn by doing. The starting point of the exercises are the notebooks used in the lectures, and you should be able to solve them by only modifying the contents not too much.\n",
 "\n",
 "The same applies to Python and the Python scientific stack (NumPy, SciPy, Matplotlib): these are easy to use, especially when you have code examples. If you are new to programming and wish to get acquainted with Python,\n",
 "[here](http://www.learnpython.org/) are [several](http://www.pythoncourse.eu/) [example courses](https://www.codecademy.com/learn/python) that start from the basics and slowly go into advanced topics. There are of course several MOOCs as well, but you will likely not need as much programming skill.\n",
 "\n",
 "**Do you have questions about installation? Use this discussion:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocDiscussion('Software', 'Help with installation')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Literature"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We are mostly going to focus on the overall structure of the field and study the most basic and general phenomena. We will also skip detailed derivations or some details.\n",
 "\n",
 "For a more formal and complete source of information on topological insulators and superconductors we recommend you to look into the reviews below. (Of course we think they will be much easier to follor after you finish the course)."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "display_html(HTML(\"Topological insulator reviews
\"),\n",
 " PreprintReference(\"0801.0901\", show_abstract=False),\n",
 " PreprintReference(\"1002.3895\", show_abstract=False),\n",
 " PreprintReference(\"1008.2026\", show_abstract=False),\n",
 " HTML(\"Majorana fermion reviews
\"),\n",
 " PreprintReference(\"1112.1950\", show_abstract=False),\n",
 " PreprintReference(\"1202.1293\", show_abstract=False),\n",
 " PreprintReference(\"1206.1736\", show_abstract=False),\n",
 " PreprintReference(\"1407.2131\", show_abstract=False),\n",
 " HTML(\"Advanced topics: Fractional particles and topological quantum computation
\"),\n",
 " PreprintReference(\"0707.1889\", show_abstract=False),\n",
 " PreprintReference(\"0711.4697\", show_abstract=False),\n",
 " PreprintReference(\"1404.0897\", show_abstract=False),\n",
 " HTML(\"Extra topics
\"),\n",
 " PreprintReference(\"1211.5623\", show_abstract=False),\n",
 " PreprintReference(\"1501.00531\", show_abstract=False))"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w0_background/intro.md b/w0_background/intro.md
new file mode 100644
index 0000000..90bd179
 /dev/null
+++ b/w0_background/intro.md
@@ 0,0 +1,182 @@
+
+
+```python
+# This cell is present in all the notebooks.
+# It makes the necessary packages available and adjusts various settings.
+# You should execute this cell at the start.
+
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+
+from IPython.display import HTML
+```
+
+# A welcome word
+
+First of all, greetings from the TOPOCMx team! We are very happy that you chose to follow our course.
+
+Through TOPOCMx we want to provide an introduction to the new topics on topology in condensed matter.
+We want it to be simple, and we want it to be useful for people with very different background and motivation.
+
+We want the course to be useful to you if you are a **master student**, and you want to get an understanding of what topology is all about.
+
+Or you could be a **PhD student or a postdoc** doing experiments, and you want to get a better theoretical understanding of what you should expect in your investigations.
+
+You could even be a **theorist working in topology** and be extremely familiar with topological invariants and vector bundles, but you would like to get a better understanding of how the mathematical ideas apply in physical systems.
+
+Finally, we also want this course to be equally useful if you are, say, a **professor working in condensed matter** and you want to apply the ideas introduced by topology in your domain, so that you just need a quick overview of what research activity is there.
+
+But even despite your different backgrounds, we want our course to feel like this:
+
+
+
+rather than this:
+
+
+
+*(Images by Bruno Touschek, © 1981 [CERN](http://cds.cern.ch/record/135949) CCBY3.0)*
+
+### What you get
+
+Let us explain what you can expect from the course, and what is special about it.
+The first thing which you need to understand is that the course is hard.
+We don't mean advanced and involved math (we took care to skip all the parts that don't help understanding).
+Instead, since topology has impact on many different physical phenomena, the course will touch a lot of different concepts in condensed matter physics.
+
+First of all, we will provide you with a description of the most **important facts and discoveries in topology** in the most simple and concise manner that we can find.
+
+This will still be hard to some of you, since the required background in condensed matter physics is still broad.
+If you see that it is the case, you will need to search for advice in the course **discussions**, so you'll also use the course as an expert community.
+
+If you are experienced already, you may find the lectures straightforward.
+However, even though active research on topological insulators began less than ten years ago,
+the field is already incredibly broad.
+
+This is why we want our course to also fulfill a role of a **journal club**:
+every week we'll ask you to read one of several suggested papers, observe how the concepts that you learn
+appear in a new context, and summarize it for the other participants.
+That way you will learn to analyze research papers and get an **overview of the field**.
+
+Most of the numerical simulations that are used in our research are actually amazingly easy if you know how to do them.
+While teaching how to do computer simulations is not our main aim, we provide already set up simulations for the systems we describe in the lectures.
+
+Using these **computer simulations** you can see for yourself how various models behave, discover new parameter regimes that we don't cover in the lectures, or even extend the simulations and see how adding new terms to the models changes the results.
+
+### How you can help us
+
+MOOCs like this one are not a usual way for providing graduatelevel materials, and even less so materials that are a topic of active research.
+
+We believe that it is a very useful and promising way of knowledge dissemination, that has advantages over a book, a university course, or a review.
+
+This is why it is extremely important for us to know what is your background and your motivation to take the course.
+We want you to share what you found difficult, what you found easy, and where you think the course can be improved.
+
+Moreover, we publish the **source code** for every single bit of this course in this [Github repository](https://github.com/topocm/topocm_content).
+So whenever you see a typo, or you would like to suggest an improvement, you can open a new issue, (or even make a pull request if you know how to use Github).
+
+# Software you will need
+
+If you don't want to be bothered trying out the numerical simulations, you are all set if you have an EdX account and you are signed up for the course.
+
+However we strongly recommend to not skip the numerical simulations part. Following it will help you to develop intuition about how the topological systems behave. The numerical simulations can also serve as an extremely useful tool helping both in experiments and theory.
+
+To get going with the simulations, you will need to get the computational software.
+Specifically you need:
+
+* Python 3.5 or 3.6
+* Python scientific stack (SciPy, NumPy, Matplotlib, Jupyter notebook)
+* Holoviews 1.7, a Python library for plotting data.
+* [Kwant](http://kwantproject.org) 1.3, a package for quantum transport simulations.
+
+The installation should be straightforward.
+Installation of most of the requirements is described [here](http://kwantproject.org/install).
+
+If you are using Windows, you are all set after following the above instructions.
+
+The easiest way to install `kwant` when you are using Linux or OS X is with `conda` which comes with Miniconda, a Python distribution.
+
+1. Open a terminal and download [Miniconda](http://conda.pydata.org/miniconda.html>)
+ (or [Anaconda](https://www.continuum.io/downloads)) by running:
+
+ wget https://repo.continuum.io/miniconda/Miniconda3latestMacOSXx86_64.sh
+
+2. Install Miniconda with:
+
+ bash Miniconda3latestMacOSXx86_64.sh
+
+ and follow its instructions. Make sure that ``conda`` is in your PATH, which you
+ can do by adding ``export PATH="$HOME/miniconda3/bin:$PATH"`` to your ``.bashrc``
+ or ``.bash_profile``.
+
+3. Add the [condaforge](https://condaforge.github.io/) channel and install
+ Kwant and its dependencies with:
+
+ conda config add channels condaforge
+ conda install kwant holoviews notebook feedparser
+
+### Jupyter notebooks
+
+A separate mention of the software we use goes to Jupyter notebooks.
+
+Every document that you see in our course (including the one that you are reading right now) was prepared as a Jupyter notebook.
+
+These notebooks are extremely handy, they allow:
+
+* To use an interactive computing environment where you can see what your simulation does right as you are creating it.
+* To combine nicely formatted text (with Latex equations and images) together with code in any language and the output of that code.
+* To easily share that same code: here, take a look at the source of [the notebook](http://nbviewer.ipython.org/github/topocm/topocm_content/blob/master/w0_background/intro.ipynb) that you are currently reading.
+* To convert it to a presentation, blog post, or an EdX course.
+
+The combination of the above nice properties with many more and with Jupyter being free software lead to the notebooks being [highlighted](http://www.nature.com/news/interactivenotebookssharingthecode1.16261) in Nature.
+
+For a short presentation of Jupyter notebooks just use `Help > User Interface Tour` inside the notebook.
+
+### Sharing notebooks
+
+Showing the results of your work is very easy.
+
+If you are using Sage Cloud, you can just click the "share the notebook" button when you have it opened, and copy the URL.
+
+Otherwise you can make the notebook visible online (for example by putting it in your Dropbox public folder or something similar), copy link, and paste it into [http://nbviewer.ipython.org](http://nbviewer.ipython.org).
+
+### Kwant, Python, and Python scientific software
+
+For most of the simulations of condensed matter systems we are going to use the Kwant package. You can learn Kwant in more detail by following the [tutorial](http://kwantproject.org/doc/1.0/tutorial/), however we aim that for most of the exercises you will be able to learn by doing. The starting point of the exercises are the notebooks used in the lectures, and you should be able to solve them by only modifying the contents not too much.
+
+The same applies to Python and the Python scientific stack (NumPy, SciPy, Matplotlib): these are easy to use, especially when you have code examples. If you are new to programming and wish to get acquainted with Python,
+[here](http://www.learnpython.org/) are [several](http://www.pythoncourse.eu/) [example courses](https://www.codecademy.com/learn/python) that start from the basics and slowly go into advanced topics. There are of course several MOOCs as well, but you will likely not need as much programming skill.
+
+**Do you have questions about installation? Use this discussion:**
+
+
+```python
+MoocDiscussion('Software', 'Help with installation')
+```
+
+# Literature
+
+We are mostly going to focus on the overall structure of the field and study the most basic and general phenomena. We will also skip detailed derivations or some details.
+
+For a more formal and complete source of information on topological insulators and superconductors we recommend you to look into the reviews below. (Of course we think they will be much easier to follor after you finish the course).
+
+
+```python
+display_html(HTML("Topological insulator reviews
"),
+ PreprintReference("0801.0901", show_abstract=False),
+ PreprintReference("1002.3895", show_abstract=False),
+ PreprintReference("1008.2026", show_abstract=False),
+ HTML("Majorana fermion reviews
"),
+ PreprintReference("1112.1950", show_abstract=False),
+ PreprintReference("1202.1293", show_abstract=False),
+ PreprintReference("1206.1736", show_abstract=False),
+ PreprintReference("1407.2131", show_abstract=False),
+ HTML("Advanced topics: Fractional particles and topological quantum computation
"),
+ PreprintReference("0707.1889", show_abstract=False),
+ PreprintReference("0711.4697", show_abstract=False),
+ PreprintReference("1404.0897", show_abstract=False),
+ HTML("Extra topics
"),
+ PreprintReference("1211.5623", show_abstract=False),
+ PreprintReference("1501.00531", show_abstract=False))
+```
diff git a/w10_extensions/gapless.ipynb b/w10_extensions/gapless.ipynb
deleted file mode 100644
index e9cbe1d..0000000
 a/w10_extensions/gapless.ipynb
+++ /dev/null
@@ 1,566 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "from matplotlib import cm\n",
 "from matplotlib.colors import hsv_to_rgb\n",
 "\n",
 "pi_ticks = [(np.pi, r'$\\pi$'), (0, '$0$'), (np.pi, r'$\\pi$')]\n",
 "\n",
 "def d_wave(w=None, direction=None):\n",
 " \"\"\"Creates a dwave system.\n",
 " \n",
 " Parameters:\n",
 " \n",
 " w : int\n",
 " Width of the system, if None the system is infinite\n",
 " direction : str\n",
 " Direction of translation symmetry, if None it's an infinite\n",
 " system in x and y.\n",
 " \"\"\"\n",
 " def hopx(site1, site2, p):\n",
 " return p.t * pauli.sz  p.delta * pauli.sx\n",
 " \n",
 " def hopy(site1, site2, p):\n",
 " return p.t * pauli.sz + p.delta * pauli.sx\n",
 " \n",
 " def onsite(site, p):\n",
 " return (4 * p.t  p.mu) * pauli.sz \n",
 "\n",
 " lat = kwant.lattice.square()\n",
 "\n",
 " if not w:\n",
 " def ribbon_shape(pos):\n",
 " (x, y) = pos\n",
 " return True\n",
 " sym = kwant.TranslationalSymmetry(*lat.prim_vecs)\n",
 " else:\n",
 " if direction == 'topo':\n",
 " def ribbon_shape(pos):\n",
 " (x, y) = pos\n",
 " return (0 <= y  x < w)\n",
 " sym = kwant.TranslationalSymmetry((1, 1)) \n",
 " elif direction == 'triv':\n",
 " def ribbon_shape(pos):\n",
 " (x, y) = pos\n",
 " return (0 <= y < w)\n",
 " sym = kwant.TranslationalSymmetry((1, 0)) \n",
 "\n",
 " syst = kwant.Builder(sym)\n",
 " \n",
 " syst[lat.shape(ribbon_shape, (0, 0))] = onsite\n",
 " syst[kwant.HoppingKind((1, 0), lat)] = hopx\n",
 " syst[kwant.HoppingKind((0, 1), lat)] = hopy\n",
 " \n",
 " return syst\n",
 "\n",
 "\n",
 "def graphene_infinite():\n",
 " lat = kwant.lattice.honeycomb()\n",
 " a, b = lat.sublattices\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))\n",
 " syst[lat.shape(lambda pos: True, (0, 0))] = 0\n",
 " syst[kwant.builder.HoppingKind((0, 0), a, b)] = lambda site1, site2, p: p.t_1\n",
 " syst[kwant.builder.HoppingKind((0, 1), a, b)] = lambda site1, site2, p: p.t_23\n",
 " syst[kwant.builder.HoppingKind((1, 1), a, b)] = lambda site1, site2, p: p.t_23 \n",
 " return syst\n",
 "\n",
 "\n",
 "def plot_dets(syst, p, ks, chiral=False):\n",
 " B = np.array(syst.symmetry.periods).T\n",
 " A = B @ np.linalg.inv(B.T @ B)\n",
 " def momentum_to_lattice(k):\n",
 " k, residuals = np.linalg.lstsq(A, k)[:2]\n",
 " return list(k)\n",
 " \n",
 " syst = kwant.wraparound.wraparound(syst).finalized()\n",
 " kys, kxs = np.meshgrid(ks, ks)\n",
 " dets = np.zeros_like(kxs, dtype=complex)\n",
 " for i, kx in enumerate(ks):\n",
 " for j, ky in enumerate(ks):\n",
 " kx, ky = momentum_to_lattice([kx, ky])\n",
 " ham = syst.hamiltonian_submatrix(args=(p, kx, ky))\n",
 " if chiral:\n",
 " # Bring the chiral symmetric Hamiltonian in offdiagonal form\n",
 " U = (pauli.s0 + 1j * pauli.sx) / np.sqrt(2)\n",
 " ham = U @ ham @ U.T.conjugate()\n",
 " dets[i, j] = ham[1, 0]\n",
 " H = np.angle(dets) / (2 * np.pi)\n",
 " V = np.abs(dets)\n",
 " H = np.mod(H, 1)\n",
 " V /= np.max(V)\n",
 " V = 1  V**2\n",
 " S = np.ones_like(H)\n",
 " HSV = np.dstack((H, S, V))\n",
 " RGB = hsv_to_rgb(HSV)\n",
 " bounds = (ks.min(), ks.min(), ks.max(), ks.max())\n",
 " pl = holoviews.RGB(RGB, bounds=bounds, label=r'$\\det(h)$', kdims=['$k_x$', '$k_y$'])\n",
 " return pl(plot={'xticks': pi_ticks, 'yticks': pi_ticks})(style={'interpolation': None})\n",
 "\n",
 "\n",
 "def Weyl_slab(w=5):\n",
 " def hopx(site1, site2, p):\n",
 " return 0.5j * p.t * pauli.sx  p.t * pauli.sz\n",
 " \n",
 " def hopy(site1, site2, p):\n",
 " return  p.t * pauli.sz\n",
 "\n",
 " def hopz(site1, site2, p):\n",
 " return 0.5j * p.t * pauli.sy  p.t * pauli.sz\n",
 " \n",
 " def onsite(site, p):\n",
 " return 6 * p.t * pauli.sz  p.mu * pauli.sz\n",
 "\n",
 " lat = kwant.lattice.general(np.eye(3))\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry([1, 0, 0], [0, 1, 0]))\n",
 " \n",
 " def shape(pos):\n",
 " (x, y, z) = pos\n",
 " return (0 <= z < w) \n",
 "\n",
 " syst[lat.shape(shape, (0, 0, 0))] = onsite\n",
 " syst[kwant.HoppingKind((1, 0, 0), lat)] = hopx\n",
 " syst[kwant.HoppingKind((0, 1, 0), lat)] = hopy\n",
 " syst[kwant.HoppingKind((0, 0, 1), lat)] = hopz\n",
 " \n",
 " return syst"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Introduction"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Ashvin Vishwanath from the University of California, Berkeley will introduce Weyl semimetals and other examples of gapless, yet topological, systems."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"MAWwa4r1qIc\", src_location='10.1intro')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Topological invariants of Fermi surfaces"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The idea that leads us to the topology of gapless systems is extremely simple. It is:\n",
 "\n",
 "> If we consider momentum as an external conserved parameter, we can study topological closings of the gap in momentum space.\n",
 "\n",
 "Let's consider the simplest type of topological invariant, one we learned about at the very beginning of this course. Remember the simplest topological invariant of a 0D Hamiltonian, the number of filled energy levels? What if we take two points in momentum space, $\\mathbf{k}_1$ and $\\mathbf{k}_2$, and consider a Hamiltonian such that the number of filled states changes by $n$ between these two points? We can conclude that there are at least $n$ Fermi surfaces that lie on every path between $\\mathbf{k}_1$ and $\\mathbf{k}_2$ in momentum space.\n",
 "\n",
 "Now we just need to take this idea and apply it to more interesting systems and topological invariants!"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "What types of topological invariants are relevant? Aside from special circumstances, we cannot make use of timereversal or particlehole symmetries: in momentum space these only have an immediate effect in isolated $\\mathbf{k}$points, where every momentum component is either $0$ or $\\pi$. So there are no paths in momentum space for which either of the symmetries is effective in each point.\n",
 "\n",
 "So we are left with only two symmetry classes: A and AIII (no symmetry at all or sublattice/chiral symmetry), and with only two invariants: if there is a sublattice symmetry, a winding number can be defined, and without it there's a Chern number."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Graphene and protected Dirac cones"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We've already analysed the 0D Chern number that stabilizes the usual Fermi surfaces. Let's go one dimension higher, and study winding numbers in systems with sublattice symmetry around 1D loops. \n",
 "\n",
 "For a winding number to be nonzero, we need to consider 1D loops in momentum space. As a reminder, with sublattice symmetry the Hamiltonian can always be brought to the form\n",
 "\n",
 "$$\n",
 "H = \\begin{pmatrix}\n",
 "0 & h(\\mathbf{k}) \\\\\n",
 "h^\\dagger(\\mathbf{k}) & 0\n",
 "\\end{pmatrix}\n",
 "$$"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The topological invariant is a nonzero winding of $\\det h(\\mathbf{k})$ when $\\mathbf{k}$ goes around some contour. Since $h(\\mathbf{k})$ is continuous, this means that its determinant also has to vanish somewhere inside this contour.\n",
 "\n",
 "To study a particular example where this appears, let's return to graphene, which we studied as a simple limit of Haldane model. For graphene we have the Hamiltonian\n",
 "\n",
 "$$h(k_x, k_y) = t_1 e^{i \\mathbf{k} \\cdot \\mathbf{a_1}} + t_2 e^{i \\mathbf{k} \\cdot \\mathbf{a_2}} + t_3 e^{i \\mathbf{k} \\cdot \\mathbf{a_3}},$$\n",
 "\n",
 "where $t_1, t_2, t_3$ are the three hoppings connecting a site in one of the two graphene sublattices, and $a_1, a_2, a_3$ are the lattice vectors connecting one unit cell to its neighbors.\n",
 "\n",
 "To consider something specific, let's take $t_2 = t_3 = t$ and vary $t_1$. This is what the band structure and $\\det h$ look like:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "%%output size=150 fig='png'\n",
 "p = SimpleNamespace(t_1=1.0, t_23=1.0)\n",
 "syst = graphene_infinite()\n",
 "ks = np.sqrt(3) * np.linspace(np.pi, np.pi, 80)\n",
 "kwargs = dict(title=lambda p: r'Graphene, $t_1 = {:.2} \\times t$'.format(p.t_1), zticks=3)\n",
 "ts = np.linspace(1, 2.4, 8)\n",
 "(holoviews.HoloMap({p.t_1: spectrum(syst, p, k_x=ks, k_y=ks, **kwargs) for p.t_1 in ts}, kdims=['$t_1$']) +\n",
 " holoviews.HoloMap({p.t_1: plot_dets(syst, p, ks) for p.t_1 in ts}, kdims=['$t_1$']))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The left panel shows the band structure, and you see that it has gapless points. The right panel shows $\\det h$ by using hue as a phase and intensity as magnitude (so white is $\\det h = 0$). There are two Dirac points (you see 6, but this is because we plot more than one Brillouin zone). \n",
 "\n",
 "We also see that the winding numbers around these two Dirac points have opposite signs (because by going around them clockwise you encounter red, blue and green colors in opposite orders). This must always be the case since the winding number around the edges of the complete Brillouin zone must vanish  as you walk down every edge of the Brillouin zone twice in opposite directions, their contributions always cancel."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As $t_1$ increases, the two poles move towards each other, eventually annihilating and leaving a completely gapped dispersion relation. Let's now try to obtain an effective model for the dispersion at each pole and at the phase transition point.\n",
 "\n",
 "We know that $\\det h$ has to vanish next to some point $\\mathbf{k}_0$. We can expand the Hamiltonian to a linear order next to this point, which immediately leaves us with a Hamiltonian\n",
 "\n",
 "$$\n",
 "H(\\mathbf{k}) =\n",
 "\\begin{pmatrix}\n",
 "0 & e^{i\\alpha} (v_x \\delta k_x + i v_y \\delta k_y) \\\\\n",
 "e^{i\\alpha} (v_x \\delta k_x  i v_y \\delta k_y) & 0\n",
 "\\end{pmatrix},\n",
 "$$\n",
 "\n",
 "where $\\mathbf{\\delta k}$ is of course the difference between $\\mathbf{k}$ and the Dirac point momentum. Of course this is the 2D Dirac equation, which should be very familiar now.\n",
 "\n",
 "At the phase transition where the two Dirac points annihilate, we can also quickly guess that the correct dispersion should be a quadratic function along the axis connecting the two Dirac points, and linear along the other axis (this is also what we see in the plot). We thus have\n",
 "\n",
 "$$\n",
 "H(\\mathbf{k}) =\n",
 "\\begin{pmatrix}\n",
 "0 & e^{i\\alpha} (\\beta \\delta k_1^2 + m + i v_2 \\delta k_2) \\\\\n",
 "e^{i\\alpha} (\\beta \\delta k_1^2 + m  i v_2 \\delta k_2) & 0\n",
 "\\end{pmatrix},\n",
 "$$\n",
 "\n",
 "such that for $m>0$ we have a fully gapped Hamiltonian, and for $m<0$ there are two Dirac points."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# $d$wave superconductors and edge states"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Gapless points with Dirac dispersion were known for quite some time before graphene. They exist in the cuprate family of high temperature superconductors, known to have a $d$wave order parameter. These materials are layered, with weak couplings between the layers, so in the study of these complicated systems, one often starts with a simplified twodimensional Hamiltonian.\n",
 "\n",
 "This Hamiltonian just has the usual kinetic energy term of a single particle band and a superconducting pairing proportional to $k_x^2  k_y^2$, namely\n",
 "\n",
 "$$\n",
 "H = \\begin{pmatrix}\n",
 "k^2/2m \\mu & \\Delta (k_x^2  k_y^2) \\\\\n",
 "\\Delta (k_x^2  k_y^2) & \\muk^2/2m\n",
 "\\end{pmatrix}.\n",
 "$$\n",
 "\n",
 "There is no spinorbit coupling here, so the Hamiltonian has a spinless timereversal symmetry $H = H^*$. It also has a particlehole symmetry $H=  \\tau_y H^* \\tau_y$. Their product, the chiral symmetry $H = \\tau_y H \\tau_y$ allows the Hamiltonian to have gapless points where both the singleparticle dispersion and the pairing vanish."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Difference between sublattice symmetries\n",
 "\n",
 "Timereversal symmetry ensures that the winding points come in pairs at opposite momenta, just like in graphene.\n",
 "In graphene however, the chiral symmetry operator $\\sigma_z$ commutes with the timereversal symmetry operator. This means that applying timereversal symmetry changes the direction of a loop in momentum space, but leaves the winding number invariant. In $d$wave superconductors on the other hand, the chiral symmetry operator $\\tau_y$ is odd under timereversal (i.e. the operators anticommute), and the winding is invariant under it.\n",
 "\n",
 "This means that a Dirac point at momentum $k$ and positive winding must come together with a Dirac point at $k$ and also positive winding. Since the total winding over the Brillouin zone must be 0, this means that in superconducting systems the Dirac points come in quadruplets: two with positive winding and two with negative winding.\n",
 "\n",
 "The $d$wave superconductor Hamiltonian gives just that: there are 4 Dirac points at $k_x = k_y = k_F / \\sqrt{2}$."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = r\"What happens if you make the 2D $d$wave Hamiltonian 3D, by adding coupling between 2D layers?\"\n",
 "\n",
 "answers = [\"The Dirac points couple and gap out.\",\n",
 " \"In 3D you cannot have a $d$wave pairing.\",\n",
 " \"There will remain isolated gapless points in the larger 3D Brillouin zone.\",\n",
 " \"You get a closed 1D Dirac line of gap closings in the 3D Brillouin zone.\"]\n",
 "\n",
 "explanation = (r\"The real and imaginary parts of the solutions of $\\det h(\\mathbf{k})=0$ form two surfaces \"\n",
 " r\"in the Brillouin zone. The intersection of these two surfaces is a line.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=3, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Edge states"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Now let's see how bulkedge correspondence can be made to work for gapless systems. The idea here is to consider the projection of the wave vector parallel to a continuous sample boundary $k_\\parallel$ as a parameter, and to apply the bulkedge correspondence to the remaining lowerdimensional Hamiltonian.\n",
 "\n",
 "Whenever the line corresponding to a constant $k_\\parallel$ crosses a Dirac point, the winding number of the Hamiltonian $H(k_\\parallel)$ changes by the winding of the Dirac point. This means that for certain values of momentum parallel to the boundary, a zero energy edge state will appear.\n",
 "\n",
 "For a $d$wave superconductor this will only happen for some crystalline orientations, as you can see for yourself:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "%%opts VLine (color='k') Curve (linestyle='')\n",
 "p = SimpleNamespace(mu=2.0, t=1.0, delta=1.0)\n",
 "k = np.arccos(1p.mu/p.t/4)\n",
 "ks = np.linspace(np.pi, np.pi, 50)\n",
 "sys0 = d_wave()\n",
 "sys1 = d_wave(50, direction='topo')\n",
 "sys2 = d_wave(50, direction='triv')\n",
 "\n",
 "det_plot = plot_dets(sys0, p, ks, chiral=True)\n",
 "\n",
 "det_plot1= (det_plot *\n",
 " holoviews.Curve(([np.pi, np.pi], [np.pi, np.pi])) *\n",
 " holoviews.Curve(([np.pi, np.pi2*k], [np.pi2*k, np.pi])) *\n",
 " holoviews.Curve(([np.pi+2*k, np.pi], [np.pi, np.pi+2*k]))).relabel('$\\det(h)$')\n",
 "\n",
 "det_plot2 = det_plot * holoviews.VLine(k) * holoviews.VLine(k)\n",
 "\n",
 "kwargs = dict(k_x=ks, ylims=[2, 2], xticks=pi_ticks, yticks=3)\n",
 "\n",
 "(spectrum(sys1, p, title='Ribbon with edge states', **kwargs) * holoviews.VLine(2*k) * holoviews.VLine(2*k) +\n",
 " det_plot1 + \n",
 " spectrum(sys2, p, title='Ribbon without edge states', **kwargs) * holoviews.VLine(k) * holoviews.VLine(k) +\n",
 " det_plot2).cols(2)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "On the right panels you once again see $\\det h$, with added lines denoting different the values of $k_{\\parallel}$ crossing the Dirac points. If the sample boundary is along the $(1, 0)$ axis, the Dirac points have coinciding $k_{\\parallel}$, and their windings cancel, so that no single value of $k_{\\parallel}$ carries an edge state.\n",
 "\n",
 "On the other hand, the crystal boundary (1, 1), which lies at an angle $\\pi/4$ with respect to the crystallographic axes, has a total winding of +2 at $k_{\\parallel}=0$ and a winding of −1 for $k_{\\parallel}=\\pm k_F$. In this case, each $k_{\\parallel} So applying the most general perturbation we can think of does not gap out the Weyl point where the energy vanishes. Instead, the perturbation only shifts the Weyl point around in momentum space. This feels like some kind of topological protection."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "%%output fig='png'\n",
 "%%opts Surface [azimuth=45]\n",
 "\n",
 "syst = Weyl_slab(w=10)\n",
 "p = SimpleNamespace(t=1.0, mu=None)\n",
 "mus = np.linspace(0.4, 2, 13)\n",
 "\n",
 "kwargs = dict(k_x=np.linspace(np.pi, 0),\n",
 " k_y=np.linspace(np.pi, np.pi),\n",
 " title=lambda p: 'Weyl semimetal, $\\mu = {:.2}$'.format(p.mu),\n",
 " num_bands=4)\n",
 "\n",
 "holoviews.HoloMap({p.mu: spectrum(syst, p, **kwargs) for p.mu in mus}, kdims=[r'$\\mu$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Is there a sense in which Weyl points are \"topological\"? They are clearly protected, but is there some topological reason for the protection? As in the rest of this section, the topology of gapless system becomes apparent by looking at the Hamiltonian in lower dimensional subspaces of momentum space. For the case of Weyl, the momentum space is three dimensional, so let us look at two dimensional subspaces of momentum space.\n",
 "\n",
 "A natural subspace to choose is to fix $k_z=m$. The Weyl Hamiltonian then becomes that of a massive 2D Dirac cone\n",
 "\n",
 "$$H_{2D,Dirac}(k_x,k_y;m)\\equiv H(k_x,k_y,k_z=m)=(\\sigma_x k_x+\\sigma_y k_y+m\\sigma_z).$$\n",
 "\n",
 "As we talked about in week 4 with Chern insulators, the massive Dirac model has a Chern number, which changes by $1$ if $m$ changes sign. \n",
 "\n",
 "> So we can think of the Weyl Hamiltonian in the momentum planes at fixed $k_z$ as Chern insulators with Chern numbers $n_{Ch}=0$ (i.e. trivial) if $k_z < 0$ and $n_{Ch}=1$ (topological) if $k_z > 0$. The Hamiltonian at $k_z=0$ is at the phase transition point of the Chern insulator, which supports a gapless Dirac point."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Systems with Weyl points are known as Weyl semimetals. Just like other topological phases, Weyl semimetals have an interesting surface spectrum. We can understand this easily by viewing the Weyl point as a stack of Chern insulators in momentum space. For any surface in a plane that contains the $z$axis, we can treat $k_z$ as a conserved quantity. At this $k_z=m$, the Hamiltonian is just that of a Chern insulator with an appropriate Chern number. For the range of $k_z$ where the Chern number $n_{Ch}(k_z)=1$, the surface spectrum supports chiral edge states with an energy approximated at low energy by \n",
 "\n",
 "$$E(k_x,k_z)\\approx v(k_z)k_x.$$\n",
 "\n",
 "We can consider the edge states over a range of $k_z$ together to visualize the \"surface states\". \n",
 "\n",
 "> The unique property of the surface states is that if we set $k_x=0$ then the energy vanishes on a line in the surface spectrum. This line actually terminates at $k_z=0$, where the Chern number changes. Such lines, which are referred to as \"Fermi arcs,\" are the unique bounday properties (hence the bulkboundary correspondence) of Weyl semimetals."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "At large enough $k_z$, the two dimensional Hamiltonian $H_{2D,Dirac}(k_x,k_y;k_z)$ becomes trivial i.e. $n_{Ch}(k_z\\rightarrow \\infty)=0$. This means that if the Chern number is $n_{Ch}=1$ in a range of $k_z$, then $n_{Ch}(k_z)$ must change twice resulting in two Weyl points. So Weyl points come in pairs. These points map onto the ends of the Fermi arcs on the surface. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/weyl.svg)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = r\"What protects the surface state of Weyl semimetals from scattering inside the bulk Weyl point?\"\n",
 "\n",
 "answers = [\"Chiral symmetry.\",\n",
 " \"The energy gap in the bulk.\",\n",
 " \"Absence of scattering.\",\n",
 " \"The nonzero Chern number of the bulk.\"]\n",
 "\n",
 "explanation = (r\"The bulk has gapless states due to the Weyl point. \"\n",
 " \"Therefore, only momentum conservation protects surface states from going into the bulk.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=2, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Questions about what you just learned? Ask them below!**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Questions\", \"Topology in gapless systems\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w10_extensions/gapless.md b/w10_extensions/gapless.md
new file mode 100644
index 0000000..cab4f3c
 /dev/null
+++ b/w10_extensions/gapless.md
@@ 0,0 +1,379 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+from matplotlib import cm
+from matplotlib.colors import hsv_to_rgb
+
+pi_ticks = [(np.pi, r'$\pi$'), (0, '$0$'), (np.pi, r'$\pi$')]
+
+def d_wave(w=None, direction=None):
+ """Creates a dwave system.
+
+ Parameters:
+ 
+ w : int
+ Width of the system, if None the system is infinite
+ direction : str
+ Direction of translation symmetry, if None it's an infinite
+ system in x and y.
+ """
+ def hopx(site1, site2, p):
+ return p.t * pauli.sz  p.delta * pauli.sx
+
+ def hopy(site1, site2, p):
+ return p.t * pauli.sz + p.delta * pauli.sx
+
+ def onsite(site, p):
+ return (4 * p.t  p.mu) * pauli.sz
+
+ lat = kwant.lattice.square()
+
+ if not w:
+ def ribbon_shape(pos):
+ (x, y) = pos
+ return True
+ sym = kwant.TranslationalSymmetry(*lat.prim_vecs)
+ else:
+ if direction == 'topo':
+ def ribbon_shape(pos):
+ (x, y) = pos
+ return (0 <= y  x < w)
+ sym = kwant.TranslationalSymmetry((1, 1))
+ elif direction == 'triv':
+ def ribbon_shape(pos):
+ (x, y) = pos
+ return (0 <= y < w)
+ sym = kwant.TranslationalSymmetry((1, 0))
+
+ syst = kwant.Builder(sym)
+
+ syst[lat.shape(ribbon_shape, (0, 0))] = onsite
+ syst[kwant.HoppingKind((1, 0), lat)] = hopx
+ syst[kwant.HoppingKind((0, 1), lat)] = hopy
+
+ return syst
+
+
+def graphene_infinite():
+ lat = kwant.lattice.honeycomb()
+ a, b = lat.sublattices
+ syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))
+ syst[lat.shape(lambda pos: True, (0, 0))] = 0
+ syst[kwant.builder.HoppingKind((0, 0), a, b)] = lambda site1, site2, p: p.t_1
+ syst[kwant.builder.HoppingKind((0, 1), a, b)] = lambda site1, site2, p: p.t_23
+ syst[kwant.builder.HoppingKind((1, 1), a, b)] = lambda site1, site2, p: p.t_23
+ return syst
+
+
+def plot_dets(syst, p, ks, chiral=False):
+ B = np.array(syst.symmetry.periods).T
+ A = B @ np.linalg.inv(B.T @ B)
+ def momentum_to_lattice(k):
+ k, residuals = np.linalg.lstsq(A, k)[:2]
+ return list(k)
+
+ syst = kwant.wraparound.wraparound(syst).finalized()
+ kys, kxs = np.meshgrid(ks, ks)
+ dets = np.zeros_like(kxs, dtype=complex)
+ for i, kx in enumerate(ks):
+ for j, ky in enumerate(ks):
+ kx, ky = momentum_to_lattice([kx, ky])
+ ham = syst.hamiltonian_submatrix(args=(p, kx, ky))
+ if chiral:
+ # Bring the chiral symmetric Hamiltonian in offdiagonal form
+ U = (pauli.s0 + 1j * pauli.sx) / np.sqrt(2)
+ ham = U @ ham @ U.T.conjugate()
+ dets[i, j] = ham[1, 0]
+ H = np.angle(dets) / (2 * np.pi)
+ V = np.abs(dets)
+ H = np.mod(H, 1)
+ V /= np.max(V)
+ V = 1  V**2
+ S = np.ones_like(H)
+ HSV = np.dstack((H, S, V))
+ RGB = hsv_to_rgb(HSV)
+ bounds = (ks.min(), ks.min(), ks.max(), ks.max())
+ pl = holoviews.RGB(RGB, bounds=bounds, label=r'$\det(h)$', kdims=['$k_x$', '$k_y$'])
+ return pl(plot={'xticks': pi_ticks, 'yticks': pi_ticks})(style={'interpolation': None})
+
+
+def Weyl_slab(w=5):
+ def hopx(site1, site2, p):
+ return 0.5j * p.t * pauli.sx  p.t * pauli.sz
+
+ def hopy(site1, site2, p):
+ return  p.t * pauli.sz
+
+ def hopz(site1, site2, p):
+ return 0.5j * p.t * pauli.sy  p.t * pauli.sz
+
+ def onsite(site, p):
+ return 6 * p.t * pauli.sz  p.mu * pauli.sz
+
+ lat = kwant.lattice.general(np.eye(3))
+ syst = kwant.Builder(kwant.TranslationalSymmetry([1, 0, 0], [0, 1, 0]))
+
+ def shape(pos):
+ (x, y, z) = pos
+ return (0 <= z < w)
+
+ syst[lat.shape(shape, (0, 0, 0))] = onsite
+ syst[kwant.HoppingKind((1, 0, 0), lat)] = hopx
+ syst[kwant.HoppingKind((0, 1, 0), lat)] = hopy
+ syst[kwant.HoppingKind((0, 0, 1), lat)] = hopz
+
+ return syst
+```
+
+# Introduction
+
+Ashvin Vishwanath from the University of California, Berkeley will introduce Weyl semimetals and other examples of gapless, yet topological, systems.
+
+
+```python
+MoocVideo("MAWwa4r1qIc", src_location='10.1intro')
+```
+
+# Topological invariants of Fermi surfaces
+
+The idea that leads us to the topology of gapless systems is extremely simple. It is:
+
+> If we consider momentum as an external conserved parameter, we can study topological closings of the gap in momentum space.
+
+Let's consider the simplest type of topological invariant, one we learned about at the very beginning of this course. Remember the simplest topological invariant of a 0D Hamiltonian, the number of filled energy levels? What if we take two points in momentum space, $\mathbf{k}_1$ and $\mathbf{k}_2$, and consider a Hamiltonian such that the number of filled states changes by $n$ between these two points? We can conclude that there are at least $n$ Fermi surfaces that lie on every path between $\mathbf{k}_1$ and $\mathbf{k}_2$ in momentum space.
+
+Now we just need to take this idea and apply it to more interesting systems and topological invariants!
+
+What types of topological invariants are relevant? Aside from special circumstances, we cannot make use of timereversal or particlehole symmetries: in momentum space these only have an immediate effect in isolated $\mathbf{k}$points, where every momentum component is either $0$ or $\pi$. So there are no paths in momentum space for which either of the symmetries is effective in each point.
+
+So we are left with only two symmetry classes: A and AIII (no symmetry at all or sublattice/chiral symmetry), and with only two invariants: if there is a sublattice symmetry, a winding number can be defined, and without it there's a Chern number.
+
+# Graphene and protected Dirac cones
+
+We've already analysed the 0D Chern number that stabilizes the usual Fermi surfaces. Let's go one dimension higher, and study winding numbers in systems with sublattice symmetry around 1D loops.
+
+For a winding number to be nonzero, we need to consider 1D loops in momentum space. As a reminder, with sublattice symmetry the Hamiltonian can always be brought to the form
+
+$$
+H = \begin{pmatrix}
+0 & h(\mathbf{k}) \\
+h^\dagger(\mathbf{k}) & 0
+\end{pmatrix}
+$$
+
+The topological invariant is a nonzero winding of $\det h(\mathbf{k})$ when $\mathbf{k}$ goes around some contour. Since $h(\mathbf{k})$ is continuous, this means that its determinant also has to vanish somewhere inside this contour.
+
+To study a particular example where this appears, let's return to graphene, which we studied as a simple limit of Haldane model. For graphene we have the Hamiltonian
+
+$$h(k_x, k_y) = t_1 e^{i \mathbf{k} \cdot \mathbf{a_1}} + t_2 e^{i \mathbf{k} \cdot \mathbf{a_2}} + t_3 e^{i \mathbf{k} \cdot \mathbf{a_3}},$$
+
+where $t_1, t_2, t_3$ are the three hoppings connecting a site in one of the two graphene sublattices, and $a_1, a_2, a_3$ are the lattice vectors connecting one unit cell to its neighbors.
+
+To consider something specific, let's take $t_2 = t_3 = t$ and vary $t_1$. This is what the band structure and $\det h$ look like:
+
+
+```python
+%%output size=150 fig='png'
+p = SimpleNamespace(t_1=1.0, t_23=1.0)
+syst = graphene_infinite()
+ks = np.sqrt(3) * np.linspace(np.pi, np.pi, 80)
+kwargs = dict(title=lambda p: r'Graphene, $t_1 = {:.2} \times t$'.format(p.t_1), zticks=3)
+ts = np.linspace(1, 2.4, 8)
+(holoviews.HoloMap({p.t_1: spectrum(syst, p, k_x=ks, k_y=ks, **kwargs) for p.t_1 in ts}, kdims=['$t_1$']) +
+ holoviews.HoloMap({p.t_1: plot_dets(syst, p, ks) for p.t_1 in ts}, kdims=['$t_1$']))
+```
+
+The left panel shows the band structure, and you see that it has gapless points. The right panel shows $\det h$ by using hue as a phase and intensity as magnitude (so white is $\det h = 0$). There are two Dirac points (you see 6, but this is because we plot more than one Brillouin zone).
+
+We also see that the winding numbers around these two Dirac points have opposite signs (because by going around them clockwise you encounter red, blue and green colors in opposite orders). This must always be the case since the winding number around the edges of the complete Brillouin zone must vanish  as you walk down every edge of the Brillouin zone twice in opposite directions, their contributions always cancel.
+
+As $t_1$ increases, the two poles move towards each other, eventually annihilating and leaving a completely gapped dispersion relation. Let's now try to obtain an effective model for the dispersion at each pole and at the phase transition point.
+
+We know that $\det h$ has to vanish next to some point $\mathbf{k}_0$. We can expand the Hamiltonian to a linear order next to this point, which immediately leaves us with a Hamiltonian
+
+$$
+H(\mathbf{k}) =
+\begin{pmatrix}
+0 & e^{i\alpha} (v_x \delta k_x + i v_y \delta k_y) \\
+e^{i\alpha} (v_x \delta k_x  i v_y \delta k_y) & 0
+\end{pmatrix},
+$$
+
+where $\mathbf{\delta k}$ is of course the difference between $\mathbf{k}$ and the Dirac point momentum. Of course this is the 2D Dirac equation, which should be very familiar now.
+
+At the phase transition where the two Dirac points annihilate, we can also quickly guess that the correct dispersion should be a quadratic function along the axis connecting the two Dirac points, and linear along the other axis (this is also what we see in the plot). We thus have
+
+$$
+H(\mathbf{k}) =
+\begin{pmatrix}
+0 & e^{i\alpha} (\beta \delta k_1^2 + m + i v_2 \delta k_2) \\
+e^{i\alpha} (\beta \delta k_1^2 + m  i v_2 \delta k_2) & 0
+\end{pmatrix},
+$$
+
+such that for $m>0$ we have a fully gapped Hamiltonian, and for $m<0$ there are two Dirac points.
+
+# $d$wave superconductors and edge states
+
+Gapless points with Dirac dispersion were known for quite some time before graphene. They exist in the cuprate family of high temperature superconductors, known to have a $d$wave order parameter. These materials are layered, with weak couplings between the layers, so in the study of these complicated systems, one often starts with a simplified twodimensional Hamiltonian.
+
+This Hamiltonian just has the usual kinetic energy term of a single particle band and a superconducting pairing proportional to $k_x^2  k_y^2$, namely
+
+$$
+H = \begin{pmatrix}
+k^2/2m \mu & \Delta (k_x^2  k_y^2) \\
+\Delta (k_x^2  k_y^2) & \muk^2/2m
+\end{pmatrix}.
+$$
+
+There is no spinorbit coupling here, so the Hamiltonian has a spinless timereversal symmetry $H = H^*$. It also has a particlehole symmetry $H=  \tau_y H^* \tau_y$. Their product, the chiral symmetry $H = \tau_y H \tau_y$ allows the Hamiltonian to have gapless points where both the singleparticle dispersion and the pairing vanish.
+
+## Difference between sublattice symmetries
+
+Timereversal symmetry ensures that the winding points come in pairs at opposite momenta, just like in graphene.
+In graphene however, the chiral symmetry operator $\sigma_z$ commutes with the timereversal symmetry operator. This means that applying timereversal symmetry changes the direction of a loop in momentum space, but leaves the winding number invariant. In $d$wave superconductors on the other hand, the chiral symmetry operator $\tau_y$ is odd under timereversal (i.e. the operators anticommute), and the winding is invariant under it.
+
+This means that a Dirac point at momentum $k$ and positive winding must come together with a Dirac point at $k$ and also positive winding. Since the total winding over the Brillouin zone must be 0, this means that in superconducting systems the Dirac points come in quadruplets: two with positive winding and two with negative winding.
+
+The $d$wave superconductor Hamiltonian gives just that: there are 4 Dirac points at $k_x = k_y = k_F / \sqrt{2}$.
+
+
+```python
+question = r"What happens if you make the 2D $d$wave Hamiltonian 3D, by adding coupling between 2D layers?"
+
+answers = ["The Dirac points couple and gap out.",
+ "In 3D you cannot have a $d$wave pairing.",
+ "There will remain isolated gapless points in the larger 3D Brillouin zone.",
+ "You get a closed 1D Dirac line of gap closings in the 3D Brillouin zone."]
+
+explanation = (r"The real and imaginary parts of the solutions of $\det h(\mathbf{k})=0$ form two surfaces "
+ r"in the Brillouin zone. The intersection of these two surfaces is a line.")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=3, explanation=explanation)
+```
+
+## Edge states
+
+Now let's see how bulkedge correspondence can be made to work for gapless systems. The idea here is to consider the projection of the wave vector parallel to a continuous sample boundary $k_\parallel$ as a parameter, and to apply the bulkedge correspondence to the remaining lowerdimensional Hamiltonian.
+
+Whenever the line corresponding to a constant $k_\parallel$ crosses a Dirac point, the winding number of the Hamiltonian $H(k_\parallel)$ changes by the winding of the Dirac point. This means that for certain values of momentum parallel to the boundary, a zero energy edge state will appear.
+
+For a $d$wave superconductor this will only happen for some crystalline orientations, as you can see for yourself:
+
+
+```python
+%%opts VLine (color='k') Curve (linestyle='')
+p = SimpleNamespace(mu=2.0, t=1.0, delta=1.0)
+k = np.arccos(1p.mu/p.t/4)
+ks = np.linspace(np.pi, np.pi, 50)
+sys0 = d_wave()
+sys1 = d_wave(50, direction='topo')
+sys2 = d_wave(50, direction='triv')
+
+det_plot = plot_dets(sys0, p, ks, chiral=True)
+
+det_plot1= (det_plot *
+ holoviews.Curve(([np.pi, np.pi], [np.pi, np.pi])) *
+ holoviews.Curve(([np.pi, np.pi2*k], [np.pi2*k, np.pi])) *
+ holoviews.Curve(([np.pi+2*k, np.pi], [np.pi, np.pi+2*k]))).relabel('$\det(h)$')
+
+det_plot2 = det_plot * holoviews.VLine(k) * holoviews.VLine(k)
+
+kwargs = dict(k_x=ks, ylims=[2, 2], xticks=pi_ticks, yticks=3)
+
+(spectrum(sys1, p, title='Ribbon with edge states', **kwargs) * holoviews.VLine(2*k) * holoviews.VLine(2*k) +
+ det_plot1 +
+ spectrum(sys2, p, title='Ribbon without edge states', **kwargs) * holoviews.VLine(k) * holoviews.VLine(k) +
+ det_plot2).cols(2)
+```
+
+On the right panels you once again see $\det h$, with added lines denoting different the values of $k_{\parallel}$ crossing the Dirac points. If the sample boundary is along the $(1, 0)$ axis, the Dirac points have coinciding $k_{\parallel}$, and their windings cancel, so that no single value of $k_{\parallel}$ carries an edge state.
+
+On the other hand, the crystal boundary (1, 1), which lies at an angle $\pi/4$ with respect to the crystallographic axes, has a total winding of +2 at $k_{\parallel}=0$ and a winding of −1 for $k_{\parallel}=\pm k_F$. In this case, each $k_{\parallel} So applying the most general perturbation we can think of does not gap out the Weyl point where the energy vanishes. Instead, the perturbation only shifts the Weyl point around in momentum space. This feels like some kind of topological protection.
+
+
+```python
+%%output fig='png'
+%%opts Surface [azimuth=45]
+
+syst = Weyl_slab(w=10)
+p = SimpleNamespace(t=1.0, mu=None)
+mus = np.linspace(0.4, 2, 13)
+
+kwargs = dict(k_x=np.linspace(np.pi, 0),
+ k_y=np.linspace(np.pi, np.pi),
+ title=lambda p: 'Weyl semimetal, $\mu = {:.2}$'.format(p.mu),
+ num_bands=4)
+
+holoviews.HoloMap({p.mu: spectrum(syst, p, **kwargs) for p.mu in mus}, kdims=[r'$\mu$'])
+```
+
+Is there a sense in which Weyl points are "topological"? They are clearly protected, but is there some topological reason for the protection? As in the rest of this section, the topology of gapless system becomes apparent by looking at the Hamiltonian in lower dimensional subspaces of momentum space. For the case of Weyl, the momentum space is three dimensional, so let us look at two dimensional subspaces of momentum space.
+
+A natural subspace to choose is to fix $k_z=m$. The Weyl Hamiltonian then becomes that of a massive 2D Dirac cone
+
+$$H_{2D,Dirac}(k_x,k_y;m)\equiv H(k_x,k_y,k_z=m)=(\sigma_x k_x+\sigma_y k_y+m\sigma_z).$$
+
+As we talked about in week 4 with Chern insulators, the massive Dirac model has a Chern number, which changes by $1$ if $m$ changes sign.
+
+> So we can think of the Weyl Hamiltonian in the momentum planes at fixed $k_z$ as Chern insulators with Chern numbers $n_{Ch}=0$ (i.e. trivial) if $k_z < 0$ and $n_{Ch}=1$ (topological) if $k_z > 0$. The Hamiltonian at $k_z=0$ is at the phase transition point of the Chern insulator, which supports a gapless Dirac point.
+
+Systems with Weyl points are known as Weyl semimetals. Just like other topological phases, Weyl semimetals have an interesting surface spectrum. We can understand this easily by viewing the Weyl point as a stack of Chern insulators in momentum space. For any surface in a plane that contains the $z$axis, we can treat $k_z$ as a conserved quantity. At this $k_z=m$, the Hamiltonian is just that of a Chern insulator with an appropriate Chern number. For the range of $k_z$ where the Chern number $n_{Ch}(k_z)=1$, the surface spectrum supports chiral edge states with an energy approximated at low energy by
+
+$$E(k_x,k_z)\approx v(k_z)k_x.$$
+
+We can consider the edge states over a range of $k_z$ together to visualize the "surface states".
+
+> The unique property of the surface states is that if we set $k_x=0$ then the energy vanishes on a line in the surface spectrum. This line actually terminates at $k_z=0$, where the Chern number changes. Such lines, which are referred to as "Fermi arcs," are the unique bounday properties (hence the bulkboundary correspondence) of Weyl semimetals.
+
+At large enough $k_z$, the two dimensional Hamiltonian $H_{2D,Dirac}(k_x,k_y;k_z)$ becomes trivial i.e. $n_{Ch}(k_z\rightarrow \infty)=0$. This means that if the Chern number is $n_{Ch}=1$ in a range of $k_z$, then $n_{Ch}(k_z)$ must change twice resulting in two Weyl points. So Weyl points come in pairs. These points map onto the ends of the Fermi arcs on the surface.
+
+![](figures/weyl.svg)
+
+
+```python
+question = r"What protects the surface state of Weyl semimetals from scattering inside the bulk Weyl point?"
+
+answers = ["Chiral symmetry.",
+ "The energy gap in the bulk.",
+ "Absence of scattering.",
+ "The nonzero Chern number of the bulk."]
+
+explanation = (r"The bulk has gapless states due to the Weyl point. "
+ "Therefore, only momentum conservation protects surface states from going into the bulk.")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=2, explanation=explanation)
+```
+
+**Questions about what you just learned? Ask them below!**
+
+
+```python
+MoocDiscussion("Questions", "Topology in gapless systems")
+```
diff git a/w10_extensions/mechanics.ipynb b/w10_extensions/mechanics.ipynb
deleted file mode 100644
index 425d0b9..0000000
 a/w10_extensions/mechanics.ipynb
+++ /dev/null
@@ 1,752 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "import topomech"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Introduction"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Today's lecture will be given by Vincenzo Vitelli, from Leiden University. You will learn about topologically protected mechanical structures, that mirror the properties of topological insulators and quantum Hall systems.\n",
 "\n",
 "The main concepts and mathematical ideas will be presented in the context of real mechanical prototypes. Hopefully, this approach will stimulate you to cross the line that too often separates theory from applications."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"ieNPei2zMg\", src_location=\"10.2intro\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The materials of this lecture are kindly provided by the Topological Mechanics lab at Leiden University: Vincenzo Vitelli (PI), Bryan Chen, Anne Meeussen, Jayson Paulose, Benny van Zuiden, and Yujie Zhou. They are copyright of their creators, and are available under \n",
 "a Creative Commons AttributionShareAlike 4.0\n",
 "International License.\n",
 "\n",
 ""
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Kink and antikink"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's consider the chain you saw in the video:\n",
 "\n",
 "![](figures/chain_scheme.png)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In the figure, the red dashed lines represent springs and the green arrows the vibrational eigenvectors. The rigid rotors are in black, while the blue dots are point masses of magnitude $m$.\n",
 "\n",
 "Imagine the system with periodic boundary conditions, that is on a closed ring. As you can see from the figure, in the bulk there are an equal number of degrees of freedom (the rotors) as there are constraints (the springs). This can be seen as a ‘‘charge neutrality‘‘ condition:"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/chaint.png)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "If you cut the ring, you remove one constraint, and now there is a zero energy mode in the system. We will discuss later that the direction the rotors lean plays a role of a ‘‘mechanical’’ polarization.\n",
 "\n",
 "The constraint counting does not tell you where the mode will be located, but if you write the dynamical matrix and find the zero eigenmode, you will learn that the zero mode (whose eigenvectors are represented in the figure as green arrows) is localized at the edge towards which the rotors are pointing. Note that we are tacitly assuming that the vibrational modes of this structure are gapped. Convince yourself that the gap closes if the angle of repose, labeled by $\\bar{\\theta}$, is equal to zero.\n",
 "\n",
 "A study of the vibrational modes of this chain was presented in the original paper of Kane and Lubensky, which was mentioned in the introductory video:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "PreprintReference('1308.0554', description=\"\", show_abstract=False)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We shall now show that the zero mode localized at the edge is a time snaphot of a nonlinear object, the kink that separates regions of left and right leaning rotors, a bit like a domain wall in an Ising model:\n",
 "\n",
 "![](figures/kink.png)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "To see that, it is easier to consider the constraint equation $l^2_{n,n+1}=\\bar{l}^2$ that demands that the length of the springs $l_{n, n+1}$ between any two rotors labeled by $n$ and $n+1$ is not stretched. This is certainly the case for the rigid bar systems shown in the video which correspond to the limit of infinite spring constant. Such systems are called [linkages](http://en.wikipedia.org/wiki/Linkage_%28mechanical%29). \n",
 "\n",
 "In terms of the parameters defined in the first figure, the constraint equation $l^2_{n,n+1}=\\bar{l}^2$ reads\n",
 "\n",
 "$$\n",
 "\\require{action}\n",
 "\\require{color}\n",
 "\\toggle{\n",
 "\\cos(\\theta _{n} + \\theta _{n+1})  \\cos(2\\bar{\\theta}) + \\frac{a}{r}(\\sin\\theta _{n}  \\sin\\theta _{n+1})=0\n",
 "\\textit{ (click for explanation)}.}{\n",
 "l^2 = r^2 (\\cos\\theta_1 + \\cos\\theta_2)^2 + [r(\\sin\\theta_1  \\sin\\theta_2) + a]^2 \\textit{ (click more)}\n",
 "}{\n",
 "l^2 = 2 r^2 + a^2 + 2r^2 \\cos\\theta_1\\cos\\theta_2  2r^2\\sin\\theta_1\\sin\\theta_2 + 2ar(\\sin\\theta_1  \\sin\\theta_2) \\textit{, and so}\n",
 "}{\n",
 "(l^2  2r^2  a^2)/2r = \\color{red}{r\\cos(\\theta_1 + \\theta_2) + a(\\sin\\theta_1  \\sin\\theta_2) = r\\cos(2\\bar{\\theta})}\n",
 "}\n",
 "\\endtoggle\n",
 "$$\n",
 "\n",
 "To take the continuum limit of the above equation, we define a slowlyvarying angular field $\\theta (x)$ and subsequently define the field $u(x)=r\\sin\\theta (x)$, the $x$component of the position of the mass. When $r/a$ is sufficiently small, we obtain\n",
 "\n",
 "$$\n",
 "\\frac{a^2}{2}\\frac{du}{dx} = u^2\\bar{u}^2,\n",
 "$$\n",
 "\n",
 "where $\\bar u\\equiv r\\sin\\bar\\theta>0$. Besides the uniform left and rightleaning solutions\n",
 "$u(x)=\\pm \\bar u$, this equation admits only one *zeroenergy* solution (for $u<\\bar{u}$) given by the kink \n",
 "\n",
 "$$\n",
 "u(x) = \\bar u\\tanh\\left(\\frac{xx_0}{w_0}\\right),\n",
 "$$\n",
 "\n",
 "where $w_0=a^2/2\\bar u$ is the width of the static domain wall that interpolates between leftleaning ($u<0$ as $x\\rightarrow\\infty$) and rightleaning ($u>0$ as $x\\rightarrow+\\infty$) states."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = r\"What happens to the kink width $w_0$ when the gap closes?\"\n",
 "\n",
 "answers = [\"It goes to zero.\",\n",
 " \"It does not vary.\",\n",
 " \"It diverges.\"]\n",
 "\n",
 "explanation = (r\"We said that a gap equal to zero corresponds to $\\bar{\\theta}\\to0$. \"\n",
 " r\"This gives $w_0 = a^2/2\\bar{u}d \\propto 1 / \\sin \\bar\\theta \\to \\infty$.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=2, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Nonlinear dynamics"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You can explicitly obtain a continuum Lagrangian for the chain which, in the limit $l(x)\\approx\\bar{l}$ and $\\bar{\\theta}\\ll 1$, reads:\n",
 "\n",
 "$$\n",
 "\\mathcal{L}=\\int dx \\left[\\frac{1}{2}M\\left(\\frac{\\partial\n",
 "u}{\\partial t}\\right)^2 \n",
 "\\frac{1}{2}K\\frac{a^4}{4}\\left(\\frac{\\partial u}{\\partial\n",
 "x}\\right)^2 \\frac{1}{2}K(\\bar u^2u^2)^2  \\frac{1}{2} K \\frac{a^2}{2}(\\bar\n",
 "u^2u^2)\\frac{\\partial u}{\\partial x}\\right].\n",
 "$$\n",
 "\n",
 "The first term is a linearized kinetic energy, while the second and third terms are the ordinary [$\\phi^4$ field theory](http://en.wikipedia.org/wiki/Quartic_interaction) that you might have encountered for instance while studying the Ising model.\n",
 "\n",
 "The final term linear in $\\partial_x u$ is topological in the sense that it integrates to the boundary. It ensures that the static kink has zero energy, since the last three terms in the Lagrangian can be combined into a perfect square, that vanishes for the static kink solution (this is sometimes called a BPS state). The topological boundary term does not affect the equations of motions in the bulk, but it breaks the $\\partial_x u \\rightarrow \\partial_x u$ symmetry of the $\\phi^4$ theory. That's why the two edges are not equivalent in terms of initiating the kink motion.\n",
 "\n",
 "The antikink solution (with left and rightleaning states reversed in space) costs a finite stretching energy. Hence, the antikink is forbidden in the ground state represented by the linkage limit, where $k_e \\rightarrow \\infty$. The antikink would require an opposite choice of sign in front of the topological boundary term.\n",
 "\n",
 "As discussed in the introductory video, however, something that behaves like an antikink can be obtained if we stick in the system a rigid bar much longer than the others:"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/antikink.png)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Rather than analyzing mathematically the dynamics of the Lagrangian above, watch the two videos below that\n",
 "show the motion in the linkage limit."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"BE4NDhfdpBQ\", src_location=\"10.2topologicallinkagesI\")"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"mRjpzC4rJx0\", src_location=\"10.2topologicallinkagesII\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "If you are curious about the mathematical details and a systematic study of the dynamics in the springsrotors system, you can check out the following paper: "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "PreprintReference('1404.2263', description=\"\", show_abstract=False)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Note that with different geometrical parameters, the same chain above can realize the [sineGordon Lagrangian](http://en.wikipedia.org/wiki/SineGordon_equation). As before, check out the following movie:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"w2k1Y0WON2E\", src_location=\"10.2topologicallinkagesIII\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The same reference above contains hints on how to build this structure with LEGO  plus of course all the mathematical details!"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Zero modes and states of selfstress"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "At this point we could expand around the kink solution and find a zero mode localized at its center where the gap closes. Such a zero mode allows the kink to translate as shown in the linkage video.\n",
 "\n",
 "For now we will simply remark that if one views the orientation along which the rotors lean as a mechanical polarization, then there will be an excess positive ‘‘charge’’ corresponding to a soft mode at the kink center and a negative one at the antikink (see the last two figures). Never mind if this electrostatic analogy is not yet clear; we will return to it and show that the antikink harbours a socalled ** state of self stress**, a dual state to the zero mode. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Before doing that we need to review the Maxwell count which is a **global** relation that stipulates that the number of zero modes $n_\\text{m}$, present in an arbitrary mechanical structure, is simply given by the difference between the number of degrees of freedom minus the number of **independent** constraints.\n",
 "\n",
 "For simplicity, assume that the mechanical structure under examination can be viewed as a network composed of $N_\\text{s}$ sites (for instance point masses) connected by $N_\\text{b}$ central force bonds (for instance springs or rigid beams) in $d$ dimensions. In this case, the number of degrees of freedom is given by $d N_\\text{s}$ and the **total** number of constraints is simply $N_\\text{b}$. The states of selfstress are the **redundant** constraints present in the structure, whose number we denote by $n_{ss}$.\n",
 "\n",
 "The Maxwell criterion then reads\n",
 "\n",
 "$$\n",
 "d N_\\text{s}  N_\\text{b} = n_{m}  n_{ss}\\,.\n",
 "$$\n",
 "\n",
 "Let's apply this equation to the following examples of mechanical structures:"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/modecount.png)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Note that on the left panel there are 4 sites in 2 dimensions, hence 8 degrees of freedom. There are also 4 bonds which leaves 4 soft modes, as prescribed by the Maxwell criterion. You can easily verify that there are 2 trivial translational and 1 rotational zero modes plus 1 nontrivial zero mode, the one indicated by the arrows in the figure.\n",
 "\n",
 "If you add two extra bonds along the diagonals, as in the right panel, the left hand side of the Maxwell count gives 2. Now, the 3 translations and rotations are still there, the nontrivial zero mode is no longer present but there is one redundant constraint or state of self stress. The difference between the 3 trivial zero modes and the state of self stress gives\n",
 "indeed 2, again as expected from the Maxwell criterion. Here we will denote structures for which the left hand side of the Maxwell count is zero as **isostatic**.\n",
 "\n",
 "(Note that this is an abuse of terminology. Strictly speaking, isostatic\n",
 "structures have $dN_{\\text{s}}n_{m,\\text{triv}}=N_\\text{b}$ and $n_{ss}=0$, where\n",
 "$n_{m,\\text{triv}}$ is the number of translations and rotations in $d$\n",
 "dimensions.)\n",
 "\n",
 "As a simple test of your knowledge, consider the following question whose answer will prove handy later."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (r\"What is the number of bonds $z_c$ emanating from each node in a $d$dimensional isostatic structure \"\n",
 " \"where all nodes have the same number of bonds (neglecting boundaries)?\")\n",
 "\n",
 "answers = [r\"$z_c=d$.\",\n",
 " r\"$z_c=2d$.\",\n",
 " r\"$z_c=d(d1)$.\",\n",
 " r\"$z_c=d^2$.\"]\n",
 "\n",
 "explanation = (\"In an isostatic structure we have equal number of degrees of freedom and number of constraints. \"\n",
 " \"This gives the equation $d N = z N /2$, because each bond is shared by two sites.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Why do we call redundant constraints with the name *states of self stress*?\n",
 "\n",
 "Consider the example in the right panel of the figure. Note that if you apply a suitable distribution of stresses in the bonds, the structure will remain in static equilibrium. In the example, you can apply a compression to the vertical and horizontal bars, which corresponds to an outgoing force on the masses, and a tension on the diagonal bars such that this outgoing force is canceled. The numbers next to the springs in the figure (positive for the compressions, negative for tensions) give the right ratios such that the forces cancel."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We see therefore that states of self stress are assignments of tensions or compressions to (some of) the bonds that do not result in net forces on the nodes. As such, they are *dual* to the zero energy mechanical modes, which are displacements of some of the sites that do not result in tensions or compressions of the bonds (that's why they cost zero elastic energy).\n",
 "\n",
 "This relation between states of self stress and zero modes can be made more precise by introducing the rigidity, or compatibility, matrix $R_{ij}$ that describes the small distortions of the mechanical structure captured by linear elastic theories. This $R$ matrix relates the bond extensions $e_i = R_{ij} u_j$ to the site displacements $u_j$. \n",
 "\n",
 "The zero energy modes are members of the null space of $R_{ij}$, which in an isostatic system are also the (right) eigenvectors of $R_{ij}$ with eigenvalue 0. (Convince yourself that the rigidity matrix is square for an isostatic system.)\n",
 "\n",
 "Conversely the states of self stress are the zero eigenvectors of the transpose matrix $R^{T}$ that relates the forces on the nodes to the tensions in the bonds. The Maxwell count equation follows from the ranknullity theorem and can be expressed as an index theorem. (We suggest the reader interested in a careful proof and statement of these results to consult [this review](http://arxiv.org/abs/1503.01324).)\n",
 "\n",
 "Here we merely remark that if one smoothly deforms the network without cutting bonds or adding sites then the left hand side of the Maxwell count does not change. This means that after such a smooth deformation, the difference between the number of zero modes and states of self stress must remain invariant even if $n_m$ and $n_{ss}$ change individually. In this sense the isostatic condition can be viewed as a charge neutrality condition. As we shall see, this electrostatic analogy is far reaching. We will now turn our attention to periodic mechanical structures that are isostatic, hence ‘‘charge neutral’’, but mechanically polarized so that edge modes can appear at the sample boundary like charges in an electrically polarized medium."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Topological band theory"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The first step is to set up a topological band theory of vibrational modes by defining the Fouriertransformed rigidity matrix $R(\\mathbf{k})$ whose determinant is complex: $\\det R(\\mathbf{k}) \\equiv \\det R(\\mathbf{k})e^{i\\phi(\\mathbf{k})}$. Consider now for simplicity a two dimensional lattice whose phonons are gapped, away from $\\mathbf{k}=\\mathbf{0}$, like the twisted Kagome lattice shown at the end of the introductory video. \n",
 "\n",
 "Two winding numbers,\n",
 "$n_i=\\{n_1,n_2\\}$, of $\\phi(\\mathbf{k})$ can be evaluated using\n",
 "\n",
 "$$\n",
 "n_i= \\frac{1}{2\\pi}\\oint_{C_i}d\\mathbf{k}\\cdot\\nabla_\\mathbf{k}\n",
 "\\phi(\\mathbf{k})\n",
 "$$\n",
 "\n",
 "along the two cycles $\\{C_1,C_2\\}$ of the Brillouin zone corresponding to the reciprocal lattice directions orthogonal to the basis vectors $\\{\\mathbf{a}_1,\\mathbf{a}_2\\}$ of the lattice. The winding numbers are invariants of the gapped lattice; smooth\n",
 "deformations do not change $n_i$ unless the lattice becomes untwisted and the phonon gap closes along a line in the Brillouin zone. We can now define the topological polarization\n",
 "\n",
 "$$\n",
 "\\mathbf{P}_T = \\sum_i n_i \\mathbf{a}_i.\n",
 "$$"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In the figure below, the topological polarization of the deformed Kagome lattice is $\\mathbf{P}_T = \\mathbf{a}_1$ in terms of the primitive vectors $\\mathbf{a}_i$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/kagome.png)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Kane and Lubensky proved that the number of topological zero modes (i.e. modes that arise without adding or removing bonds anywhere in the structure) minus the number of topological states of self stress, $\\nu_\\text{T}$, in any lattice subsystem bounded by $\\cal C$ is given by\n",
 "\n",
 "$$\n",
 "\\nu_\\text{T} = \\oint_{\\cal C} \\frac{d^{d1}S}{V_\\text{cell}} \\mathbf{P}_T \\cdot\\hat{n},\n",
 "$$\n",
 "\n",
 "where $\\hat{n}$ is the inwardpointing normal to the boundary, and $V_\\text{cell}$ is the $d$dimensional volume of the unit cell.\n",
 "\n",
 "Notice that this result applies to a **patch** of the material, unlike the original Maxwell count which is a **global** statement. It can be understood intuitively with the aid of the electrostatic analogy to polarized media. Just as Gauss's law yields the net charge enclosed in a region from the flux of the *electric* polarization through its boundary, the net \n",
 "value of $\\nu_\\text{T}$ in an arbitrary portion of an isostatic lattice is given by the flux of the *topological* polarization through its boundary. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Dislocations and topological zero modes"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Watch now the following video that explains visually how to insert inside a twisted Kagome lattice a topological defect called a dislocation. You encountered dislocations and disclinations in a previous lecture by Taylor Hughes. (Alternatively, an excellent introduction to topological defects is given in chapter nine of the book by Chaikin and Lubensky, *Principles of Condensed Matter Physics*). The video will show you how to localize topological zero modes or states of self stress in the interior of a lattice with defects that act as internal boundary where the gap locally closes. "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"Mrm7JH6LJJI\", src_location=\"10.2dislocations\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The key point in designing the lattice in the video is that the dislocations must not change the local balance between degrees of freedom and constraints. The video shows such a dislocation, obtained by pairing a fivecoordinated plaquette with a sevencoordinated plaquette."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "More details can be found in this paper:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "PreprintReference('1406.3323', show_abstract=False)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Since no lattice point disclinations are used, every lattice point still has exactly four bonds emanating from it (remember the condition for isostaticity from the first control question!). \n",
 "\n",
 "Each dislocation is characterized by a topological charge of its own called the Burgers vector, $\\bf b$, that measures the deficit in *any* circuit surrounding it that would be closed in a perfect lattice. The dipole moment, $\\bf d$, of the \n",
 "five and sevenfold coordinated plaquettes (highlighted in green and orange respectively)\n",
 "is obtained upon rotating $\\bf b$ by $\\pi/2$. It points outward from the added strip of material that terminates at the dislocation, and its length is equal to the width of that strip. Therefore, $\\bf d$ quantifies the orientation and size of the effective ‘‘edge’’ created by the dislocation. The dipole moments of the dislocation on the left in the video (${\\bf d}_l = (2/\\sqrt{3})({\\bf a}_1 {\\bf a}_2/2)$) and on the right (${\\bf d}_r ={\\bf d}_l$) are aligned with and against the\n",
 "lattice polarization, respectively (see also the last figure)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "If you evaluate the flux of the topological polarization, $\\mathbf{P}_T$, through a contour encircling an isolated dislocation using the last equation of the previous unit, you obtain \n",
 "\n",
 "$$\n",
 "\\nu_\\text{T} =\\frac{1}{V_\\text{cell}}\\mathbf{P}_T \\cdot \\mathbf{d},\n",
 "$$\n",
 "\n",
 "where $V_\\text{cell} = \\,\\textbf{a}_1\\,\\times\\,\\textbf{a}_2\\,$ is the unit cell area. The topologically protected modes arise from a delicate interplay between \n",
 "a Berry phase associated with cycles in the Brillouin zone, embedded in ${\\bf P}_T$, and the Berry phase of a topological \n",
 "defect in real space, represented by its Burgers vector (or dipole $\\mathbf{d}$).\n",
 "\n",
 "A similar interplay dictates the existence of localized electronic modes at dislocations in conventional topological insulators. One obtains $\\nu_\\textrm{T}=+1\\,(1)$ for the left (right) dislocation in the deformed Kagome lattice shown in the figure and in the video. The sign of $\\nu_\\text{T}$ distinguishes zero modes ($+$) or states of self stress ($$), while its magnitude gives their numbers. "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (\"Consider the square lattice shown in the following figure, where the primitive vectors $a_i$ \"\n",
 " r\"are of equal length and have an angle $\\pi/2$ between them, \"\n",
 " r\"$P_T=a_1a_2$, $d_L = a_1a_2$, and $d_R=d_L$. \"\n",
 " r\"What is the topological mode count $\\nu_T$ associated with the left and right dislocation respectively?\")\n",
 "\n",
 "answers = [r\"$(1,1)$.\",\n",
 " r\"$(1,1)$.\",\n",
 " r\"$(2,2)$.\",\n",
 " r\"$(2,2)$.\"]\n",
 "\n",
 "explanation = (r\"$P_T$ is parallel to $d_L$ and antiparallel to $d_R$, and they all have length $\\sqrt{2}$. \"\n",
 " r\"The unit cell has unit area, so the formula gives $\\nu_T=(2, 2)$.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=2, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/square.png)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Notice that the zero modes in the Kagome lattice can also be localized at domain walls and the localization length diverges as the gap closes.\n",
 "\n",
 "In the numerical simulation below, you can see explicitly that transforming the unit cell of the deformed Kagome lattice changes the localization properties and ultimately the location of the topological zero mode. In the simulation, we set up a perfectly isostatic lattice with periodic boundary conditions, and two domain walls separating a fixed unit cell on the outside with a unit cell that we modify in the inner region.\n",
 "\n",
 "The unit cell chosen on the outside has topological polarization zero, while the topological polarization on the inside changes as you deform the unit cell by moving the slider. What you see plotted as you move the slider is the eigenvector associated with the lowestenergy eigenstate of the dynamical matrix, represented as a set of displacements on the lattice points (red arrows)."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "from holoviews import Element2D\n",
 "from holoviews.plotting.mpl import ElementPlot\n",
 "\n",
 "class Figure(Element2D):\n",
 " pass\n",
 "\n",
 "class FigurePlot(ElementPlot):\n",
 "\n",
 " def initialize_plot(self, ranges=None):\n",
 " element = self.hmap.last\n",
 " self.handles['fig'] = element.data\n",
 " return self.handles['fig']\n",
 " \n",
 " def _init_axis(self, fig, ax):\n",
 " \"\"\"Override this method to avoid creating a useless figure.\"\"\"\n",
 " return None, None\n",
 "\n",
 " def update_frame(self, key, ranges=None, element=None):\n",
 " element = self._get_frame(key)\n",
 " self.handles['fig'] = element.data\n",
 " return self.handles['fig']\n",
 "\n",
 "holoviews.Store.register({Figure: FigurePlot}, 'matplotlib')\n",
 "\n",
 "def get_figure(x):\n",
 " x1 = (0.1, 0.1, 0.1)\n",
 " x2 = (x, x, x)\n",
 " mesh = topomech.dwallslab(x1, x2)\n",
 " fig = topomech.showlocalizedmode(mesh)\n",
 " plt.close(fig)\n",
 " return fig\n",
 "\n",
 "holoviews.HoloMap({i: Figure(get_figure(i)) for i in np.linspace(.1, .1, 21)})"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "(We thank Jayson Paulose for providing the simulation.)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You can see that the localized mode changes position from left to right between the beginning and the end of the deformation procedure. This is because our deformation has switched the polarization of the unit cell in the inner part of the system. In the middle of the transformation, there is a gap closing in the bulk, i.e. the zero mode extends through the bulk rather than being confined to either domain wall. You can explain this behavior using the analogy of polarization flux we have developed above."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "These examples show how to insert topologically protected mechanical modes anywhere you want in the lattice. In the video and in the numerical simulation, the activation was performed ‘‘by hand’’. However, these soft motions can also be activated by adding motors that can cause some motions that perform a desired task, as is the case in robotic structures."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# States of selfstress and selective buckling"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You may get the impression that only the zero modes are potentially useful and the states of self stress are merely bookeeping devices that do nothing. This is far from truth, as will be illustrated in the next video."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"RbJTxKFqO7I\", src_location=\"10.2buckling\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As you can see, by controlling the position of states of self stress, you can preselect the region of a material that will fail, for example by buckling. All you have to do is to activate the self stress by pushing on the structure in the same way as you had to activate the zero modes to set them in motion.\n",
 "\n",
 "\n",
 "You can find out more details in this paper."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "PreprintReference('1502.03396', show_abstract=False)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In summary, states of self stress and zero modes represent **propensities** that a structure has to respond by mechanical failure (triggered by stress concentrations) or free motion respectively. In topological mechanics we control how these states of motion or stress are positioned in a material by lattice geometry and topology, rather than variations in local properties like elastic moduli or local coordination.\n",
 "\n",
 "As a result these states are designed to be topologically robust under smooth deformations and yet tunable, e.g. you can choose where to position them by adding defects to the lattice and choose their localization properties by playing with the gap. The tunability in response to changes in lattice structure is a crucial feature that lets us exploit the properties of weak topological insulators in a mechanical context. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Conclusions"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"j0X0sVy_6Og\", src_location=\"10.2summary\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Questions about what you just learned? Ask them below!**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Questions\", \"Topological Mechanics\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w10_extensions/mechanics.md b/w10_extensions/mechanics.md
new file mode 100644
index 0000000..cdc9aa2
 /dev/null
+++ b/w10_extensions/mechanics.md
@@ 0,0 +1,396 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+import topomech
+```
+
+# Introduction
+
+Today's lecture will be given by Vincenzo Vitelli, from Leiden University. You will learn about topologically protected mechanical structures, that mirror the properties of topological insulators and quantum Hall systems.
+
+The main concepts and mathematical ideas will be presented in the context of real mechanical prototypes. Hopefully, this approach will stimulate you to cross the line that too often separates theory from applications.
+
+
+```python
+MoocVideo("ieNPei2zMg", src_location="10.2intro")
+```
+
+The materials of this lecture are kindly provided by the Topological Mechanics lab at Leiden University: Vincenzo Vitelli (PI), Bryan Chen, Anne Meeussen, Jayson Paulose, Benny van Zuiden, and Yujie Zhou. They are copyright of their creators, and are available under
+a Creative Commons AttributionShareAlike 4.0
+International License.
+
+
+
+# Kink and antikink
+
+Let's consider the chain you saw in the video:
+
+![](figures/chain_scheme.png)
+
+In the figure, the red dashed lines represent springs and the green arrows the vibrational eigenvectors. The rigid rotors are in black, while the blue dots are point masses of magnitude $m$.
+
+Imagine the system with periodic boundary conditions, that is on a closed ring. As you can see from the figure, in the bulk there are an equal number of degrees of freedom (the rotors) as there are constraints (the springs). This can be seen as a ‘‘charge neutrality‘‘ condition:
+
+![](figures/chaint.png)
+
+If you cut the ring, you remove one constraint, and now there is a zero energy mode in the system. We will discuss later that the direction the rotors lean plays a role of a ‘‘mechanical’’ polarization.
+
+The constraint counting does not tell you where the mode will be located, but if you write the dynamical matrix and find the zero eigenmode, you will learn that the zero mode (whose eigenvectors are represented in the figure as green arrows) is localized at the edge towards which the rotors are pointing. Note that we are tacitly assuming that the vibrational modes of this structure are gapped. Convince yourself that the gap closes if the angle of repose, labeled by $\bar{\theta}$, is equal to zero.
+
+A study of the vibrational modes of this chain was presented in the original paper of Kane and Lubensky, which was mentioned in the introductory video:
+
+
+```python
+PreprintReference('1308.0554', description="", show_abstract=False)
+```
+
+We shall now show that the zero mode localized at the edge is a time snaphot of a nonlinear object, the kink that separates regions of left and right leaning rotors, a bit like a domain wall in an Ising model:
+
+![](figures/kink.png)
+
+To see that, it is easier to consider the constraint equation $l^2_{n,n+1}=\bar{l}^2$ that demands that the length of the springs $l_{n, n+1}$ between any two rotors labeled by $n$ and $n+1$ is not stretched. This is certainly the case for the rigid bar systems shown in the video which correspond to the limit of infinite spring constant. Such systems are called [linkages](http://en.wikipedia.org/wiki/Linkage_%28mechanical%29).
+
+In terms of the parameters defined in the first figure, the constraint equation $l^2_{n,n+1}=\bar{l}^2$ reads
+
+$$
+\require{action}
+\require{color}
+\toggle{
+\cos(\theta _{n} + \theta _{n+1})  \cos(2\bar{\theta}) + \frac{a}{r}(\sin\theta _{n}  \sin\theta _{n+1})=0
+\textit{ (click for explanation)}.}{
+l^2 = r^2 (\cos\theta_1 + \cos\theta_2)^2 + [r(\sin\theta_1  \sin\theta_2) + a]^2 \textit{ (click more)}
+}{
+l^2 = 2 r^2 + a^2 + 2r^2 \cos\theta_1\cos\theta_2  2r^2\sin\theta_1\sin\theta_2 + 2ar(\sin\theta_1  \sin\theta_2) \textit{, and so}
+}{
+(l^2  2r^2  a^2)/2r = \color{red}{r\cos(\theta_1 + \theta_2) + a(\sin\theta_1  \sin\theta_2) = r\cos(2\bar{\theta})}
+}
+\endtoggle
+$$
+
+To take the continuum limit of the above equation, we define a slowlyvarying angular field $\theta (x)$ and subsequently define the field $u(x)=r\sin\theta (x)$, the $x$component of the position of the mass. When $r/a$ is sufficiently small, we obtain
+
+$$
+\frac{a^2}{2}\frac{du}{dx} = u^2\bar{u}^2,
+$$
+
+where $\bar u\equiv r\sin\bar\theta>0$. Besides the uniform left and rightleaning solutions
+$u(x)=\pm \bar u$, this equation admits only one *zeroenergy* solution (for $u<\bar{u}$) given by the kink
+
+$$
+u(x) = \bar u\tanh\left(\frac{xx_0}{w_0}\right),
+$$
+
+where $w_0=a^2/2\bar u$ is the width of the static domain wall that interpolates between leftleaning ($u<0$ as $x\rightarrow\infty$) and rightleaning ($u>0$ as $x\rightarrow+\infty$) states.
+
+
+```python
+question = r"What happens to the kink width $w_0$ when the gap closes?"
+
+answers = ["It goes to zero.",
+ "It does not vary.",
+ "It diverges."]
+
+explanation = (r"We said that a gap equal to zero corresponds to $\bar{\theta}\to0$. "
+ r"This gives $w_0 = a^2/2\bar{u}d \propto 1 / \sin \bar\theta \to \infty$.")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=2, explanation=explanation)
+```
+
+# Nonlinear dynamics
+
+You can explicitly obtain a continuum Lagrangian for the chain which, in the limit $l(x)\approx\bar{l}$ and $\bar{\theta}\ll 1$, reads:
+
+$$
+\mathcal{L}=\int dx \left[\frac{1}{2}M\left(\frac{\partial
+u}{\partial t}\right)^2 
+\frac{1}{2}K\frac{a^4}{4}\left(\frac{\partial u}{\partial
+x}\right)^2 \frac{1}{2}K(\bar u^2u^2)^2  \frac{1}{2} K \frac{a^2}{2}(\bar
+u^2u^2)\frac{\partial u}{\partial x}\right].
+$$
+
+The first term is a linearized kinetic energy, while the second and third terms are the ordinary [$\phi^4$ field theory](http://en.wikipedia.org/wiki/Quartic_interaction) that you might have encountered for instance while studying the Ising model.
+
+The final term linear in $\partial_x u$ is topological in the sense that it integrates to the boundary. It ensures that the static kink has zero energy, since the last three terms in the Lagrangian can be combined into a perfect square, that vanishes for the static kink solution (this is sometimes called a BPS state). The topological boundary term does not affect the equations of motions in the bulk, but it breaks the $\partial_x u \rightarrow \partial_x u$ symmetry of the $\phi^4$ theory. That's why the two edges are not equivalent in terms of initiating the kink motion.
+
+The antikink solution (with left and rightleaning states reversed in space) costs a finite stretching energy. Hence, the antikink is forbidden in the ground state represented by the linkage limit, where $k_e \rightarrow \infty$. The antikink would require an opposite choice of sign in front of the topological boundary term.
+
+As discussed in the introductory video, however, something that behaves like an antikink can be obtained if we stick in the system a rigid bar much longer than the others:
+
+![](figures/antikink.png)
+
+Rather than analyzing mathematically the dynamics of the Lagrangian above, watch the two videos below that
+show the motion in the linkage limit.
+
+
+```python
+MoocVideo("BE4NDhfdpBQ", src_location="10.2topologicallinkagesI")
+```
+
+
+```python
+MoocVideo("mRjpzC4rJx0", src_location="10.2topologicallinkagesII")
+```
+
+If you are curious about the mathematical details and a systematic study of the dynamics in the springsrotors system, you can check out the following paper:
+
+
+```python
+PreprintReference('1404.2263', description="", show_abstract=False)
+```
+
+Note that with different geometrical parameters, the same chain above can realize the [sineGordon Lagrangian](http://en.wikipedia.org/wiki/SineGordon_equation). As before, check out the following movie:
+
+
+```python
+MoocVideo("w2k1Y0WON2E", src_location="10.2topologicallinkagesIII")
+```
+
+The same reference above contains hints on how to build this structure with LEGO  plus of course all the mathematical details!
+
+# Zero modes and states of selfstress
+
+At this point we could expand around the kink solution and find a zero mode localized at its center where the gap closes. Such a zero mode allows the kink to translate as shown in the linkage video.
+
+For now we will simply remark that if one views the orientation along which the rotors lean as a mechanical polarization, then there will be an excess positive ‘‘charge’’ corresponding to a soft mode at the kink center and a negative one at the antikink (see the last two figures). Never mind if this electrostatic analogy is not yet clear; we will return to it and show that the antikink harbours a socalled ** state of self stress**, a dual state to the zero mode.
+
+Before doing that we need to review the Maxwell count which is a **global** relation that stipulates that the number of zero modes $n_\text{m}$, present in an arbitrary mechanical structure, is simply given by the difference between the number of degrees of freedom minus the number of **independent** constraints.
+
+For simplicity, assume that the mechanical structure under examination can be viewed as a network composed of $N_\text{s}$ sites (for instance point masses) connected by $N_\text{b}$ central force bonds (for instance springs or rigid beams) in $d$ dimensions. In this case, the number of degrees of freedom is given by $d N_\text{s}$ and the **total** number of constraints is simply $N_\text{b}$. The states of selfstress are the **redundant** constraints present in the structure, whose number we denote by $n_{ss}$.
+
+The Maxwell criterion then reads
+
+$$
+d N_\text{s}  N_\text{b} = n_{m}  n_{ss}\,.
+$$
+
+Let's apply this equation to the following examples of mechanical structures:
+
+![](figures/modecount.png)
+
+Note that on the left panel there are 4 sites in 2 dimensions, hence 8 degrees of freedom. There are also 4 bonds which leaves 4 soft modes, as prescribed by the Maxwell criterion. You can easily verify that there are 2 trivial translational and 1 rotational zero modes plus 1 nontrivial zero mode, the one indicated by the arrows in the figure.
+
+If you add two extra bonds along the diagonals, as in the right panel, the left hand side of the Maxwell count gives 2. Now, the 3 translations and rotations are still there, the nontrivial zero mode is no longer present but there is one redundant constraint or state of self stress. The difference between the 3 trivial zero modes and the state of self stress gives
+indeed 2, again as expected from the Maxwell criterion. Here we will denote structures for which the left hand side of the Maxwell count is zero as **isostatic**.
+
+(Note that this is an abuse of terminology. Strictly speaking, isostatic
+structures have $dN_{\text{s}}n_{m,\text{triv}}=N_\text{b}$ and $n_{ss}=0$, where
+$n_{m,\text{triv}}$ is the number of translations and rotations in $d$
+dimensions.)
+
+As a simple test of your knowledge, consider the following question whose answer will prove handy later.
+
+
+```python
+question = (r"What is the number of bonds $z_c$ emanating from each node in a $d$dimensional isostatic structure "
+ "where all nodes have the same number of bonds (neglecting boundaries)?")
+
+answers = [r"$z_c=d$.",
+ r"$z_c=2d$.",
+ r"$z_c=d(d1)$.",
+ r"$z_c=d^2$."]
+
+explanation = ("In an isostatic structure we have equal number of degrees of freedom and number of constraints. "
+ "This gives the equation $d N = z N /2$, because each bond is shared by two sites.")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)
+```
+
+Why do we call redundant constraints with the name *states of self stress*?
+
+Consider the example in the right panel of the figure. Note that if you apply a suitable distribution of stresses in the bonds, the structure will remain in static equilibrium. In the example, you can apply a compression to the vertical and horizontal bars, which corresponds to an outgoing force on the masses, and a tension on the diagonal bars such that this outgoing force is canceled. The numbers next to the springs in the figure (positive for the compressions, negative for tensions) give the right ratios such that the forces cancel.
+
+We see therefore that states of self stress are assignments of tensions or compressions to (some of) the bonds that do not result in net forces on the nodes. As such, they are *dual* to the zero energy mechanical modes, which are displacements of some of the sites that do not result in tensions or compressions of the bonds (that's why they cost zero elastic energy).
+
+This relation between states of self stress and zero modes can be made more precise by introducing the rigidity, or compatibility, matrix $R_{ij}$ that describes the small distortions of the mechanical structure captured by linear elastic theories. This $R$ matrix relates the bond extensions $e_i = R_{ij} u_j$ to the site displacements $u_j$.
+
+The zero energy modes are members of the null space of $R_{ij}$, which in an isostatic system are also the (right) eigenvectors of $R_{ij}$ with eigenvalue 0. (Convince yourself that the rigidity matrix is square for an isostatic system.)
+
+Conversely the states of self stress are the zero eigenvectors of the transpose matrix $R^{T}$ that relates the forces on the nodes to the tensions in the bonds. The Maxwell count equation follows from the ranknullity theorem and can be expressed as an index theorem. (We suggest the reader interested in a careful proof and statement of these results to consult [this review](http://arxiv.org/abs/1503.01324).)
+
+Here we merely remark that if one smoothly deforms the network without cutting bonds or adding sites then the left hand side of the Maxwell count does not change. This means that after such a smooth deformation, the difference between the number of zero modes and states of self stress must remain invariant even if $n_m$ and $n_{ss}$ change individually. In this sense the isostatic condition can be viewed as a charge neutrality condition. As we shall see, this electrostatic analogy is far reaching. We will now turn our attention to periodic mechanical structures that are isostatic, hence ‘‘charge neutral’’, but mechanically polarized so that edge modes can appear at the sample boundary like charges in an electrically polarized medium.
+
+# Topological band theory
+
+The first step is to set up a topological band theory of vibrational modes by defining the Fouriertransformed rigidity matrix $R(\mathbf{k})$ whose determinant is complex: $\det R(\mathbf{k}) \equiv \det R(\mathbf{k})e^{i\phi(\mathbf{k})}$. Consider now for simplicity a two dimensional lattice whose phonons are gapped, away from $\mathbf{k}=\mathbf{0}$, like the twisted Kagome lattice shown at the end of the introductory video.
+
+Two winding numbers,
+$n_i=\{n_1,n_2\}$, of $\phi(\mathbf{k})$ can be evaluated using
+
+$$
+n_i= \frac{1}{2\pi}\oint_{C_i}d\mathbf{k}\cdot\nabla_\mathbf{k}
+\phi(\mathbf{k})
+$$
+
+along the two cycles $\{C_1,C_2\}$ of the Brillouin zone corresponding to the reciprocal lattice directions orthogonal to the basis vectors $\{\mathbf{a}_1,\mathbf{a}_2\}$ of the lattice. The winding numbers are invariants of the gapped lattice; smooth
+deformations do not change $n_i$ unless the lattice becomes untwisted and the phonon gap closes along a line in the Brillouin zone. We can now define the topological polarization
+
+$$
+\mathbf{P}_T = \sum_i n_i \mathbf{a}_i.
+$$
+
+In the figure below, the topological polarization of the deformed Kagome lattice is $\mathbf{P}_T = \mathbf{a}_1$ in terms of the primitive vectors $\mathbf{a}_i$.
+
+![](figures/kagome.png)
+
+Kane and Lubensky proved that the number of topological zero modes (i.e. modes that arise without adding or removing bonds anywhere in the structure) minus the number of topological states of self stress, $\nu_\text{T}$, in any lattice subsystem bounded by $\cal C$ is given by
+
+$$
+\nu_\text{T} = \oint_{\cal C} \frac{d^{d1}S}{V_\text{cell}} \mathbf{P}_T \cdot\hat{n},
+$$
+
+where $\hat{n}$ is the inwardpointing normal to the boundary, and $V_\text{cell}$ is the $d$dimensional volume of the unit cell.
+
+Notice that this result applies to a **patch** of the material, unlike the original Maxwell count which is a **global** statement. It can be understood intuitively with the aid of the electrostatic analogy to polarized media. Just as Gauss's law yields the net charge enclosed in a region from the flux of the *electric* polarization through its boundary, the net
+value of $\nu_\text{T}$ in an arbitrary portion of an isostatic lattice is given by the flux of the *topological* polarization through its boundary.
+
+# Dislocations and topological zero modes
+
+Watch now the following video that explains visually how to insert inside a twisted Kagome lattice a topological defect called a dislocation. You encountered dislocations and disclinations in a previous lecture by Taylor Hughes. (Alternatively, an excellent introduction to topological defects is given in chapter nine of the book by Chaikin and Lubensky, *Principles of Condensed Matter Physics*). The video will show you how to localize topological zero modes or states of self stress in the interior of a lattice with defects that act as internal boundary where the gap locally closes.
+
+
+```python
+MoocVideo("Mrm7JH6LJJI", src_location="10.2dislocations")
+```
+
+The key point in designing the lattice in the video is that the dislocations must not change the local balance between degrees of freedom and constraints. The video shows such a dislocation, obtained by pairing a fivecoordinated plaquette with a sevencoordinated plaquette.
+
+More details can be found in this paper:
+
+
+```python
+PreprintReference('1406.3323', show_abstract=False)
+```
+
+Since no lattice point disclinations are used, every lattice point still has exactly four bonds emanating from it (remember the condition for isostaticity from the first control question!).
+
+Each dislocation is characterized by a topological charge of its own called the Burgers vector, $\bf b$, that measures the deficit in *any* circuit surrounding it that would be closed in a perfect lattice. The dipole moment, $\bf d$, of the
+five and sevenfold coordinated plaquettes (highlighted in green and orange respectively)
+is obtained upon rotating $\bf b$ by $\pi/2$. It points outward from the added strip of material that terminates at the dislocation, and its length is equal to the width of that strip. Therefore, $\bf d$ quantifies the orientation and size of the effective ‘‘edge’’ created by the dislocation. The dipole moments of the dislocation on the left in the video (${\bf d}_l = (2/\sqrt{3})({\bf a}_1 {\bf a}_2/2)$) and on the right (${\bf d}_r ={\bf d}_l$) are aligned with and against the
+lattice polarization, respectively (see also the last figure).
+
+If you evaluate the flux of the topological polarization, $\mathbf{P}_T$, through a contour encircling an isolated dislocation using the last equation of the previous unit, you obtain
+
+$$
+\nu_\text{T} =\frac{1}{V_\text{cell}}\mathbf{P}_T \cdot \mathbf{d},
+$$
+
+where $V_\text{cell} = \,\textbf{a}_1\,\times\,\textbf{a}_2\,$ is the unit cell area. The topologically protected modes arise from a delicate interplay between
+a Berry phase associated with cycles in the Brillouin zone, embedded in ${\bf P}_T$, and the Berry phase of a topological
+defect in real space, represented by its Burgers vector (or dipole $\mathbf{d}$).
+
+A similar interplay dictates the existence of localized electronic modes at dislocations in conventional topological insulators. One obtains $\nu_\textrm{T}=+1\,(1)$ for the left (right) dislocation in the deformed Kagome lattice shown in the figure and in the video. The sign of $\nu_\text{T}$ distinguishes zero modes ($+$) or states of self stress ($$), while its magnitude gives their numbers.
+
+
+```python
+question = ("Consider the square lattice shown in the following figure, where the primitive vectors $a_i$ "
+ r"are of equal length and have an angle $\pi/2$ between them, "
+ r"$P_T=a_1a_2$, $d_L = a_1a_2$, and $d_R=d_L$. "
+ r"What is the topological mode count $\nu_T$ associated with the left and right dislocation respectively?")
+
+answers = [r"$(1,1)$.",
+ r"$(1,1)$.",
+ r"$(2,2)$.",
+ r"$(2,2)$."]
+
+explanation = (r"$P_T$ is parallel to $d_L$ and antiparallel to $d_R$, and they all have length $\sqrt{2}$. "
+ r"The unit cell has unit area, so the formula gives $\nu_T=(2, 2)$.")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=2, explanation=explanation)
+```
+
+![](figures/square.png)
+
+Notice that the zero modes in the Kagome lattice can also be localized at domain walls and the localization length diverges as the gap closes.
+
+In the numerical simulation below, you can see explicitly that transforming the unit cell of the deformed Kagome lattice changes the localization properties and ultimately the location of the topological zero mode. In the simulation, we set up a perfectly isostatic lattice with periodic boundary conditions, and two domain walls separating a fixed unit cell on the outside with a unit cell that we modify in the inner region.
+
+The unit cell chosen on the outside has topological polarization zero, while the topological polarization on the inside changes as you deform the unit cell by moving the slider. What you see plotted as you move the slider is the eigenvector associated with the lowestenergy eigenstate of the dynamical matrix, represented as a set of displacements on the lattice points (red arrows).
+
+
+```python
+from holoviews import Element2D
+from holoviews.plotting.mpl import ElementPlot
+
+class Figure(Element2D):
+ pass
+
+class FigurePlot(ElementPlot):
+
+ def initialize_plot(self, ranges=None):
+ element = self.hmap.last
+ self.handles['fig'] = element.data
+ return self.handles['fig']
+
+ def _init_axis(self, fig, ax):
+ """Override this method to avoid creating a useless figure."""
+ return None, None
+
+ def update_frame(self, key, ranges=None, element=None):
+ element = self._get_frame(key)
+ self.handles['fig'] = element.data
+ return self.handles['fig']
+
+holoviews.Store.register({Figure: FigurePlot}, 'matplotlib')
+
+def get_figure(x):
+ x1 = (0.1, 0.1, 0.1)
+ x2 = (x, x, x)
+ mesh = topomech.dwallslab(x1, x2)
+ fig = topomech.showlocalizedmode(mesh)
+ plt.close(fig)
+ return fig
+
+holoviews.HoloMap({i: Figure(get_figure(i)) for i in np.linspace(.1, .1, 21)})
+```
+
+(We thank Jayson Paulose for providing the simulation.)
+
+You can see that the localized mode changes position from left to right between the beginning and the end of the deformation procedure. This is because our deformation has switched the polarization of the unit cell in the inner part of the system. In the middle of the transformation, there is a gap closing in the bulk, i.e. the zero mode extends through the bulk rather than being confined to either domain wall. You can explain this behavior using the analogy of polarization flux we have developed above.
+
+These examples show how to insert topologically protected mechanical modes anywhere you want in the lattice. In the video and in the numerical simulation, the activation was performed ‘‘by hand’’. However, these soft motions can also be activated by adding motors that can cause some motions that perform a desired task, as is the case in robotic structures.
+
+# States of selfstress and selective buckling
+
+You may get the impression that only the zero modes are potentially useful and the states of self stress are merely bookeeping devices that do nothing. This is far from truth, as will be illustrated in the next video.
+
+
+```python
+MoocVideo("RbJTxKFqO7I", src_location="10.2buckling")
+```
+
+As you can see, by controlling the position of states of self stress, you can preselect the region of a material that will fail, for example by buckling. All you have to do is to activate the self stress by pushing on the structure in the same way as you had to activate the zero modes to set them in motion.
+
+
+You can find out more details in this paper.
+
+
+```python
+PreprintReference('1502.03396', show_abstract=False)
+```
+
+In summary, states of self stress and zero modes represent **propensities** that a structure has to respond by mechanical failure (triggered by stress concentrations) or free motion respectively. In topological mechanics we control how these states of motion or stress are positioned in a material by lattice geometry and topology, rather than variations in local properties like elastic moduli or local coordination.
+
+As a result these states are designed to be topologically robust under smooth deformations and yet tunable, e.g. you can choose where to position them by adding defects to the lattice and choose their localization properties by playing with the gap. The tunability in response to changes in lattice structure is a crucial feature that lets us exploit the properties of weak topological insulators in a mechanical context.
+
+# Conclusions
+
+
+```python
+MoocVideo("j0X0sVy_6Og", src_location="10.2summary")
+```
+
+**Questions about what you just learned? Ask them below!**
+
+
+```python
+MoocDiscussion("Questions", "Topological Mechanics")
+```
diff git a/w10_extensions/w10_assignments.ipynb b/w10_extensions/w10_assignments.ipynb
deleted file mode 100644
index b2addf0..0000000
 a/w10_extensions/w10_assignments.ipynb
+++ /dev/null
@@ 1,160 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Simulations"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As usual, start by grabbing the notebooks of this week (`w10_extensions`). They are once again over [here](http://tiny.cc/topocm_smc)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Weyl semimetal with timereversal symmetry.\n",
 "\n",
 "Timereversal symmetry has a very similar effect on Weyl semimetals as it has on gapless superconductors: it keeps the value of the Chern number around the Weyl point the same, and leads to appearance of quadruplets of Weyl points.\n",
 "\n",
 "Your task is to construct a Weyl semimetal with time reversal symmetry. As we discussed, 4 Weyl points are needed.\n",
 "\n",
 "If you don't know where to start, here's a hint: you're not the first one who wants to construct a Weyl semimetal with time reversal, search on arxiv."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Graphene edge states.\n",
 "\n",
 "Graphene, just like $d$wave superconductors has edge states. They only exist when the Dirac points are not located at coinciding momenta parallel to the boundary.\n",
 "\n",
 "Define a graphene ribbon supporting edge states. For that you'll need to figure out which orientation to choose.\n",
 "\n",
 "Then try to add a term to the boundary that breaks the sublattice symmetry and moves the edge states from zero energy. What happens?\n",
 "\n",
 "What if you add the nextnearest neighbor hopping in the bulk. What do you see now?\n",
 "\n",
 "Try to remove the edge states completely by tweaking the sublattice symmetry breaking term at the edge. Did you succeed? How?"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocSelfAssessment()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Now share your results:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion('Labs', 'Extensions')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Review assignment"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "display_html(PreprintReference('1504.01350'))\n",
 "display_html(PreprintReference('1503.06808', description=\"Different mechanical TI\"))\n",
 "display_html(PreprintReference('1309.5846', description=\"Weyl + disorder\"))\n",
 "display_html(PreprintReference('1410.1320', description=\"The best of both worlds\"))\n",
 "display_html(PreprintReference('0909.5680', description=\"A general approach to gapless superconductors.\"))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Bonus: Find your own paper to review!\n",
 "\n",
 "Do you know of another paper that fits into the topics of this week, and you think is good?\n",
 "Then you can get bonus points by reviewing that paper instead!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocPeerAssessment()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Reviews\", \"Extensions\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w10_extensions/w10_assignments.md b/w10_extensions/w10_assignments.md
new file mode 100644
index 0000000..e8ea862
 /dev/null
+++ b/w10_extensions/w10_assignments.md
@@ 0,0 +1,72 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+```
+
+# Simulations
+
+As usual, start by grabbing the notebooks of this week (`w10_extensions`). They are once again over [here](http://tiny.cc/topocm_smc).
+
+## Weyl semimetal with timereversal symmetry.
+
+Timereversal symmetry has a very similar effect on Weyl semimetals as it has on gapless superconductors: it keeps the value of the Chern number around the Weyl point the same, and leads to appearance of quadruplets of Weyl points.
+
+Your task is to construct a Weyl semimetal with time reversal symmetry. As we discussed, 4 Weyl points are needed.
+
+If you don't know where to start, here's a hint: you're not the first one who wants to construct a Weyl semimetal with time reversal, search on arxiv.
+
+## Graphene edge states.
+
+Graphene, just like $d$wave superconductors has edge states. They only exist when the Dirac points are not located at coinciding momenta parallel to the boundary.
+
+Define a graphene ribbon supporting edge states. For that you'll need to figure out which orientation to choose.
+
+Then try to add a term to the boundary that breaks the sublattice symmetry and moves the edge states from zero energy. What happens?
+
+What if you add the nextnearest neighbor hopping in the bulk. What do you see now?
+
+Try to remove the edge states completely by tweaking the sublattice symmetry breaking term at the edge. Did you succeed? How?
+
+
+```python
+MoocSelfAssessment()
+```
+
+**Now share your results:**
+
+
+```python
+MoocDiscussion('Labs', 'Extensions')
+```
+
+# Review assignment
+
+
+```python
+display_html(PreprintReference('1504.01350'))
+display_html(PreprintReference('1503.06808', description="Different mechanical TI"))
+display_html(PreprintReference('1309.5846', description="Weyl + disorder"))
+display_html(PreprintReference('1410.1320', description="The best of both worlds"))
+display_html(PreprintReference('0909.5680', description="A general approach to gapless superconductors."))
+```
+
+### Bonus: Find your own paper to review!
+
+Do you know of another paper that fits into the topics of this week, and you think is good?
+Then you can get bonus points by reviewing that paper instead!
+
+
+```python
+MoocPeerAssessment()
+```
+
+**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**
+
+
+```python
+MoocDiscussion("Reviews", "Extensions")
+```
diff git a/w11_extensions2/cti.ipynb b/w11_extensions2/cti.ipynb
deleted file mode 100644
index 11c4b75..0000000
 a/w11_extensions2/cti.ipynb
+++ /dev/null
@@ 1,374 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "%output size=150"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Introduction"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Crystalline topological insulators are introduced by Liang Fu from MIT."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"N9tUYjXC1s\", src_location=\"11.2intro\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# The role of crystalline symmetries"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In the very beginning of the course, we told you that conservation laws  unitary symmetries of the Hamiltonian  do not lead to striking consequences on topology. They allow to reduce the problem by making the Hamiltonian blockdiagonal, but not much else (see also Shinsei Ryu's introductory video to week eight).\n",
 "\n",
 "At first sight, it may seem that crystalline symmetries: mirror or reflection symmetries, rotation symmetries, and so on  are no exception to the above consideration. They are unitary symmetries whose operators commute with the Hamiltonian. \n",
 "\n",
 "Nevertheless, the role of crystalline symmetries can be quite subtle and it can have important consequences. The reason is that crystalline symmetries are nonlocal. They relate one point in a crystal to another point, possibly a very distant point. This means that in terms of the Bloch Hamiltonian of the crystal, these symmetries mix different values of momentum.\n",
 "\n",
 "Consider for instance a 2D crystal with a reflection symmetry $\\mathcal{R}: (x, y) \\to (x, y)$ around the $x=0$ axis. In momentum space, this symmetry will read $RH(k_x, k_y)R^\\dagger = H(k_x, k_y)$, with a certain unitary operator $R$.\n",
 "\n",
 "Due to this type of constraint on the Brillouin zone, crystalline symmetries can have important consequences on the topological properties of Bloch Hamiltonians.\n",
 "\n",
 "Note however, that sometimes the mere presence of a surface can break a crystalline symmetry of the bulk, so that one should be careful when applying the bulkboundary correspondence to properties based on crystalline symmetries."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (r\"In which case can inversion symmetry protect gapless surface states?\")\n",
 "\n",
 "answers = [\"Never.\",\n",
 " \"In the case of 2D TIs with inversion symmetry.\",\n",
 " \"Only in three dimensions.\",\n",
 " \"Only in combination with particlehole or timereversal symmetry. \"]\n",
 "\n",
 "explanation = \"Any surface would break inversion symmetry of a crystal.\"\n",
 "\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=0, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Reflection symmetry"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The secondsimplest crystalline symmetry (after translation symmetry of course) occurring in many materials is reflection (or mirror) symmetry around one spatial coordinate. For instance, in a 3D crystal, reflection symmetry around the $z$ axis transforms the wavewector as\n",
 "\n",
 "$$\n",
 "(k_x, k_y, k_z)\\rightarrow (k_x, k_y, k_z).\n",
 "$$\n",
 "\n",
 "Reflection symmetry also applies a 180 degree rotation about the $z$axis to the electron spin, so $\\psi_{\\uparrow}\\rightarrow i \\psi_{\\uparrow}$ and $\\psi_{\\downarrow}\\rightarrow i \\psi_{\\downarrow}$, so that the operator squares to $1$ when acting on a spin.\n",
 "\n",
 "Next, if we consider the application of reflection symmetry to either a twodimensional material or a plane in a three dimensional material, then we can choose $k_z=0$ and the reflection symmetry just becomes a regular unitary symmetry i.e., the $C_2$ rotation.\n",
 "\n",
 "In this case, the topological classification follows rather simply from our earlier discussion. $C_2$ is a unitary symmetry with eigenvalues $\\pm i$. We can split our Hamiltonian into the corresponding two sector $H_{\\pm}$ acting on the $C_2=\\pm i$ sectors respectively. Each of the Hamiltonians $H_{\\pm}$ are 2 dimensional Hamiltonians in class A (i.e. with no symmetry) and therefore we can associate a Chern number $N_{\\pm}$ with each of them. \n",
 "\n",
 ">If the Hamiltonian overall is trivial then the total Chern number $N_++N_=0$ so we can classify the 2 dimensional mirror symmetric Hamiltonians by a **mirror Chern number** $N_M=N_+N_$.\n",
 "\n",
 "The mirror Chern number is a topological invariant in the sense that it cannot change without a closure of the bulk gap provided the reflection symmetry remains intact. Moreover, the reflection symmetry together with nontrivial values of the invariant will guarantee edge states.\n",
 "\n",
 "Naturally, the same recipe allows to construct a reflection symmetric topological insulator starting from any other topological invariant, not just a Chern number. We will now try to do this."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (\"How would you attempt to make a model of a topological\"\n",
 " \" insulator with surface states protected by reflection symmetry?\")\n",
 "\n",
 "answers = [\"By using the interface of a material with reflection symmetry, and that of one without it.\",\n",
 " \"By stacking many layers of a lower dimensional topological insulator, \"\n",
 " \"and coupling them in a reflectionsymmetric fashion.\",\n",
 " \"Reflection symmetry alone cannot protect any gapless surface state.\",\n",
 " \"By making a narrow ribbon of the material where only the momentum orthogonal to the reflection axis can be nonzero.\"]\n",
 "\n",
 "explanation = (\"Such a stack would have a reflection symmetry around any of the layers, \"\n",
 " \"which is not broken by the presence of a surface parallel to the stacking direction.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Examples"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's think, what could be the simplest topological system protected by reflection symmetry.\n",
 "\n",
 "We need $d=2$, since the only possible reflection symmetry is broken by the boundary in $d=1$, and we can once again consider coupled Majorana nanowires.\n",
 "\n",
 "We can put two nanowires in a unit cell of the lattice and make their parameters different. In this way, the weak topological invariant is trivial (there is an even number of Majoranas per unit cell).\n",
 "\n",
 "On the other hand, if the hopping between the nanowires is reflection invariant, there will be a reflection symmetry axis passing through each nanowire, like this:"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/reflection.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "If we do everything right (this does require some trial and error in searching for the hopping that actually can couple the two Majoranas from the edge), we get a painfully familiar dispersion:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "\n",
 "def nanowire_chains(length=40, n=2):\n",
 " def onsite(site, p):\n",
 " (x, y) = site.pos\n",
 " return ((2*p.t  p.mu) * pauli.szs0 + p.delta * pauli.sxs0\n",
 " + (y % 2 == 0) * p.B * pauli.s0sz + (y % 2 == 1) * p.B * pauli.s0sy)\n",
 "\n",
 " def hopy(site1, site2, p):\n",
 " return p.t * pauli.szs0 + 0.5 * 1j * p.alpha * pauli.szsx\n",
 "\n",
 " def hopx(site1, site2, p):\n",
 " (x1, y1) = site1.pos\n",
 " (x2, y2) = site2.pos\n",
 " return 1j * (1)**((x1 + x2  1) % 2 == 0) * p.tx * pauli.sysx\n",
 "\n",
 " def shape(pos):\n",
 " (x, y) = pos\n",
 " return (0 <= x < n) and (0 <= y < length)\n",
 "\n",
 " lat = kwant.lattice.square()\n",
 " sym = kwant.TranslationalSymmetry((n, 0))\n",
 " syst = kwant.Builder(sym)\n",
 "\n",
 " syst[lat.shape(shape, (0, 0))] = onsite\n",
 " syst[kwant.HoppingKind((1, 0), lat)] = hopx\n",
 " syst[kwant.HoppingKind((0, 1), lat)] = hopy\n",
 "\n",
 " return syst\n",
 "\n",
 "syst = nanowire_chains()\n",
 "p = SimpleNamespace(t=1.0, tx=0.2, mu=0.0, B=0.4, delta=0.15, alpha=0.3)\n",
 "spectrum(syst, p, k_x=np.linspace(1, 1, 101), ylims=(0.2, 0.2),\n",
 " xticks=3, yticks=3, title='Stacked Majorana wires')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In a similar way, we can also construct a tightbinding model with a mirror Chern number. The only difference with the Majorana wires that we need to worry about is that Chern number is a $\\mathbb{Z}$ invariant instead of $\\mathbb{Z}_2$.\n",
 "\n",
 "This means that the Chern number of the alternating layers has to have opposite signs, or otherwise the surface would just have surface states going in a single direction.\n",
 "\n",
 "Once again, coupling the layers we get a familiar Dirac cone on the surface:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "def stacked_qwz(w=50):\n",
 " def shape(pos):\n",
 " (x, y, z) = pos\n",
 " return (0 <= z < w)\n",
 "\n",
 " def hopx(site1, site2, p):\n",
 " return 0.5j * p.delta * pauli.sx  p.t * pauli.sz\n",
 "\n",
 " def hopy(site1, site2, p):\n",
 " return p.gamma * pauli.sy\n",
 "\n",
 " def hopz(site1, site2, p):\n",
 " (x, y, z) = site1.pos\n",
 " return 0.5j * p.delta * pauli.sy * (1)**(y)  p.t * pauli.sz\n",
 "\n",
 " def onsite(site, p):\n",
 " return pauli.sz * (4 * p.t + p.mu)\n",
 "\n",
 " lat = kwant.lattice.general(np.eye(3))\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry((1, 0, 0), (0, 2, 0)))\n",
 "\n",
 " syst[lat.shape(shape, (0, 0, 0))] = onsite\n",
 " syst[kwant.HoppingKind((1, 0, 0), lat)] = hopx\n",
 " syst[kwant.HoppingKind((0, 1, 0), lat)] = hopy\n",
 " syst[kwant.HoppingKind((0, 0, 1), lat)] = hopz\n",
 "\n",
 " return syst\n",
 "\n",
 "xticks = [(np.pi, r\"$\\pi$\"), (0, r\"$0$\"), (np.pi, r\"$\\pi$\")]\n",
 "yticks = [(0, r\"$0$\"), (np.pi / 2, r\"$\\pi/2$\"), (np.pi, r\"$\\pi$\")]\n",
 "\n",
 "p = SimpleNamespace(t=1.0, delta=1, gamma=.5, mu=0.5)\n",
 "syst = stacked_qwz(30)\n",
 "\n",
 "spectrum(syst, p, num_bands=2, \n",
 " k_x=np.linspace(np.pi, np.pi, 51), \n",
 " k_y=np.linspace(0, np.pi, 51),\n",
 " xticks=xticks, yticks=yticks, title='Stacked Chern insulator')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Again, the dispersion of the edge states looks exactly like what we saw already because the edge state dispersion in any topological insulator is just given by the Dirac equation."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Experimental realization of a 3D crystalline topological insulator"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As mentioned by Liang Fu, three dimensional crystalline topological insulators have been both predicted and also found in nature. The magical material, which is topological turns out to be SnTe, which is actually a \"rocksalt\" structure. We won't bore you with the details of the rocksalt structure, which you can find for yourself on [Wikipedia](https://en.wikipedia.org/wiki/Cubic_crystal_system#Rocksalt_structure). \n",
 "\n",
 "We will just start with the key ingredients for the crystalline topological insulator, namely the symmetries of the crystal. These include, spatial inversion $P$, timereversal symmetry $\\Theta$ and most importantly the three mirror planes in the cubic Brillouin zone. The three mirror planes $\\Gamma L_1 L_2$, $\\Gamma L_3 L_4$ and $\\Gamma L_3 L_1$ in the Brillouin zone are reflectionsymmetric directions that are created out of four timereversal invariant momenta $\\Gamma, L_1, L_2, L_3, L_4$. \n",
 "\n",
 "While the reflection symmetry acts nontrivially on general wavevectors $\\bf k$, the symmetry preserves the mirror planes in the Brillouin zone. Following the idea of dimensional reduction that we used for three dimensional topological insulators (week 6) and also in subsequent weeks, we can define the topological invariant for the crystalline topological insulator in terms of the three mirror Chern numbers for the three mirror planes. For SnTe, all these mirror Chern numbers turn out to be $N_{M}(\\Gamma L_i L_j)=2$. This topological invariant leads to surface Dirac cones on certain surfaces as shown below."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/SnTefig.png)\n",
 "\n",
 "Figure copyright of the Zahid Hasan lab, Princeton, 2015, available under CCBYNCSA 4.0 International license."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "This surface spectrum is very easy to interpret.\n",
 "\n",
 "The crystal surface you see here is perpendicular to two mirror planes projected on $\\bar{\\Gamma}\\bar{X}$ axes. Since the mirror Chern number with respect to each of these planes is $2$, there is a pair of Dirac cones near each $X$point protected by a respective mirror symmetry.\n",
 "\n",
 "The reflection symmetry pins the pairs of Dirac cones to the mirror planes, while time reversal symmetry requires their momenta to be opposite. The 90 degree rotation symmetry interchanges the pairs of cones."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Conclusion"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In short, crystalline topological insulators combine the variety of topological phases with the variety of the crystalline symmetry groups, leading to a multitude of new opportunities."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Questions about what you just learned? Ask them below!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Questions\", \"Crystalline TI\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w11_extensions2/cti.md b/w11_extensions2/cti.md
new file mode 100644
index 0000000..91d440a
 /dev/null
+++ b/w11_extensions2/cti.md
@@ 0,0 +1,213 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+%output size=150
+```
+
+# Introduction
+
+Crystalline topological insulators are introduced by Liang Fu from MIT.
+
+
+```python
+MoocVideo("N9tUYjXC1s", src_location="11.2intro")
+```
+
+# The role of crystalline symmetries
+
+In the very beginning of the course, we told you that conservation laws  unitary symmetries of the Hamiltonian  do not lead to striking consequences on topology. They allow to reduce the problem by making the Hamiltonian blockdiagonal, but not much else (see also Shinsei Ryu's introductory video to week eight).
+
+At first sight, it may seem that crystalline symmetries: mirror or reflection symmetries, rotation symmetries, and so on  are no exception to the above consideration. They are unitary symmetries whose operators commute with the Hamiltonian.
+
+Nevertheless, the role of crystalline symmetries can be quite subtle and it can have important consequences. The reason is that crystalline symmetries are nonlocal. They relate one point in a crystal to another point, possibly a very distant point. This means that in terms of the Bloch Hamiltonian of the crystal, these symmetries mix different values of momentum.
+
+Consider for instance a 2D crystal with a reflection symmetry $\mathcal{R}: (x, y) \to (x, y)$ around the $x=0$ axis. In momentum space, this symmetry will read $RH(k_x, k_y)R^\dagger = H(k_x, k_y)$, with a certain unitary operator $R$.
+
+Due to this type of constraint on the Brillouin zone, crystalline symmetries can have important consequences on the topological properties of Bloch Hamiltonians.
+
+Note however, that sometimes the mere presence of a surface can break a crystalline symmetry of the bulk, so that one should be careful when applying the bulkboundary correspondence to properties based on crystalline symmetries.
+
+
+```python
+question = (r"In which case can inversion symmetry protect gapless surface states?")
+
+answers = ["Never.",
+ "In the case of 2D TIs with inversion symmetry.",
+ "Only in three dimensions.",
+ "Only in combination with particlehole or timereversal symmetry. "]
+
+explanation = "Any surface would break inversion symmetry of a crystal."
+
+MoocMultipleChoiceAssessment(question, answers, correct_answer=0, explanation=explanation)
+```
+
+# Reflection symmetry
+
+The secondsimplest crystalline symmetry (after translation symmetry of course) occurring in many materials is reflection (or mirror) symmetry around one spatial coordinate. For instance, in a 3D crystal, reflection symmetry around the $z$ axis transforms the wavewector as
+
+$$
+(k_x, k_y, k_z)\rightarrow (k_x, k_y, k_z).
+$$
+
+Reflection symmetry also applies a 180 degree rotation about the $z$axis to the electron spin, so $\psi_{\uparrow}\rightarrow i \psi_{\uparrow}$ and $\psi_{\downarrow}\rightarrow i \psi_{\downarrow}$, so that the operator squares to $1$ when acting on a spin.
+
+Next, if we consider the application of reflection symmetry to either a twodimensional material or a plane in a three dimensional material, then we can choose $k_z=0$ and the reflection symmetry just becomes a regular unitary symmetry i.e., the $C_2$ rotation.
+
+In this case, the topological classification follows rather simply from our earlier discussion. $C_2$ is a unitary symmetry with eigenvalues $\pm i$. We can split our Hamiltonian into the corresponding two sector $H_{\pm}$ acting on the $C_2=\pm i$ sectors respectively. Each of the Hamiltonians $H_{\pm}$ are 2 dimensional Hamiltonians in class A (i.e. with no symmetry) and therefore we can associate a Chern number $N_{\pm}$ with each of them.
+
+>If the Hamiltonian overall is trivial then the total Chern number $N_++N_=0$ so we can classify the 2 dimensional mirror symmetric Hamiltonians by a **mirror Chern number** $N_M=N_+N_$.
+
+The mirror Chern number is a topological invariant in the sense that it cannot change without a closure of the bulk gap provided the reflection symmetry remains intact. Moreover, the reflection symmetry together with nontrivial values of the invariant will guarantee edge states.
+
+Naturally, the same recipe allows to construct a reflection symmetric topological insulator starting from any other topological invariant, not just a Chern number. We will now try to do this.
+
+
+```python
+question = ("How would you attempt to make a model of a topological"
+ " insulator with surface states protected by reflection symmetry?")
+
+answers = ["By using the interface of a material with reflection symmetry, and that of one without it.",
+ "By stacking many layers of a lower dimensional topological insulator, "
+ "and coupling them in a reflectionsymmetric fashion.",
+ "Reflection symmetry alone cannot protect any gapless surface state.",
+ "By making a narrow ribbon of the material where only the momentum orthogonal to the reflection axis can be nonzero."]
+
+explanation = ("Such a stack would have a reflection symmetry around any of the layers, "
+ "which is not broken by the presence of a surface parallel to the stacking direction.")
+
+MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)
+```
+
+# Examples
+
+Let's think, what could be the simplest topological system protected by reflection symmetry.
+
+We need $d=2$, since the only possible reflection symmetry is broken by the boundary in $d=1$, and we can once again consider coupled Majorana nanowires.
+
+We can put two nanowires in a unit cell of the lattice and make their parameters different. In this way, the weak topological invariant is trivial (there is an even number of Majoranas per unit cell).
+
+On the other hand, if the hopping between the nanowires is reflection invariant, there will be a reflection symmetry axis passing through each nanowire, like this:
+
+![](figures/reflection.svg)
+
+If we do everything right (this does require some trial and error in searching for the hopping that actually can couple the two Majoranas from the edge), we get a painfully familiar dispersion:
+
+
+```python
+
+def nanowire_chains(length=40, n=2):
+ def onsite(site, p):
+ (x, y) = site.pos
+ return ((2*p.t  p.mu) * pauli.szs0 + p.delta * pauli.sxs0
+ + (y % 2 == 0) * p.B * pauli.s0sz + (y % 2 == 1) * p.B * pauli.s0sy)
+
+ def hopy(site1, site2, p):
+ return p.t * pauli.szs0 + 0.5 * 1j * p.alpha * pauli.szsx
+
+ def hopx(site1, site2, p):
+ (x1, y1) = site1.pos
+ (x2, y2) = site2.pos
+ return 1j * (1)**((x1 + x2  1) % 2 == 0) * p.tx * pauli.sysx
+
+ def shape(pos):
+ (x, y) = pos
+ return (0 <= x < n) and (0 <= y < length)
+
+ lat = kwant.lattice.square()
+ sym = kwant.TranslationalSymmetry((n, 0))
+ syst = kwant.Builder(sym)
+
+ syst[lat.shape(shape, (0, 0))] = onsite
+ syst[kwant.HoppingKind((1, 0), lat)] = hopx
+ syst[kwant.HoppingKind((0, 1), lat)] = hopy
+
+ return syst
+
+syst = nanowire_chains()
+p = SimpleNamespace(t=1.0, tx=0.2, mu=0.0, B=0.4, delta=0.15, alpha=0.3)
+spectrum(syst, p, k_x=np.linspace(1, 1, 101), ylims=(0.2, 0.2),
+ xticks=3, yticks=3, title='Stacked Majorana wires')
+```
+
+In a similar way, we can also construct a tightbinding model with a mirror Chern number. The only difference with the Majorana wires that we need to worry about is that Chern number is a $\mathbb{Z}$ invariant instead of $\mathbb{Z}_2$.
+
+This means that the Chern number of the alternating layers has to have opposite signs, or otherwise the surface would just have surface states going in a single direction.
+
+Once again, coupling the layers we get a familiar Dirac cone on the surface:
+
+
+```python
+def stacked_qwz(w=50):
+ def shape(pos):
+ (x, y, z) = pos
+ return (0 <= z < w)
+
+ def hopx(site1, site2, p):
+ return 0.5j * p.delta * pauli.sx  p.t * pauli.sz
+
+ def hopy(site1, site2, p):
+ return p.gamma * pauli.sy
+
+ def hopz(site1, site2, p):
+ (x, y, z) = site1.pos
+ return 0.5j * p.delta * pauli.sy * (1)**(y)  p.t * pauli.sz
+
+ def onsite(site, p):
+ return pauli.sz * (4 * p.t + p.mu)
+
+ lat = kwant.lattice.general(np.eye(3))
+ syst = kwant.Builder(kwant.TranslationalSymmetry((1, 0, 0), (0, 2, 0)))
+
+ syst[lat.shape(shape, (0, 0, 0))] = onsite
+ syst[kwant.HoppingKind((1, 0, 0), lat)] = hopx
+ syst[kwant.HoppingKind((0, 1, 0), lat)] = hopy
+ syst[kwant.HoppingKind((0, 0, 1), lat)] = hopz
+
+ return syst
+
+xticks = [(np.pi, r"$\pi$"), (0, r"$0$"), (np.pi, r"$\pi$")]
+yticks = [(0, r"$0$"), (np.pi / 2, r"$\pi/2$"), (np.pi, r"$\pi$")]
+
+p = SimpleNamespace(t=1.0, delta=1, gamma=.5, mu=0.5)
+syst = stacked_qwz(30)
+
+spectrum(syst, p, num_bands=2,
+ k_x=np.linspace(np.pi, np.pi, 51),
+ k_y=np.linspace(0, np.pi, 51),
+ xticks=xticks, yticks=yticks, title='Stacked Chern insulator')
+```
+
+Again, the dispersion of the edge states looks exactly like what we saw already because the edge state dispersion in any topological insulator is just given by the Dirac equation.
+
+# Experimental realization of a 3D crystalline topological insulator
+
+As mentioned by Liang Fu, three dimensional crystalline topological insulators have been both predicted and also found in nature. The magical material, which is topological turns out to be SnTe, which is actually a "rocksalt" structure. We won't bore you with the details of the rocksalt structure, which you can find for yourself on [Wikipedia](https://en.wikipedia.org/wiki/Cubic_crystal_system#Rocksalt_structure).
+
+We will just start with the key ingredients for the crystalline topological insulator, namely the symmetries of the crystal. These include, spatial inversion $P$, timereversal symmetry $\Theta$ and most importantly the three mirror planes in the cubic Brillouin zone. The three mirror planes $\Gamma L_1 L_2$, $\Gamma L_3 L_4$ and $\Gamma L_3 L_1$ in the Brillouin zone are reflectionsymmetric directions that are created out of four timereversal invariant momenta $\Gamma, L_1, L_2, L_3, L_4$.
+
+While the reflection symmetry acts nontrivially on general wavevectors $\bf k$, the symmetry preserves the mirror planes in the Brillouin zone. Following the idea of dimensional reduction that we used for three dimensional topological insulators (week 6) and also in subsequent weeks, we can define the topological invariant for the crystalline topological insulator in terms of the three mirror Chern numbers for the three mirror planes. For SnTe, all these mirror Chern numbers turn out to be $N_{M}(\Gamma L_i L_j)=2$. This topological invariant leads to surface Dirac cones on certain surfaces as shown below.
+
+![](figures/SnTefig.png)
+
+Figure copyright of the Zahid Hasan lab, Princeton, 2015, available under CCBYNCSA 4.0 International license.
+
+This surface spectrum is very easy to interpret.
+
+The crystal surface you see here is perpendicular to two mirror planes projected on $\bar{\Gamma}\bar{X}$ axes. Since the mirror Chern number with respect to each of these planes is $2$, there is a pair of Dirac cones near each $X$point protected by a respective mirror symmetry.
+
+The reflection symmetry pins the pairs of Dirac cones to the mirror planes, while time reversal symmetry requires their momenta to be opposite. The 90 degree rotation symmetry interchanges the pairs of cones.
+
+# Conclusion
+
+In short, crystalline topological insulators combine the variety of topological phases with the variety of the crystalline symmetry groups, leading to a multitude of new opportunities.
+
+Questions about what you just learned? Ask them below!
+
+
+```python
+MoocDiscussion("Questions", "Crystalline TI")
+```
diff git a/w11_extensions2/floquet.ipynb b/w11_extensions2/floquet.ipynb
deleted file mode 100644
index 4929047..0000000
 a/w11_extensions2/floquet.ipynb
+++ /dev/null
@@ 1,630 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "\n",
 "from scipy import linalg as la\n",
 "from functools import reduce\n",
 "\n",
 "pi_ticks = [(np.pi, r\"$\\pi$\"),\n",
 " (np.pi / 2, r\"$\\pi/2$\"),\n",
 " (0, r\"$0$\"),\n",
 " (np.pi / 2, r\"$\\pi/2$\"),\n",
 " (np.pi, r\"$\\pi$\")]\n",
 "\n",
 "\n",
 "def checkerboard(W=None):\n",
 " lat = kwant.lattice.general([[2, 0], [1, 1]], [(0, 0), (1, 0)])\n",
 " a, b = lat.sublattices\n",
 " if W:\n",
 " def lead_shape(pos):\n",
 " (x, y) = pos\n",
 " return (0 <= y < W and 0 <= x < W)\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry((1, 1)))\n",
 " syst[a.shape(lead_shape, (0, 0))] = 0\n",
 " syst[b.shape(lead_shape, (1, 0))] = 0\n",
 " else:\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs)) \n",
 " syst[lat.shape(lambda pos: True, (0, 0))] = 0\n",
 " syst[kwant.HoppingKind((0, 0), b, a)] = lambda s1, s2, p: p.t1\n",
 " syst[kwant.HoppingKind((1, 1), b, a)] = lambda s1, s2, p: p.t2\n",
 " syst[kwant.HoppingKind((1, 0), a, b)] = lambda s1, s2, p: p.t3\n",
 " syst[kwant.HoppingKind((0, 1), a, b)] = lambda s1, s2, p: p.t4\n",
 " return syst\n",
 "\n",
 "\n",
 "def evolution_operator(hamiltonians, T):\n",
 " n = len(hamiltonians)\n",
 " exps = [la.expm(1j * h * T / n) for h in hamiltonians]\n",
 " return reduce(np.dot, exps)\n",
 "\n",
 "\n",
 "def get_h_k(lead, p):\n",
 " bands = kwant.physics.Bands(lead, args=[p])\n",
 " h, t = bands.ham, bands.hop\n",
 " return lambda k: h + t * np.exp(1j * k) + t.T.conj() * np.exp(1j * k)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Introduction"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Today's topic, Floquet topological insulators, is introduced by Mark Rudner from the Niels Bohr Institute at Copenhagen."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"1peVp_IZ7Ts\", src_location=\"11.1intro\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Periodically driven systems"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We will now learn about a new generalization of topology, namely how it applies to the quantum evolution of systems with a timedependent Hamiltonian. As you may recall, we've already encountered time dependence, back when we considered quantum pumps. However, back then we assumed that the time evolution was very slow, such that the system stayed in the ground state at all times, i.e. it was adiabatic. Can we relax the adiabaticity constraint? Can we find an analog of topology in systems that are driven so fast that energy isn't conserved?\n",
 "\n",
 "For the same reasons as before, we'll consider periodic driving\n",
 "\n",
 "$$\n",
 "H(t + T) = H(t).\n",
 "$$\n",
 "\n",
 "Once again, this is necessary because otherwise, any system can be continuously deformed into any other, and there is no way to define a gap."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Before we get to topology, let's refresh our knowledge of timedependent systems.\n",
 "\n",
 "The Schrödinger equation is:\n",
 "\n",
 "$$\n",
 "i\\frac{d \\psi}{dt} = H(t) \\psi.\n",
 "$$\n",
 "\n",
 "It is a linear equation, so we can write its solution as\n",
 "\n",
 "$$\n",
 "\\psi(t_2) = U(t_2, t_1) \\psi(t_1),\n",
 "$$\n",
 "\n",
 "where $U$ is a unitary *time evolution operator*. It solves the same Schrödinger equation as the wave function, and is equal to the identity matrix at the initial time. It is commonly written as\n",
 "\n",
 "$$\n",
 "U(t_2, t_1) = \\mathcal{T} \\exp\\,\\left[i\\int_{t_1}^{t_2} H(t) dt\\right],\n",
 "$$\n",
 "\n",
 "where $\\mathcal{T}$ represents timeordering (not timereversal symmetry). The timeordering is just a shorthand notation for the need to solve the full differential equation, and it is necessary if the Hamiltonians evaluated at different times in the integral do not commute.\n",
 "\n",
 "The time evolution operator satisfies a very simple multiplication rule:\n",
 "\n",
 "$$\n",
 "U(t_3, t_1) = U(t_3, t_2) U(t_2, t_1),\n",
 "$$\n",
 "\n",
 "which just says that time evolution from $t_1$ to $t_3$ is a product of time evolutions from $t_1$ to $t_2$ and then from $t_2$ to $t_3$. Of course an immediate consequence of this is the equality $U(t_2, t_1)^\\dagger = U(t_2, t_1)^{1} = U(t_1, t_2)$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Floquet theory"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The central object for the study of driven systems is the evolution operator over one period of the driving,\n",
 "\n",
 "$$\n",
 "U(t + T, t) \\equiv U,\n",
 "$$\n",
 "\n",
 "which is called the Floquet time evolution operator. It is important because it allows us to identify the wave functions that are the same if an integer number of drive periods passes. These are the stationary states of a driven system, and they are given by the eigenvalues of the Floquet operator:\n",
 "\n",
 "$$\n",
 "U \\psi = e^{i \\alpha} \\psi.\n",
 "$$\n",
 "\n",
 "The stationary states are very similar to the eigenstates of a stationary Hamiltonian, except that they are only stationary if we look at fixed times $t + nT$. That's why the Floquet time evolution operator is also called a stroboscopic time evolution operator.\n",
 "\n",
 "We can very easily construct a Hermitian matrix from $U$, the **Floquet Hamiltonian**:\n",
 "\n",
 "$$\n",
 "H_\\textrm{eff} = i T^{1} \\,\\ln U.\n",
 "$$\n",
 "\n",
 "Its eigenvalues $\\varepsilon = \\alpha / T$ are called quasienergies, and they always belong to the interval $\\pi < \\alpha \\leq \\pi$.\n",
 "\n",
 "If the system is translationally invariant, we can study the effective band structure of $H_\\textrm{eff}(\\mathbf{k})$, find an energy in which the bulk Hamiltonian has no states, and study the topological properties of such a Hamiltonian: most of the things we already know still apply.\n",
 "\n",
 "Of course, selecting a single quasienergy as the Fermi level is arbitrary, since the equilibrium state of driven systems doesn't correspond to a Fermi distribution of filling factors, but at least it seems close enough for us to try to apply topological ideas."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (\"But wait, we arbitrarily chose the starting point $t$ in time for calculating the \"\n",
 " \"Floquet operator. What if we chose a different one?\")\n",
 "\n",
 "answers = [\"The starting time is just an extra parameter of our system, and topology depends on it.\",\n",
 " \"It doesn't matter, the wave function evolution within one period \"\n",
 " \"can be neglected, since we are interested in many periods.\",\n",
 " \"There's only one correct starting point in time.\",\n",
 " \"It doesn't matter since the quasienergies are independent of the starting point.\"]\n",
 "\n",
 "explanation = (\"Choosing a different starting point applies a unitary transformation \"\n",
 " \"to the Floquet evolution operator, and so it keeps the quasienergies the same.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=3, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Driven Majorana wire"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let us start by considering something we know very well, namely the superconducting Majorana nanowire model from week 2. This model has three important parameters which determine whether the wire is in the topological Majorana phase or not: the chemical potential $\\mu$, the superconducting gap $\\Delta$, and the magnetic field $B$. The topological phase with unpaired Majorana modes at zero energy is realized for $B > \\sqrt{\\mu^2 + \\Delta^2}$.\n",
 "\n",
 "Now, imagine that we can periodically drive some of these parameters. For instance, consider the simple example when\n",
 "\n",
 "$$\n",
 "\\mu = \\left\\{\n",
 "\\begin{matrix}\n",
 "\\mu_1 \\quad \\text{for } 0 < t < T/2 \\\\\n",
 "\\mu_2 \\quad \\text{for } T/2 < t < T\n",
 "\\end{matrix}\\right.\n",
 "$$\n",
 "\n",
 "Then, the integral to find the time evolution operator is easy to evaluate, and we simply have\n",
 "\n",
 "$$\n",
 "U = \\exp(i T H_2 / 2) \\exp(i T H_1 / 2)\n",
 "$$\n",
 "\n",
 "with $H_1$ and $H_2$ the nanowire Hamiltonians with chemical potential $\\mu_1$ and $\\mu_2$. A peculiar property of driven systems is that as the period becomes large, the band structure 'folds': if the driving is very weak, and the original Hamiltonian has energy $E$, the Floquet Hamiltonian has a much smaller quasienergy $(E\\bmod 2\\pi /T)$. This means that even when $H_1$ and $H_2$ correspond to trivial systems, we can still obtain nontrivial topology if we make the period large enough, as you can see for yourself:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "%%opts Path {+axiswise}\n",
 "\n",
 "def nanowire_chain(L=None):\n",
 " lat = kwant.lattice.chain()\n",
 "\n",
 " def onsite(site, p):\n",
 " return (2*p.t  p.mu) * pauli.szs0 + p.B * pauli.s0sz + p.delta * pauli.sxs0\n",
 "\n",
 " def hopping(site1, site2, p):\n",
 " return p.t * pauli.szs0 + 0.5 * 1j * p.alpha * pauli.szsx\n",
 "\n",
 " if L:\n",
 " syst = kwant.Builder()\n",
 " else:\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry((1,)))\n",
 " L = 1\n",
 "\n",
 " syst[(lat(x) for x in range(L))] = onsite\n",
 " syst[kwant.HoppingKind((1,), lat)] = hopping\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def calculate_finite_spectrum(periods, hamiltonians):\n",
 " energies = []\n",
 " for T in periods:\n",
 " U = evolution_operator(hamiltonians, T)\n",
 " phases = np.angle(la.eigvals(U))\n",
 " phases = np.sort(np.abs(phases))\n",
 " ev = np.sort([(1)**n * val for n, val in enumerate(phases)])\n",
 " energies.append(ev)\n",
 " return np.array(energies).real\n",
 "\n",
 "\n",
 "def calculate_bands(momenta, hamiltonians_k, T):\n",
 " energies = []\n",
 " for k in momenta:\n",
 " hamiltonians = [h_k(k) for h_k in hamiltonians_k]\n",
 " U = evolution_operator(hamiltonians, T)\n",
 " phases = np.angle(la.eigvals(U))\n",
 " phases = np.sort(np.abs(phases))\n",
 " ev = np.sort([(1)**n * val for n, val in enumerate(phases)])\n",
 " energies.append(ev)\n",
 " return np.array(energies).real\n",
 "\n",
 "\n",
 "J = 2.0\n",
 "p1 = SimpleNamespace(t=J/2, mu=1*J, B=J, delta=2*J, alpha=J)\n",
 "p2 = SimpleNamespace(t=J/2, mu=3*J, B=J, delta=2*J, alpha=J)\n",
 "\n",
 "syst = nanowire_chain(L=20).finalized()\n",
 "H1 = syst.hamiltonian_submatrix(args=[p1])\n",
 "H2 = syst.hamiltonian_submatrix(args=[p2])\n",
 "\n",
 "lead = kwant.wraparound.wraparound(nanowire_chain(L=None)).finalized()\n",
 "h1_k = lambda kx: lead.hamiltonian_submatrix(args=[p1, kx])\n",
 "h2_k = lambda kx: lead.hamiltonian_submatrix(args=[p2, kx])\n",
 "\n",
 "periods = np.linspace(0.2 / J, 1.6 / J, 100)\n",
 "momenta = np.linspace(np.pi, np.pi)\n",
 "\n",
 "energies = calculate_finite_spectrum(periods, [H1, H2])\n",
 "spectrum = np.array([calculate_bands(momenta, [h1_k, h2_k], T) for T in periods])\n",
 "\n",
 "\n",
 "def plot(n):\n",
 " T = J * periods[n]\n",
 "\n",
 " plot_1 = holoviews.Path((J * periods, energies),\n",
 " kdims=[r'Driving period $(JT)$', r'Quasienergy $(ET)$'],\n",
 " label='Finite system')(plot={'xticks': 5, 'yticks': pi_ticks})\n",
 "\n",
 " VLine = holoviews.VLine(T)(style={'color': 'b', 'linestyle': ''})\n",
 "\n",
 " plot_2 = holoviews.Path((momenta, spectrum[n]),\n",
 " kdims=['$k$', '$E_kT$'],\n",
 " label='Floquet bands')(plot={'xticks': pi_ticks,\n",
 " 'yticks': pi_ticks,\n",
 " 'aspect': 'equal'})\n",
 " return plot_1 * VLine + plot_2\n",
 "\n",
 "holoviews.HoloMap({n: plot(n) for n in np.arange(0, 100, 10)}, kdims=['n']).collate()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "On the left you see the Floquet spectrum of a finite system as a function of the driving period measured in units of the hopping strength, and on the right you see the Floquet dispersion in momentum space."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We now witness a cool phenomenon: just like in the undriven case, the particlehole symmetry maps $E \\rightarrow E$, but now this means that not only $E = 0$ is special, but also $E = \\pi$!\n",
 "\n",
 "In other words, this means that there are two relevant gaps in the effective Floquet BdG Hamiltonian $H_\\textrm{eff}$. Now, by using the same argument as we used for the regular Majoranas, we learn that if we have an isolated Floquet state with a quasienergy $\\epsilon=0$ or $\\epsilon=\\pi$, it cannot be removed unless the gap surrounding it closes.\n",
 "\n",
 "In other words:\n",
 "\n",
 "> A Floquet superconductor has two types of Majorana bound states: the usual ones with quasienergy $\\epsilon=0$, and the $\\pi$Majoranas that are as far from zero energy as possible."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "So the calculation above reveals two interesting features of driven systems: the first is that the periodic driving can turn a trivial system into a nontrivial system with topologically protected Floquet states. The second is that topology is richer than in the nondriven system: for instance, here the richness comes from the fact that the topologically protected states may occur at two different points in the spectrum."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Now try to answer the following question: what's the topological invariant of this system? How do we tell whether normal Majoranas are present, and whether $\\pi$Majoranas are present? (We'll return to this question in the end of the lecture.)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# A Floquet Chern insulator"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As a second example of a driven system that shows something that the undriven system doesn't, let's consider the following toy model.\n",
 "\n",
 "We take a square lattice with timedependent nearest neighbor hopping $t$. Next, let's engineer a timeevolution of the hopping between sites such that during a period $T$ hoppings are turned on in an alternate fashion, as in the following figure:"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/time_steps.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Each step lasts one quarter of a period.\n",
 "\n",
 "Now let's tune the period such that the probability for an electron to hop along a hopping is one at the end of each quarter period [$t = (\\pi / 2) / (T / 4)$]. Over the complete period the trajectories of electrons will look like this:"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/floquet_bulk.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Every electron makes a closed loop and ends up back at its origin. After every single period the system is back to its initial state. In other words, the Floquet operator is $U=1$, and $H_\\textrm{eff}=0$.\n",
 "\n",
 "Let's have a look at the dispersion, and also see what happens as we tune the driving period:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "%%output size=200\n",
 "def plot_dispersion_2D(T):\n",
 " syst = checkerboard()\n",
 " B = np.array(syst.symmetry.periods).T\n",
 " A = B @ np.linalg.inv(B.T @ B)\n",
 " syst = kwant.wraparound.wraparound(syst).finalized()\n",
 " \n",
 " def hamiltonian_k(par):\n",
 " def f(kx, ky):\n",
 " kx, ky = np.linalg.lstsq(A, [kx, ky])[0]\n",
 " ham = syst.hamiltonian_submatrix(args=[par, kx, ky])\n",
 " return ham\n",
 " return f\n",
 "\n",
 " hamiltonians_k = [\n",
 " hamiltonian_k(SimpleNamespace(t1=1, t2=0, t3=0, t4=0)), \n",
 " hamiltonian_k(SimpleNamespace(t1=0, t2=1, t3=0, t4=0)), \n",
 " hamiltonian_k(SimpleNamespace(t1=0, t2=0, t3=1, t4=0)), \n",
 " hamiltonian_k(SimpleNamespace(t1=0, t2=0, t3=0, t4=1))]\n",
 "\n",
 " def get_energies(kx, ky):\n",
 " hamiltonians = [h_k(kx, ky) for h_k in hamiltonians_k]\n",
 " U = evolution_operator(hamiltonians, T)\n",
 " ev = np.sort(np.angle(la.eigvals(U)))\n",
 " return ev\n",
 "\n",
 " K = np.linspace(np.pi, np.pi, 50)\n",
 " energies = np.array([[get_energies(kx, ky) for kx in K] for ky in K])\n",
 "\n",
 " ticks = {'xticks': pi_ticks[::2], 'yticks': pi_ticks[::2], 'zticks': 3}\n",
 " kwargs = {'extents': (np.pi, np.pi, 4, np.pi, np.pi, 4),\n",
 " 'kdims': ['$k_x$', '$k_y$'],\n",
 " 'vdims': ['$E$']}\n",
 "\n",
 " title = r'$T = {:.2} \\pi$'.format(T / np.pi)\n",
 " \n",
 " return (holoviews.Surface(energies[:, :, 0], **kwargs)(plot=ticks) *\n",
 " holoviews.Surface(energies[:, :, 1], **kwargs)(plot=ticks)).relabel(title)\n",
 "\n",
 "Ts = np.linspace(1, 3, 11, endpoint=True)\n",
 "holoviews.HoloMap({T: plot_dispersion_2D(np.pi*T) for T in Ts}, kdims=['$T$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Now, there isn't a Hamiltonian which is more topologically trivial than the zero Hamiltonian. We may be tempted to conclude that our system is trivial and, by bulkboundary correspondence, has no edge states.\n",
 "\n",
 "That's something we can also very easily verify by computing the dispersion of a finite size ribbon:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "%%output size=200\n",
 "%%opts Path {+axiswise}\n",
 "\n",
 "def calculate_bands(momenta, hamiltonians_k, T):\n",
 " energies = []\n",
 " for k in momenta:\n",
 " hamiltonians = [h_k(k) for h_k in hamiltonians_k]\n",
 " U = evolution_operator(hamiltonians, T)\n",
 " energies.append(np.sort(np.angle(la.eigvals(U))))\n",
 " return np.array(energies).real\n",
 "\n",
 "\n",
 "ribbon_lead = checkerboard(10).finalized()\n",
 "\n",
 "hamiltonians_k = [\n",
 " get_h_k(ribbon_lead, SimpleNamespace(t1=1, t2=0, t3=0, t4=0)),\n",
 " get_h_k(ribbon_lead, SimpleNamespace(t1=0, t2=1, t3=0, t4=0)),\n",
 " get_h_k(ribbon_lead, SimpleNamespace(t1=0, t2=0, t3=1, t4=0)),\n",
 " get_h_k(ribbon_lead, SimpleNamespace(t1=0, t2=0, t3=0, t4=1))]\n",
 "\n",
 "periods = np.linspace(0, 4*np.pi, 11)\n",
 "momenta = np.linspace(np.pi, np.pi)\n",
 "spectrum = np.array([calculate_bands(momenta, hamiltonians_k, T) for T in periods])\n",
 "\n",
 "def plot(n):\n",
 " T = periods[n]\n",
 " title = r'spectrum: $T={:.2} \\pi$'.format(T/np.pi)\n",
 " return holoviews.Path((momenta, spectrum[n]),\n",
 " label=title,\n",
 " kdims=['$k$', '$E_kT$'])(plot={'xticks': pi_ticks,\n",
 " 'yticks': pi_ticks,\n",
 " 'aspect': 3})\n",
 "\n",
 "holoviews.HoloMap({n: plot(n) for n in range(11)}, kdims=['n'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We see something very different from our expectations. All the bulk states are indeed at $E=0$, but there are two branches of dispersion that are clearly propagating. These can only belong to the edges, and since the two edges look identical, these two modes have to belong to the opposite edges. We seem to conclude that even though the bulk Hamiltonian is trivial, the edges carry chiral edge states, as if there was a finite Chern number.\n",
 "\n",
 "When the driving period is tuned to ensure the absence of bulk dispersion, we can also understand why the edge states appear. If we select a state that starts on the edge, and follow it for one period, we find that there are modes that never leave the edge, since one of the hoppings in the vertical direction is absent."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/trajectories.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "So what is happening with bulkedge correspondence?"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (\"How can you change the chirality of the edge states in the figure above?\")\n",
 "\n",
 "answers = [\"By changing the driving period.\",\n",
 " \"By reversing the driving protocol sequence.\",\n",
 " \"By changing the sign of the nearest neighbor hopping.\",\n",
 " \"By making the electrons start from the black sublattice.\"]\n",
 "\n",
 "explanation = (\"Reversing the driving protocol is the same as applying timereversal symmetry, \"\n",
 " \"so it will reverse the direction of the chiral edge modes\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Bulkedge correspondence in driven systems"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The two examples we've studied reveal an imporant feature of topological Floquet insulators. It seems that knowing the bulk Floquet Hamiltonian is sufficient to calculate the topological invariant, by just applying the known expression to the Floquet Hamiltonian. However, that's not enough.\n",
 "\n",
 "In rough terms, the reason for this insufficiency is due to Floquet topological insulators missing a topologically trivial state which can be taken as a reference. With any regular 2D Hamiltonian, we know that if we take $E \\rightarrow \\infty$, we will get a trivial system with the Chern number zero. In a Floquet system, the only thing that lowering the energy tells us is that the Chern number is periodic in quasienergy, like any other observable property.\n",
 "\n",
 "What do we need to know to derive the full topological invariant from the bulk properties? The answer is that we need the complete evolution operator for all moments in time, or in other words the full dependence $H(t)$. The actual calculation of the topological invariant is technically involved, and falls beyond what we can cover in this course. Moreover, to the best of our knowledge, the full classification of Floquet topological insulators is not yet accomplished."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Conclusions"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"DbyqIczcR9c\", src_location=\"11.1summary\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Questions about what you just learned? Ask them below!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Questions\", \"Floquet\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w11_extensions2/floquet.md b/w11_extensions2/floquet.md
new file mode 100644
index 0000000..0d81b98
 /dev/null
+++ b/w11_extensions2/floquet.md
@@ 0,0 +1,417 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+
+from scipy import linalg as la
+from functools import reduce
+
+pi_ticks = [(np.pi, r"$\pi$"),
+ (np.pi / 2, r"$\pi/2$"),
+ (0, r"$0$"),
+ (np.pi / 2, r"$\pi/2$"),
+ (np.pi, r"$\pi$")]
+
+
+def checkerboard(W=None):
+ lat = kwant.lattice.general([[2, 0], [1, 1]], [(0, 0), (1, 0)])
+ a, b = lat.sublattices
+ if W:
+ def lead_shape(pos):
+ (x, y) = pos
+ return (0 <= y < W and 0 <= x < W)
+ syst = kwant.Builder(kwant.TranslationalSymmetry((1, 1)))
+ syst[a.shape(lead_shape, (0, 0))] = 0
+ syst[b.shape(lead_shape, (1, 0))] = 0
+ else:
+ syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))
+ syst[lat.shape(lambda pos: True, (0, 0))] = 0
+ syst[kwant.HoppingKind((0, 0), b, a)] = lambda s1, s2, p: p.t1
+ syst[kwant.HoppingKind((1, 1), b, a)] = lambda s1, s2, p: p.t2
+ syst[kwant.HoppingKind((1, 0), a, b)] = lambda s1, s2, p: p.t3
+ syst[kwant.HoppingKind((0, 1), a, b)] = lambda s1, s2, p: p.t4
+ return syst
+
+
+def evolution_operator(hamiltonians, T):
+ n = len(hamiltonians)
+ exps = [la.expm(1j * h * T / n) for h in hamiltonians]
+ return reduce(np.dot, exps)
+
+
+def get_h_k(lead, p):
+ bands = kwant.physics.Bands(lead, args=[p])
+ h, t = bands.ham, bands.hop
+ return lambda k: h + t * np.exp(1j * k) + t.T.conj() * np.exp(1j * k)
+```
+
+# Introduction
+
+Today's topic, Floquet topological insulators, is introduced by Mark Rudner from the Niels Bohr Institute at Copenhagen.
+
+
+```python
+MoocVideo("1peVp_IZ7Ts", src_location="11.1intro")
+```
+
+# Periodically driven systems
+
+We will now learn about a new generalization of topology, namely how it applies to the quantum evolution of systems with a timedependent Hamiltonian. As you may recall, we've already encountered time dependence, back when we considered quantum pumps. However, back then we assumed that the time evolution was very slow, such that the system stayed in the ground state at all times, i.e. it was adiabatic. Can we relax the adiabaticity constraint? Can we find an analog of topology in systems that are driven so fast that energy isn't conserved?
+
+For the same reasons as before, we'll consider periodic driving
+
+$$
+H(t + T) = H(t).
+$$
+
+Once again, this is necessary because otherwise, any system can be continuously deformed into any other, and there is no way to define a gap.
+
+Before we get to topology, let's refresh our knowledge of timedependent systems.
+
+The Schrödinger equation is:
+
+$$
+i\frac{d \psi}{dt} = H(t) \psi.
+$$
+
+It is a linear equation, so we can write its solution as
+
+$$
+\psi(t_2) = U(t_2, t_1) \psi(t_1),
+$$
+
+where $U$ is a unitary *time evolution operator*. It solves the same Schrödinger equation as the wave function, and is equal to the identity matrix at the initial time. It is commonly written as
+
+$$
+U(t_2, t_1) = \mathcal{T} \exp\,\left[i\int_{t_1}^{t_2} H(t) dt\right],
+$$
+
+where $\mathcal{T}$ represents timeordering (not timereversal symmetry). The timeordering is just a shorthand notation for the need to solve the full differential equation, and it is necessary if the Hamiltonians evaluated at different times in the integral do not commute.
+
+The time evolution operator satisfies a very simple multiplication rule:
+
+$$
+U(t_3, t_1) = U(t_3, t_2) U(t_2, t_1),
+$$
+
+which just says that time evolution from $t_1$ to $t_3$ is a product of time evolutions from $t_1$ to $t_2$ and then from $t_2$ to $t_3$. Of course an immediate consequence of this is the equality $U(t_2, t_1)^\dagger = U(t_2, t_1)^{1} = U(t_1, t_2)$.
+
+## Floquet theory
+
+The central object for the study of driven systems is the evolution operator over one period of the driving,
+
+$$
+U(t + T, t) \equiv U,
+$$
+
+which is called the Floquet time evolution operator. It is important because it allows us to identify the wave functions that are the same if an integer number of drive periods passes. These are the stationary states of a driven system, and they are given by the eigenvalues of the Floquet operator:
+
+$$
+U \psi = e^{i \alpha} \psi.
+$$
+
+The stationary states are very similar to the eigenstates of a stationary Hamiltonian, except that they are only stationary if we look at fixed times $t + nT$. That's why the Floquet time evolution operator is also called a stroboscopic time evolution operator.
+
+We can very easily construct a Hermitian matrix from $U$, the **Floquet Hamiltonian**:
+
+$$
+H_\textrm{eff} = i T^{1} \,\ln U.
+$$
+
+Its eigenvalues $\varepsilon = \alpha / T$ are called quasienergies, and they always belong to the interval $\pi < \alpha \leq \pi$.
+
+If the system is translationally invariant, we can study the effective band structure of $H_\textrm{eff}(\mathbf{k})$, find an energy in which the bulk Hamiltonian has no states, and study the topological properties of such a Hamiltonian: most of the things we already know still apply.
+
+Of course, selecting a single quasienergy as the Fermi level is arbitrary, since the equilibrium state of driven systems doesn't correspond to a Fermi distribution of filling factors, but at least it seems close enough for us to try to apply topological ideas.
+
+
+```python
+question = ("But wait, we arbitrarily chose the starting point $t$ in time for calculating the "
+ "Floquet operator. What if we chose a different one?")
+
+answers = ["The starting time is just an extra parameter of our system, and topology depends on it.",
+ "It doesn't matter, the wave function evolution within one period "
+ "can be neglected, since we are interested in many periods.",
+ "There's only one correct starting point in time.",
+ "It doesn't matter since the quasienergies are independent of the starting point."]
+
+explanation = ("Choosing a different starting point applies a unitary transformation "
+ "to the Floquet evolution operator, and so it keeps the quasienergies the same.")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=3, explanation=explanation)
+```
+
+# Driven Majorana wire
+
+Let us start by considering something we know very well, namely the superconducting Majorana nanowire model from week 2. This model has three important parameters which determine whether the wire is in the topological Majorana phase or not: the chemical potential $\mu$, the superconducting gap $\Delta$, and the magnetic field $B$. The topological phase with unpaired Majorana modes at zero energy is realized for $B > \sqrt{\mu^2 + \Delta^2}$.
+
+Now, imagine that we can periodically drive some of these parameters. For instance, consider the simple example when
+
+$$
+\mu = \left\{
+\begin{matrix}
+\mu_1 \quad \text{for } 0 < t < T/2 \\
+\mu_2 \quad \text{for } T/2 < t < T
+\end{matrix}\right.
+$$
+
+Then, the integral to find the time evolution operator is easy to evaluate, and we simply have
+
+$$
+U = \exp(i T H_2 / 2) \exp(i T H_1 / 2)
+$$
+
+with $H_1$ and $H_2$ the nanowire Hamiltonians with chemical potential $\mu_1$ and $\mu_2$. A peculiar property of driven systems is that as the period becomes large, the band structure 'folds': if the driving is very weak, and the original Hamiltonian has energy $E$, the Floquet Hamiltonian has a much smaller quasienergy $(E\bmod 2\pi /T)$. This means that even when $H_1$ and $H_2$ correspond to trivial systems, we can still obtain nontrivial topology if we make the period large enough, as you can see for yourself:
+
+
+```python
+%%opts Path {+axiswise}
+
+def nanowire_chain(L=None):
+ lat = kwant.lattice.chain()
+
+ def onsite(site, p):
+ return (2*p.t  p.mu) * pauli.szs0 + p.B * pauli.s0sz + p.delta * pauli.sxs0
+
+ def hopping(site1, site2, p):
+ return p.t * pauli.szs0 + 0.5 * 1j * p.alpha * pauli.szsx
+
+ if L:
+ syst = kwant.Builder()
+ else:
+ syst = kwant.Builder(kwant.TranslationalSymmetry((1,)))
+ L = 1
+
+ syst[(lat(x) for x in range(L))] = onsite
+ syst[kwant.HoppingKind((1,), lat)] = hopping
+
+ return syst
+
+
+def calculate_finite_spectrum(periods, hamiltonians):
+ energies = []
+ for T in periods:
+ U = evolution_operator(hamiltonians, T)
+ phases = np.angle(la.eigvals(U))
+ phases = np.sort(np.abs(phases))
+ ev = np.sort([(1)**n * val for n, val in enumerate(phases)])
+ energies.append(ev)
+ return np.array(energies).real
+
+
+def calculate_bands(momenta, hamiltonians_k, T):
+ energies = []
+ for k in momenta:
+ hamiltonians = [h_k(k) for h_k in hamiltonians_k]
+ U = evolution_operator(hamiltonians, T)
+ phases = np.angle(la.eigvals(U))
+ phases = np.sort(np.abs(phases))
+ ev = np.sort([(1)**n * val for n, val in enumerate(phases)])
+ energies.append(ev)
+ return np.array(energies).real
+
+
+J = 2.0
+p1 = SimpleNamespace(t=J/2, mu=1*J, B=J, delta=2*J, alpha=J)
+p2 = SimpleNamespace(t=J/2, mu=3*J, B=J, delta=2*J, alpha=J)
+
+syst = nanowire_chain(L=20).finalized()
+H1 = syst.hamiltonian_submatrix(args=[p1])
+H2 = syst.hamiltonian_submatrix(args=[p2])
+
+lead = kwant.wraparound.wraparound(nanowire_chain(L=None)).finalized()
+h1_k = lambda kx: lead.hamiltonian_submatrix(args=[p1, kx])
+h2_k = lambda kx: lead.hamiltonian_submatrix(args=[p2, kx])
+
+periods = np.linspace(0.2 / J, 1.6 / J, 100)
+momenta = np.linspace(np.pi, np.pi)
+
+energies = calculate_finite_spectrum(periods, [H1, H2])
+spectrum = np.array([calculate_bands(momenta, [h1_k, h2_k], T) for T in periods])
+
+
+def plot(n):
+ T = J * periods[n]
+
+ plot_1 = holoviews.Path((J * periods, energies),
+ kdims=[r'Driving period $(JT)$', r'Quasienergy $(ET)$'],
+ label='Finite system')(plot={'xticks': 5, 'yticks': pi_ticks})
+
+ VLine = holoviews.VLine(T)(style={'color': 'b', 'linestyle': ''})
+
+ plot_2 = holoviews.Path((momenta, spectrum[n]),
+ kdims=['$k$', '$E_kT$'],
+ label='Floquet bands')(plot={'xticks': pi_ticks,
+ 'yticks': pi_ticks,
+ 'aspect': 'equal'})
+ return plot_1 * VLine + plot_2
+
+holoviews.HoloMap({n: plot(n) for n in np.arange(0, 100, 10)}, kdims=['n']).collate()
+```
+
+On the left you see the Floquet spectrum of a finite system as a function of the driving period measured in units of the hopping strength, and on the right you see the Floquet dispersion in momentum space.
+
+We now witness a cool phenomenon: just like in the undriven case, the particlehole symmetry maps $E \rightarrow E$, but now this means that not only $E = 0$ is special, but also $E = \pi$!
+
+In other words, this means that there are two relevant gaps in the effective Floquet BdG Hamiltonian $H_\textrm{eff}$. Now, by using the same argument as we used for the regular Majoranas, we learn that if we have an isolated Floquet state with a quasienergy $\epsilon=0$ or $\epsilon=\pi$, it cannot be removed unless the gap surrounding it closes.
+
+In other words:
+
+> A Floquet superconductor has two types of Majorana bound states: the usual ones with quasienergy $\epsilon=0$, and the $\pi$Majoranas that are as far from zero energy as possible.
+
+So the calculation above reveals two interesting features of driven systems: the first is that the periodic driving can turn a trivial system into a nontrivial system with topologically protected Floquet states. The second is that topology is richer than in the nondriven system: for instance, here the richness comes from the fact that the topologically protected states may occur at two different points in the spectrum.
+
+Now try to answer the following question: what's the topological invariant of this system? How do we tell whether normal Majoranas are present, and whether $\pi$Majoranas are present? (We'll return to this question in the end of the lecture.)
+
+# A Floquet Chern insulator
+
+As a second example of a driven system that shows something that the undriven system doesn't, let's consider the following toy model.
+
+We take a square lattice with timedependent nearest neighbor hopping $t$. Next, let's engineer a timeevolution of the hopping between sites such that during a period $T$ hoppings are turned on in an alternate fashion, as in the following figure:
+
+![](figures/time_steps.svg)
+
+Each step lasts one quarter of a period.
+
+Now let's tune the period such that the probability for an electron to hop along a hopping is one at the end of each quarter period [$t = (\pi / 2) / (T / 4)$]. Over the complete period the trajectories of electrons will look like this:
+
+![](figures/floquet_bulk.svg)
+
+Every electron makes a closed loop and ends up back at its origin. After every single period the system is back to its initial state. In other words, the Floquet operator is $U=1$, and $H_\textrm{eff}=0$.
+
+Let's have a look at the dispersion, and also see what happens as we tune the driving period:
+
+
+```python
+%%output size=200
+def plot_dispersion_2D(T):
+ syst = checkerboard()
+ B = np.array(syst.symmetry.periods).T
+ A = B @ np.linalg.inv(B.T @ B)
+ syst = kwant.wraparound.wraparound(syst).finalized()
+
+ def hamiltonian_k(par):
+ def f(kx, ky):
+ kx, ky = np.linalg.lstsq(A, [kx, ky])[0]
+ ham = syst.hamiltonian_submatrix(args=[par, kx, ky])
+ return ham
+ return f
+
+ hamiltonians_k = [
+ hamiltonian_k(SimpleNamespace(t1=1, t2=0, t3=0, t4=0)),
+ hamiltonian_k(SimpleNamespace(t1=0, t2=1, t3=0, t4=0)),
+ hamiltonian_k(SimpleNamespace(t1=0, t2=0, t3=1, t4=0)),
+ hamiltonian_k(SimpleNamespace(t1=0, t2=0, t3=0, t4=1))]
+
+ def get_energies(kx, ky):
+ hamiltonians = [h_k(kx, ky) for h_k in hamiltonians_k]
+ U = evolution_operator(hamiltonians, T)
+ ev = np.sort(np.angle(la.eigvals(U)))
+ return ev
+
+ K = np.linspace(np.pi, np.pi, 50)
+ energies = np.array([[get_energies(kx, ky) for kx in K] for ky in K])
+
+ ticks = {'xticks': pi_ticks[::2], 'yticks': pi_ticks[::2], 'zticks': 3}
+ kwargs = {'extents': (np.pi, np.pi, 4, np.pi, np.pi, 4),
+ 'kdims': ['$k_x$', '$k_y$'],
+ 'vdims': ['$E$']}
+
+ title = r'$T = {:.2} \pi$'.format(T / np.pi)
+
+ return (holoviews.Surface(energies[:, :, 0], **kwargs)(plot=ticks) *
+ holoviews.Surface(energies[:, :, 1], **kwargs)(plot=ticks)).relabel(title)
+
+Ts = np.linspace(1, 3, 11, endpoint=True)
+holoviews.HoloMap({T: plot_dispersion_2D(np.pi*T) for T in Ts}, kdims=['$T$'])
+```
+
+Now, there isn't a Hamiltonian which is more topologically trivial than the zero Hamiltonian. We may be tempted to conclude that our system is trivial and, by bulkboundary correspondence, has no edge states.
+
+That's something we can also very easily verify by computing the dispersion of a finite size ribbon:
+
+
+```python
+%%output size=200
+%%opts Path {+axiswise}
+
+def calculate_bands(momenta, hamiltonians_k, T):
+ energies = []
+ for k in momenta:
+ hamiltonians = [h_k(k) for h_k in hamiltonians_k]
+ U = evolution_operator(hamiltonians, T)
+ energies.append(np.sort(np.angle(la.eigvals(U))))
+ return np.array(energies).real
+
+
+ribbon_lead = checkerboard(10).finalized()
+
+hamiltonians_k = [
+ get_h_k(ribbon_lead, SimpleNamespace(t1=1, t2=0, t3=0, t4=0)),
+ get_h_k(ribbon_lead, SimpleNamespace(t1=0, t2=1, t3=0, t4=0)),
+ get_h_k(ribbon_lead, SimpleNamespace(t1=0, t2=0, t3=1, t4=0)),
+ get_h_k(ribbon_lead, SimpleNamespace(t1=0, t2=0, t3=0, t4=1))]
+
+periods = np.linspace(0, 4*np.pi, 11)
+momenta = np.linspace(np.pi, np.pi)
+spectrum = np.array([calculate_bands(momenta, hamiltonians_k, T) for T in periods])
+
+def plot(n):
+ T = periods[n]
+ title = r'spectrum: $T={:.2} \pi$'.format(T/np.pi)
+ return holoviews.Path((momenta, spectrum[n]),
+ label=title,
+ kdims=['$k$', '$E_kT$'])(plot={'xticks': pi_ticks,
+ 'yticks': pi_ticks,
+ 'aspect': 3})
+
+holoviews.HoloMap({n: plot(n) for n in range(11)}, kdims=['n'])
+```
+
+We see something very different from our expectations. All the bulk states are indeed at $E=0$, but there are two branches of dispersion that are clearly propagating. These can only belong to the edges, and since the two edges look identical, these two modes have to belong to the opposite edges. We seem to conclude that even though the bulk Hamiltonian is trivial, the edges carry chiral edge states, as if there was a finite Chern number.
+
+When the driving period is tuned to ensure the absence of bulk dispersion, we can also understand why the edge states appear. If we select a state that starts on the edge, and follow it for one period, we find that there are modes that never leave the edge, since one of the hoppings in the vertical direction is absent.
+
+![](figures/trajectories.svg)
+
+So what is happening with bulkedge correspondence?
+
+
+```python
+question = ("How can you change the chirality of the edge states in the figure above?")
+
+answers = ["By changing the driving period.",
+ "By reversing the driving protocol sequence.",
+ "By changing the sign of the nearest neighbor hopping.",
+ "By making the electrons start from the black sublattice."]
+
+explanation = ("Reversing the driving protocol is the same as applying timereversal symmetry, "
+ "so it will reverse the direction of the chiral edge modes")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)
+```
+
+# Bulkedge correspondence in driven systems
+
+The two examples we've studied reveal an imporant feature of topological Floquet insulators. It seems that knowing the bulk Floquet Hamiltonian is sufficient to calculate the topological invariant, by just applying the known expression to the Floquet Hamiltonian. However, that's not enough.
+
+In rough terms, the reason for this insufficiency is due to Floquet topological insulators missing a topologically trivial state which can be taken as a reference. With any regular 2D Hamiltonian, we know that if we take $E \rightarrow \infty$, we will get a trivial system with the Chern number zero. In a Floquet system, the only thing that lowering the energy tells us is that the Chern number is periodic in quasienergy, like any other observable property.
+
+What do we need to know to derive the full topological invariant from the bulk properties? The answer is that we need the complete evolution operator for all moments in time, or in other words the full dependence $H(t)$. The actual calculation of the topological invariant is technically involved, and falls beyond what we can cover in this course. Moreover, to the best of our knowledge, the full classification of Floquet topological insulators is not yet accomplished.
+
+# Conclusions
+
+
+```python
+MoocVideo("DbyqIczcR9c", src_location="11.1summary")
+```
+
+Questions about what you just learned? Ask them below!
+
+
+```python
+MoocDiscussion("Questions", "Floquet")
+```
diff git a/w11_extensions2/w11_assignments.ipynb b/w11_extensions2/w11_assignments.ipynb
deleted file mode 100644
index d0be10f..0000000
 a/w11_extensions2/w11_assignments.ipynb
+++ /dev/null
@@ 1,142 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Simulation: powers combined"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As usual, start by grabbing the notebooks of this week (`w11_extensions2`). They are once again over [here](http://tiny.cc/topocm_smc)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Are you tired yet of all the different kinds of topology? If no, this assignment is for you :)\n",
 "\n",
 "By now you should have a feel for how to make new topological phases. Your task now is to combine the two systems you've learned about and to create a Floquet crystalline topological insulator. If you want even more challenge, create also a gapless Floquet topological material.\n",
 "\n",
 "Take care however: if you take a topologically nontrivial system and just apply rapid driving, you'll still get a topological one. This cheating way is prohibited: at any moment during the driving cycle the Hamiltonian of your system should remain gapped."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocSelfAssessment()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Now share your results:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion('Labs', 'Floquet and crystalline')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Review assignment"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "display_html(PreprintReference('1010.6126', description=\"Computes topological edge states from floquet Hamiltonian.\"))\n",
 "display_html(PreprintReference('1212.3324', description=\"Points out and explains why the floquet Hamiltonian in momentum space \"\n",
 " \"does not capture the presence of floquet edge states.\"))\n",
 "display_html(PreprintReference('1202.1003', description=\"Theoretical prediction of topological crystalline insulator\"))\n",
 "display_html(PreprintReference('1212.6191', description=\"Are topological crystalline surface states stable against \"\n",
 " \"disorder?\"))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Bonus: Find your own paper to review!\n",
 "\n",
 "Do you know of another paper that fits into the topics of this week, and you think is good?\n",
 "Then you can get bonus points by reviewing that paper instead!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocPeerAssessment()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Reviews\", \"Floquet and crystalline\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w11_extensions2/w11_assignments.md b/w11_extensions2/w11_assignments.md
new file mode 100644
index 0000000..239d6f4
 /dev/null
+++ b/w11_extensions2/w11_assignments.md
@@ 0,0 +1,59 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+```
+
+# Simulation: powers combined
+
+As usual, start by grabbing the notebooks of this week (`w11_extensions2`). They are once again over [here](http://tiny.cc/topocm_smc).
+
+Are you tired yet of all the different kinds of topology? If no, this assignment is for you :)
+
+By now you should have a feel for how to make new topological phases. Your task now is to combine the two systems you've learned about and to create a Floquet crystalline topological insulator. If you want even more challenge, create also a gapless Floquet topological material.
+
+Take care however: if you take a topologically nontrivial system and just apply rapid driving, you'll still get a topological one. This cheating way is prohibited: at any moment during the driving cycle the Hamiltonian of your system should remain gapped.
+
+
+```python
+MoocSelfAssessment()
+```
+
+**Now share your results:**
+
+
+```python
+MoocDiscussion('Labs', 'Floquet and crystalline')
+```
+
+# Review assignment
+
+
+```python
+display_html(PreprintReference('1010.6126', description="Computes topological edge states from floquet Hamiltonian."))
+display_html(PreprintReference('1212.3324', description="Points out and explains why the floquet Hamiltonian in momentum space "
+ "does not capture the presence of floquet edge states."))
+display_html(PreprintReference('1202.1003', description="Theoretical prediction of topological crystalline insulator"))
+display_html(PreprintReference('1212.6191', description="Are topological crystalline surface states stable against "
+ "disorder?"))
+```
+
+### Bonus: Find your own paper to review!
+
+Do you know of another paper that fits into the topics of this week, and you think is good?
+Then you can get bonus points by reviewing that paper instead!
+
+
+```python
+MoocPeerAssessment()
+```
+
+**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**
+
+
+```python
+MoocDiscussion("Reviews", "Floquet and crystalline")
+```
diff git a/w12_manybody/fqhe.ipynb b/w12_manybody/fqhe.ipynb
deleted file mode 100644
index ab92b15..0000000
 a/w12_manybody/fqhe.ipynb
+++ /dev/null
@@ 1,315 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Introduction"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "This topic is introduced by Sankar Das Sarma from the university of Maryland."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"4gSJSo3olfg\", src_location=\"12.1intro\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Interacting systems"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "One obvious thing that we completely ignored throughout the course is the effects of interactions on topology. It is of course possible to generalize all the symmetry classes that we have studied to manybody Hamiltonians, but what happens to the classification of the topological phases?\n",
 "\n",
 "The first statement we should make here is that our work so far wasn't wasted: most of the usual topological insulators turn out to tolerate interactions as long as the interactions do not spontaneously break the symmetry, or close the bulk gap.\n",
 "There are interesting cases where the classification collapses. For example, the 1D BDI chain with Majorana fermions on one of the two sublattice degrees of freedom allows a $\\mathbb{Z}_8$ classification with interactions instead of $\\mathbb{Z}$. The reason for this is that the 8Majorana interaction term doesn't break the symmetries anymore.\n",
 "\n",
 "However this is relatively minor compared to the real can of worms that the interactions open: the amount of possibilities for the interacting phases is much larger. To begin with, we'll discuss the oldest known example of a strongly interacting topological phase, the fractional quantum Hall effect. Note that it only covers a single dimension ($D=2$), and a single symmetry class (no symmetry at all). Yet, classifying all such states turns out to be a very hard task."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Fractional charge and statistics in the fractional quantized Hall effect"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "If you followed what we learned about the integer quantum Hall effect, you'll remember that we used the pumping argument to establish that the Hall conductance in an incompressible liquid is quantized in integers. You might now wonder if the experimental evidence for the fractional quantum Hall effect completely invalidates this argument in some way. The key step in the argument was to realize that the pumped charge that results from the insertion of one flux quantum $\\Phi_0$ into a Corbino geometry is \n",
 "\n",
 "$$\n",
 "Q_{pump}=\\sigma_{xy}\\Phi_0\\equiv \\nu e,\n",
 "$$\n",
 "\n",
 "where $\\nu=\\sigma_{xy}/G_0$ is the Hall conductance in dimensionless units. For the noninteracting system that we studied in the quantum Hall effect, we assumed that only an integer number of electrons could be transferred between the edges  so $\\nu$ had to be an integer. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The real reason that the charge transferred had to be an integer multiple of the electron charge was that the Hamiltonian for the electrons was identical between flux $\\Phi=0$ and flux $\\Phi=\\Phi_0$. Since the system is incompressible, it is reasonable to assume that all excitations in the system are local. Usually we expect different excited states to differ by rearranging electrons. Within this framework, such excitations can differ by integer multiples of electronic charge.\n",
 "\n",
 "The existence of fractional values of $\\nu$ implies that the edge can have local excitations that differ by a fractional electron charge. In principle, the inner edge of the Corbino geometry can be shrunk to a point, and if we do this, we're forced to conclude that the system can now host excitations that have fractional charge."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The fractional charged excitations are local particles just like the electrons themselves. So we can ask about the statistics under exchange of two such particles. On performing such an exchange, the total manybody wave function of the system returns to itself, but\n",
 "the wave function can pick up a Berry phase. For fermions this phase is $\\pi$ and for Bosons it is zero. Instead of computing the phase directly, let us consider doing a double exchange, which is topologically equivalent to taking a particle around another one and computing the phase for that. \n",
 "\n",
 "![](figures/exchange.svg)\n",
 "\n",
 "Let us first assume that one of the particles was created by a flux quantum. Since the flux quantum created this particle adiabatically by a pumping process, locality dictates that the particle going around the flux quantum + particle cannot know about the existence of the other particle. Thus the phase from going around a particle together with its flux quantum must vanish. On the other hand, the particle picks up a phase of $2\\pi \\nu$ from just going around the flux quantum. Thus double exchange of a pair of particles leads to a Berry phase of $2\\pi\\nu$. This is another strange property of excitations in the FQH state! They must obey different statistics than both fermions and bosons, and are thus referred to as anyons. Therefore the exchange phase of anyons in the simple FQH states is given by \n",
 "\n",
 "$$\n",
 "\\phi_{exch}=\\pi\\nu.\n",
 "$$"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"The Laughlin argument was used to prove that the Hall effect must be quantized in integers. What is the key assumption\"\n",
 " \"that must be dropped in order to understand the fractional quantum Hall effect?\")\n",
 "\n",
 "answers = [\"Allow electrons to have fractional statistics.\",\n",
 " \"Allow quasiparticles with fractional charge.\",\n",
 " \"Require that the system forms an incompressible fluid.\",\n",
 " \"Allow electrons to have fractional charge.\",\n",
 " \"Allow quasiparticles to have fractional statistics.\"]\n",
 "\n",
 "explanation = (\"The key assumption in the Laughlin argument for the integer case was that the charge that was added by pumping could\"\n",
 " \"only be an integer multiple of an electronic charge.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Topological degeneracy"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Knowing that the system supports particles with nontrivial braiding statistics, we can derive its next important property, the topological degeneracy of the ground state.\n",
 "\n",
 "To do this, we turn around the argument for computing the statistics of particles and consider the statistics of fluxes. A particle going around a flux acquires a phase of $2\\pi\\nu$. As noted in the last unit, the combination of a particle and flux does not have any nontrivial exchange statistics. So replacing the particle by another flux will lead to a phase of $2\\pi \\nu$. Therefore the exchange phase of fluxes gives a phase of $\\pi\\nu$, just like the exchange of particles."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let us now put the FQH system on a torus. A natural operation on the torus is to create a flux antiflux pair, move them around a cycle of the torus and annihilate them at the end. This operation inserts a flux into one of the two nontrivial cycles of the torus. Let's label this operation $T_{1,2}$ for each of the cycles of the torus:\n",
 "\n",
 "![](figures/torus.svg)\n",
 "\n",
 "The last physical step to deriving the degeneracy is to ask what is the commutator $T_1^{1}T_2^{1}T_1 T_2$. This operator describes first moving a vortex around the red contour, then moving the vortex around the blue contour, moving the vortex back around the red contour, and finally undoing the motion of the vortex along the blue contour.\n",
 "No matter which path we choose for this operation, we will need to take one vortex all the way around the other one. According to the braiding rule we get:\n",
 "\n",
 "$$\n",
 "T_1^{1}T_2^{1}T_1 T_2 =e^{i2\\pi \\nu}.\n",
 "$$\n",
 "\n",
 "Now all we need to do is an exercise in elementary quantum mechanics. First of all, both $T_{1,2}$ commute with the Hamiltonian. Let's take $\\Psi\\rangle$ as a simultaneous ground state of the Hamiltonian and eigenstate of $T_1$. If in addition $e^{i\\alpha}\\Psi\\rangle=T_2\\Psi\\rangle$, then $T_1$ and $T_2$ would commute. Since we know this isn't the case, $T_2\\Psi\\rangle$ must be a ground state of the Hamiltonian which is not the same as $\\Psi\\rangle$.\n",
 "\n",
 "> We conclude that fractional quantum Hall phases have ground state degeneracy on the torus.\n",
 "\n",
 "We have seen an example of ground state degeneracy in Majorana wires, where the degeneracy of the zero modes could not be lifted by any local perturbation. The difference between the Majorana case and fractional quantum Hall is that in the latter we don't rely on the presence of defects, and the degeneracy is a property of the surface on which we put the fractional quantum Hall state."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Creating an FQH state"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "How can we describe a fractional quantum Hall state? Laughlin used a representation of the manyelectron wave function in complex coordinates to guess a wave function of an incompressible state. We will instead follow the more intuitive \"Composite Fermion\" approach due to Jain to understand this state. \n",
 "\n",
 "The starting point for the FQH state is of course the same as for the integer quantum Hall states, i.e. electrons in a magnetic field that occupy Landau levels. As we noticed in week 3, every state in a single Landau level is at exactly the same energy. The simplest family of FQH states are ones where the lowest Landau level states are only partially filled. Since there is no kinetic energy, the state is determined entirely by optimizing the Coulomb repulsion such that the electrons are as far away from each other as possible."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The composite fermion theory postulates that electrons manage to space themselves out by associating themselves with \"vortex\"like excitations. As you hopefully recall, a vortex in a superconductor is a defect where the superconducting phase $\\varphi$ winds by $2\\pi$ when going around the vortex. An electron going around the vortex picks up a $\\pi$phase shift. On the other hand, an electron can go around a double vortex and pick up effectively no (i.e. $2\\pi$) phase shift. However, the electron feels a phase gradient or a vector potential ${\\bf A}={\\bf\\nabla}\\varphi$ as it goes around the vortex. Such a vector potential is like a magnetic field and repels the electron. \n",
 "\n",
 "Of course we have no superconductivity at hand, but we can mimic the vortex properties using a mathematical trick involving complex numbers. First let us introduce complex coordinates for the electrons $z=x+iy$. Then we notice that we can insert a double vortex at $z_0$ in a gas of electrons with wave function $\\Psi(z_1,\\dots)$ by the transformation\n",
 "\n",
 "$$\n",
 "\\Psi(z_1,\\dots)\\rightarrow \\prod(z_iz_0)^2\\Psi(z_1,\\dots).\n",
 "$$\n",
 "\n",
 "> The basic trick of composite fermions in trying to keep electrons far apart is to say that each electron binds an even number $(2m)$ vortices to form a composite fermion.\n",
 "\n",
 "This amounts to the transformation of the manybody wave function $\\Psi_{CF}(z_1,z_2,\\dots)=\\prod_{i < j}(z_iz_j)^2\\Psi(z_1,z_2,\\dots)$, where $z_j$ are the electron wavefunctions.\n",
 "\n",
 "Pictorially the composite fermion transformation is represented as:\n",
 "\n",
 ""
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The next step in the composite fermion approach to the FQH state is to say that all the correlation effects of the Coulomb interaction are taken care of by the flux attachment. Beyond this, the composite fermions are weakly interacting particles. If we believe in this picture, then the only noninteracting incompressible states that we can get are integer quantum Hall states. This means that the FQH states are integer quantum Hall states of the composite fermions.\n",
 "\n",
 "How does this explain a fractionally filled state? Well, the original electron is $2m$ flux quanta together with a composite fermion. If we smear out the flux created by the electron density $\\nu$, we get a magnetic field of $2m\\nu$ flux quanta per unit area. This is in addition to the one flux quantum per unit area of the external magnetic field. Therefore the composite fermions, which are at a density of $\\nu$ per unit area, see a magnetic field of $2m\\nu+1$ per unit area. We can make the composite fermions form an incompressible state with $p$Landau levels filled if \n",
 "$\\nu=p(2m\\nu+1),$ so that we describe a state of filling \n",
 "\n",
 "$$\n",
 "\\nu=\\frac{p}{2 m p1}.\n",
 "$$\n",
 "\n",
 "Thus the composite fermion theory provides an explanation for how electrons can form incompressible states at a fractional sequence of filling fractions that is known as the \"Jain sequence\". These states were all seen in experiments."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"Composite fermions allow one to explain incompressible states at fractional filling of the Landau levels by \"\n",
 " \"postulating that:\")\n",
 "\n",
 "answers = [\"The quantum Hall system forms an incompressible liquid.\",\n",
 " \"The fractionally charged quasiparticles bind to fluxes to reduce the filling.\",\n",
 " \"The electrons become fractionally charged.\",\n",
 " \"The electrons bind to fluxes and reduce the effective magnetic field.\"]\n",
 "\n",
 "explanation = (\"Composite fermions are electrons bound to fluxes. Electrons are the fundamental particles and they cannot change \"\n",
 " \"their charge. The fractional charged quasiparticles are invoked by composite fermions not explained by the theory. \"\n",
 " \" The incompressible liquid is true for either integer or fractional quantum Hall.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=3, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Classification and fractional topological insulators"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Before we approach the classification of topological insulators in the presence of symmetries, let us discuss the fractional quantum Hall effect. In fact, there is a whole bunch of fractional quantum Hall states, so there is clearly room for classification. However, at first glance it looks more challenging because we cannot really solve general two dimensional interacting Hamiltonians. The tool that is used to understand what phases might exist is braiding. Based on all the examples of twodimensional topological states with no symmetry that we have so far, it is believed that distinct topological states are characterized by distinct particlelike anyonic excitations with distinct topological properties. It is certainly obvious that if two states have topologically distinct excitations in the bulk they cannot be adiabatically deformed into one another, since the braiding rules cannot change continuously.\n",
 "\n",
 "So the basic rule of the game is to ask what are all possible braiding rules for excitations in two dimensions. One would think that it would simply be arbitrary. Turns out that the situation is not quite as bad  locality and unitarity put rather strong constraints on the possible braidings of particles. The answer is obtained through a branch of mathematics called modular tensor category theory, and the theory tells us that valid sets of fractional excitations must obey the socalled pentagon and hexagon equations. All this being said, not all solutions of these equations are known  so basically the set of possible phases is not quite known. And this is all very abstract  and not even all the abstractly known phases that have acceptable braiding rules are known to be realized in nature. In fact, so far most of the known phases seem to be composite fermion ones that are well understood."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Symmetries\n",
 "\n",
 "To approach the classification of interacting topological insulators with symmetries, we can start by playing the same game as Kane and Mele, and combine two fractional quantum Hall states (instead of integer ones) to make a fractional topological insulator. If we choose a pair of FQH states which are related by timereversal and stack them together for spinup and spindown electrons, that technically leads to a timereversal invariant state. The key question that needs to be asked is whether one can gap out the edge states by adding timereversal invariant perturbations. If one can do that, then unlike the KaneMele quantum spin Hall state, the state is not a phase that is protected by just timereversal symmetry. This question is not too mathematically involved, though still beyond this course and can be answered by the bosonization technique as was done by [Stern and Levin](http://arxiv.org/abs/0906.2769).\n",
 "\n",
 "We can however explain the result. If one stacks the two FQH states one obtains a spinHall conductance $\\sigma_{sh}$, which is equal to the Hall conductance of each layer. Let the smallest charge of an excitation of our phase be $e^*$, some fraction of electron charge. It turns out that the edge states are protected from gapping by timereversal invariant perturbations if and only if $\\sigma_{sh}/e^*$ is an odd integer. This gives some idea as to what kind of interacting analogues of quantum spin Hall states one may get. But again, as with the nonsymmetric case, the general classification is still up in the air. More importantly, we don't really have realistic candidates for such states yet."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Conclusions"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"zrLqxjKfGw\", src_location=\"12.1summary\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Questions about what you just learned? Ask them below!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Questions\", \"FQHE\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w12_manybody/fqhe.md b/w12_manybody/fqhe.md
new file mode 100644
index 0000000..55505fd
 /dev/null
+++ b/w12_manybody/fqhe.md
@@ 0,0 +1,167 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+```
+
+# Introduction
+
+This topic is introduced by Sankar Das Sarma from the university of Maryland.
+
+
+```python
+MoocVideo("4gSJSo3olfg", src_location="12.1intro")
+```
+
+# Interacting systems
+
+One obvious thing that we completely ignored throughout the course is the effects of interactions on topology. It is of course possible to generalize all the symmetry classes that we have studied to manybody Hamiltonians, but what happens to the classification of the topological phases?
+
+The first statement we should make here is that our work so far wasn't wasted: most of the usual topological insulators turn out to tolerate interactions as long as the interactions do not spontaneously break the symmetry, or close the bulk gap.
+There are interesting cases where the classification collapses. For example, the 1D BDI chain with Majorana fermions on one of the two sublattice degrees of freedom allows a $\mathbb{Z}_8$ classification with interactions instead of $\mathbb{Z}$. The reason for this is that the 8Majorana interaction term doesn't break the symmetries anymore.
+
+However this is relatively minor compared to the real can of worms that the interactions open: the amount of possibilities for the interacting phases is much larger. To begin with, we'll discuss the oldest known example of a strongly interacting topological phase, the fractional quantum Hall effect. Note that it only covers a single dimension ($D=2$), and a single symmetry class (no symmetry at all). Yet, classifying all such states turns out to be a very hard task.
+
+# Fractional charge and statistics in the fractional quantized Hall effect
+
+If you followed what we learned about the integer quantum Hall effect, you'll remember that we used the pumping argument to establish that the Hall conductance in an incompressible liquid is quantized in integers. You might now wonder if the experimental evidence for the fractional quantum Hall effect completely invalidates this argument in some way. The key step in the argument was to realize that the pumped charge that results from the insertion of one flux quantum $\Phi_0$ into a Corbino geometry is
+
+$$
+Q_{pump}=\sigma_{xy}\Phi_0\equiv \nu e,
+$$
+
+where $\nu=\sigma_{xy}/G_0$ is the Hall conductance in dimensionless units. For the noninteracting system that we studied in the quantum Hall effect, we assumed that only an integer number of electrons could be transferred between the edges  so $\nu$ had to be an integer.
+
+The real reason that the charge transferred had to be an integer multiple of the electron charge was that the Hamiltonian for the electrons was identical between flux $\Phi=0$ and flux $\Phi=\Phi_0$. Since the system is incompressible, it is reasonable to assume that all excitations in the system are local. Usually we expect different excited states to differ by rearranging electrons. Within this framework, such excitations can differ by integer multiples of electronic charge.
+
+The existence of fractional values of $\nu$ implies that the edge can have local excitations that differ by a fractional electron charge. In principle, the inner edge of the Corbino geometry can be shrunk to a point, and if we do this, we're forced to conclude that the system can now host excitations that have fractional charge.
+
+The fractional charged excitations are local particles just like the electrons themselves. So we can ask about the statistics under exchange of two such particles. On performing such an exchange, the total manybody wave function of the system returns to itself, but
+the wave function can pick up a Berry phase. For fermions this phase is $\pi$ and for Bosons it is zero. Instead of computing the phase directly, let us consider doing a double exchange, which is topologically equivalent to taking a particle around another one and computing the phase for that.
+
+![](figures/exchange.svg)
+
+Let us first assume that one of the particles was created by a flux quantum. Since the flux quantum created this particle adiabatically by a pumping process, locality dictates that the particle going around the flux quantum + particle cannot know about the existence of the other particle. Thus the phase from going around a particle together with its flux quantum must vanish. On the other hand, the particle picks up a phase of $2\pi \nu$ from just going around the flux quantum. Thus double exchange of a pair of particles leads to a Berry phase of $2\pi\nu$. This is another strange property of excitations in the FQH state! They must obey different statistics than both fermions and bosons, and are thus referred to as anyons. Therefore the exchange phase of anyons in the simple FQH states is given by
+
+$$
+\phi_{exch}=\pi\nu.
+$$
+
+
+```python
+question = ("The Laughlin argument was used to prove that the Hall effect must be quantized in integers. What is the key assumption"
+ "that must be dropped in order to understand the fractional quantum Hall effect?")
+
+answers = ["Allow electrons to have fractional statistics.",
+ "Allow quasiparticles with fractional charge.",
+ "Require that the system forms an incompressible fluid.",
+ "Allow electrons to have fractional charge.",
+ "Allow quasiparticles to have fractional statistics."]
+
+explanation = ("The key assumption in the Laughlin argument for the integer case was that the charge that was added by pumping could"
+ "only be an integer multiple of an electronic charge.")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)
+```
+
+# Topological degeneracy
+
+Knowing that the system supports particles with nontrivial braiding statistics, we can derive its next important property, the topological degeneracy of the ground state.
+
+To do this, we turn around the argument for computing the statistics of particles and consider the statistics of fluxes. A particle going around a flux acquires a phase of $2\pi\nu$. As noted in the last unit, the combination of a particle and flux does not have any nontrivial exchange statistics. So replacing the particle by another flux will lead to a phase of $2\pi \nu$. Therefore the exchange phase of fluxes gives a phase of $\pi\nu$, just like the exchange of particles.
+
+Let us now put the FQH system on a torus. A natural operation on the torus is to create a flux antiflux pair, move them around a cycle of the torus and annihilate them at the end. This operation inserts a flux into one of the two nontrivial cycles of the torus. Let's label this operation $T_{1,2}$ for each of the cycles of the torus:
+
+![](figures/torus.svg)
+
+The last physical step to deriving the degeneracy is to ask what is the commutator $T_1^{1}T_2^{1}T_1 T_2$. This operator describes first moving a vortex around the red contour, then moving the vortex around the blue contour, moving the vortex back around the red contour, and finally undoing the motion of the vortex along the blue contour.
+No matter which path we choose for this operation, we will need to take one vortex all the way around the other one. According to the braiding rule we get:
+
+$$
+T_1^{1}T_2^{1}T_1 T_2 =e^{i2\pi \nu}.
+$$
+
+Now all we need to do is an exercise in elementary quantum mechanics. First of all, both $T_{1,2}$ commute with the Hamiltonian. Let's take $\Psi\rangle$ as a simultaneous ground state of the Hamiltonian and eigenstate of $T_1$. If in addition $e^{i\alpha}\Psi\rangle=T_2\Psi\rangle$, then $T_1$ and $T_2$ would commute. Since we know this isn't the case, $T_2\Psi\rangle$ must be a ground state of the Hamiltonian which is not the same as $\Psi\rangle$.
+
+> We conclude that fractional quantum Hall phases have ground state degeneracy on the torus.
+
+We have seen an example of ground state degeneracy in Majorana wires, where the degeneracy of the zero modes could not be lifted by any local perturbation. The difference between the Majorana case and fractional quantum Hall is that in the latter we don't rely on the presence of defects, and the degeneracy is a property of the surface on which we put the fractional quantum Hall state.
+
+# Creating an FQH state
+
+How can we describe a fractional quantum Hall state? Laughlin used a representation of the manyelectron wave function in complex coordinates to guess a wave function of an incompressible state. We will instead follow the more intuitive "Composite Fermion" approach due to Jain to understand this state.
+
+The starting point for the FQH state is of course the same as for the integer quantum Hall states, i.e. electrons in a magnetic field that occupy Landau levels. As we noticed in week 3, every state in a single Landau level is at exactly the same energy. The simplest family of FQH states are ones where the lowest Landau level states are only partially filled. Since there is no kinetic energy, the state is determined entirely by optimizing the Coulomb repulsion such that the electrons are as far away from each other as possible.
+
+The composite fermion theory postulates that electrons manage to space themselves out by associating themselves with "vortex"like excitations. As you hopefully recall, a vortex in a superconductor is a defect where the superconducting phase $\varphi$ winds by $2\pi$ when going around the vortex. An electron going around the vortex picks up a $\pi$phase shift. On the other hand, an electron can go around a double vortex and pick up effectively no (i.e. $2\pi$) phase shift. However, the electron feels a phase gradient or a vector potential ${\bf A}={\bf\nabla}\varphi$ as it goes around the vortex. Such a vector potential is like a magnetic field and repels the electron.
+
+Of course we have no superconductivity at hand, but we can mimic the vortex properties using a mathematical trick involving complex numbers. First let us introduce complex coordinates for the electrons $z=x+iy$. Then we notice that we can insert a double vortex at $z_0$ in a gas of electrons with wave function $\Psi(z_1,\dots)$ by the transformation
+
+$$
+\Psi(z_1,\dots)\rightarrow \prod(z_iz_0)^2\Psi(z_1,\dots).
+$$
+
+> The basic trick of composite fermions in trying to keep electrons far apart is to say that each electron binds an even number $(2m)$ vortices to form a composite fermion.
+
+This amounts to the transformation of the manybody wave function $\Psi_{CF}(z_1,z_2,\dots)=\prod_{i < j}(z_iz_j)^2\Psi(z_1,z_2,\dots)$, where $z_j$ are the electron wavefunctions.
+
+Pictorially the composite fermion transformation is represented as:
+
+
+
+The next step in the composite fermion approach to the FQH state is to say that all the correlation effects of the Coulomb interaction are taken care of by the flux attachment. Beyond this, the composite fermions are weakly interacting particles. If we believe in this picture, then the only noninteracting incompressible states that we can get are integer quantum Hall states. This means that the FQH states are integer quantum Hall states of the composite fermions.
+
+How does this explain a fractionally filled state? Well, the original electron is $2m$ flux quanta together with a composite fermion. If we smear out the flux created by the electron density $\nu$, we get a magnetic field of $2m\nu$ flux quanta per unit area. This is in addition to the one flux quantum per unit area of the external magnetic field. Therefore the composite fermions, which are at a density of $\nu$ per unit area, see a magnetic field of $2m\nu+1$ per unit area. We can make the composite fermions form an incompressible state with $p$Landau levels filled if
+$\nu=p(2m\nu+1),$ so that we describe a state of filling
+
+$$
+\nu=\frac{p}{2 m p1}.
+$$
+
+Thus the composite fermion theory provides an explanation for how electrons can form incompressible states at a fractional sequence of filling fractions that is known as the "Jain sequence". These states were all seen in experiments.
+
+
+```python
+question = ("Composite fermions allow one to explain incompressible states at fractional filling of the Landau levels by "
+ "postulating that:")
+
+answers = ["The quantum Hall system forms an incompressible liquid.",
+ "The fractionally charged quasiparticles bind to fluxes to reduce the filling.",
+ "The electrons become fractionally charged.",
+ "The electrons bind to fluxes and reduce the effective magnetic field."]
+
+explanation = ("Composite fermions are electrons bound to fluxes. Electrons are the fundamental particles and they cannot change "
+ "their charge. The fractional charged quasiparticles are invoked by composite fermions not explained by the theory. "
+ " The incompressible liquid is true for either integer or fractional quantum Hall.")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=3, explanation=explanation)
+```
+
+# Classification and fractional topological insulators
+
+Before we approach the classification of topological insulators in the presence of symmetries, let us discuss the fractional quantum Hall effect. In fact, there is a whole bunch of fractional quantum Hall states, so there is clearly room for classification. However, at first glance it looks more challenging because we cannot really solve general two dimensional interacting Hamiltonians. The tool that is used to understand what phases might exist is braiding. Based on all the examples of twodimensional topological states with no symmetry that we have so far, it is believed that distinct topological states are characterized by distinct particlelike anyonic excitations with distinct topological properties. It is certainly obvious that if two states have topologically distinct excitations in the bulk they cannot be adiabatically deformed into one another, since the braiding rules cannot change continuously.
+
+So the basic rule of the game is to ask what are all possible braiding rules for excitations in two dimensions. One would think that it would simply be arbitrary. Turns out that the situation is not quite as bad  locality and unitarity put rather strong constraints on the possible braidings of particles. The answer is obtained through a branch of mathematics called modular tensor category theory, and the theory tells us that valid sets of fractional excitations must obey the socalled pentagon and hexagon equations. All this being said, not all solutions of these equations are known  so basically the set of possible phases is not quite known. And this is all very abstract  and not even all the abstractly known phases that have acceptable braiding rules are known to be realized in nature. In fact, so far most of the known phases seem to be composite fermion ones that are well understood.
+
+## Symmetries
+
+To approach the classification of interacting topological insulators with symmetries, we can start by playing the same game as Kane and Mele, and combine two fractional quantum Hall states (instead of integer ones) to make a fractional topological insulator. If we choose a pair of FQH states which are related by timereversal and stack them together for spinup and spindown electrons, that technically leads to a timereversal invariant state. The key question that needs to be asked is whether one can gap out the edge states by adding timereversal invariant perturbations. If one can do that, then unlike the KaneMele quantum spin Hall state, the state is not a phase that is protected by just timereversal symmetry. This question is not too mathematically involved, though still beyond this course and can be answered by the bosonization technique as was done by [Stern and Levin](http://arxiv.org/abs/0906.2769).
+
+We can however explain the result. If one stacks the two FQH states one obtains a spinHall conductance $\sigma_{sh}$, which is equal to the Hall conductance of each layer. Let the smallest charge of an excitation of our phase be $e^*$, some fraction of electron charge. It turns out that the edge states are protected from gapping by timereversal invariant perturbations if and only if $\sigma_{sh}/e^*$ is an odd integer. This gives some idea as to what kind of interacting analogues of quantum spin Hall states one may get. But again, as with the nonsymmetric case, the general classification is still up in the air. More importantly, we don't really have realistic candidates for such states yet.
+
+# Conclusions
+
+
+```python
+MoocVideo("zrLqxjKfGw", src_location="12.1summary")
+```
+
+Questions about what you just learned? Ask them below!
+
+
+```python
+MoocDiscussion("Questions", "FQHE")
+```
diff git a/w12_manybody/topoorder.ipynb b/w12_manybody/topoorder.ipynb
deleted file mode 100644
index 0a30dd4..0000000
 a/w12_manybody/topoorder.ipynb
+++ /dev/null
@@ 1,205 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Introduction"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The topological order is introduced by Barbara Terhal from RWTH Aachen."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"rLdHCKxMumY\", src_location=\"12.2intro\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Simplest model for topological degeneracy: Toric code"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We have worked hard to create topological models so far. The FQH system, which is the most topological in some sense, was also more obscure in terms of microscopics. Here, we follow Alexei Kitaev and write down a simple Hamiltonian that is obviously topological, but also relatively easy to analyse.\n",
 "\n",
 "Let's consider a system of localized spin$1/2$ electrons that live on the bonds of a square lattice. The particular Hamiltonian that Kitaev wrote down is:\n",
 "\n",
 "$$H=A_v\\sum_{+}\\prod_+ \\sigma_zB_p\\sum_{\\Box}\\prod_{\\Box} \\sigma_x.$$"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As you can see in the figure below, $\\Box$ refers to the spins on the bonds that surround a plaquette and $+$ refers to the bonds that surround a vertex. The beauty of this Hamiltonian is that all the terms commute between themselves. The only terms that you might suspect not to commute are a plaquette term and a vertex term that share some bonds. But you can convince yourself easily (by looking at the figure) that such terms always share an even number of spins. This means that the commutation picks up an even number of minus signs and so these terms commute as well.\n",
 "\n",
 "![](figures/toric_layout.svg)\n",
 "\n",
 "Since $H$ is a sum of commuting terms, we can calculate the ground state as the simultaneous ground state for all the terms. \n",
 "Let us first look at the vertex terms proportional to $A$. If we draw a red line through bond connecting neighboring spins with $\\sigma_z=1$ on our lattice (as shown below), then we find that each vertex in the ground state configuration has an even number of red lines coming in. Thus, we can think of the red lines forming loops that can never be open ended. This allows us to view the ground state of the toric code as a loop gas. \n",
 "\n",
 "![](figures/loops.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "What if we focus on the large plaquette term limit i.e. $A_v\\ll B_p$ instead? The toric code is fairly symmetric between the vertex and plaquette terms. Clearly, focusing on the $\\sigma_z$ diagonal basis was a choice. If we draw loops (blue lines) through the dual lattice (whose vertices are in the middle of the original lattice) whenever $\\sigma_x=1$ on some link. This results in a loop gas picture (blue lines) on the dual lattice, which focusses on the $\\sigma_x$ terms. \n",
 "\n",
 "Returning to the $\\sigma_z$ representation, it looks like every loop configuration is a ground state wavefunction and so is a massively degenerate loop space $L$. But this conclusion doesn't include the plaquette terms (i.e. the $B_p$ coefficient) yet. Since the plaquette terms commute with the vertex terms in the Hamiltonian, the plaquette terms take us between different loop configurations. Considering the plaquette Hamiltonian in the low energy space of closed loops we can show that the ground state wavefunction must be the sum of all possible (i.e. ones that can be reached by applying the plaquette terms) loop configurations with equal weight. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The ground state looks pretty nondegenerate at this point but if we consider the system with periodic boundary conditions  namely on a torus, we immediately see that there are 4 topologically distinct loop configurations that are degenerate. Basically, the plaquette terms can only deform the loops smoothly and therefore cannot change the parity of the winding numbers of the loops. \n",
 "\n",
 "It is however possible to continuously deform a closed loop into a pair of loops along some cycle of the torus. So only the parity of the loop winding across a cut cannot be changed. Thus, the toric code on a torus has 4 degenerate ground state wavefunctions (all with the same energy), which are topologically distinct. The difference between these wave functions is the parity of the number of loops crossing a vertical or a horizontal cycle on the torus.\n",
 "\n",
 "Does this have anything to do with the way we have defined topology in this course, using the bulkedge correspondence? Unfortunately and confusingly, not. These interacting systems are topological in the sense of having a topological degeneracy between topologically distinct states that cannot be continuously deformed into one another. In a sense, this is a more amazing feature than the bulk edge correspondence itself  the degeneracy between these states cannot be lifted by any reasonable (local) perturbation. This is sort of similar to Majorana fermions, but even more robust. In fact, the toric code does not even have edge states, so there is really no bulkedge correspondence to speak of.\n",
 "\n",
 "The topological robustness makes the topologically degenerate states particularly attractive to store quantum information. The main challenge of quantum information is the quantum decoherence problem, where local fluctuations in the Hamiltonian destroy the phase coherence of the quantum system used to store information. The solution proposed by topological quantum computation is to use the topologically degenerate space of a toric code to store the information. In fact, this is in essence what is being attempted by experimentalists who work on superconducting qubits, under the framework of the surface code. "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"How would the topological degeneracy of the ground state that comes from the loop configurations \"\n",
 " \"change if we put it on a torus (donut) with two holes?\")\n",
 "\n",
 "answers = [\"Since there is still an infinite number of loop configurations, the degeneracy would be infinite.\",\n",
 " \"Since there is one additional hole there are two more distinct cycles. \"\n",
 " \"So the number of ground states increases by a factor of 4.\",\n",
 " \"It still remains 4 since the loops is topologically forbidden from going around the extra loops.\",\n",
 " \"Since there is one additional hole the loops can go around this hole an even or an odd number of time, \"\n",
 " \"so the degeneracy increases from 4 to 8.\"]\n",
 "\n",
 "explanation = (\"The additional hole introduces the possibility of 2 values of parity on each extra cycle. This adds a \"\n",
 " \"factor of $2 \\\\times 2=4$.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Particlelike excitations"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As we saw in the FQH systems, excitations with fractional charge and statistics was really the hallmark of topologically degenerate states. Since the basic degree of freedom in the toric code are spin, we expect all excitations to be neutral. But there is a possibility that we get fractionalized statistics. The neat thing about the toric code Hamiltonian is that it allows us to not only compute the ground state for the toric code but also all the excited states. Again, this is not too surprising since all the terms in the Hamiltonian commute, so all eigenstates are simultaneous eigenstates of the vertex and plaquette terms. If we focus on the vertex terms first (let's say by assuming that $B_p\\ll A_v$), we can get excitations of the vertex Hamiltonian by breaking loops. We can think of the end points of the loops as excitations, since the plaquette terms proportional to $B_p$ make the plaquette terms fluctuate. These particles (that you see in the figure below) because of analogy with $Z_2$ gauge theory, are called the electric defects, which we label 'e'. As shown below, analogous defects in $\\sigma_x=1$loops on the dual lattice are referred to as magnetic defects, which we will label 'm'. \n",
 "\n",
 "![](figures/toric_exchanges.svg)\n",
 "\n",
 "While the intuitive picture for the excitations as ends of broken loops is nice, to describe these exctiation in the more general case, where $A_v$ and $B_p$ are comparable, it is convenient to define the socalled Wilson path operators \n",
 "\n",
 "$$W_e=\\prod_{\\mathcal{l}_e} \\sigma_z,\\quad\\, W_m=\\prod_{\\mathcal{l}_m} \\sigma_x.$$\n",
 "\n",
 "By viewing the system in the $\\sigma_z$basis in the limit $B_p\\rightarrow 0$, we see that the operator $W_e$ counts the parity of $\\sigma_z=1$ spins that lie on the loop $\\mathcal{l}_e$. Therefore, in this limit $W_e$ measures the parity of 'e' excitations inside the loop $\\mathcal{l}_e$. The operator $W_e$ is a product of the vertex terms inside the loop $\\mathcal{l}_e$ and hence commutes with $H$ for any strength of the plaquette terms proportional to $B_p$. \n",
 "\n",
 "> Therefore $W_e$ and $W_m$ are conserved 'flux' operators that measure the parity of the number of electric and magnetic defects inside the loops $\\mathcal{l}_{e,m}$ respectively.\n",
 "\n",
 "Thus, the values $W_{e,m}=1$ can also be used to define what it means to have a localized 'e' or 'm' excitation respectively. These defects describe the localized excitations of the toric code. In fact in this model, this excitation on the ground states are localized to exactly one lattice site and may be viewed as pointlike particles in a vacuum. \n",
 "\n",
 "Just like in the quantum Hall effect, we can use the Wilson loops $W_{e,m}$ to characterize the degenerate ground states of the toric code on a torus. The value of the Wilson loop $W_e$ counts the parity of intersections of $\\sigma_z=1$ loops (red lines) crossing the Wilson loop. Therefore, the value of the Wilson loop $W_e$ along one of the cycles of the torus counts the parity of the $\\sigma_z=1$ loops crossing it. Since we can draw a pair of commuting Wilson loop $W_e$, one through each cycle of the torus, the degeneracy of the torus from $W_e=\\pm 1$ is 4. This is exactly what we got from the loop picture. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Semionic statistics of excitations"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The loop gas picture makes the 'e' and 'm' excitations, which are ends of loops look quite topological. But are they topological in a sense similar to the charges in the FQH system? To see this, let us try to interchange an 'e' particle and an 'm' particle. For starters let us see how to move each of these particles. To do this we use the 'path' operators \n",
 "\n",
 "$$\\Gamma^{(e)}(a,b)=\\prod_{a\\rightarrow b}\\sigma_x,\\quad\\,\\Gamma^{(m)}(a,b)=\\prod_{a\\rightarrow b}\\sigma_z,$$\n",
 "\n",
 "to move an excitation from point $a$ to $b$. This is because this operator will flip $W_{e,m}(a):1\\rightarrow +1$ at end $a$ and hence destroy the excitation and also flip $W_{e,m}(b):+1\\rightarrow 1$ to create an excitation. \n",
 "\n",
 "Now, if we try to take an 'e' particle around an 'm' particle, the path forms a loop $W_e$ around 'm'. This adds a factor of $W_e=1$ to the wavefunction, for the double exchange process between 'e' and 'm', which is topologically equivalent to taking one particle around the other. This strange exchange statistics, which is not quite the same as the exchange of identical particles that we are used to is referred to as \"semionic\" statistics.\n",
 "\n",
 "Next, we try to exchange a pair of 'e' particles. We can do this by applying a pair of path operators $\\Gamma^{(e)}$ to the particles \n",
 "that form a loop. This pair of operators form loop operator $W_e$, which must be $W_e=+1$ unless there is an 'm' particle inside. Therefore the 'e' particles are bosons and so are the 'm' particles by a similar argument.\n",
 "\n",
 "Finally, if we exchange an 'e''m' pair with another 'e''m' pair, we see, that the result is equivalent to a double exchange between an 'e' particle and an 'm' particle in addition some 'e' and 'm' exchanges. The double exchange produces a $$ sign as we saw. However, unlike the case of exchanging 'e' and 'm' particles, the 'e''m' pairs (also called dyons) are identical particles and therefore we can treat them analogous to exchanging quantum particles in nature. In this context, the $$ sign should suggest to you that the dyon 'e''m' are really fermions. This is rather strange because the microscopic constituents of our theory were spins whose exchange phases are always $1$ (i.e. bosons) and we end up with fermions, which are in some sense half of bosons.\n",
 "Thus, the toric code, in a sense, gives us a microscopic model of \"fractional statistics\"."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Questions about what you just learned? Ask them below!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Questions\", \"Topological order\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w12_manybody/topoorder.md b/w12_manybody/topoorder.md
new file mode 100644
index 0000000..bfd36bb
 /dev/null
+++ b/w12_manybody/topoorder.md
@@ 0,0 +1,105 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+```
+
+# Introduction
+
+The topological order is introduced by Barbara Terhal from RWTH Aachen.
+
+
+```python
+MoocVideo("rLdHCKxMumY", src_location="12.2intro")
+```
+
+# Simplest model for topological degeneracy: Toric code
+
+We have worked hard to create topological models so far. The FQH system, which is the most topological in some sense, was also more obscure in terms of microscopics. Here, we follow Alexei Kitaev and write down a simple Hamiltonian that is obviously topological, but also relatively easy to analyse.
+
+Let's consider a system of localized spin$1/2$ electrons that live on the bonds of a square lattice. The particular Hamiltonian that Kitaev wrote down is:
+
+$$H=A_v\sum_{+}\prod_+ \sigma_zB_p\sum_{\Box}\prod_{\Box} \sigma_x.$$
+
+As you can see in the figure below, $\Box$ refers to the spins on the bonds that surround a plaquette and $+$ refers to the bonds that surround a vertex. The beauty of this Hamiltonian is that all the terms commute between themselves. The only terms that you might suspect not to commute are a plaquette term and a vertex term that share some bonds. But you can convince yourself easily (by looking at the figure) that such terms always share an even number of spins. This means that the commutation picks up an even number of minus signs and so these terms commute as well.
+
+![](figures/toric_layout.svg)
+
+Since $H$ is a sum of commuting terms, we can calculate the ground state as the simultaneous ground state for all the terms.
+Let us first look at the vertex terms proportional to $A$. If we draw a red line through bond connecting neighboring spins with $\sigma_z=1$ on our lattice (as shown below), then we find that each vertex in the ground state configuration has an even number of red lines coming in. Thus, we can think of the red lines forming loops that can never be open ended. This allows us to view the ground state of the toric code as a loop gas.
+
+![](figures/loops.svg)
+
+What if we focus on the large plaquette term limit i.e. $A_v\ll B_p$ instead? The toric code is fairly symmetric between the vertex and plaquette terms. Clearly, focusing on the $\sigma_z$ diagonal basis was a choice. If we draw loops (blue lines) through the dual lattice (whose vertices are in the middle of the original lattice) whenever $\sigma_x=1$ on some link. This results in a loop gas picture (blue lines) on the dual lattice, which focusses on the $\sigma_x$ terms.
+
+Returning to the $\sigma_z$ representation, it looks like every loop configuration is a ground state wavefunction and so is a massively degenerate loop space $L$. But this conclusion doesn't include the plaquette terms (i.e. the $B_p$ coefficient) yet. Since the plaquette terms commute with the vertex terms in the Hamiltonian, the plaquette terms take us between different loop configurations. Considering the plaquette Hamiltonian in the low energy space of closed loops we can show that the ground state wavefunction must be the sum of all possible (i.e. ones that can be reached by applying the plaquette terms) loop configurations with equal weight.
+
+The ground state looks pretty nondegenerate at this point but if we consider the system with periodic boundary conditions  namely on a torus, we immediately see that there are 4 topologically distinct loop configurations that are degenerate. Basically, the plaquette terms can only deform the loops smoothly and therefore cannot change the parity of the winding numbers of the loops.
+
+It is however possible to continuously deform a closed loop into a pair of loops along some cycle of the torus. So only the parity of the loop winding across a cut cannot be changed. Thus, the toric code on a torus has 4 degenerate ground state wavefunctions (all with the same energy), which are topologically distinct. The difference between these wave functions is the parity of the number of loops crossing a vertical or a horizontal cycle on the torus.
+
+Does this have anything to do with the way we have defined topology in this course, using the bulkedge correspondence? Unfortunately and confusingly, not. These interacting systems are topological in the sense of having a topological degeneracy between topologically distinct states that cannot be continuously deformed into one another. In a sense, this is a more amazing feature than the bulk edge correspondence itself  the degeneracy between these states cannot be lifted by any reasonable (local) perturbation. This is sort of similar to Majorana fermions, but even more robust. In fact, the toric code does not even have edge states, so there is really no bulkedge correspondence to speak of.
+
+The topological robustness makes the topologically degenerate states particularly attractive to store quantum information. The main challenge of quantum information is the quantum decoherence problem, where local fluctuations in the Hamiltonian destroy the phase coherence of the quantum system used to store information. The solution proposed by topological quantum computation is to use the topologically degenerate space of a toric code to store the information. In fact, this is in essence what is being attempted by experimentalists who work on superconducting qubits, under the framework of the surface code.
+
+
+```python
+question = ("How would the topological degeneracy of the ground state that comes from the loop configurations "
+ "change if we put it on a torus (donut) with two holes?")
+
+answers = ["Since there is still an infinite number of loop configurations, the degeneracy would be infinite.",
+ "Since there is one additional hole there are two more distinct cycles. "
+ "So the number of ground states increases by a factor of 4.",
+ "It still remains 4 since the loops is topologically forbidden from going around the extra loops.",
+ "Since there is one additional hole the loops can go around this hole an even or an odd number of time, "
+ "so the degeneracy increases from 4 to 8."]
+
+explanation = ("The additional hole introduces the possibility of 2 values of parity on each extra cycle. This adds a "
+ "factor of $2 \\times 2=4$.")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)
+```
+
+# Particlelike excitations
+
+As we saw in the FQH systems, excitations with fractional charge and statistics was really the hallmark of topologically degenerate states. Since the basic degree of freedom in the toric code are spin, we expect all excitations to be neutral. But there is a possibility that we get fractionalized statistics. The neat thing about the toric code Hamiltonian is that it allows us to not only compute the ground state for the toric code but also all the excited states. Again, this is not too surprising since all the terms in the Hamiltonian commute, so all eigenstates are simultaneous eigenstates of the vertex and plaquette terms. If we focus on the vertex terms first (let's say by assuming that $B_p\ll A_v$), we can get excitations of the vertex Hamiltonian by breaking loops. We can think of the end points of the loops as excitations, since the plaquette terms proportional to $B_p$ make the plaquette terms fluctuate. These particles (that you see in the figure below) because of analogy with $Z_2$ gauge theory, are called the electric defects, which we label 'e'. As shown below, analogous defects in $\sigma_x=1$loops on the dual lattice are referred to as magnetic defects, which we will label 'm'.
+
+![](figures/toric_exchanges.svg)
+
+While the intuitive picture for the excitations as ends of broken loops is nice, to describe these exctiation in the more general case, where $A_v$ and $B_p$ are comparable, it is convenient to define the socalled Wilson path operators
+
+$$W_e=\prod_{\mathcal{l}_e} \sigma_z,\quad\, W_m=\prod_{\mathcal{l}_m} \sigma_x.$$
+
+By viewing the system in the $\sigma_z$basis in the limit $B_p\rightarrow 0$, we see that the operator $W_e$ counts the parity of $\sigma_z=1$ spins that lie on the loop $\mathcal{l}_e$. Therefore, in this limit $W_e$ measures the parity of 'e' excitations inside the loop $\mathcal{l}_e$. The operator $W_e$ is a product of the vertex terms inside the loop $\mathcal{l}_e$ and hence commutes with $H$ for any strength of the plaquette terms proportional to $B_p$.
+
+> Therefore $W_e$ and $W_m$ are conserved 'flux' operators that measure the parity of the number of electric and magnetic defects inside the loops $\mathcal{l}_{e,m}$ respectively.
+
+Thus, the values $W_{e,m}=1$ can also be used to define what it means to have a localized 'e' or 'm' excitation respectively. These defects describe the localized excitations of the toric code. In fact in this model, this excitation on the ground states are localized to exactly one lattice site and may be viewed as pointlike particles in a vacuum.
+
+Just like in the quantum Hall effect, we can use the Wilson loops $W_{e,m}$ to characterize the degenerate ground states of the toric code on a torus. The value of the Wilson loop $W_e$ counts the parity of intersections of $\sigma_z=1$ loops (red lines) crossing the Wilson loop. Therefore, the value of the Wilson loop $W_e$ along one of the cycles of the torus counts the parity of the $\sigma_z=1$ loops crossing it. Since we can draw a pair of commuting Wilson loop $W_e$, one through each cycle of the torus, the degeneracy of the torus from $W_e=\pm 1$ is 4. This is exactly what we got from the loop picture.
+
+# Semionic statistics of excitations
+
+The loop gas picture makes the 'e' and 'm' excitations, which are ends of loops look quite topological. But are they topological in a sense similar to the charges in the FQH system? To see this, let us try to interchange an 'e' particle and an 'm' particle. For starters let us see how to move each of these particles. To do this we use the 'path' operators
+
+$$\Gamma^{(e)}(a,b)=\prod_{a\rightarrow b}\sigma_x,\quad\,\Gamma^{(m)}(a,b)=\prod_{a\rightarrow b}\sigma_z,$$
+
+to move an excitation from point $a$ to $b$. This is because this operator will flip $W_{e,m}(a):1\rightarrow +1$ at end $a$ and hence destroy the excitation and also flip $W_{e,m}(b):+1\rightarrow 1$ to create an excitation.
+
+Now, if we try to take an 'e' particle around an 'm' particle, the path forms a loop $W_e$ around 'm'. This adds a factor of $W_e=1$ to the wavefunction, for the double exchange process between 'e' and 'm', which is topologically equivalent to taking one particle around the other. This strange exchange statistics, which is not quite the same as the exchange of identical particles that we are used to is referred to as "semionic" statistics.
+
+Next, we try to exchange a pair of 'e' particles. We can do this by applying a pair of path operators $\Gamma^{(e)}$ to the particles
+that form a loop. This pair of operators form loop operator $W_e$, which must be $W_e=+1$ unless there is an 'm' particle inside. Therefore the 'e' particles are bosons and so are the 'm' particles by a similar argument.
+
+Finally, if we exchange an 'e''m' pair with another 'e''m' pair, we see, that the result is equivalent to a double exchange between an 'e' particle and an 'm' particle in addition some 'e' and 'm' exchanges. The double exchange produces a $$ sign as we saw. However, unlike the case of exchanging 'e' and 'm' particles, the 'e''m' pairs (also called dyons) are identical particles and therefore we can treat them analogous to exchanging quantum particles in nature. In this context, the $$ sign should suggest to you that the dyon 'e''m' are really fermions. This is rather strange because the microscopic constituents of our theory were spins whose exchange phases are always $1$ (i.e. bosons) and we end up with fermions, which are in some sense half of bosons.
+Thus, the toric code, in a sense, gives us a microscopic model of "fractional statistics".
+
+Questions about what you just learned? Ask them below!
+
+
+```python
+MoocDiscussion("Questions", "Topological order")
+```
diff git a/w12_manybody/w12_assignments.ipynb b/w12_manybody/w12_assignments.ipynb
deleted file mode 100644
index d1407d4..0000000
 a/w12_manybody/w12_assignments.ipynb
+++ /dev/null
@@ 1,98 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Review assignment"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "display_html(PreprintReference('0910.2763', description=\"Fractional quantum Hall effect in graphene\"))\n",
 "display_html(PreprintReference('1204.5479', description=\"Fractional Majoranas in fractional quantum Hall edges\"))\n",
 "display_html(PreprintReference('0803.0272', description=\"A scheme for quantum computation using the toric code\"))\n",
 "display_html(PreprintReference('1502.01665', description=\"Making a fractional quantum Hall effect by coupling wires\"))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Bonus: Find your own paper to review!\n",
 "\n",
 "Do you know of another paper that fits into the topics of this week, and you think is good?\n",
 "Then you can get bonus points by reviewing that paper instead!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocPeerAssessment(due=7, review_due=11)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Reviews\", \"Manybody topology\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
diff git a/w12_manybody/w12_assignments.md b/w12_manybody/w12_assignments.md
new file mode 100644
index 0000000..feeeafa
 /dev/null
+++ b/w12_manybody/w12_assignments.md
@@ 0,0 +1,35 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+```
+
+# Review assignment
+
+
+```python
+display_html(PreprintReference('0910.2763', description="Fractional quantum Hall effect in graphene"))
+display_html(PreprintReference('1204.5479', description="Fractional Majoranas in fractional quantum Hall edges"))
+display_html(PreprintReference('0803.0272', description="A scheme for quantum computation using the toric code"))
+display_html(PreprintReference('1502.01665', description="Making a fractional quantum Hall effect by coupling wires"))
+```
+
+### Bonus: Find your own paper to review!
+
+Do you know of another paper that fits into the topics of this week, and you think is good?
+Then you can get bonus points by reviewing that paper instead!
+
+
+```python
+MoocPeerAssessment(due=7, review_due=11)
+```
+
+**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**
+
+
+```python
+MoocDiscussion("Reviews", "Manybody topology")
+```
diff git a/w1_topointro/0d.ipynb b/w1_topointro/0d.ipynb
deleted file mode 100644
index 1b3a91a..0000000
 a/w1_topointro/0d.ipynb
+++ /dev/null
@@ 1,863 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "\n",
 "%opts Layout [sublabel_format='' aspect_weight=1 figure_size=(100) vspace=0.4]\n",
 "%output size = 150\n",
 "\n",
 "randn = np.random.randn\n",
 "\n",
 "alphas = np.linspace(0, 1, 1000)\n",
 "\n",
 "dims = SimpleNamespace(E=holoviews.Dimension(r'$E$'),\n",
 " alpha=holoviews.Dimension(r'$\\alpha$'),\n",
 " Q=holoviews.Dimension(r'$Q$'),\n",
 " Q_BdG=holoviews.Dimension(r'$Q_{BdG}$'))\n",
 "\n",
 "def make_random_real_ham(N):\n",
 " H = randn(N, N)\n",
 " H += H.T\n",
 " return H / 2\n",
 "\n",
 "\n",
 "def make_cons_ham(N):\n",
 " H = np.kron(pauli.s0, randn(N, N)) + np.kron(pauli.sz, randn(N, N))\n",
 " H += H.T.conj()\n",
 " return H / 2\n",
 "\n",
 "\n",
 "def make_random_ham(N):\n",
 " H = randn(N, N) + 1j * randn(N, N)\n",
 " H += H.T.conj()\n",
 " return H / 2\n",
 "\n",
 "\n",
 "def make_random_symplectic_ham(N):\n",
 " if N % 2:\n",
 " raise ValueError('Matrix dimension should be a multiple of 2')\n",
 " sy = np.kron(np.eye(N // 2), np.array([[0, 1j], [1j, 0]]))\n",
 " h = randn(N, N) + 1j * randn(N, N)\n",
 " h += h.T.conj()\n",
 " Th = sy @ h.conj() @ sy\n",
 " return (h + Th) / 4\n",
 "\n",
 "\n",
 "def make_chiral_ham(N):\n",
 " temp1 = randn(N, N) + 1j * randn(N, N)\n",
 " temp2 = randn(N, N) + 1j * randn(N, N) \n",
 " H = np.kron(pauli.sx, temp1) + np.kron(pauli.sy, temp2)\n",
 " H += H.T.conj()\n",
 " return H / 2\n",
 "\n",
 "\n",
 "def make_BdG_ham(N):\n",
 " # This is antisymmetric basis\n",
 " H = 1j * randn(2*N, 2*N)\n",
 " H += H.T.conj()\n",
 " return H / 2\n",
 "\n",
 "\n",
 "def energies(alpha, H0, H1):\n",
 " H = (1  alpha) * H0 + alpha * H1\n",
 " return np.linalg.eigvalsh(H)\n",
 "\n",
 "\n",
 "def find_spectrum(alphas, H0, H1):\n",
 " spectrum = [energies(a, H0, H1) for a in alphas]\n",
 " return np.array(spectrum)\n",
 "\n",
 "\n",
 "def find_Q(spectrum):\n",
 " \"\"\"Finds the number of bands that are under zero energy.\n",
 "\n",
 " Parameters:\n",
 " \n",
 " spectrum : numpy array\n",
 " Array that contains the energies levels for every alpha.\n",
 "\n",
 " Returns:\n",
 " \n",
 " Q : list\n",
 " Number of bands under zero energy.\n",
 " \"\"\"\n",
 " return [len(s[s<0]) for s in spectrum]\n",
 "\n",
 "\n",
 "def plot_hamiltonian_spectrum(alphas, spectrum, E_range=(4, 4)):\n",
 " \"\"\"Function that plots a spectrum for a range of alphas.\n",
 "\n",
 " Parameters:\n",
 " \n",
 " alphas : numpy array\n",
 " Range of alphas for which the energies are calculated.\n",
 " spectrum : numpy array\n",
 " Array that contains the energies levels for every alpha.\n",
 " E_range : tuple\n",
 " The upper and lower limit of the ydimension.\n",
 "\n",
 " Returns:\n",
 " \n",
 " plot : holoviews.Path object\n",
 " Plot of alphas vs. spectrum.\n",
 " \"\"\"\n",
 " E_min, E_max = E_range\n",
 " plot = holoviews.Path((alphas, spectrum), kdims=[dims.alpha, dims.E])[:, E_min:E_max] * holoviews.HLine(0)\n",
 " return plot(plot={'xticks':[0, 0.5, 1], 'yticks':[E_min, 0, E_max]})\n",
 "\n",
 "\n",
 "def plot_Q(alphas, Q, Q_range, Q_dim=dims.Q):\n",
 " \"\"\"Function that plots value of Q for a range of alphas.\n",
 "\n",
 " Parameters:\n",
 " \n",
 " alphas : numpy array\n",
 " Range of alphas for which the energies are calculated.\n",
 " Q : numpy array\n",
 " Vector that contains the value of Q for every alpha.\n",
 " Q_range : tuple\n",
 " The upper and lower limit of the ydimension.\n",
 "\n",
 " Returns:\n",
 " \n",
 " plot : holoviews.Path object\n",
 " Plot of alphas vs. Q.\n",
 " \"\"\"\n",
 " Q_min, Q_max = Q_range\n",
 " Q_mid = (Q_max + Q_min) / 2\n",
 " plot = holoviews.Area((alphas, Q), kdims=[dims.alpha], vdims=[Q_dim])[:, Q_min:Q_max](style={'alpha': 0.4})\n",
 " plot *= holoviews.Curve((alphas, Q), kdims=[dims.alpha], vdims=[Q_dim])[:, Q_min:Q_max]\n",
 " return plot(plot={'xticks':[0, 0.5, 1], 'yticks':[Q_min, Q_mid, Q_max], 'aspect':4})"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Topology and symmetry"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"5ysdSoorJz4\", src_location='1.1intro')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Zerodimensional quantum systems"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Imagine a quantum system with a finite number of states $N$. The Hamiltonian of such a system is represented by a matrix $H$ of dimension $N\\times N$.\n",
 "This matrix is Hermitian, $H=H^\\dagger$. Its real eigenvalues $E_n$ correspond to the allowed energies of the system,\n",
 "\n",
 "$$H\\,\\leftn\\right\\rangle = E_n\\,\\leftn\\right\\rangle\\,,$$\n",
 "\n",
 "with $\\leftn\\right\\rangle$ the corresponding eigenstate. Let's say that $H$ describes a small quantum dot with a few levels. We can imagine that the quantum dot is in weak contact with a metallic lead, as in the following sketch:\n",
 "\n",
 "\n",
 "![](figures/dot.svg)\n",
 "\n",
 "\n",
 "The presence of a metallic lead allows us to measure all the energies $E_n$ of the electronic states in the dot with respect to the Fermi level $E_F$ of the electrons in the metallic lead. In the following we will set $E_F=0$. Hence, all negative energies $E_n<0$ correspond to filled states in the dot, and all positive energies $E_n>0$ to empty states. In the sketch, the lead and the dot are separated by a potential barrier, such that they are only coupled very weakly. Thus, we can still consider the dot as an isolated system, to a good approximation.\n",
 "\n",
 "\n",
 "We are now ready to start on the main theme of this course, topology."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Topology and gapped quantum systems\n",
 "\n",
 "Topology studies whether objects can be transformed continuously into each other. In condensed matter physics we can ask whether the Hamiltonians of two quantum systems can be continuously transformed into each other. If that is the case, then we can say that two systems are 'topologically equivalent'.\n",
 "\n",
 "If we considered all Hamiltonians without any constraint, every Hamiltonian could be continuously deformed into every other Hamiltonian, and all quantum systems would be topologically equivalent. This changes drastically if we restrict ourselves to systems with an energy gap. This means that there is a finite energy cost to excite the system above its ground state.\n",
 "If an energy gap is present, then the Hamiltonian of the system has no eigenvalues in a finite interval around zero energy.\n",
 "\n",
 "We can now use the following criterion: we say that two gapped quantum systems are topologically equivalent if their Hamiltonians can be continuously deformed into each other *without ever closing the energy gap*.\n",
 "\n",
 "In the following, we will see that often one is interested in some more specific criterion: for instance, that some symmetry may be preserved throughout the continuous path which connects two Hamiltonians.\n",
 "\n",
 "However, for the moment let's just see these ideas at play using our quantum dot as a simple test case. Imagine our dot is initially described by a random $H$, such as:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "np.random.seed(30)\n",
 "H0 = make_random_real_ham(N=4)\n",
 "pprint_matrix(H0)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "For simplicity, we have taken $H$ to be real. Let's now deform this Hamiltonian into another Hamiltonian $H'$, also real. We can imagine that this deformation describes the changes that occur to the dot as an external parameter, such as a gate voltage, is varied. We can parameterize the deformation by\n",
 "\n",
 "$H(\\alpha) = \\alpha H' + (1\\alpha) H,$\n",
 "\n",
 "so that at $\\alpha=0$ we are at the initial Hamiltonian and at $\\alpha=1$ we are at the final Hamiltonian. Let's see what the energy levels do as a function of $\\alpha$ (we use more levels here than in the matrix above so that the spectrum looks more interesting)."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "np.random.seed(69) \n",
 "H0 = make_random_real_ham(N=10)\n",
 "H1 = make_random_real_ham(N=10)\n",
 "spectrum = find_spectrum(alphas, H0, H1)\n",
 "plot_hamiltonian_spectrum(alphas, spectrum)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You may notice from the plot that as $\\alpha$ varies, it can happen that an energy level crosses zero energy. When this happens, we break the condition that there should be an energy gap in the system. Notice, however, that this does not necessarily mean that there is no continuous transformation between $H$ and $H'$ such that the gap does not close. It simply means that this particular path has gap closings. Perhaps it is possible to find another path which does not."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "So are $H$ and $H'$ topologically equivalent or not? Let's look at this situation:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "np.random.seed(6)\n",
 "H0 = make_random_real_ham(N=10)\n",
 "H1 = make_random_real_ham(N=10)\n",
 "spectrum = find_spectrum(alphas, H0, H1)\n",
 "plot_hamiltonian_spectrum(alphas, spectrum)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We see that one level does cross zero (even twice), but it seems obvious that we can just push it down a little bit and we find a continuous path between two Hamiltonians. So we need to come up with an easier way to figure out if Hamiltonians can be transformed into each other or not."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# The concept of a topological invariant"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In order to know whether there is any path which connects $H$ and $H'$ without closing the gap, we can count the number of levels below zero energy, i.e. the number of filled energy levels. This is possible because the eigenvalues of gapped Hamiltonians can move freely as long as they don't cross zero energy. Therefore continuous transformations exist exactly between Hamiltonians with the same number of energy levels below zero.\n",
 "\n",
 "Since this number can not change under continuous transformations inside the set of gapped Hamiltonians, we call it a *topological invariant* $Q$.\n",
 "\n",
 "Below, we plot the energy levels along our path from $H$ to $H'$ again, together with our topological invariant, the number of filled energy levels. You can see that this number changes between 3, 4 and 5. Hence we can say that $H$ and $H'$ are not topologically equivalent."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "np.random.seed(69) \n",
 "H0 = make_random_real_ham(N=10)\n",
 "H1 = make_random_real_ham(N=10) \n",
 "spectrum = find_spectrum(alphas, H0, H1)\n",
 "Q = find_Q(spectrum)\n",
 "(plot_hamiltonian_spectrum(alphas, spectrum) + plot_Q(alphas, Q, [2, 6])).cols(1)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The plot makes it clear that we do not actually have to count the number of filled energy levels for both $H$ and $H'$, so it is enough to keep track of *zero energy crossings*. Whenever an energy level crosses zero energy, the number of levels below zero energy changes. Such a crossing therefore changes the topological invariant. We call that a *topological phase transition*.\n",
 "\n",
 "If two Hamiltonians have a different topological invariant, they must be separated by such a transition. In other words, it is impossible to go from one to the other without closing the gap.\n",
 "\n",
 "On the other hand, if there are equally many levels crossing from below to above zero energy as the other way around, the number of levels below zero energy does not change. The topological invariant is therefore the same for the initial and final Hamiltonian. In this case, there must be a continuous transformation between the initial and final Hamiltonian which does not close the gap.\n",
 "\n",
 "Once we have identified a topological invariant, we can *classify* all quantum Hamiltonians according to its value. In this way we create classes of Hamiltonians which are all topologically equivalent, and we can keep track of all the different *topological phases* that these Hamiltonians can support."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Role of conservation laws\n",
 "\n",
 "Let's now consider the case that the Hamiltonian of the quantum dot satisfies a symmetry constraint. This means that there is a unitary matrix, for example $U = \\sigma_z \\otimes 1\\!\\!1$ where $\\sigma_z$ is the third Pauli matrix, such that the Hamiltonian commutes with this matrix:\n",
 "\n",
 "$$U^\\dagger H U = H.$$\n",
 "\n",
 "This means that the system has a conservation law, and that the Hamiltonian can be brought to a blockdiagonal form:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "modes = 5\n",
 "np.random.seed(10) \n",
 "H0 = make_cons_ham(2)\n",
 "pprint_matrix(H0)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We can now look at the spectrum and the topological invariant of each subblock individually,"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "%%opts Layout [aspect_weight=1 fig_inches=(8, 6) fig_size=100 ]\n",
 "np.random.seed(13) \n",
 "H0 = make_cons_ham(modes)\n",
 "H1 = make_cons_ham(modes)\n",
 "spectrum1 = find_spectrum(alphas, H0[:modes, :modes], H1[:modes, :modes])\n",
 "spectrum2 = find_spectrum(alphas, H0[modes:, modes:], H1[modes:, modes:])\n",
 "Q1 = find_Q(spectrum1)\n",
 "Q2 = find_Q(spectrum2)\n",
 "(plot_hamiltonian_spectrum(alphas, spectrum1, [3, 3]) + plot_hamiltonian_spectrum(alphas, spectrum2, [3, 3])\n",
 " + plot_Q(alphas, Q1, [0, 4]) + plot_Q(alphas, Q2, [0, 4])).cols(2)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "and combine them to get the spectrum and the topological invariant of the whole system:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "spectrum = find_spectrum(alphas, H0, H1)\n",
 "Q = find_Q(spectrum)\n",
 "(plot_hamiltonian_spectrum(alphas, spectrum) + plot_Q(alphas, Q, [3, 7])).cols(1)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As you can see, unitary symmetries play a rather boring role. As usual, they allow to reduce the dimension of the problem at hand, but nothing more. There are however other symmetries which can have a rich influence on topology. An important example is timereversal symmetry, as we will see next."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Timereversal symmetry"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In our previous examples, you might have wondered, whether there was anything special with choosing real matrices? Indeed there was something special. A real Hamiltonian is a manifestation of timereversal symmetry. Timereversal symmetry is represented by an antiunitary operator, and as such it can always be written as the product $\\mathcal{T}=U\\mathcal{K}$ of a unitary matrix times complex conjugation. In the case above, we had simply $\\mathcal{T}\\equiv\\mathcal{K}$. Our real Hamiltonians clearly obeyed timereversal symmetry since $H=H^*$.\n",
 "\n",
 "Let's now break timereversal symmetry, create random Hamiltonians with complex entries and see what happens."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "np.random.seed(91) \n",
 "H0 = make_random_ham(N=4)\n",
 "pprint_matrix(H0)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "np.random.seed(92) \n",
 "H0 = make_random_ham(N=10)\n",
 "H1 = make_random_ham(N=10) \n",
 "spectrum = find_spectrum(alphas, H0, H1)\n",
 "Q = find_Q(spectrum)\n",
 "(plot_hamiltonian_spectrum(alphas, spectrum) + plot_Q(alphas, Q, [3, 7])).cols(1)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As you can see, there aren't really many differences with the previous case. The different energy levels move, and the topological invariant changes when one of them crosses zero.\n",
 "\n",
 "There is, however, a very important case where timereversal symmetry makes a real difference. For systems with spin $1/2$, timereversal symmetry has the operator\n",
 "\n",
 "$$\n",
 "\\mathcal{T}=i\\sigma_y \\mathcal{K},\n",
 "$$\n",
 "\n",
 "with $\\sigma_y$ the second Pauli matrix acting on the spin degree of freedom. In that case $\\mathcal{T}^2=1$. A Hamiltonian with this type of timereversal symmetry obeys the equation\n",
 "\n",
 "$$\n",
 "H = \\sigma_y\\, H^* \\sigma_y.\n",
 "$$\n",
 "\n",
 "The following matrix is an example of such Hamiltonian:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "np.random.seed(49) \n",
 "H0 = make_random_symplectic_ham(N=4)\n",
 "pprint_matrix(H0)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Hamiltonians of this type have the following property: every energy eigenvalue $E_n$ is doubly degenerate (Kramers' degeneracy). We can see the consequences of Kramers' degeneracy on our game of deforming one random Hamiltonian into another."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "np.random.seed(2285) \n",
 "H0 = make_random_symplectic_ham(N=10)\n",
 "H1 = make_random_symplectic_ham(N=10) \n",
 "spectrum = find_spectrum(alphas, H0, H1)\n",
 "Q = find_Q(spectrum)\n",
 "(plot_hamiltonian_spectrum(alphas, spectrum) + plot_Q(alphas, Q, [3, 7])).cols(1)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "While the spectrum looks quite similar to the previous ones, whenever a line crosses zero energy, our topological invariant makes a jump of two, and not one! In this case, timereversal symmetry constrains the topological invariant to only take even values. This is an example of how topological properties can be influenced by discrete symmetries."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Sublattice symmetry"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We just saw that timereversal symmetry can forbid the topological invariant to take a certain set of values. We now study another case where a symmetry changes the topological properties dramatically. \n",
 "\n",
 "Let's now take a system where we can split all the degrees of freedom into two groups (say group $A$ and group $B$) such that the Hamiltonian only has nonzero matrix elements between two groups, and not inside each group. This situation arises naturally when the lattice has two sublattices, as in the hexagonal carbon lattice of graphene. So let's imagine our quantum dot is now a graphene dot:\n",
 "\n",
 "![](figures/graphene_dot.svg)\n",
 "\n",
 "As a consequence of sublattice symmetry, the Hamiltonian of the graphene dot looks like this:\n",
 "\n",
 "$$\n",
 "H =\n",
 "\\begin{pmatrix}\n",
 "0 & H_{AB} \\\\\n",
 "H_{AB}^\\dagger & 0\n",
 "\\end{pmatrix}.\n",
 "$$\n",
 "\n",
 "We can once again generate a random Hamiltonian with sublattice symmetry, here:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "np.random.seed(98)\n",
 "pprint_matrix(make_chiral_ham(2))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "If we introduce a diagonal matrix $\\sigma_z$ that equals $+1$ for sites on sublattice $A$, and $1$ for sites on sublattice $B$, we can write the sublattice symmetry of the Hamiltonian as\n",
 "\n",
 "$$\n",
 "\\sigma_z H \\sigma_z = H.\n",
 "$$\n",
 "\n",
 "This immediately means that if $(\\psi_A, \\psi_B)^T$ is an eigenvector of the Hamiltonian with energy $\\varepsilon$, then\n",
 "$(\\psi_A, \\psi_B)^T$ is an eigenvector with energy $\\varepsilon$. A symmetric spectrum is the consequence of sublattice symmetry.\n",
 "\n",
 "What does this mean for the topological classification?\n",
 "Clearly, the number of states with negative energy is the same as the number of states with positive energy, and that means we don't ever expect a single level to cross zero energy.\n",
 "\n",
 "Let's once again see if this is correct by transforming a random Hamiltonian with sublattice symmetry into another one."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "modes = 10\n",
 "np.random.seed(99) \n",
 "H0 = make_chiral_ham(modes)\n",
 "H1 = make_chiral_ham(modes)\n",
 "spectrum = find_spectrum(alphas, H0, H1)\n",
 "plot_hamiltonian_spectrum(alphas, spectrum, [3, 3])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Indeed, we can deform all the Hamiltonians with sublattice symmetry into one another without closing the gap.\n",
 "This means that an extra symmetry may render topological classification trivial. "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"OK, let's see what we have so far. Which symmetry certainly \"\n",
 " \"does not restrict the values that the topological invariant can take?\")\n",
 "\n",
 "answers = [\"Spinless timereversal symmetry\", \"Sublattice symmetry\", \"Conservation law\", \"Spinful timereversal symmetry\"]\n",
 "\n",
 "explanation = (\"We cannot be sure about the conservation law, since the blocks may have different remaining symmetries. \"\n",
 " \"And we just saw that sublattice symmetry makes every system trivial, while spinful timereversal \"\n",
 " \"makes the numbers of levels even.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=0, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Particlehole symmetry"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "There is another symmetry that has a strong influence on topology: particlehole symmetry. It shows up in superconducting systems. As an example, imagine bringing our quantum dot in contact with a superconductor, like this:\n",
 "\n",
 "![](figures/SCdot.svg)\n",
 "\n",
 "A superconductor will create and annihilate pairs of electrons by breaking apart [Cooper pairs](https://en.wikipedia.org/wiki/Cooper_pair) and forming them.\n",
 "This results in a Hamiltonian:\n",
 "\n",
 "$$\n",
 "\\mathcal{H} = \\sum_{nm} H_{nm} c^\\dagger_nc_m + \\tfrac{1}{2} (\\Delta_{nm} c^\\dagger_n c^\\dagger_m + \\Delta^*_{nm} c_m c_n),\n",
 "$$\n",
 "\n",
 "where $c^\\dagger_n, c_n$ are the creation and annihilation operators of the electrons. We recall that these operators anticommute, obeying the relations $c_nc_m+c_mc_n=0$ and $c^\\dagger_n c_m + c_m c^\\dagger_n = \\delta_{mn}$, where $\\delta_{mn}=0$ if $m\\neq n$ and $1$ if $m=n$.\n",
 "\n",
 "The $H$term is the dynamics of the electrons in the dot, while $\\Delta$ describes the pair creation and annihilation. The matrix $\\Delta$ is antisymmetric because the fermion operators anticommute. Now $\\mathcal{H}$ does not conserve the number of electrons, but still conserves the parity of the number of electrons, that is whether the number of electrons is even or odd. We can now group all the creation and annihilation operators in a vector, $C = (c_1, \\dots, c_n, c^\\dagger_1, \\dots, c^\\dagger_n)^T$. Then we write $\\mathcal{H}$ in the form 'row multiplies matrix multiplies column':\n",
 "\n",
 "$$\n",
 "\\mathcal{H} = \\frac{1}{2} C^\\dagger H_\\textrm{BdG}\\,C\\,.\n",
 "$$\n",
 "\n",
 "The matrix $H_\\textrm{BdG}$ is known as the Bogoliubovde Gennes Hamiltonian, and it has the following structure:\n",
 "\n",
 "$$\n",
 "H_\\textrm{BdG} = \\begin{pmatrix} H & \\Delta \\\\ \\Delta^* & H^* \\end{pmatrix}.\n",
 "$$\n",
 "\n",
 "The Bogoliubovde Gennes Hamiltonian acts on wave functions whose first half is composed out of annihilation operators of electrons, and the second half out of creations operators of the same electrons.\n",
 "We can think of them as annihilation operators of an extra set of holes, so that we double the amount of degrees of freedom in the system.\n",
 "\n",
 "Since holes are related to the electrons, $H_{BdG}$ automatically has an extra symmetry.\n",
 "This symmetry exchanges electrons with holes, and has an antiunitary operator $\\mathcal{P}=\\tau_x \\mathcal{K}$, where the Pauli matrix $\\tau_x$ acts on the particle and hole blocks. We have that:\n",
 "\n",
 "$$\n",
 "\\mathcal{P} H_\\textrm{BdG} \\mathcal{P}^{1} = H_\\textrm{BdG}.\n",
 "$$\n",
 "\n",
 "Particlehole symmetry is represented by an antiunitary operator which anticommutes with the Hamiltonian (compare this situation with that of timereversal and sublattice symmetries). Because of the minus sign in the particlehole symmetry, the spectrum of $H_\\textrm{BdG}$ must be symmetric around zero energy (that is, the Fermi level). Indeed, for every eigenvector $\\psi = (u, v)^T$ of $H_\\textrm{BdG}$ with energy $E$, there will be a particlehole symmetric eigenvector $\\mathcal{P}\\psi=(v^*, u^*)^T$ with energy $E$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Fermi level crossings in a random Bogoliubovde Gennes Hamiltonian\n",
 "\n",
 "Let's generate a random Bogoliubovde Gennes Hamiltonian $H_\\textrm{BdG}$:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "modes = 2\n",
 "np.random.seed(101) \n",
 "H0 = make_BdG_ham(modes)\n",
 "H1 = make_BdG_ham(modes)\n",
 "\n",
 "#Print in 'normal' basis\n",
 "H0_normal = np.kron(np.array([[1, 1j],[1, 1j]]), np.identity(modes)) @ H0\n",
 "H0_normal = H0_normal @ np.kron(np.array([[1, 1],[1j, 1j]]), np.identity(modes))\n",
 "pprint_matrix(H0_normal)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We can now see what happens when we deform it into a second one. You can indeed see clearly that the spectrum is mirrored around the line $E=0$, just like it was in the presence of sublattice symmetry."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "modes = 10\n",
 "np.random.seed(5)\n",
 "H0 = make_BdG_ham(modes)\n",
 "H1 = make_BdG_ham(modes)\n",
 "spectrum = find_spectrum(alphas, H0, H1)\n",
 "plot_hamiltonian_spectrum(alphas, spectrum, [3, 3])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You can however notice that, unlike in the case of sublattice symmetry, energy levels do not repel around zero energy, so that crossings at zero energy appear."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Fermion parity switches\n",
 "\n",
 "Let's think a bit more about these crossings. At first, they might look a bit mysterious. In general a crossing between energy levels happens in the presence of a conserved quantity, and our random Bogoliubovde Gennes Hamiltonian does not seem to have an obvious one. Let's however recall what we said earlier: While the meanfield Hamiltonian of a superconductor does not conserve the number of particles, it conserves the parity of this number. In other words, forming and breaking Cooper pairs does not affect whether the superconducting quantum dots contains an even or odd number of electrons. In short, fermion parity is a conserved quantity (provided that isolated electrons do not enter or leave the dot, a possibility which we will disregard).\n",
 "\n",
 "The above observation reveals that the existence of crossings is due to the fermion parity conservation. Fermion parity, however, is a manybody quantity, which cannot be directly described in terms of the single particle picture of the Bogoliubovde Gennes Hamiltonian. \n",
 "To understand the existence of the crossings, recall that to obtain a Bogoliubovde Gennes description of the superconductor we had to double the number of degrees of freedom by introducing holes.\n",
 "Hence, unlike in the case of sublattice symmetry, a pair of $\\pm E$ energy levels does not corresponds to two distinct quantum states, but to a *single* quantum state.\n",
 "This quantum state is a coherent superposition of electrons and holes  a *Bogoliubov quasiparticle*: it has an excitation energy $E$, and it is created by an operator $a^\\dagger = u c^\\dagger + v c$.\n",
 "Populating the partner state at energy $E$ is the same as emptying the positive energy state.\n",
 "\n",
 "When a pair of levels crosses zero energy, the excitation energy $E$ of the Bogoliubov quasiparticle changes sign and it becomes favorable to add a Bogoliubov quasiparticle to, or remove it from the superconducting quantum dot. In other words, at each crossing the fermion parity in the ground state of the dot changes from even to odd, or vice versa. Hence these crossings are *fermion parity switches*.\n",
 "\n",
 "Since the ground state fermion parity is preserved by the superconducting Hamiltonian if there are no Bogoliubov quasiparticles crossing zero energy, the ground state fermion parity is the topological invariant of this system. It is clear however that this invariant is of a different nature than the one of the nonsuperconducting systems, which is given by the number of negative eigenvalues of the Hamiltonian. The latter cannot change for a Bogoliubovde Gennes Hamiltonian, which has a symmetric energy spectrum, and hence it is not suitable to describe changes in fermion parity. Is there a way to compute this new invariant directly from the Bogoliubovde Gennes Hamiltonian?"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## The Pfaffian invariant\n",
 "\n",
 "In order to introduce the new invariant, we have to start with a basis transformation, that makes the Hamiltonian an antisymmetric matrix. We use the following unitary transformation in particlehole space,\n",
 "\n",
 "$$\n",
 "\\tilde{H}_{BdG}=\\frac{1}{2}\\left( \\begin{array}{cc}\n",
 "1 & 1 \\\\\n",
 "i & i \\end{array} \\right) \n",
 "H_{BdG} \n",
 "\\left( \\begin{array}{cc}\n",
 "1 & i \\\\\n",
 "1 & i \\end{array} \\right)\\,.\n",
 "$$\n",
 "\n",
 "We then have\n",
 "\n",
 "$$\n",
 "\\tilde{H}_\\textrm{BdG} = \\frac{1}{2}\\begin{pmatrix} HH^*+\\Delta\\Delta^* & iHiH^*+i\\Delta+i\\Delta^* \\\\ +iH+iH^*+i\\Delta+i\\Delta^* & HH^*\\Delta+\\Delta^* \\end{pmatrix}.\n",
 "$$\n",
 "\n",
 "We already know that the pairing matrix $\\Delta$ is antisymmetric. Since $H$ is Hermitian $HH^*$ is also antisymmetric and $H+H^*$ is symmetric. Then we can see that $\\tilde{H}_\\textrm{BdG}$ is antisymmetric.\n",
 "\n",
 "There is a special number that we can compute for antisymmetric matrices, the [Pfaffian](http://en.wikipedia.org/wiki/Pfaffian). Its rigorous definition is not important for our course. The basic idea is simple: The eigenvalues of antisymmetric matrices always come in pairs. In the case of our $\\tilde{H}_{BdG}$, these are the energy eigenvalues $\\pm E_n$. By taking their product we obtain the determinant of the matrix, equal to $\\prod_n (E_n^2)$. The key property of the Pfaffian is that it allows to take a square root of the determinant, equal to $\\pm i\\prod_n E_n$, in such a way that the sign of the product is uniquely defined. At a fermion parity switch a single $E_n$ changes sign, so the Pfaffian changes sign as well (while the determinant stays the same).\n",
 "\n",
 "This feature of the Pfaffian really makes it what we are looking for. Let's try out the sign of the Pfaffian as our topological invariant $Q_\\textrm{BdG}$:\n",
 "\n",
 "$$ Q_\\textrm{BdG} = \\textrm{sign}\\left[\\,\\textrm{Pf} (i H_\\textrm{BdG})\\,\\right]\\,.$$\n",
 "\n",
 "We have included a factor of $i$ just for convenience, so that the Pfaffian is a real number.\n",
 "\n",
 "Whenever we need to compute a Pfaffian we just use the [Pfapack](http://arxiv.org/abs/1102.3440) package that calculates Pfaffians for numerical matrices. Let's use that package and check that the Pfaffian indeed allows us to calculate the fermion parity of the ground state of $H_\\textrm{BdG}$."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "%%opts Overlay [yticks=[1, 0, 1]]\n",
 "\n",
 "def find_pfaffian(alphas, H0, H1):\n",
 " \"\"\"Function caculates the Pfaffian for a Hamiltonian.\n",
 "\n",
 " Parameters:\n",
 " \n",
 " alphas : numpy array\n",
 " Range of alphas for which the energies are calculated.\n",
 " H0 : numpy array\n",
 " Hamiltonian, same size as H1.\n",
 " H1 : numpy array\n",
 " Hamiltonian, same size as H0.\n",
 " \n",
 " Returns:\n",
 " \n",
 " pfaffians : numpy array\n",
 " Pfaffians for each alpha.\n",
 " \"\"\"\n",
 " def H(alpha):\n",
 " return (1  alpha) * H0 + alpha * H1\n",
 " pfaffians = [np.sign(np.real(pf.pfaffian(1j*H(a)))) for a in alphas]\n",
 " return np.array(pfaffians)\n",
 "\n",
 "pfaffian = find_pfaffian(alphas, H0, H1)\n",
 "(plot_hamiltonian_spectrum(alphas, spectrum, [1.5, 1.5]) + plot_Q(alphas, pfaffian, [1.5, 1.5], dims.Q_BdG)).cols(1)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You can see how the Pfaffian invariant $Q_\\textrm{BdG}$ changes its value from $+1$ to $1$ at every zeroenergy crossing. \n",
 "This means that it is the correct expression for the ground state fermion parity and for the topological invariant."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"What happens to the topological invariant if we take the superconducting\" +\n",
 " \" Hamiltonian and set $\\Delta=0$?\")\n",
 "answers = [\"The Pfaffian invariant still captures all of the topological properties.\",\n",
 " \"The Hamiltonian loses particlehole symmetry and becomes topologically trivial.\",\n",
 " \"The Hamiltonian now has a new conservation law so there are two blocks, each with its own invariant.\",\n",
 " \"It isn't allowed to set $\\Delta=0$\"]\n",
 "explanation = (\"If $\\Delta=0$ the numbers of filled electron and hole states is conserved, and so the invariant once again\"\n",
 " \" becomes just the number of filled states.\")\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=2, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Conclusion"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"C7HoXjVbpoM\", src_location='1.1summary')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Questions about what you learned? Ask them below**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion('Questions', 'Hamiltonians, Topology and Symmetry')"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w1_topointro/0d.md b/w1_topointro/0d.md
new file mode 100644
index 0000000..fdcdb73
 /dev/null
+++ b/w1_topointro/0d.md
@@ 0,0 +1,581 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+
+%opts Layout [sublabel_format='' aspect_weight=1 figure_size=(100) vspace=0.4]
+%output size = 150
+
+randn = np.random.randn
+
+alphas = np.linspace(0, 1, 1000)
+
+dims = SimpleNamespace(E=holoviews.Dimension(r'$E$'),
+ alpha=holoviews.Dimension(r'$\alpha$'),
+ Q=holoviews.Dimension(r'$Q$'),
+ Q_BdG=holoviews.Dimension(r'$Q_{BdG}$'))
+
+def make_random_real_ham(N):
+ H = randn(N, N)
+ H += H.T
+ return H / 2
+
+
+def make_cons_ham(N):
+ H = np.kron(pauli.s0, randn(N, N)) + np.kron(pauli.sz, randn(N, N))
+ H += H.T.conj()
+ return H / 2
+
+
+def make_random_ham(N):
+ H = randn(N, N) + 1j * randn(N, N)
+ H += H.T.conj()
+ return H / 2
+
+
+def make_random_symplectic_ham(N):
+ if N % 2:
+ raise ValueError('Matrix dimension should be a multiple of 2')
+ sy = np.kron(np.eye(N // 2), np.array([[0, 1j], [1j, 0]]))
+ h = randn(N, N) + 1j * randn(N, N)
+ h += h.T.conj()
+ Th = sy @ h.conj() @ sy
+ return (h + Th) / 4
+
+
+def make_chiral_ham(N):
+ temp1 = randn(N, N) + 1j * randn(N, N)
+ temp2 = randn(N, N) + 1j * randn(N, N)
+ H = np.kron(pauli.sx, temp1) + np.kron(pauli.sy, temp2)
+ H += H.T.conj()
+ return H / 2
+
+
+def make_BdG_ham(N):
+ # This is antisymmetric basis
+ H = 1j * randn(2*N, 2*N)
+ H += H.T.conj()
+ return H / 2
+
+
+def energies(alpha, H0, H1):
+ H = (1  alpha) * H0 + alpha * H1
+ return np.linalg.eigvalsh(H)
+
+
+def find_spectrum(alphas, H0, H1):
+ spectrum = [energies(a, H0, H1) for a in alphas]
+ return np.array(spectrum)
+
+
+def find_Q(spectrum):
+ """Finds the number of bands that are under zero energy.
+
+ Parameters:
+ 
+ spectrum : numpy array
+ Array that contains the energies levels for every alpha.
+
+ Returns:
+ 
+ Q : list
+ Number of bands under zero energy.
+ """
+ return [len(s[s<0]) for s in spectrum]
+
+
+def plot_hamiltonian_spectrum(alphas, spectrum, E_range=(4, 4)):
+ """Function that plots a spectrum for a range of alphas.
+
+ Parameters:
+ 
+ alphas : numpy array
+ Range of alphas for which the energies are calculated.
+ spectrum : numpy array
+ Array that contains the energies levels for every alpha.
+ E_range : tuple
+ The upper and lower limit of the ydimension.
+
+ Returns:
+ 
+ plot : holoviews.Path object
+ Plot of alphas vs. spectrum.
+ """
+ E_min, E_max = E_range
+ plot = holoviews.Path((alphas, spectrum), kdims=[dims.alpha, dims.E])[:, E_min:E_max] * holoviews.HLine(0)
+ return plot(plot={'xticks':[0, 0.5, 1], 'yticks':[E_min, 0, E_max]})
+
+
+def plot_Q(alphas, Q, Q_range, Q_dim=dims.Q):
+ """Function that plots value of Q for a range of alphas.
+
+ Parameters:
+ 
+ alphas : numpy array
+ Range of alphas for which the energies are calculated.
+ Q : numpy array
+ Vector that contains the value of Q for every alpha.
+ Q_range : tuple
+ The upper and lower limit of the ydimension.
+
+ Returns:
+ 
+ plot : holoviews.Path object
+ Plot of alphas vs. Q.
+ """
+ Q_min, Q_max = Q_range
+ Q_mid = (Q_max + Q_min) / 2
+ plot = holoviews.Area((alphas, Q), kdims=[dims.alpha], vdims=[Q_dim])[:, Q_min:Q_max](style={'alpha': 0.4})
+ plot *= holoviews.Curve((alphas, Q), kdims=[dims.alpha], vdims=[Q_dim])[:, Q_min:Q_max]
+ return plot(plot={'xticks':[0, 0.5, 1], 'yticks':[Q_min, Q_mid, Q_max], 'aspect':4})
+```
+
+# Topology and symmetry
+
+
+```python
+MoocVideo("5ysdSoorJz4", src_location='1.1intro')
+```
+
+# Zerodimensional quantum systems
+
+Imagine a quantum system with a finite number of states $N$. The Hamiltonian of such a system is represented by a matrix $H$ of dimension $N\times N$.
+This matrix is Hermitian, $H=H^\dagger$. Its real eigenvalues $E_n$ correspond to the allowed energies of the system,
+
+$$H\,\leftn\right\rangle = E_n\,\leftn\right\rangle\,,$$
+
+with $\leftn\right\rangle$ the corresponding eigenstate. Let's say that $H$ describes a small quantum dot with a few levels. We can imagine that the quantum dot is in weak contact with a metallic lead, as in the following sketch:
+
+
+![](figures/dot.svg)
+
+
+The presence of a metallic lead allows us to measure all the energies $E_n$ of the electronic states in the dot with respect to the Fermi level $E_F$ of the electrons in the metallic lead. In the following we will set $E_F=0$. Hence, all negative energies $E_n<0$ correspond to filled states in the dot, and all positive energies $E_n>0$ to empty states. In the sketch, the lead and the dot are separated by a potential barrier, such that they are only coupled very weakly. Thus, we can still consider the dot as an isolated system, to a good approximation.
+
+
+We are now ready to start on the main theme of this course, topology.
+
+## Topology and gapped quantum systems
+
+Topology studies whether objects can be transformed continuously into each other. In condensed matter physics we can ask whether the Hamiltonians of two quantum systems can be continuously transformed into each other. If that is the case, then we can say that two systems are 'topologically equivalent'.
+
+If we considered all Hamiltonians without any constraint, every Hamiltonian could be continuously deformed into every other Hamiltonian, and all quantum systems would be topologically equivalent. This changes drastically if we restrict ourselves to systems with an energy gap. This means that there is a finite energy cost to excite the system above its ground state.
+If an energy gap is present, then the Hamiltonian of the system has no eigenvalues in a finite interval around zero energy.
+
+We can now use the following criterion: we say that two gapped quantum systems are topologically equivalent if their Hamiltonians can be continuously deformed into each other *without ever closing the energy gap*.
+
+In the following, we will see that often one is interested in some more specific criterion: for instance, that some symmetry may be preserved throughout the continuous path which connects two Hamiltonians.
+
+However, for the moment let's just see these ideas at play using our quantum dot as a simple test case. Imagine our dot is initially described by a random $H$, such as:
+
+
+```python
+np.random.seed(30)
+H0 = make_random_real_ham(N=4)
+pprint_matrix(H0)
+```
+
+For simplicity, we have taken $H$ to be real. Let's now deform this Hamiltonian into another Hamiltonian $H'$, also real. We can imagine that this deformation describes the changes that occur to the dot as an external parameter, such as a gate voltage, is varied. We can parameterize the deformation by
+
+$H(\alpha) = \alpha H' + (1\alpha) H,$
+
+so that at $\alpha=0$ we are at the initial Hamiltonian and at $\alpha=1$ we are at the final Hamiltonian. Let's see what the energy levels do as a function of $\alpha$ (we use more levels here than in the matrix above so that the spectrum looks more interesting).
+
+
+```python
+np.random.seed(69)
+H0 = make_random_real_ham(N=10)
+H1 = make_random_real_ham(N=10)
+spectrum = find_spectrum(alphas, H0, H1)
+plot_hamiltonian_spectrum(alphas, spectrum)
+```
+
+You may notice from the plot that as $\alpha$ varies, it can happen that an energy level crosses zero energy. When this happens, we break the condition that there should be an energy gap in the system. Notice, however, that this does not necessarily mean that there is no continuous transformation between $H$ and $H'$ such that the gap does not close. It simply means that this particular path has gap closings. Perhaps it is possible to find another path which does not.
+
+So are $H$ and $H'$ topologically equivalent or not? Let's look at this situation:
+
+
+```python
+np.random.seed(6)
+H0 = make_random_real_ham(N=10)
+H1 = make_random_real_ham(N=10)
+spectrum = find_spectrum(alphas, H0, H1)
+plot_hamiltonian_spectrum(alphas, spectrum)
+```
+
+We see that one level does cross zero (even twice), but it seems obvious that we can just push it down a little bit and we find a continuous path between two Hamiltonians. So we need to come up with an easier way to figure out if Hamiltonians can be transformed into each other or not.
+
+# The concept of a topological invariant
+
+In order to know whether there is any path which connects $H$ and $H'$ without closing the gap, we can count the number of levels below zero energy, i.e. the number of filled energy levels. This is possible because the eigenvalues of gapped Hamiltonians can move freely as long as they don't cross zero energy. Therefore continuous transformations exist exactly between Hamiltonians with the same number of energy levels below zero.
+
+Since this number can not change under continuous transformations inside the set of gapped Hamiltonians, we call it a *topological invariant* $Q$.
+
+Below, we plot the energy levels along our path from $H$ to $H'$ again, together with our topological invariant, the number of filled energy levels. You can see that this number changes between 3, 4 and 5. Hence we can say that $H$ and $H'$ are not topologically equivalent.
+
+
+```python
+np.random.seed(69)
+H0 = make_random_real_ham(N=10)
+H1 = make_random_real_ham(N=10)
+spectrum = find_spectrum(alphas, H0, H1)
+Q = find_Q(spectrum)
+(plot_hamiltonian_spectrum(alphas, spectrum) + plot_Q(alphas, Q, [2, 6])).cols(1)
+```
+
+The plot makes it clear that we do not actually have to count the number of filled energy levels for both $H$ and $H'$, so it is enough to keep track of *zero energy crossings*. Whenever an energy level crosses zero energy, the number of levels below zero energy changes. Such a crossing therefore changes the topological invariant. We call that a *topological phase transition*.
+
+If two Hamiltonians have a different topological invariant, they must be separated by such a transition. In other words, it is impossible to go from one to the other without closing the gap.
+
+On the other hand, if there are equally many levels crossing from below to above zero energy as the other way around, the number of levels below zero energy does not change. The topological invariant is therefore the same for the initial and final Hamiltonian. In this case, there must be a continuous transformation between the initial and final Hamiltonian which does not close the gap.
+
+Once we have identified a topological invariant, we can *classify* all quantum Hamiltonians according to its value. In this way we create classes of Hamiltonians which are all topologically equivalent, and we can keep track of all the different *topological phases* that these Hamiltonians can support.
+
+## Role of conservation laws
+
+Let's now consider the case that the Hamiltonian of the quantum dot satisfies a symmetry constraint. This means that there is a unitary matrix, for example $U = \sigma_z \otimes 1\!\!1$ where $\sigma_z$ is the third Pauli matrix, such that the Hamiltonian commutes with this matrix:
+
+$$U^\dagger H U = H.$$
+
+This means that the system has a conservation law, and that the Hamiltonian can be brought to a blockdiagonal form:
+
+
+```python
+modes = 5
+np.random.seed(10)
+H0 = make_cons_ham(2)
+pprint_matrix(H0)
+```
+
+We can now look at the spectrum and the topological invariant of each subblock individually,
+
+
+```python
+%%opts Layout [aspect_weight=1 fig_inches=(8, 6) fig_size=100 ]
+np.random.seed(13)
+H0 = make_cons_ham(modes)
+H1 = make_cons_ham(modes)
+spectrum1 = find_spectrum(alphas, H0[:modes, :modes], H1[:modes, :modes])
+spectrum2 = find_spectrum(alphas, H0[modes:, modes:], H1[modes:, modes:])
+Q1 = find_Q(spectrum1)
+Q2 = find_Q(spectrum2)
+(plot_hamiltonian_spectrum(alphas, spectrum1, [3, 3]) + plot_hamiltonian_spectrum(alphas, spectrum2, [3, 3])
+ + plot_Q(alphas, Q1, [0, 4]) + plot_Q(alphas, Q2, [0, 4])).cols(2)
+```
+
+and combine them to get the spectrum and the topological invariant of the whole system:
+
+
+```python
+spectrum = find_spectrum(alphas, H0, H1)
+Q = find_Q(spectrum)
+(plot_hamiltonian_spectrum(alphas, spectrum) + plot_Q(alphas, Q, [3, 7])).cols(1)
+```
+
+As you can see, unitary symmetries play a rather boring role. As usual, they allow to reduce the dimension of the problem at hand, but nothing more. There are however other symmetries which can have a rich influence on topology. An important example is timereversal symmetry, as we will see next.
+
+# Timereversal symmetry
+
+In our previous examples, you might have wondered, whether there was anything special with choosing real matrices? Indeed there was something special. A real Hamiltonian is a manifestation of timereversal symmetry. Timereversal symmetry is represented by an antiunitary operator, and as such it can always be written as the product $\mathcal{T}=U\mathcal{K}$ of a unitary matrix times complex conjugation. In the case above, we had simply $\mathcal{T}\equiv\mathcal{K}$. Our real Hamiltonians clearly obeyed timereversal symmetry since $H=H^*$.
+
+Let's now break timereversal symmetry, create random Hamiltonians with complex entries and see what happens.
+
+
+```python
+np.random.seed(91)
+H0 = make_random_ham(N=4)
+pprint_matrix(H0)
+```
+
+
+```python
+np.random.seed(92)
+H0 = make_random_ham(N=10)
+H1 = make_random_ham(N=10)
+spectrum = find_spectrum(alphas, H0, H1)
+Q = find_Q(spectrum)
+(plot_hamiltonian_spectrum(alphas, spectrum) + plot_Q(alphas, Q, [3, 7])).cols(1)
+```
+
+As you can see, there aren't really many differences with the previous case. The different energy levels move, and the topological invariant changes when one of them crosses zero.
+
+There is, however, a very important case where timereversal symmetry makes a real difference. For systems with spin $1/2$, timereversal symmetry has the operator
+
+$$
+\mathcal{T}=i\sigma_y \mathcal{K},
+$$
+
+with $\sigma_y$ the second Pauli matrix acting on the spin degree of freedom. In that case $\mathcal{T}^2=1$. A Hamiltonian with this type of timereversal symmetry obeys the equation
+
+$$
+H = \sigma_y\, H^* \sigma_y.
+$$
+
+The following matrix is an example of such Hamiltonian:
+
+
+```python
+np.random.seed(49)
+H0 = make_random_symplectic_ham(N=4)
+pprint_matrix(H0)
+```
+
+Hamiltonians of this type have the following property: every energy eigenvalue $E_n$ is doubly degenerate (Kramers' degeneracy). We can see the consequences of Kramers' degeneracy on our game of deforming one random Hamiltonian into another.
+
+
+```python
+np.random.seed(2285)
+H0 = make_random_symplectic_ham(N=10)
+H1 = make_random_symplectic_ham(N=10)
+spectrum = find_spectrum(alphas, H0, H1)
+Q = find_Q(spectrum)
+(plot_hamiltonian_spectrum(alphas, spectrum) + plot_Q(alphas, Q, [3, 7])).cols(1)
+```
+
+While the spectrum looks quite similar to the previous ones, whenever a line crosses zero energy, our topological invariant makes a jump of two, and not one! In this case, timereversal symmetry constrains the topological invariant to only take even values. This is an example of how topological properties can be influenced by discrete symmetries.
+
+# Sublattice symmetry
+
+We just saw that timereversal symmetry can forbid the topological invariant to take a certain set of values. We now study another case where a symmetry changes the topological properties dramatically.
+
+Let's now take a system where we can split all the degrees of freedom into two groups (say group $A$ and group $B$) such that the Hamiltonian only has nonzero matrix elements between two groups, and not inside each group. This situation arises naturally when the lattice has two sublattices, as in the hexagonal carbon lattice of graphene. So let's imagine our quantum dot is now a graphene dot:
+
+![](figures/graphene_dot.svg)
+
+As a consequence of sublattice symmetry, the Hamiltonian of the graphene dot looks like this:
+
+$$
+H =
+\begin{pmatrix}
+0 & H_{AB} \\
+H_{AB}^\dagger & 0
+\end{pmatrix}.
+$$
+
+We can once again generate a random Hamiltonian with sublattice symmetry, here:
+
+
+```python
+np.random.seed(98)
+pprint_matrix(make_chiral_ham(2))
+```
+
+If we introduce a diagonal matrix $\sigma_z$ that equals $+1$ for sites on sublattice $A$, and $1$ for sites on sublattice $B$, we can write the sublattice symmetry of the Hamiltonian as
+
+$$
+\sigma_z H \sigma_z = H.
+$$
+
+This immediately means that if $(\psi_A, \psi_B)^T$ is an eigenvector of the Hamiltonian with energy $\varepsilon$, then
+$(\psi_A, \psi_B)^T$ is an eigenvector with energy $\varepsilon$. A symmetric spectrum is the consequence of sublattice symmetry.
+
+What does this mean for the topological classification?
+Clearly, the number of states with negative energy is the same as the number of states with positive energy, and that means we don't ever expect a single level to cross zero energy.
+
+Let's once again see if this is correct by transforming a random Hamiltonian with sublattice symmetry into another one.
+
+
+```python
+modes = 10
+np.random.seed(99)
+H0 = make_chiral_ham(modes)
+H1 = make_chiral_ham(modes)
+spectrum = find_spectrum(alphas, H0, H1)
+plot_hamiltonian_spectrum(alphas, spectrum, [3, 3])
+```
+
+Indeed, we can deform all the Hamiltonians with sublattice symmetry into one another without closing the gap.
+This means that an extra symmetry may render topological classification trivial.
+
+
+```python
+question = ("OK, let's see what we have so far. Which symmetry certainly "
+ "does not restrict the values that the topological invariant can take?")
+
+answers = ["Spinless timereversal symmetry", "Sublattice symmetry", "Conservation law", "Spinful timereversal symmetry"]
+
+explanation = ("We cannot be sure about the conservation law, since the blocks may have different remaining symmetries. "
+ "And we just saw that sublattice symmetry makes every system trivial, while spinful timereversal "
+ "makes the numbers of levels even.")
+
+MoocMultipleChoiceAssessment(question, answers, correct_answer=0, explanation=explanation)
+```
+
+# Particlehole symmetry
+
+There is another symmetry that has a strong influence on topology: particlehole symmetry. It shows up in superconducting systems. As an example, imagine bringing our quantum dot in contact with a superconductor, like this:
+
+![](figures/SCdot.svg)
+
+A superconductor will create and annihilate pairs of electrons by breaking apart [Cooper pairs](https://en.wikipedia.org/wiki/Cooper_pair) and forming them.
+This results in a Hamiltonian:
+
+$$
+\mathcal{H} = \sum_{nm} H_{nm} c^\dagger_nc_m + \tfrac{1}{2} (\Delta_{nm} c^\dagger_n c^\dagger_m + \Delta^*_{nm} c_m c_n),
+$$
+
+where $c^\dagger_n, c_n$ are the creation and annihilation operators of the electrons. We recall that these operators anticommute, obeying the relations $c_nc_m+c_mc_n=0$ and $c^\dagger_n c_m + c_m c^\dagger_n = \delta_{mn}$, where $\delta_{mn}=0$ if $m\neq n$ and $1$ if $m=n$.
+
+The $H$term is the dynamics of the electrons in the dot, while $\Delta$ describes the pair creation and annihilation. The matrix $\Delta$ is antisymmetric because the fermion operators anticommute. Now $\mathcal{H}$ does not conserve the number of electrons, but still conserves the parity of the number of electrons, that is whether the number of electrons is even or odd. We can now group all the creation and annihilation operators in a vector, $C = (c_1, \dots, c_n, c^\dagger_1, \dots, c^\dagger_n)^T$. Then we write $\mathcal{H}$ in the form 'row multiplies matrix multiplies column':
+
+$$
+\mathcal{H} = \frac{1}{2} C^\dagger H_\textrm{BdG}\,C\,.
+$$
+
+The matrix $H_\textrm{BdG}$ is known as the Bogoliubovde Gennes Hamiltonian, and it has the following structure:
+
+$$
+H_\textrm{BdG} = \begin{pmatrix} H & \Delta \\ \Delta^* & H^* \end{pmatrix}.
+$$
+
+The Bogoliubovde Gennes Hamiltonian acts on wave functions whose first half is composed out of annihilation operators of electrons, and the second half out of creations operators of the same electrons.
+We can think of them as annihilation operators of an extra set of holes, so that we double the amount of degrees of freedom in the system.
+
+Since holes are related to the electrons, $H_{BdG}$ automatically has an extra symmetry.
+This symmetry exchanges electrons with holes, and has an antiunitary operator $\mathcal{P}=\tau_x \mathcal{K}$, where the Pauli matrix $\tau_x$ acts on the particle and hole blocks. We have that:
+
+$$
+\mathcal{P} H_\textrm{BdG} \mathcal{P}^{1} = H_\textrm{BdG}.
+$$
+
+Particlehole symmetry is represented by an antiunitary operator which anticommutes with the Hamiltonian (compare this situation with that of timereversal and sublattice symmetries). Because of the minus sign in the particlehole symmetry, the spectrum of $H_\textrm{BdG}$ must be symmetric around zero energy (that is, the Fermi level). Indeed, for every eigenvector $\psi = (u, v)^T$ of $H_\textrm{BdG}$ with energy $E$, there will be a particlehole symmetric eigenvector $\mathcal{P}\psi=(v^*, u^*)^T$ with energy $E$.
+
+## Fermi level crossings in a random Bogoliubovde Gennes Hamiltonian
+
+Let's generate a random Bogoliubovde Gennes Hamiltonian $H_\textrm{BdG}$:
+
+
+```python
+modes = 2
+np.random.seed(101)
+H0 = make_BdG_ham(modes)
+H1 = make_BdG_ham(modes)
+
+#Print in 'normal' basis
+H0_normal = np.kron(np.array([[1, 1j],[1, 1j]]), np.identity(modes)) @ H0
+H0_normal = H0_normal @ np.kron(np.array([[1, 1],[1j, 1j]]), np.identity(modes))
+pprint_matrix(H0_normal)
+```
+
+We can now see what happens when we deform it into a second one. You can indeed see clearly that the spectrum is mirrored around the line $E=0$, just like it was in the presence of sublattice symmetry.
+
+
+```python
+modes = 10
+np.random.seed(5)
+H0 = make_BdG_ham(modes)
+H1 = make_BdG_ham(modes)
+spectrum = find_spectrum(alphas, H0, H1)
+plot_hamiltonian_spectrum(alphas, spectrum, [3, 3])
+```
+
+You can however notice that, unlike in the case of sublattice symmetry, energy levels do not repel around zero energy, so that crossings at zero energy appear.
+
+## Fermion parity switches
+
+Let's think a bit more about these crossings. At first, they might look a bit mysterious. In general a crossing between energy levels happens in the presence of a conserved quantity, and our random Bogoliubovde Gennes Hamiltonian does not seem to have an obvious one. Let's however recall what we said earlier: While the meanfield Hamiltonian of a superconductor does not conserve the number of particles, it conserves the parity of this number. In other words, forming and breaking Cooper pairs does not affect whether the superconducting quantum dots contains an even or odd number of electrons. In short, fermion parity is a conserved quantity (provided that isolated electrons do not enter or leave the dot, a possibility which we will disregard).
+
+The above observation reveals that the existence of crossings is due to the fermion parity conservation. Fermion parity, however, is a manybody quantity, which cannot be directly described in terms of the single particle picture of the Bogoliubovde Gennes Hamiltonian.
+To understand the existence of the crossings, recall that to obtain a Bogoliubovde Gennes description of the superconductor we had to double the number of degrees of freedom by introducing holes.
+Hence, unlike in the case of sublattice symmetry, a pair of $\pm E$ energy levels does not corresponds to two distinct quantum states, but to a *single* quantum state.
+This quantum state is a coherent superposition of electrons and holes  a *Bogoliubov quasiparticle*: it has an excitation energy $E$, and it is created by an operator $a^\dagger = u c^\dagger + v c$.
+Populating the partner state at energy $E$ is the same as emptying the positive energy state.
+
+When a pair of levels crosses zero energy, the excitation energy $E$ of the Bogoliubov quasiparticle changes sign and it becomes favorable to add a Bogoliubov quasiparticle to, or remove it from the superconducting quantum dot. In other words, at each crossing the fermion parity in the ground state of the dot changes from even to odd, or vice versa. Hence these crossings are *fermion parity switches*.
+
+Since the ground state fermion parity is preserved by the superconducting Hamiltonian if there are no Bogoliubov quasiparticles crossing zero energy, the ground state fermion parity is the topological invariant of this system. It is clear however that this invariant is of a different nature than the one of the nonsuperconducting systems, which is given by the number of negative eigenvalues of the Hamiltonian. The latter cannot change for a Bogoliubovde Gennes Hamiltonian, which has a symmetric energy spectrum, and hence it is not suitable to describe changes in fermion parity. Is there a way to compute this new invariant directly from the Bogoliubovde Gennes Hamiltonian?
+
+## The Pfaffian invariant
+
+In order to introduce the new invariant, we have to start with a basis transformation, that makes the Hamiltonian an antisymmetric matrix. We use the following unitary transformation in particlehole space,
+
+$$
+\tilde{H}_{BdG}=\frac{1}{2}\left( \begin{array}{cc}
+1 & 1 \\
+i & i \end{array} \right)
+H_{BdG}
+\left( \begin{array}{cc}
+1 & i \\
+1 & i \end{array} \right)\,.
+$$
+
+We then have
+
+$$
+\tilde{H}_\textrm{BdG} = \frac{1}{2}\begin{pmatrix} HH^*+\Delta\Delta^* & iHiH^*+i\Delta+i\Delta^* \\ +iH+iH^*+i\Delta+i\Delta^* & HH^*\Delta+\Delta^* \end{pmatrix}.
+$$
+
+We already know that the pairing matrix $\Delta$ is antisymmetric. Since $H$ is Hermitian $HH^*$ is also antisymmetric and $H+H^*$ is symmetric. Then we can see that $\tilde{H}_\textrm{BdG}$ is antisymmetric.
+
+There is a special number that we can compute for antisymmetric matrices, the [Pfaffian](http://en.wikipedia.org/wiki/Pfaffian). Its rigorous definition is not important for our course. The basic idea is simple: The eigenvalues of antisymmetric matrices always come in pairs. In the case of our $\tilde{H}_{BdG}$, these are the energy eigenvalues $\pm E_n$. By taking their product we obtain the determinant of the matrix, equal to $\prod_n (E_n^2)$. The key property of the Pfaffian is that it allows to take a square root of the determinant, equal to $\pm i\prod_n E_n$, in such a way that the sign of the product is uniquely defined. At a fermion parity switch a single $E_n$ changes sign, so the Pfaffian changes sign as well (while the determinant stays the same).
+
+This feature of the Pfaffian really makes it what we are looking for. Let's try out the sign of the Pfaffian as our topological invariant $Q_\textrm{BdG}$:
+
+$$ Q_\textrm{BdG} = \textrm{sign}\left[\,\textrm{Pf} (i H_\textrm{BdG})\,\right]\,.$$
+
+We have included a factor of $i$ just for convenience, so that the Pfaffian is a real number.
+
+Whenever we need to compute a Pfaffian we just use the [Pfapack](http://arxiv.org/abs/1102.3440) package that calculates Pfaffians for numerical matrices. Let's use that package and check that the Pfaffian indeed allows us to calculate the fermion parity of the ground state of $H_\textrm{BdG}$.
+
+
+```python
+%%opts Overlay [yticks=[1, 0, 1]]
+
+def find_pfaffian(alphas, H0, H1):
+ """Function caculates the Pfaffian for a Hamiltonian.
+
+ Parameters:
+ 
+ alphas : numpy array
+ Range of alphas for which the energies are calculated.
+ H0 : numpy array
+ Hamiltonian, same size as H1.
+ H1 : numpy array
+ Hamiltonian, same size as H0.
+
+ Returns:
+ 
+ pfaffians : numpy array
+ Pfaffians for each alpha.
+ """
+ def H(alpha):
+ return (1  alpha) * H0 + alpha * H1
+ pfaffians = [np.sign(np.real(pf.pfaffian(1j*H(a)))) for a in alphas]
+ return np.array(pfaffians)
+
+pfaffian = find_pfaffian(alphas, H0, H1)
+(plot_hamiltonian_spectrum(alphas, spectrum, [1.5, 1.5]) + plot_Q(alphas, pfaffian, [1.5, 1.5], dims.Q_BdG)).cols(1)
+```
+
+You can see how the Pfaffian invariant $Q_\textrm{BdG}$ changes its value from $+1$ to $1$ at every zeroenergy crossing.
+This means that it is the correct expression for the ground state fermion parity and for the topological invariant.
+
+
+```python
+question = ("What happens to the topological invariant if we take the superconducting" +
+ " Hamiltonian and set $\Delta=0$?")
+answers = ["The Pfaffian invariant still captures all of the topological properties.",
+ "The Hamiltonian loses particlehole symmetry and becomes topologically trivial.",
+ "The Hamiltonian now has a new conservation law so there are two blocks, each with its own invariant.",
+ "It isn't allowed to set $\Delta=0$"]
+explanation = ("If $\Delta=0$ the numbers of filled electron and hole states is conserved, and so the invariant once again"
+ " becomes just the number of filled states.")
+MoocMultipleChoiceAssessment(question, answers, correct_answer=2, explanation=explanation)
+```
+
+# Conclusion
+
+
+```python
+MoocVideo("C7HoXjVbpoM", src_location='1.1summary')
+```
+
+**Questions about what you learned? Ask them below**
+
+
+```python
+MoocDiscussion('Questions', 'Hamiltonians, Topology and Symmetry')
+```
diff git a/w1_topointro/1D.ipynb b/w1_topointro/1D.ipynb
deleted file mode 100644
index 0429b0b..0000000
 a/w1_topointro/1D.ipynb
+++ /dev/null
@@ 1,658 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "\n",
 "%output size=150\n",
 "dims = SimpleNamespace(E_t=holoviews.Dimension(r'$E/t$'),\n",
 " mu_t=holoviews.Dimension(r'$\\mu/t$'),\n",
 " lambda_=holoviews.Dimension(r'$\\lambda$'),\n",
 " x=holoviews.Dimension(r'$x$'),\n",
 " k=holoviews.Dimension(r'$k$'),\n",
 " amplitude=holoviews.Dimension(r'$u^2 + v^2$'))\n",
 "\n",
 "holoviews.core.dimension.title_format = ''\n",
 "\n",
 "def kitaev_chain(L=None, periodic=False):\n",
 " lat = kwant.lattice.chain()\n",
 "\n",
 " if L is None:\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry((1,)))\n",
 " L = 1\n",
 " else:\n",
 " syst = kwant.Builder()\n",
 "\n",
 " # transformation to antisymmetric basis\n",
 " U = np.array([[1.0, 1.0], [1.j, 1.j]]) / np.sqrt(2)\n",
 "\n",
 " def onsite(onsite, p): \n",
 " return  p.mu * U @ pauli.sz @ U.T.conj()\n",
 " \n",
 " for x in range(L):\n",
 " syst[lat(x)] = onsite\n",
 "\n",
 " def hop(site1, site2, p):\n",
 " return U @ (p.t * pauli.sz  1j * p.delta * pauli.sy) @ U.T.conj()\n",
 " \n",
 " syst[kwant.HoppingKind((1,), lat)] = hop\n",
 "\n",
 " if periodic:\n",
 " def last_hop(site1, site2, p):\n",
 " return hop(site1, site2, p) * (1  2 * p.lambda_)\n",
 " \n",
 " syst[lat(0), lat(L  1)] = last_hop\n",
 " return syst\n",
 "\n",
 "\n",
 "def bandstructure(mu, delta=1, t=1, Dirac_cone=\"Hide\", show_pf=False):\n",
 " syst = kitaev_chain(None)\n",
 " p = SimpleNamespace(t=t, delta=delta, mu=mu)\n",
 " plot = holoviews.Overlay([spectrum(syst, p, ydim=\"$E/T$\", xdim='$k$')][4:4])\n",
 " h_1 = h_k(syst, p, 0)\n",
 " h_2 = h_k(syst, p, np.pi)\n",
 " pfaffians = [find_pfaffian(h_1), find_pfaffian(h_2)]\n",
 " \n",
 " if show_pf:\n",
 " signs = [('>' if pf > 0 else '<') for pf in pfaffians]\n",
 " title = \"$\\mu = {mu} t$, Pf$(iH_{{k=0}}) {sign1} 0$, Pf$(iH_{{k=\\pi}}) {sign2} 0$\"\n",
 " title = title.format(mu=mu, sign1=signs[0], sign2=signs[1])\n",
 " plot *= holoviews.VLine(0) * holoviews.VLine(np.pi)\n",
 " else:\n",
 " if pfaffians[0] * pfaffians[1] < 0:\n",
 " title = \"$\\mu = {mu} t$, topological \".format(mu=mu)\n",
 " else:\n",
 " title = \"$\\mu = {mu} t$, trivial \".format(mu=mu)\n",
 " \n",
 " if Dirac_cone == \"Show\":\n",
 " ks = np.linspace(np.pi, np.pi)\n",
 " ec = np.sqrt((mu + 2 * t)**2 + 4.0 * (delta * ks)**2)\n",
 " plot *= holoviews.Path((ks, ec), kdims=[dims.k, dims.E_t])(style={'linestyle':'', 'color':'r'})\n",
 " plot *= holoviews.Path((ks, ec), kdims=[dims.k, dims.E_t])(style={'linestyle':'', 'color':'r'})\n",
 " return plot.relabel(title)\n",
 "\n",
 "def find_pfaffian(H):\n",
 " return np.sign(np.real(pf.pfaffian(1j*H)))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Kitaev chain and bulkedge correspondence"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"U84MzZm9Gbo\", src_location='1.2intro')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Unpaired Majorana modes in onedimensional systems"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Fermion operators and Majorana operators\n",
 "\n",
 "Let's start from the creation and annihilation operators $c^\\dagger$ and $c$ of a fermionic mode. These operators satisfy the anticommutation relation $c^\\dagger c + cc^\\dagger = 1$ and, furthermore, square to zero, $c^2=0$ and $(c^\\dagger)^2=0$. They connect two states $\\left0\\right\\rangle$ and $\\left1\\right\\rangle$ which correspond to the 'vacuum' state with no particle and the 'excited' state with one particle, according to the following rules $c \\left0\\right\\rangle = 0$, $c^\\dagger\\left0\\right\\rangle=\\left1\\right\\rangle$ and $c^\\dagger \\left1\\right\\rangle = 0$.\n",
 "\n",
 "When you have a pair of $c$ and $c^\\dagger$ operators, you can write them down in the following way\n",
 "\n",
 "$$ c^\\dagger = \\tfrac{1}{2}(\\gamma_1+i\\gamma_2),\\;\\; c = \\tfrac{1}{2}(\\gamma_1i\\gamma_2).$$\n",
 "\n",
 "The operators $\\gamma_1$ and $\\gamma_2$ are known as Majorana operators. By inverting the transformation above, you can see that $\\gamma_1=\\gamma_1^\\dagger$ and $\\gamma_2=\\gamma_2^\\dagger$. Because of this property, we cannot think of a single Majorana mode as being 'empty' or 'filled', as we can do for a normal fermionic mode. This makes Majorana modes special.\n",
 "\n",
 "You can also check that to maintain all the properties of $c$ and $c^\\dagger$, the operators $\\gamma_1$ and $\\gamma_2$ must satisfy the following relations:\n",
 "\n",
 "$$\\gamma_1\\gamma_2 + \\gamma_2\\gamma_1 = 0\\;,\\;\\gamma_1^2=1\\;,\\;\\gamma_2^2=1\\;.$$\n",
 "\n",
 "You can see that Majorana modes are similar to normal fermions in the sense that they have operators which all anticommute with each other. Using Majorana modes instead of normal fermionic modes is very similar to writing down two real numbers in place of a complex number. Indeed, every fermion operator can always be expressed in terms of a pair of Majorana operators. This also means that Majorana modes always come in even numbers.\n",
 "\n",
 "The two Majorana operators $\\gamma_1, \\gamma_2$ still act on the same states $\\left0\\right\\rangle$ and $\\left1\\right\\rangle$.\n",
 "If these two states have an energy difference $\\epsilon$, this corresponds to a Hamiltonian $H=\\epsilon c^\\dagger c$.\n",
 "We can also express this Hamiltonian in terms of Majoranas as $H=\\tfrac{1}{2}\\,\\epsilon\\,(1  i\\gamma_1\\gamma_2)$.\n",
 "\n",
 "But is it possible to have a single isolated Majorana mode, one that is not close to its partner?\n",
 "The naive answer is 'no': condensed matter systems are made out of electrons, and these always correspond to pairs of Majoranas.\n",
 "However, it turns out that by engineering the Hamiltonian in a special way it actually is possible to separate two Majoranas."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Unpaired Majorana modes in a model of dominoes\n",
 "\n",
 "Let's see how creating isolated Majoranas can be done. Let us consider a chain of $N$ sites, where each site can host a fermion with creation operator $c^\\dagger_n$. Equivalently, each site hosts two Majorana modes $\\gamma_{2n1}$ and $\\gamma_{2n}$. This situation is illustrated below for $N=4$, where each site is represented by a domino tile.\n",
 "\n",
 "![](figures/majorana_dominoes.svg)\n",
 "\n",
 "What happens if we pair the Majoranas? This means that the energy cost for each fermion to be occupied is $\\mu$, and the Hamiltonian becomes\n",
 "\n",
 "$$H=(i/2)\\,\\mu\\, \\sum_{n=1}^{N} \\gamma_{2n1}\\gamma_{2n}.$$\n",
 "\n",
 "This is how the pairing looks:\n",
 "\n",
 "![](figures/trivial_dominoes.svg)\n",
 "\n",
 "All the excitations in this system have an energy $\\pm\\mu/2$, and the chain has a gapped bulk and no zero energy edge states.\n",
 "\n",
 "Of course this didn't help us to achieve our aim, so let's pair the Majoranas differently.\n",
 "We want only one Majorana to remain at an edge, so let's pair up the Majoranas from *adjacent* sites, leaving the first one and the last one without a neighboring partner:\n",
 "\n",
 "![](figures/topological_dominoes.svg)\n",
 "\n",
 "To every pair formed in this way, we assign an energy difference $2t$ between the empty and filled state, hence arriving at the Hamiltonian\n",
 "\n",
 "$$H=it \\sum_{n=1}^{N1} \\gamma_{2n}\\gamma_{2n+1}.$$\n",
 "\n",
 "You can see that the two end Majorana modes $\\gamma_1$ and $\\gamma_{2N}$ do not appear in $H$ at all.\n",
 "Hence our chain has two zeroenergy states, localized at its ends.\n",
 "All the states which are not at the ends of the chain have an energy of $\\pm t$, independently on the length of the chain. Hence, we have a onedimensional system with a gapped bulk and zero energy states at the edges."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## The Kitaev chain model\n",
 "\n",
 "Let us now try to write the Hamiltonian $H$, which we have so far written in terms of Majoranas, in terms of regular fermions by substituting $\\gamma_{2n1}=(c_n^\\dagger+c_n)$ and $\\gamma_{2n}=i(c_n^\\daggerc_n)$. We find that both pairings sketched above are extreme limits of one tightbinding Hamiltonian for a onedimensional superconducting wire:\n",
 "\n",
 "$$H=\\mu\\sum_n c_n^\\dagger c_nt\\sum_n (c_{n+1}^\\dagger c_n+\\textrm{h.c.}) + \\Delta\\sum_n (c_n c_{n+1}+\\textrm{h.c.})\\,.$$\n",
 "\n",
 "It has three real parameters: the onsite energy $\\mu$, the hopping $t$ between different sites, and the superconducting pairing $\\Delta$. Note that the $\\Delta$ terms create or annihilate pairs of particles at neighboring sites.\n",
 "\n",
 "Starting from this Hamiltonian, the unpaired Majorana regime is the special point $\\Delta=t$ and $\\mu=0$, while the completely trivial regime of isolated fermions is $\\Delta=t=0$ and $\\mu\\neq 0$.\n",
 "\n",
 "As we learned just before, it is useful to write down the above superconducting Hamiltonian in the Bogoliubovde Gennes formalism $H = \\tfrac{1}{2} C^\\dagger H_\\textrm{BdG} C$, with $C$ a column vector containing all creation and annihilation operators, $C=(c_1, \\dots, c_N, c_1^\\dagger, \\dots, c^\\dagger_N)^T$. The $2N\\times 2N$ matrix $H_\\textrm{BdG}$ can be written in a compact way by using Pauli matrices $\\tau$ in particle and hole space, and denoting with $\\leftn\\right\\rangle$ a column basis vector $(0,\\dots,1,0,\\dots)^T$ corresponding to the $n$th site of the chain. In this way, we have for instance that $C^\\dagger\\,\\tau_z\\,\\leftn\\right\\rangle\\left\\langle n\\right\\,C = 2c_n^\\dagger c_n1$. The Bogoliubovde Gennes Hamiltonian is then given by\n",
 "\n",
 "$$H_{BdG}=\\sum_n \\mu \\tau_z\\leftn\\right\\rangle\\left\\langle n\\right\\sum_n \\left[(t\\tau_z+i\\Delta\\tau_y)\\,\\leftn\\right\\rangle\\left\\langle n+1 \\right + \\textrm{h.c.}\\right].$$\n",
 "\n",
 "The BdG Hamiltonian acts on a set of basis states $\\leftn\\right\\rangle\\left\\tau\\right\\rangle$, with $\\tau=\\pm 1$ corresponding to electron and hole states respectively. It has particlehole symmetry, $\\mathcal{P}H_\\textrm{BdG}\\mathcal{P}^{1}=H_\\textrm{BdG}$ with $\\mathcal{P}=\\tau_x\\mathcal{K}$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Topological protection of edge Majorana modes\n",
 "\n",
 "The fact that the Kitaev model can have unpaired Majorana zero modes is certainly interesting. At this point you might however object:\n",
 "\n",
 "\"Unpaired Majoranas appear because you chose one particular, and perhaps even unreachable, set of parameters! Clearly by setting $\\mu=0$ you have cut the first and last Majorana mode from the rest of the chain. I bet that if you change the value of $\\mu$ only slightly from zero, the zero modes will be coupled to the rest of the chain and quickly disappear. So these Majorana modes may just be an artefact appearing in this highly tuned model!\"\n",
 "\n",
 "Well, let's test if this objection is true. Let's start from the situation with unpaired Majorana modes ($\\Delta=t, \\mu=0$) and then increase $\\mu$. Then let's plot the energy spectrum of a chain with $N=25$ sites as a function of $\\mu$, and also keep track how do the two lowest energy states of our system look like, when we change $\\mu$ **(move the slider)**:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "def plot_wf(syst, wf1, wf2, lstyle='', lcolor='b'):\n",
 " xs = np.array([i.pos[0] for i in syst.sites])\n",
 " indx = np.argsort(xs)\n",
 " wf_sq = np.linalg.norm(wf1.reshape(1, 2), axis=1)**2 + np.linalg.norm(wf2.reshape(1, 2), axis=1)**2\n",
 " plot = holoviews.Path((xs[indx], wf_sq[indx]), kdims=[dims.x, dims.amplitude])\n",
 " return plot(style={'linestyle': lstyle, 'color': lcolor},\n",
 " plot={'yticks': 0, 'xticks': list(range(0, len(xs), 10))})\n",
 "\n",
 "def plot_pwave(L, t, delta, mu):\n",
 " # At mu=0 the first exited state is not well defined due to the massive degeneracy.\n",
 " # That is why we add a small offset to mu.\n",
 " syst = kitaev_chain(L).finalized()\n",
 " p = SimpleNamespace(t=t, delta=delta, mu=mu+1e4)\n",
 " ham = syst.hamiltonian_submatrix(args=[p])\n",
 " ev, evec = np.linalg.eigh(ham)\n",
 " return (plot_wf(syst, evec[:, L], evec[:, L1]) *\n",
 " plot_wf(syst, evec[:, L+1] , evec[:, L2], lstyle='', lcolor='r'))\n",
 "\n",
 "syst = kitaev_chain(L=25)\n",
 "mus = np.arange(0, 4, 0.2)\n",
 "p = SimpleNamespace(t=1, delta=1, mu=mus)\n",
 "\n",
 "(spectrum(syst, p, xticks=[0, 1, 2, 3], yticks=range(3, 4), \n",
 " xdim=dims.mu_t, ydim=dims.E_t, ylims=(3, 3)) * \n",
 " holoviews.HoloMap({mu: holoviews.VLine(mu) for mu in mus}, kdims=[dims.mu_t]) +\n",
 " holoviews.HoloMap({mu: plot_pwave(25, 1.0, 1.0, mu) for mu in mus}, kdims=[dims.mu_t]))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The left panel shows the spectrum, where we see two states at zero energy that split. On the right panel the blue line is the wave function of the state corresponding to the pair of Majorana modes, while the red dashed line is the wave function of the first excited state."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As you can see, the zero energy eigenvalues corresponding to the two unpaired Majorana zero modes persist for a long time, and they only split in energy when $\\mu \\simeq 2t$. Another thing that we observe is that the wave function of the Majoranas stays zero in the middle of our wire.\n",
 "\n",
 "As we increase $\\mu$ (try it), the wave function of the Majoranas becomes less localized near the edges of the wire, but the coupling between two ends only appears later.\n",
 "\n",
 "You would observe a similar behavior if you varied $\\mu$ in the negative direction starting from $\\mu=0$. The Majoranas persist until $\\mu\\simeq2t$, where the bulk gap closes.\n",
 "\n",
 "In fact, the Majoranas only split when the higherenergy states in the bulk, originally separated by an energy gap of $2 t$, come very close to zero energy. So our investigation shows that the Majorana modes are protected **as long as the bulk energy gap is finite**.\n",
 "\n",
 "How can we understand this? Recall that we are dealing with a particlehole symmetric Hamiltonian. Hence, the spectrum has to be symmetric around zero energy. When $\\mu=0$, we have two zero energy levels, corresponding to the Majorana modes which are localized far away from each other and separated by a gapped medium. Trying to move these levels from zero energy individually is impossible, as it would violate particlehole symmetry:\n",
 "\n",
 "![](figures/level_deformation_fig.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The only possibility to move the energy levels from zero is to couple the two unpaired Majorana modes to each other. However, because of the spatial separation between Majoranas and of the presence of an energy gap, this coupling is impossible. The only way to split the Majorana modes in energy is to first close the bulk energy gap, and that is exactly what happens at large values of $\\mu$ (to be precise, it happens at $\\mu=2t$).\n",
 "\n",
 "So we have just learned the following:\n",
 "\n",
 "> Isolated zero endmodes at each end in the Kitaev chain are protected by **symmetry** between positive and negative energy, and by the **absence of zeroenergy excitations in the bulk of the wire**, but not by finetuning of the chain parameters.\n",
 "\n",
 "As you see, our conclusion sounds a lot like what we learned about topology just before. We have come to these conclusions by studying a Kitaev chain on an open geometry with boundaries, and by focusing on the presence or absence of edge states localized at the boundaries of the chain. In the rest of the unit we will see that the presence or absence of edge states can be deduced by studying the bulk alone. In order to do this, we will now study an infinite Kitaev chain without boundaries."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (\"But wait! What happens if we remove the last Majorana site of a Kitaev chain\"\n",
 " \" in the topological phase?\")\n",
 "answers = [\"We get a chain with a single Majorana mode.\",\n",
 " \"We cannot remove a single Majorana site because electrons (pairs of Majoranas) \"\n",
 " \"are the only physical degrees of freedom.\",\n",
 " \"The Hamiltonian becomes topologically trivial.\",\n",
 " \"Removing a single Majorana is not allowed by particlehole symmetry\"]\n",
 "explanation = \"Indeed, as we explained, removing a single Majorana is like removing a single pole of a magnet. So not possible.\"\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Topological phases from the bulk spectrum"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Going to momentum space\n",
 "\n",
 "The Majoranas are edge excitations that arise from the bulkedge correspondence. You might wonder if there is a way to deduce the existence of Majorana modes by looking at the bulk? To answer this, eliminate the boundaries from the study of the Kitaev chain. You can imagine that the last site of the chain is reconnected to the first, so that the chain is closed in a ring (a “Kitaev ring”). In the absence of boundaries, the Bogoliubovde Gennes Hamiltonian has a translational symmetry $\\leftn\\right\\rangle\\,\\to\\,\\leftn+1\\right\\rangle$, since all parameters $t, \\Delta$ and $\\mu$ do not depend on the chain site $n$. In the presence of translational symmetries, it is always convenient to use [Bloch's theorem](http://en.wikipedia.org/wiki/Bloch_wave#Preliminaries:_Crystal_symmetries.2C_lattice.2C_and_reciprocal_lattice) and write down the Hamiltonian in momentum space rather than in real space. In our case, a state with momentum $k$ is given by\n",
 "\n",
 "$$ \\leftk\\right\\rangle =(N)^{1/2} \\sum_{n=1}^{N} e^{ikn} \\leftn\\right\\rangle.$$\n",
 "\n",
 "We apply periodic boundary conditions, that is $\\left\\langle k  n=0 \\right\\rangle=\\left\\langle k  n=N \\right\\rangle$. The momentum $k$ is then a conserved quantum number with allowed values $2\\pi p /N$ where $p=0, 1, 2, \\dots, N1$. Values of $k$ which differ by $2\\pi$ are equivalent. One can also imagine that for very large $N$, $k$ is a continuous periodic variable with values in the interval $[\\pi,\\pi]$, the **Brillouin zone**. Because $k$ is a good quantum number, the Bogoliubovde Gennes Hamiltonian in momentum space can be reduced to a $2\\times 2$ matrix:\n",
 "\n",
 "$$ H(k) \\equiv \\left\\langle k\\right H_\\textrm{BdG} \\left k \\right\\rangle = (2t\\cos{k}\\mu)\\,\\tau_z + 2\\Delta \\sin{k}\\,\\,\\tau_y.$$\n",
 "\n",
 "The full Bogoliubovde Gennes Hamiltonian is obtained by summing all these $2\\times 2$ blocks:\n",
 "\n",
 "$$ H_\\textrm{BdG} = \\sum_k H(k) \\left k \\right\\rangle\\left\\langle k \\right.$$\n",
 "\n",
 "In the limit of an infinite chain the sum becomes an integral over the Brillouin zone."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Particlehole symmetry in momentum space\n",
 "\n",
 "Going to momentum space does not affect the particlehole symmetry of the Bogoliubovde Gennes Hamiltonian. However, one must always be careful in dealing with antiunitary operators when making a basis transformation. The reason is that the action of the complex conjugation operator might depend on the basis. In our case, we have\n",
 "\n",
 "$$\\mathcal{P}\\leftk\\right\\rangle\\!\\left\\tau\\right\\rangle = \\left(\\sum_n\\,e^{ikn}\\right)^*\\,\\leftn\\right\\rangle\\,\\tau_x\\left\\tau\\right\\rangle^*=\\leftk\\right\\rangle\\,\\tau_x\\left\\tau\\right\\rangle^*.$$\n",
 "\n",
 "Note that the particlehole symmetry operator changes $k$ to $k$. Therefore, the action of $\\mathcal{P}$ on the Bogoliubovde Gennes Hamiltonian written in momentum space is the following:\n",
 "\n",
 "$$\\mathcal{P}H_\\textrm{BdG}\\mathcal{P}^{1} = \\sum_k \\tau_xH^*(k)\\tau_x \\left k \\right\\rangle\\left\\langle k \\right=\\sum_k \\tau_xH^*(k)\\tau_x \\left k \\right\\rangle\\left\\langle k \\right\\,.$$\n",
 "\n",
 "In the last equality, we have used the fact that the allowed values of $k$ always come in $(k, k)$ pairs, plus the two symmetric points $k=0$ and $k=\\pi$. Therefore, particlehole symmetry $\\mathcal{P}H_\\textrm{BdG}\\mathcal{P}^{1}= H_\\textrm{BdG}$ implies that\n",
 "\n",
 "$$H(k)=\\tau_xH^*(k)\\tau_x.$$\n",
 "\n",
 "You can verify that it is indeed the case:\n",
 "\n",
 "$$\\tau_x H^*(k) \\tau_x = (2t\\cos{k}+\\mu)\\,\\tau_z  2\\Delta \\sin{k}\\,\\,\\tau_y.$$\n",
 "\n",
 "Given a solution with energy $E$ and momentum $k$, particlehole symmetry dictates in general the presence of a solution with energy $E$ and momentum $k$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Band structure\n",
 "\n",
 "At this point, we only need to diagonalize this $2\\times 2$ matrix to obtain the *band structure* of the Kitaev chain model, that is the energy levels $E(k)$. This can be done very easily, and results in two energy bands, one with positive energy and one with negative energy:\n",
 "\n",
 "$$ E(k) = \\pm\\sqrt{(2t\\cos{k}+\\mu)^2 + 4\\Delta^2\\sin^2{k}}. $$\n",
 "\n",
 "Let's see what this band structure looks like (**once again move the slider** to change $\\mu$):"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "mus = np.arange(3, 3, 0.25)\n",
 "\n",
 "plots = {(mu, Dirac_cone): bandstructure(mu, Dirac_cone=Dirac_cone) \n",
 " for mu in mus \n",
 " for Dirac_cone in [\"Show\", \"Hide\"]}\n",
 "\n",
 "holoviews.HoloMap(plots, kdims=[dims.mu_t, \"Dirac cone\"])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You can see that the energy spectrum is gapped at all $k$ for $\\mu=0$. This is natural: Since our chain does not have boundaries anymore, the energy spectrum does not contain the zero energy Majorana modes which we found in the previous subsection at $\\mu=0$. However, you can see very clearly the bulk gap closing which occurs at the points $\\mu=2t$ and $\\mu=2t$. Indeed, for these values of $\\mu$ the two bands at negative and positive energy touch at $E=0$, for $k=\\pi$ and $k=0$ respectively.\n",
 "\n",
 "At first sight, the band structure looks quite similar on both sides of the bulk gap closings. Just from the above plot, it is not clear that the bulk gap closings separate two distinct phases of the model. Nevertheless, we will see that it is possible to rigorously come to this conclusion by studying the properties of $H(k)$ in more detail. But in the meantime, we will start by understanding better what happens close to the transition, by writing down a simple effective model from which we will be able to deduce a lot of information."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Study of the bulk transition with an effective Dirac model\n",
 "\n",
 "Let's look at the gapless points more in detail. We focus on the gap closing at $\\mu=2t$, which happens at $k=0$. Close to this point where the two bands touch, we can make a linear expansion of the Hamiltonian $H(k)$,\n",
 "\n",
 "$$H(k) \\simeq m \\tau_z + 2\\Delta\\,k\\,\\tau_y\\,,$$\n",
 "\n",
 "with $m=\\mu2t$. We can see that $H(k)$ becomes a **Dirac Hamiltonian**  note that condensed matter physicists use this term quite loosely to refer to any Hamiltonian which is linear in the momentum operator. You can easily check that this Hamiltonian gives an energy spectrum $E(k) = \\pm\\sqrt{m^2 + 4\\Delta^2k^2}$, and by returning to the plot above you can indeed verify that this is a very good approximation of the exact band structure around $\\mu=2t$.\n",
 "\n",
 "The ''mass'' $m$ appearing in this Dirac Hamiltonian is a very important parameter to describe what is happening. Its magnitude is equal to the energy gap $\\left\\mu+2t\\right$ in the band structure close to the gap closing. Its sign reminds us of the two original phases which we encountered in the previous part of the lecture:\n",
 "\n",
 "* $m<0$ for $\\mu>2t$, which corresponds to the **topological** phase, the one with Majorana modes in the open chain.\n",
 "* $m>0$ for $\\mu<2t$, which corresponds to the **trivial** phase, the one without Majorana modes in the open chain.\n",
 "\n",
 "Previously, we had identified the point $\\mu=2t$ as a phase transition between two phases with or without zero energy edge modes. By looking at the bulk Hamiltonian, the same point $\\mu=2t$ appears as a point where the bulk gap closes and *changes sign*.\n",
 "\n",
 "When $m=0$, the Hamiltonian has two eigenstates with energy $E=\\pm 2\\Delta k$. These states are the eigenstates of $\\tau_y$, hence they are equal weight superpositions of electron and holes. They are in fact Majorana modes, that are leftmoving on the branch $E = 2\\Delta k$ and rightmoving on $E = 2\\Delta k$. Now they are free to propagate in the chain since there is no bulk gap anymore. In our simple model, the speed of these modes is given by $v=2\\Delta$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Majorana modes appearing at a domain wall between different phases\n",
 "\n",
 "Let us consider the following question: What happens if the mass parameter $m(x)$ varies continuously *in space*, and changes sign at a certain point?\n",
 "\n",
 "To answer the question, let's write down the Dirac Hamiltonian above in real space. Then we have\n",
 "\n",
 "$$H = v\\,\\tau_y\\,i\\partial_x + m(x)\\, \\tau_z.$$\n",
 "\n",
 "As anticipated, the mass is now a function of position, $m(x)$, with the property that $m(x)\\to \\pm m$ for $x\\to\\pm\\infty$ and $m(x=0)=0$. The point $x=0$ is a *domain wall*, the border between two regions of space with opposite sign of the mass.\n",
 "\n",
 "We already know that when $m=0$, the Hamiltonian above has a zero energy Majorana mode as a solution. Let us look at it in more detail. We need to solve the equation $H\\Psi=0$, which can be rewritten as\n",
 "\n",
 "$$\\partial_x\\Psi(x) = (1/v)\\,m(x)\\,\\tau_x\\,\\Psi(x).$$\n",
 "\n",
 "Only a single Pauli matrix $\\tau_x$ appears in this equation, which is therefore quite easy to solve. The solutions have the form\n",
 "\n",
 "$$\\Psi(x) = \\exp\\,\\left(\\tau_x\\int_0^x \\frac{m(x')}{v}\\, dx'\\right) \\Psi(0).$$\n",
 "\n",
 "Two linearly independent solutions are given by the eigenstates of $\\tau_x$:\n",
 "\n",
 "$$\\Psi(x) = \\exp\\,\\left(\\pm\\int_0^x \\frac{m(x')}{v}\\, dx'\\right) \\begin{pmatrix} 1 \\\\ \\pm 1 \\end{pmatrix}\\,.$$\n",
 "\n",
 "Only one of the two is normalizable, thanks to the fact that $m(x)$ changes sign at $x=0$. In this way we obtain a wave function localized at $x=0$, with two exponential tails on the sides. This solution is our Majorana mode which, in this case, is a bound state localized at the domain wall. Note that no zeroenergy solution would exist if $m(x)$ did not change sign. In this case $\\Psi(x)$ would not be normalizable at either side of the domain wall.\n",
 "\n",
 "Physically, we are considering a situation where our system is in the topological phase for $x<0$ and in the trivial phase for $x>0$. Therefore we have just demonstrated that at the interface between these two regions *there must be* a zero energy mode.\n",
 "\n",
 "![](figures/domain_wall_zero_mode.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "To clarify the situation, we can represent the same domain wall with our domino tiles. When you join together two chains of dominoes paired up in a different way, one single unpaired Majorana *must be* left in the middle:\n",
 "\n",
 "![](figures/domain_wall_with_dominoes.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Bulk topological invariant and the bulkedge correspondence"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Bulk topological invariant\n",
 "\n",
 "Now that we understand the topological transition in more detail, let's go back to the bulk Hamiltonian $H(k)$ of the Kitaev ring and try to generalize our Diracequation based criterion for Majorana modes. In our effective Dirac model it was easy to identify a quantity, the mass parameter $m$, whose sign determined whether the system could support unpaired Majorana modes at its ends. Let's now try to turn this effective description into a **bulk topological invariant** which can be computed directly from $H(k)$. We will not attempt to give a rigorous derivation of the bulk invariant  a task which is often difficult even for advanced researchers in the field  but rather to arrive at it in a heuristic manner.\n",
 "\n",
 "We can start with some important clues. On the one hand, we are studying a Bogoliubovde Gennes Hamiltonian, and we have already learned that quantum dots with particlehole symmetry are characterized by a topological invariant, the sign of the Pfaffian, which changes sign at every gap closing. On the other hand, we have just seen that the gap closing in the Kitaev chain model is accompanied by a change of sign of $m$. This suggests to try to link the quantity $m$ to a Pfaffian. How to do so?\n",
 "\n",
 "In fact, you can think of the full $H_\\textrm{BdG}$ as a very large matrix with particlehole symmetry. It can be put in antisymmetric form and we can compute its Pfaffian. This Pfaffian may change only when an eigenvalue of $H(k)$ passes through zero. Because of particlehole symmetry, for every eigenvalue $E(k)$ we have one at $E(k)$. So if $E(k)$ passes through zero, also its partner does. Furthermore, the spectrum has to be periodic in the Brillouin zone, which means that gap closings at finite momentum always come in pairs, and cannot change the Pfaffian. There are only two points which make exception: $k=0$ and $k=\\pi$, which are mapped onto themselves by particlehole symmetry. In fact, for these points we have:\n",
 "\n",
 "$$ \\tau_x H^*(0)\\tau_x=H(0),$$\n",
 "$$ \\tau_x H^*(\\pi)\\tau_x=H(\\pi).$$\n",
 "\n",
 "So $H(0)$ and $H(\\pi)$ can always be put individually in antisymmetric form, and we can always compute their Pfaffian. Also, note that these are precisely the points in momentum space where the gap closes: at $k=0$ for $\\mu=2t$ and at $k=\\pi$ for $\\mu=2t$. All things considered, we have a strong reason to focus exclusively on $H(0)$ and $H(\\pi)$. Following the procedure that we learned in the last chapter, we can therefore put $H(0)$ and $H(\\pi)$ in antisymmetric form,\n",
 "\n",
 "$$\\tilde{H}(0) = \\frac{1}{2}\n",
 "\\begin{pmatrix} 1 & 1 \\\\ i & i \\end{pmatrix} \n",
 "\\begin{pmatrix} 2t\\mu & 0 \\\\ 0 & 2t+\\mu \\end{pmatrix}\n",
 "\\begin{pmatrix} 1 & i \\\\ 1 & i \\end{pmatrix} = i\n",
 "\\begin{pmatrix} 0 & 2t\\mu \\\\ 2t+\\mu & 0\\end{pmatrix},$$\n",
 "$$\\tilde{H}(\\pi) = \\frac{1}{2}\n",
 "\\begin{pmatrix} 1 & 1 \\\\ i & i \\end{pmatrix} \n",
 "\\begin{pmatrix} 2t\\mu & 0 \\\\ 0 & 2t+\\mu \\end{pmatrix}\n",
 "\\begin{pmatrix} 1 & i \\\\ 1 & i \\end{pmatrix} = i\n",
 "\\begin{pmatrix} 0 & 2t\\mu \\\\ 2t+\\mu & 0\\end{pmatrix}.$$\n",
 "\n",
 "We now easily obtain that\n",
 "\n",
 "$$\\textrm{Pf}[iH(0)]=2t\\mu,$$\n",
 "$$\\textrm{Pf}[iH(\\pi)]=2t\\mu.$$\n",
 "\n",
 "You see that the Pfaffian of $H(0)$ changes sign at $\\mu=2t$, and the Pfaffian of $H(\\pi)$ does so at $\\mu=2t$, in perfect agreement with the position of the gap closing in the band structure:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "mus = np.arange(3, 3, 0.25)\n",
 "holoviews.HoloMap({mu: bandstructure(mu, show_pf=True) for mu in mus}, kdims=[dims.mu_t])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Individually, the two Pfaffians account for one of the two bulk gap closings which can occur in the model. To obtain a single bulk invariant $Q$ we can simply multiply the two! Hence we arrive at the following expression:\n",
 "\n",
 "$$Q = \\textrm{sign}\\left(\\, \\textrm{Pf}[iH(0)]\\,\\textrm{Pf}[iH(\\pi)]\\,\\right).$$\n",
 "\n",
 "A value $Q=1$ means that the bulk is in a topological phase, such that if the wire was cut at a point, two unpaired Majorana modes would appear at the ends of it. On the other hand, a value $Q=+1$ means that the bulk is in the trivial phase. Again, you might think that this expression for $Q$, that we have just cooked up, is only valid for the particular model that we are considering. However, you would be wrong:\n",
 "\n",
 "> The topological invariant $Q$ cannot change under continuous deformations of the Hamiltonian unless the gap closes."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Connecting the bulk invariant and the edge modes\n",
 "\n",
 "At the moment, the bulk topological invariant $Q$ defined above might look just like an abstract mathematical object. We know that $Q=1$ corresponds to the topological phase, but can we give a more concrete physical meaning to this value? This is the goal of this last part of the lecture.\n",
 "\n",
 "We have already connected the Pfaffian of a Bogoliubovde Gennes Hamiltonian to a physical quantity: The ground state fermion parity of the system. Our onedimensional invariant involves the product of two Pfaffians, $\\textrm{Pf}[iH(0)]$ and $\\textrm{Pf}[iH(\\pi)]$. By taking their product we are somehow *comparing* the fermion parity of the two states of the chain with $k=0$ and $k=\\pi$, and we have that $Q=1$ if and only if the two parities are different.\n",
 "\n",
 "This means that if we *continuously deform* $H(0)$ into $H(\\pi)$ in some way without breaking the particlehole symmetry, we must encounter a zeroenergy level crossing in the energy spectrum, what we called a *fermion parity switch* in the last chapter.\n",
 "\n",
 "In practice, this can be done in the following way. Let's imagine that we change the boundary conditions of a Kitaev ring with $N$ sites from *periodic* to *antiperiodic* boundary conditions, that is from $\\left\\langle k  n=0 \\right\\rangle=\\left\\langle k  n=N \\right\\rangle$ to $\\left\\langle k  n=0 \\right\\rangle=\\left\\langle k  n=N \\right\\rangle$. This means that the allowed values of momentum shift from $k=2\\pi p/N$ to $k = 2\\pi p/N + \\pi /N$.\n",
 "\n",
 "Let's now ask what is the difference in ground state fermion parity of the two chains. The value $k=0$ is always present in the chain with periodic boundary conditions, while $k=\\pi$ is in the first set if $N$ is even and in the second set if $N$ is odd. This means that in either case, the difference in the ground state fermion parities between the chains with periodic and antiperiodic boundary conditions is equal to $Q$!\n",
 "\n",
 "To verify this statement, we will now *physically change the boundary condition in real space*. For simplicity, we will do so for a Kitaev ring with $\\Delta=t$. You will remember that, in the Majorana basis, this corresponds to the limit where neighboring Majoranas from different sites are coupled by hopping of strength $t$.\n",
 "\n",
 "To go from periodic to antiperiodic boundary condition, we can change the hopping on the last bond of the ring (the one connecting sites $n=N1$ and $n=0$) from $t$ to $t$. This can easily be done continuously and without breaking particlehole symmetry, for instance by setting the last hopping to be equal to $t\\,(12\\lambda)$ and varying $\\lambda$ in the interval $[0,1]$, as shown in this picture:"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/majorana_ring.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You can check that the Bogoliubovde Gennes Hamiltonian of this closed ring satisfies particlehole symmetry at every value of $\\lambda$. Let's now look at the energy spectrum $E(\\lambda)$ of the system as we vary $\\mu$ from $0$ to $4t$, passing once again through the gap closing at $\\mu=2t$."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "syst = kitaev_chain(L=25, periodic=True)\n",
 "\n",
 "p = SimpleNamespace(t=1, delta=1, lambda_=np.linspace(0.0, 1.0, 101), mu=None)\n",
 "\n",
 "kwargs = {'xticks': np.linspace(0, 1, 5), \n",
 " 'yticks': np.linspace(4, 4, 5), \n",
 " 'xdim': dims.lambda_, \n",
 " 'ydim': dims.E_t}\n",
 "\n",
 "mus = np.arange(0, 4, 0.1)\n",
 "holoviews.HoloMap({p.mu: spectrum(syst, p, **kwargs) for p.mu in mus}, kdims=[dims.mu_t])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You can see that for $\\mu<2t$, the energy spectrum shows a zeroenergy level crossing at $\\lambda=1/2$. The fermion parity of the system is therefore different at $\\lambda=0$ and $\\lambda=1$. When $\\lambda=1/2$ the hopping on the last bond is equal to zero. We have introduced a “cut” to the system, such that our closed Kitaev ring is effectively transformed to an open Kitaev chain. Because we are in the topological phase, this open Kitaev chain has two zeroenergy unpaired Majorana modes!\n",
 "\n",
 "On the other hand, when $\\mu>2 t$ no zeroenergy level crossing is present. The ground state fermion parity is the same at $\\lambda=0$ and $\\lambda=1$. In this case, when we cut the system at $\\lambda=1/2$, we find no unpaired Majorana modes, consistent with our knowledge of the behavior of the open chain in the trivial phase.\n",
 "\n",
 "We have therefore learned the essence of the bulkboundary correspondence: A nontrivial value $Q=1$ of the bulk invariant for the closed chain implies the existence of unpaired Majorana modes for the open chain. Also, we have been able to connect the value of the bulk invariant to a measurable quantity, in this case the ground state fermion parity of the closed chain."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (\"What will happen if we take a 100 site Kitaev chain in the topological phase \" \n",
 " \"and change the potential mu to a very large negative value for the last 50 sites?\")\n",
 "answers = [\"The topological gap at the last 50 sites closes and reopens as $\\mu$ changes from $0$ to $\\infty$.\",\n",
 " \"The Majoranas get destroyed by the drastic change of chemical potential $\\mu_j$.\",\n",
 " \"One of the Majoranas moves from being the end of the system to the middle.\"]\n",
 "MoocCheckboxesAssessment(question, answers, correct_answers=[0, 2])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Three approaches to analysing topological systems"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"wiHPQlEha6g\", src_location='1.2summary')"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocDiscussion('Questions', 'Bulkedge correspondence in the Kitaev chain')"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w1_topointro/1D.md b/w1_topointro/1D.md
new file mode 100644
index 0000000..cab6137
 /dev/null
+++ b/w1_topointro/1D.md
@@ 0,0 +1,449 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+
+%output size=150
+dims = SimpleNamespace(E_t=holoviews.Dimension(r'$E/t$'),
+ mu_t=holoviews.Dimension(r'$\mu/t$'),
+ lambda_=holoviews.Dimension(r'$\lambda$'),
+ x=holoviews.Dimension(r'$x$'),
+ k=holoviews.Dimension(r'$k$'),
+ amplitude=holoviews.Dimension(r'$u^2 + v^2$'))
+
+holoviews.core.dimension.title_format = ''
+
+def kitaev_chain(L=None, periodic=False):
+ lat = kwant.lattice.chain()
+
+ if L is None:
+ syst = kwant.Builder(kwant.TranslationalSymmetry((1,)))
+ L = 1
+ else:
+ syst = kwant.Builder()
+
+ # transformation to antisymmetric basis
+ U = np.array([[1.0, 1.0], [1.j, 1.j]]) / np.sqrt(2)
+
+ def onsite(onsite, p):
+ return  p.mu * U @ pauli.sz @ U.T.conj()
+
+ for x in range(L):
+ syst[lat(x)] = onsite
+
+ def hop(site1, site2, p):
+ return U @ (p.t * pauli.sz  1j * p.delta * pauli.sy) @ U.T.conj()
+
+ syst[kwant.HoppingKind((1,), lat)] = hop
+
+ if periodic:
+ def last_hop(site1, site2, p):
+ return hop(site1, site2, p) * (1  2 * p.lambda_)
+
+ syst[lat(0), lat(L  1)] = last_hop
+ return syst
+
+
+def bandstructure(mu, delta=1, t=1, Dirac_cone="Hide", show_pf=False):
+ syst = kitaev_chain(None)
+ p = SimpleNamespace(t=t, delta=delta, mu=mu)
+ plot = holoviews.Overlay([spectrum(syst, p, ydim="$E/T$", xdim='$k$')][4:4])
+ h_1 = h_k(syst, p, 0)
+ h_2 = h_k(syst, p, np.pi)
+ pfaffians = [find_pfaffian(h_1), find_pfaffian(h_2)]
+
+ if show_pf:
+ signs = [('>' if pf > 0 else '<') for pf in pfaffians]
+ title = "$\mu = {mu} t$, Pf$(iH_{{k=0}}) {sign1} 0$, Pf$(iH_{{k=\pi}}) {sign2} 0$"
+ title = title.format(mu=mu, sign1=signs[0], sign2=signs[1])
+ plot *= holoviews.VLine(0) * holoviews.VLine(np.pi)
+ else:
+ if pfaffians[0] * pfaffians[1] < 0:
+ title = "$\mu = {mu} t$, topological ".format(mu=mu)
+ else:
+ title = "$\mu = {mu} t$, trivial ".format(mu=mu)
+
+ if Dirac_cone == "Show":
+ ks = np.linspace(np.pi, np.pi)
+ ec = np.sqrt((mu + 2 * t)**2 + 4.0 * (delta * ks)**2)
+ plot *= holoviews.Path((ks, ec), kdims=[dims.k, dims.E_t])(style={'linestyle':'', 'color':'r'})
+ plot *= holoviews.Path((ks, ec), kdims=[dims.k, dims.E_t])(style={'linestyle':'', 'color':'r'})
+ return plot.relabel(title)
+
+def find_pfaffian(H):
+ return np.sign(np.real(pf.pfaffian(1j*H)))
+```
+
+# Kitaev chain and bulkedge correspondence
+
+
+```python
+MoocVideo("U84MzZm9Gbo", src_location='1.2intro')
+```
+
+# Unpaired Majorana modes in onedimensional systems
+
+## Fermion operators and Majorana operators
+
+Let's start from the creation and annihilation operators $c^\dagger$ and $c$ of a fermionic mode. These operators satisfy the anticommutation relation $c^\dagger c + cc^\dagger = 1$ and, furthermore, square to zero, $c^2=0$ and $(c^\dagger)^2=0$. They connect two states $\left0\right\rangle$ and $\left1\right\rangle$ which correspond to the 'vacuum' state with no particle and the 'excited' state with one particle, according to the following rules $c \left0\right\rangle = 0$, $c^\dagger\left0\right\rangle=\left1\right\rangle$ and $c^\dagger \left1\right\rangle = 0$.
+
+When you have a pair of $c$ and $c^\dagger$ operators, you can write them down in the following way
+
+$$ c^\dagger = \tfrac{1}{2}(\gamma_1+i\gamma_2),\;\; c = \tfrac{1}{2}(\gamma_1i\gamma_2).$$
+
+The operators $\gamma_1$ and $\gamma_2$ are known as Majorana operators. By inverting the transformation above, you can see that $\gamma_1=\gamma_1^\dagger$ and $\gamma_2=\gamma_2^\dagger$. Because of this property, we cannot think of a single Majorana mode as being 'empty' or 'filled', as we can do for a normal fermionic mode. This makes Majorana modes special.
+
+You can also check that to maintain all the properties of $c$ and $c^\dagger$, the operators $\gamma_1$ and $\gamma_2$ must satisfy the following relations:
+
+$$\gamma_1\gamma_2 + \gamma_2\gamma_1 = 0\;,\;\gamma_1^2=1\;,\;\gamma_2^2=1\;.$$
+
+You can see that Majorana modes are similar to normal fermions in the sense that they have operators which all anticommute with each other. Using Majorana modes instead of normal fermionic modes is very similar to writing down two real numbers in place of a complex number. Indeed, every fermion operator can always be expressed in terms of a pair of Majorana operators. This also means that Majorana modes always come in even numbers.
+
+The two Majorana operators $\gamma_1, \gamma_2$ still act on the same states $\left0\right\rangle$ and $\left1\right\rangle$.
+If these two states have an energy difference $\epsilon$, this corresponds to a Hamiltonian $H=\epsilon c^\dagger c$.
+We can also express this Hamiltonian in terms of Majoranas as $H=\tfrac{1}{2}\,\epsilon\,(1  i\gamma_1\gamma_2)$.
+
+But is it possible to have a single isolated Majorana mode, one that is not close to its partner?
+The naive answer is 'no': condensed matter systems are made out of electrons, and these always correspond to pairs of Majoranas.
+However, it turns out that by engineering the Hamiltonian in a special way it actually is possible to separate two Majoranas.
+
+## Unpaired Majorana modes in a model of dominoes
+
+Let's see how creating isolated Majoranas can be done. Let us consider a chain of $N$ sites, where each site can host a fermion with creation operator $c^\dagger_n$. Equivalently, each site hosts two Majorana modes $\gamma_{2n1}$ and $\gamma_{2n}$. This situation is illustrated below for $N=4$, where each site is represented by a domino tile.
+
+![](figures/majorana_dominoes.svg)
+
+What happens if we pair the Majoranas? This means that the energy cost for each fermion to be occupied is $\mu$, and the Hamiltonian becomes
+
+$$H=(i/2)\,\mu\, \sum_{n=1}^{N} \gamma_{2n1}\gamma_{2n}.$$
+
+This is how the pairing looks:
+
+![](figures/trivial_dominoes.svg)
+
+All the excitations in this system have an energy $\pm\mu/2$, and the chain has a gapped bulk and no zero energy edge states.
+
+Of course this didn't help us to achieve our aim, so let's pair the Majoranas differently.
+We want only one Majorana to remain at an edge, so let's pair up the Majoranas from *adjacent* sites, leaving the first one and the last one without a neighboring partner:
+
+![](figures/topological_dominoes.svg)
+
+To every pair formed in this way, we assign an energy difference $2t$ between the empty and filled state, hence arriving at the Hamiltonian
+
+$$H=it \sum_{n=1}^{N1} \gamma_{2n}\gamma_{2n+1}.$$
+
+You can see that the two end Majorana modes $\gamma_1$ and $\gamma_{2N}$ do not appear in $H$ at all.
+Hence our chain has two zeroenergy states, localized at its ends.
+All the states which are not at the ends of the chain have an energy of $\pm t$, independently on the length of the chain. Hence, we have a onedimensional system with a gapped bulk and zero energy states at the edges.
+
+## The Kitaev chain model
+
+Let us now try to write the Hamiltonian $H$, which we have so far written in terms of Majoranas, in terms of regular fermions by substituting $\gamma_{2n1}=(c_n^\dagger+c_n)$ and $\gamma_{2n}=i(c_n^\daggerc_n)$. We find that both pairings sketched above are extreme limits of one tightbinding Hamiltonian for a onedimensional superconducting wire:
+
+$$H=\mu\sum_n c_n^\dagger c_nt\sum_n (c_{n+1}^\dagger c_n+\textrm{h.c.}) + \Delta\sum_n (c_n c_{n+1}+\textrm{h.c.})\,.$$
+
+It has three real parameters: the onsite energy $\mu$, the hopping $t$ between different sites, and the superconducting pairing $\Delta$. Note that the $\Delta$ terms create or annihilate pairs of particles at neighboring sites.
+
+Starting from this Hamiltonian, the unpaired Majorana regime is the special point $\Delta=t$ and $\mu=0$, while the completely trivial regime of isolated fermions is $\Delta=t=0$ and $\mu\neq 0$.
+
+As we learned just before, it is useful to write down the above superconducting Hamiltonian in the Bogoliubovde Gennes formalism $H = \tfrac{1}{2} C^\dagger H_\textrm{BdG} C$, with $C$ a column vector containing all creation and annihilation operators, $C=(c_1, \dots, c_N, c_1^\dagger, \dots, c^\dagger_N)^T$. The $2N\times 2N$ matrix $H_\textrm{BdG}$ can be written in a compact way by using Pauli matrices $\tau$ in particle and hole space, and denoting with $\leftn\right\rangle$ a column basis vector $(0,\dots,1,0,\dots)^T$ corresponding to the $n$th site of the chain. In this way, we have for instance that $C^\dagger\,\tau_z\,\leftn\right\rangle\left\langle n\right\,C = 2c_n^\dagger c_n1$. The Bogoliubovde Gennes Hamiltonian is then given by
+
+$$H_{BdG}=\sum_n \mu \tau_z\leftn\right\rangle\left\langle n\right\sum_n \left[(t\tau_z+i\Delta\tau_y)\,\leftn\right\rangle\left\langle n+1 \right + \textrm{h.c.}\right].$$
+
+The BdG Hamiltonian acts on a set of basis states $\leftn\right\rangle\left\tau\right\rangle$, with $\tau=\pm 1$ corresponding to electron and hole states respectively. It has particlehole symmetry, $\mathcal{P}H_\textrm{BdG}\mathcal{P}^{1}=H_\textrm{BdG}$ with $\mathcal{P}=\tau_x\mathcal{K}$.
+
+## Topological protection of edge Majorana modes
+
+The fact that the Kitaev model can have unpaired Majorana zero modes is certainly interesting. At this point you might however object:
+
+"Unpaired Majoranas appear because you chose one particular, and perhaps even unreachable, set of parameters! Clearly by setting $\mu=0$ you have cut the first and last Majorana mode from the rest of the chain. I bet that if you change the value of $\mu$ only slightly from zero, the zero modes will be coupled to the rest of the chain and quickly disappear. So these Majorana modes may just be an artefact appearing in this highly tuned model!"
+
+Well, let's test if this objection is true. Let's start from the situation with unpaired Majorana modes ($\Delta=t, \mu=0$) and then increase $\mu$. Then let's plot the energy spectrum of a chain with $N=25$ sites as a function of $\mu$, and also keep track how do the two lowest energy states of our system look like, when we change $\mu$ **(move the slider)**:
+
+
+```python
+def plot_wf(syst, wf1, wf2, lstyle='', lcolor='b'):
+ xs = np.array([i.pos[0] for i in syst.sites])
+ indx = np.argsort(xs)
+ wf_sq = np.linalg.norm(wf1.reshape(1, 2), axis=1)**2 + np.linalg.norm(wf2.reshape(1, 2), axis=1)**2
+ plot = holoviews.Path((xs[indx], wf_sq[indx]), kdims=[dims.x, dims.amplitude])
+ return plot(style={'linestyle': lstyle, 'color': lcolor},
+ plot={'yticks': 0, 'xticks': list(range(0, len(xs), 10))})
+
+def plot_pwave(L, t, delta, mu):
+ # At mu=0 the first exited state is not well defined due to the massive degeneracy.
+ # That is why we add a small offset to mu.
+ syst = kitaev_chain(L).finalized()
+ p = SimpleNamespace(t=t, delta=delta, mu=mu+1e4)
+ ham = syst.hamiltonian_submatrix(args=[p])
+ ev, evec = np.linalg.eigh(ham)
+ return (plot_wf(syst, evec[:, L], evec[:, L1]) *
+ plot_wf(syst, evec[:, L+1] , evec[:, L2], lstyle='', lcolor='r'))
+
+syst = kitaev_chain(L=25)
+mus = np.arange(0, 4, 0.2)
+p = SimpleNamespace(t=1, delta=1, mu=mus)
+
+(spectrum(syst, p, xticks=[0, 1, 2, 3], yticks=range(3, 4),
+ xdim=dims.mu_t, ydim=dims.E_t, ylims=(3, 3)) *
+ holoviews.HoloMap({mu: holoviews.VLine(mu) for mu in mus}, kdims=[dims.mu_t]) +
+ holoviews.HoloMap({mu: plot_pwave(25, 1.0, 1.0, mu) for mu in mus}, kdims=[dims.mu_t]))
+```
+
+The left panel shows the spectrum, where we see two states at zero energy that split. On the right panel the blue line is the wave function of the state corresponding to the pair of Majorana modes, while the red dashed line is the wave function of the first excited state.
+
+As you can see, the zero energy eigenvalues corresponding to the two unpaired Majorana zero modes persist for a long time, and they only split in energy when $\mu \simeq 2t$. Another thing that we observe is that the wave function of the Majoranas stays zero in the middle of our wire.
+
+As we increase $\mu$ (try it), the wave function of the Majoranas becomes less localized near the edges of the wire, but the coupling between two ends only appears later.
+
+You would observe a similar behavior if you varied $\mu$ in the negative direction starting from $\mu=0$. The Majoranas persist until $\mu\simeq2t$, where the bulk gap closes.
+
+In fact, the Majoranas only split when the higherenergy states in the bulk, originally separated by an energy gap of $2 t$, come very close to zero energy. So our investigation shows that the Majorana modes are protected **as long as the bulk energy gap is finite**.
+
+How can we understand this? Recall that we are dealing with a particlehole symmetric Hamiltonian. Hence, the spectrum has to be symmetric around zero energy. When $\mu=0$, we have two zero energy levels, corresponding to the Majorana modes which are localized far away from each other and separated by a gapped medium. Trying to move these levels from zero energy individually is impossible, as it would violate particlehole symmetry:
+
+![](figures/level_deformation_fig.svg)
+
+The only possibility to move the energy levels from zero is to couple the two unpaired Majorana modes to each other. However, because of the spatial separation between Majoranas and of the presence of an energy gap, this coupling is impossible. The only way to split the Majorana modes in energy is to first close the bulk energy gap, and that is exactly what happens at large values of $\mu$ (to be precise, it happens at $\mu=2t$).
+
+So we have just learned the following:
+
+> Isolated zero endmodes at each end in the Kitaev chain are protected by **symmetry** between positive and negative energy, and by the **absence of zeroenergy excitations in the bulk of the wire**, but not by finetuning of the chain parameters.
+
+As you see, our conclusion sounds a lot like what we learned about topology just before. We have come to these conclusions by studying a Kitaev chain on an open geometry with boundaries, and by focusing on the presence or absence of edge states localized at the boundaries of the chain. In the rest of the unit we will see that the presence or absence of edge states can be deduced by studying the bulk alone. In order to do this, we will now study an infinite Kitaev chain without boundaries.
+
+
+```python
+question = ("But wait! What happens if we remove the last Majorana site of a Kitaev chain"
+ " in the topological phase?")
+answers = ["We get a chain with a single Majorana mode.",
+ "We cannot remove a single Majorana site because electrons (pairs of Majoranas) "
+ "are the only physical degrees of freedom.",
+ "The Hamiltonian becomes topologically trivial.",
+ "Removing a single Majorana is not allowed by particlehole symmetry"]
+explanation = "Indeed, as we explained, removing a single Majorana is like removing a single pole of a magnet. So not possible."
+MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)
+```
+
+# Topological phases from the bulk spectrum
+
+## Going to momentum space
+
+The Majoranas are edge excitations that arise from the bulkedge correspondence. You might wonder if there is a way to deduce the existence of Majorana modes by looking at the bulk? To answer this, eliminate the boundaries from the study of the Kitaev chain. You can imagine that the last site of the chain is reconnected to the first, so that the chain is closed in a ring (a “Kitaev ring”). In the absence of boundaries, the Bogoliubovde Gennes Hamiltonian has a translational symmetry $\leftn\right\rangle\,\to\,\leftn+1\right\rangle$, since all parameters $t, \Delta$ and $\mu$ do not depend on the chain site $n$. In the presence of translational symmetries, it is always convenient to use [Bloch's theorem](http://en.wikipedia.org/wiki/Bloch_wave#Preliminaries:_Crystal_symmetries.2C_lattice.2C_and_reciprocal_lattice) and write down the Hamiltonian in momentum space rather than in real space. In our case, a state with momentum $k$ is given by
+
+$$ \leftk\right\rangle =(N)^{1/2} \sum_{n=1}^{N} e^{ikn} \leftn\right\rangle.$$
+
+We apply periodic boundary conditions, that is $\left\langle k  n=0 \right\rangle=\left\langle k  n=N \right\rangle$. The momentum $k$ is then a conserved quantum number with allowed values $2\pi p /N$ where $p=0, 1, 2, \dots, N1$. Values of $k$ which differ by $2\pi$ are equivalent. One can also imagine that for very large $N$, $k$ is a continuous periodic variable with values in the interval $[\pi,\pi]$, the **Brillouin zone**. Because $k$ is a good quantum number, the Bogoliubovde Gennes Hamiltonian in momentum space can be reduced to a $2\times 2$ matrix:
+
+$$ H(k) \equiv \left\langle k\right H_\textrm{BdG} \left k \right\rangle = (2t\cos{k}\mu)\,\tau_z + 2\Delta \sin{k}\,\,\tau_y.$$
+
+The full Bogoliubovde Gennes Hamiltonian is obtained by summing all these $2\times 2$ blocks:
+
+$$ H_\textrm{BdG} = \sum_k H(k) \left k \right\rangle\left\langle k \right.$$
+
+In the limit of an infinite chain the sum becomes an integral over the Brillouin zone.
+
+## Particlehole symmetry in momentum space
+
+Going to momentum space does not affect the particlehole symmetry of the Bogoliubovde Gennes Hamiltonian. However, one must always be careful in dealing with antiunitary operators when making a basis transformation. The reason is that the action of the complex conjugation operator might depend on the basis. In our case, we have
+
+$$\mathcal{P}\leftk\right\rangle\!\left\tau\right\rangle = \left(\sum_n\,e^{ikn}\right)^*\,\leftn\right\rangle\,\tau_x\left\tau\right\rangle^*=\leftk\right\rangle\,\tau_x\left\tau\right\rangle^*.$$
+
+Note that the particlehole symmetry operator changes $k$ to $k$. Therefore, the action of $\mathcal{P}$ on the Bogoliubovde Gennes Hamiltonian written in momentum space is the following:
+
+$$\mathcal{P}H_\textrm{BdG}\mathcal{P}^{1} = \sum_k \tau_xH^*(k)\tau_x \left k \right\rangle\left\langle k \right=\sum_k \tau_xH^*(k)\tau_x \left k \right\rangle\left\langle k \right\,.$$
+
+In the last equality, we have used the fact that the allowed values of $k$ always come in $(k, k)$ pairs, plus the two symmetric points $k=0$ and $k=\pi$. Therefore, particlehole symmetry $\mathcal{P}H_\textrm{BdG}\mathcal{P}^{1}= H_\textrm{BdG}$ implies that
+
+$$H(k)=\tau_xH^*(k)\tau_x.$$
+
+You can verify that it is indeed the case:
+
+$$\tau_x H^*(k) \tau_x = (2t\cos{k}+\mu)\,\tau_z  2\Delta \sin{k}\,\,\tau_y.$$
+
+Given a solution with energy $E$ and momentum $k$, particlehole symmetry dictates in general the presence of a solution with energy $E$ and momentum $k$.
+
+## Band structure
+
+At this point, we only need to diagonalize this $2\times 2$ matrix to obtain the *band structure* of the Kitaev chain model, that is the energy levels $E(k)$. This can be done very easily, and results in two energy bands, one with positive energy and one with negative energy:
+
+$$ E(k) = \pm\sqrt{(2t\cos{k}+\mu)^2 + 4\Delta^2\sin^2{k}}. $$
+
+Let's see what this band structure looks like (**once again move the slider** to change $\mu$):
+
+
+```python
+mus = np.arange(3, 3, 0.25)
+
+plots = {(mu, Dirac_cone): bandstructure(mu, Dirac_cone=Dirac_cone)
+ for mu in mus
+ for Dirac_cone in ["Show", "Hide"]}
+
+holoviews.HoloMap(plots, kdims=[dims.mu_t, "Dirac cone"])
+```
+
+You can see that the energy spectrum is gapped at all $k$ for $\mu=0$. This is natural: Since our chain does not have boundaries anymore, the energy spectrum does not contain the zero energy Majorana modes which we found in the previous subsection at $\mu=0$. However, you can see very clearly the bulk gap closing which occurs at the points $\mu=2t$ and $\mu=2t$. Indeed, for these values of $\mu$ the two bands at negative and positive energy touch at $E=0$, for $k=\pi$ and $k=0$ respectively.
+
+At first sight, the band structure looks quite similar on both sides of the bulk gap closings. Just from the above plot, it is not clear that the bulk gap closings separate two distinct phases of the model. Nevertheless, we will see that it is possible to rigorously come to this conclusion by studying the properties of $H(k)$ in more detail. But in the meantime, we will start by understanding better what happens close to the transition, by writing down a simple effective model from which we will be able to deduce a lot of information.
+
+## Study of the bulk transition with an effective Dirac model
+
+Let's look at the gapless points more in detail. We focus on the gap closing at $\mu=2t$, which happens at $k=0$. Close to this point where the two bands touch, we can make a linear expansion of the Hamiltonian $H(k)$,
+
+$$H(k) \simeq m \tau_z + 2\Delta\,k\,\tau_y\,,$$
+
+with $m=\mu2t$. We can see that $H(k)$ becomes a **Dirac Hamiltonian**  note that condensed matter physicists use this term quite loosely to refer to any Hamiltonian which is linear in the momentum operator. You can easily check that this Hamiltonian gives an energy spectrum $E(k) = \pm\sqrt{m^2 + 4\Delta^2k^2}$, and by returning to the plot above you can indeed verify that this is a very good approximation of the exact band structure around $\mu=2t$.
+
+The ''mass'' $m$ appearing in this Dirac Hamiltonian is a very important parameter to describe what is happening. Its magnitude is equal to the energy gap $\left\mu+2t\right$ in the band structure close to the gap closing. Its sign reminds us of the two original phases which we encountered in the previous part of the lecture:
+
+* $m<0$ for $\mu>2t$, which corresponds to the **topological** phase, the one with Majorana modes in the open chain.
+* $m>0$ for $\mu<2t$, which corresponds to the **trivial** phase, the one without Majorana modes in the open chain.
+
+Previously, we had identified the point $\mu=2t$ as a phase transition between two phases with or without zero energy edge modes. By looking at the bulk Hamiltonian, the same point $\mu=2t$ appears as a point where the bulk gap closes and *changes sign*.
+
+When $m=0$, the Hamiltonian has two eigenstates with energy $E=\pm 2\Delta k$. These states are the eigenstates of $\tau_y$, hence they are equal weight superpositions of electron and holes. They are in fact Majorana modes, that are leftmoving on the branch $E = 2\Delta k$ and rightmoving on $E = 2\Delta k$. Now they are free to propagate in the chain since there is no bulk gap anymore. In our simple model, the speed of these modes is given by $v=2\Delta$.
+
+## Majorana modes appearing at a domain wall between different phases
+
+Let us consider the following question: What happens if the mass parameter $m(x)$ varies continuously *in space*, and changes sign at a certain point?
+
+To answer the question, let's write down the Dirac Hamiltonian above in real space. Then we have
+
+$$H = v\,\tau_y\,i\partial_x + m(x)\, \tau_z.$$
+
+As anticipated, the mass is now a function of position, $m(x)$, with the property that $m(x)\to \pm m$ for $x\to\pm\infty$ and $m(x=0)=0$. The point $x=0$ is a *domain wall*, the border between two regions of space with opposite sign of the mass.
+
+We already know that when $m=0$, the Hamiltonian above has a zero energy Majorana mode as a solution. Let us look at it in more detail. We need to solve the equation $H\Psi=0$, which can be rewritten as
+
+$$\partial_x\Psi(x) = (1/v)\,m(x)\,\tau_x\,\Psi(x).$$
+
+Only a single Pauli matrix $\tau_x$ appears in this equation, which is therefore quite easy to solve. The solutions have the form
+
+$$\Psi(x) = \exp\,\left(\tau_x\int_0^x \frac{m(x')}{v}\, dx'\right) \Psi(0).$$
+
+Two linearly independent solutions are given by the eigenstates of $\tau_x$:
+
+$$\Psi(x) = \exp\,\left(\pm\int_0^x \frac{m(x')}{v}\, dx'\right) \begin{pmatrix} 1 \\ \pm 1 \end{pmatrix}\,.$$
+
+Only one of the two is normalizable, thanks to the fact that $m(x)$ changes sign at $x=0$. In this way we obtain a wave function localized at $x=0$, with two exponential tails on the sides. This solution is our Majorana mode which, in this case, is a bound state localized at the domain wall. Note that no zeroenergy solution would exist if $m(x)$ did not change sign. In this case $\Psi(x)$ would not be normalizable at either side of the domain wall.
+
+Physically, we are considering a situation where our system is in the topological phase for $x<0$ and in the trivial phase for $x>0$. Therefore we have just demonstrated that at the interface between these two regions *there must be* a zero energy mode.
+
+![](figures/domain_wall_zero_mode.svg)
+
+To clarify the situation, we can represent the same domain wall with our domino tiles. When you join together two chains of dominoes paired up in a different way, one single unpaired Majorana *must be* left in the middle:
+
+![](figures/domain_wall_with_dominoes.svg)
+
+# Bulk topological invariant and the bulkedge correspondence
+
+## Bulk topological invariant
+
+Now that we understand the topological transition in more detail, let's go back to the bulk Hamiltonian $H(k)$ of the Kitaev ring and try to generalize our Diracequation based criterion for Majorana modes. In our effective Dirac model it was easy to identify a quantity, the mass parameter $m$, whose sign determined whether the system could support unpaired Majorana modes at its ends. Let's now try to turn this effective description into a **bulk topological invariant** which can be computed directly from $H(k)$. We will not attempt to give a rigorous derivation of the bulk invariant  a task which is often difficult even for advanced researchers in the field  but rather to arrive at it in a heuristic manner.
+
+We can start with some important clues. On the one hand, we are studying a Bogoliubovde Gennes Hamiltonian, and we have already learned that quantum dots with particlehole symmetry are characterized by a topological invariant, the sign of the Pfaffian, which changes sign at every gap closing. On the other hand, we have just seen that the gap closing in the Kitaev chain model is accompanied by a change of sign of $m$. This suggests to try to link the quantity $m$ to a Pfaffian. How to do so?
+
+In fact, you can think of the full $H_\textrm{BdG}$ as a very large matrix with particlehole symmetry. It can be put in antisymmetric form and we can compute its Pfaffian. This Pfaffian may change only when an eigenvalue of $H(k)$ passes through zero. Because of particlehole symmetry, for every eigenvalue $E(k)$ we have one at $E(k)$. So if $E(k)$ passes through zero, also its partner does. Furthermore, the spectrum has to be periodic in the Brillouin zone, which means that gap closings at finite momentum always come in pairs, and cannot change the Pfaffian. There are only two points which make exception: $k=0$ and $k=\pi$, which are mapped onto themselves by particlehole symmetry. In fact, for these points we have:
+
+$$ \tau_x H^*(0)\tau_x=H(0),$$
+$$ \tau_x H^*(\pi)\tau_x=H(\pi).$$
+
+So $H(0)$ and $H(\pi)$ can always be put individually in antisymmetric form, and we can always compute their Pfaffian. Also, note that these are precisely the points in momentum space where the gap closes: at $k=0$ for $\mu=2t$ and at $k=\pi$ for $\mu=2t$. All things considered, we have a strong reason to focus exclusively on $H(0)$ and $H(\pi)$. Following the procedure that we learned in the last chapter, we can therefore put $H(0)$ and $H(\pi)$ in antisymmetric form,
+
+$$\tilde{H}(0) = \frac{1}{2}
+\begin{pmatrix} 1 & 1 \\ i & i \end{pmatrix}
+\begin{pmatrix} 2t\mu & 0 \\ 0 & 2t+\mu \end{pmatrix}
+\begin{pmatrix} 1 & i \\ 1 & i \end{pmatrix} = i
+\begin{pmatrix} 0 & 2t\mu \\ 2t+\mu & 0\end{pmatrix},$$
+$$\tilde{H}(\pi) = \frac{1}{2}
+\begin{pmatrix} 1 & 1 \\ i & i \end{pmatrix}
+\begin{pmatrix} 2t\mu & 0 \\ 0 & 2t+\mu \end{pmatrix}
+\begin{pmatrix} 1 & i \\ 1 & i \end{pmatrix} = i
+\begin{pmatrix} 0 & 2t\mu \\ 2t+\mu & 0\end{pmatrix}.$$
+
+We now easily obtain that
+
+$$\textrm{Pf}[iH(0)]=2t\mu,$$
+$$\textrm{Pf}[iH(\pi)]=2t\mu.$$
+
+You see that the Pfaffian of $H(0)$ changes sign at $\mu=2t$, and the Pfaffian of $H(\pi)$ does so at $\mu=2t$, in perfect agreement with the position of the gap closing in the band structure:
+
+
+```python
+mus = np.arange(3, 3, 0.25)
+holoviews.HoloMap({mu: bandstructure(mu, show_pf=True) for mu in mus}, kdims=[dims.mu_t])
+```
+
+Individually, the two Pfaffians account for one of the two bulk gap closings which can occur in the model. To obtain a single bulk invariant $Q$ we can simply multiply the two! Hence we arrive at the following expression:
+
+$$Q = \textrm{sign}\left(\, \textrm{Pf}[iH(0)]\,\textrm{Pf}[iH(\pi)]\,\right).$$
+
+A value $Q=1$ means that the bulk is in a topological phase, such that if the wire was cut at a point, two unpaired Majorana modes would appear at the ends of it. On the other hand, a value $Q=+1$ means that the bulk is in the trivial phase. Again, you might think that this expression for $Q$, that we have just cooked up, is only valid for the particular model that we are considering. However, you would be wrong:
+
+> The topological invariant $Q$ cannot change under continuous deformations of the Hamiltonian unless the gap closes.
+
+## Connecting the bulk invariant and the edge modes
+
+At the moment, the bulk topological invariant $Q$ defined above might look just like an abstract mathematical object. We know that $Q=1$ corresponds to the topological phase, but can we give a more concrete physical meaning to this value? This is the goal of this last part of the lecture.
+
+We have already connected the Pfaffian of a Bogoliubovde Gennes Hamiltonian to a physical quantity: The ground state fermion parity of the system. Our onedimensional invariant involves the product of two Pfaffians, $\textrm{Pf}[iH(0)]$ and $\textrm{Pf}[iH(\pi)]$. By taking their product we are somehow *comparing* the fermion parity of the two states of the chain with $k=0$ and $k=\pi$, and we have that $Q=1$ if and only if the two parities are different.
+
+This means that if we *continuously deform* $H(0)$ into $H(\pi)$ in some way without breaking the particlehole symmetry, we must encounter a zeroenergy level crossing in the energy spectrum, what we called a *fermion parity switch* in the last chapter.
+
+In practice, this can be done in the following way. Let's imagine that we change the boundary conditions of a Kitaev ring with $N$ sites from *periodic* to *antiperiodic* boundary conditions, that is from $\left\langle k  n=0 \right\rangle=\left\langle k  n=N \right\rangle$ to $\left\langle k  n=0 \right\rangle=\left\langle k  n=N \right\rangle$. This means that the allowed values of momentum shift from $k=2\pi p/N$ to $k = 2\pi p/N + \pi /N$.
+
+Let's now ask what is the difference in ground state fermion parity of the two chains. The value $k=0$ is always present in the chain with periodic boundary conditions, while $k=\pi$ is in the first set if $N$ is even and in the second set if $N$ is odd. This means that in either case, the difference in the ground state fermion parities between the chains with periodic and antiperiodic boundary conditions is equal to $Q$!
+
+To verify this statement, we will now *physically change the boundary condition in real space*. For simplicity, we will do so for a Kitaev ring with $\Delta=t$. You will remember that, in the Majorana basis, this corresponds to the limit where neighboring Majoranas from different sites are coupled by hopping of strength $t$.
+
+To go from periodic to antiperiodic boundary condition, we can change the hopping on the last bond of the ring (the one connecting sites $n=N1$ and $n=0$) from $t$ to $t$. This can easily be done continuously and without breaking particlehole symmetry, for instance by setting the last hopping to be equal to $t\,(12\lambda)$ and varying $\lambda$ in the interval $[0,1]$, as shown in this picture:
+
+![](figures/majorana_ring.svg)
+
+You can check that the Bogoliubovde Gennes Hamiltonian of this closed ring satisfies particlehole symmetry at every value of $\lambda$. Let's now look at the energy spectrum $E(\lambda)$ of the system as we vary $\mu$ from $0$ to $4t$, passing once again through the gap closing at $\mu=2t$.
+
+
+```python
+syst = kitaev_chain(L=25, periodic=True)
+
+p = SimpleNamespace(t=1, delta=1, lambda_=np.linspace(0.0, 1.0, 101), mu=None)
+
+kwargs = {'xticks': np.linspace(0, 1, 5),
+ 'yticks': np.linspace(4, 4, 5),
+ 'xdim': dims.lambda_,
+ 'ydim': dims.E_t}
+
+mus = np.arange(0, 4, 0.1)
+holoviews.HoloMap({p.mu: spectrum(syst, p, **kwargs) for p.mu in mus}, kdims=[dims.mu_t])
+```
+
+You can see that for $\mu<2t$, the energy spectrum shows a zeroenergy level crossing at $\lambda=1/2$. The fermion parity of the system is therefore different at $\lambda=0$ and $\lambda=1$. When $\lambda=1/2$ the hopping on the last bond is equal to zero. We have introduced a “cut” to the system, such that our closed Kitaev ring is effectively transformed to an open Kitaev chain. Because we are in the topological phase, this open Kitaev chain has two zeroenergy unpaired Majorana modes!
+
+On the other hand, when $\mu>2 t$ no zeroenergy level crossing is present. The ground state fermion parity is the same at $\lambda=0$ and $\lambda=1$. In this case, when we cut the system at $\lambda=1/2$, we find no unpaired Majorana modes, consistent with our knowledge of the behavior of the open chain in the trivial phase.
+
+We have therefore learned the essence of the bulkboundary correspondence: A nontrivial value $Q=1$ of the bulk invariant for the closed chain implies the existence of unpaired Majorana modes for the open chain. Also, we have been able to connect the value of the bulk invariant to a measurable quantity, in this case the ground state fermion parity of the closed chain.
+
+
+```python
+question = ("What will happen if we take a 100 site Kitaev chain in the topological phase "
+ "and change the potential mu to a very large negative value for the last 50 sites?")
+answers = ["The topological gap at the last 50 sites closes and reopens as $\mu$ changes from $0$ to $\infty$.",
+ "The Majoranas get destroyed by the drastic change of chemical potential $\mu_j$.",
+ "One of the Majoranas moves from being the end of the system to the middle."]
+MoocCheckboxesAssessment(question, answers, correct_answers=[0, 2])
+```
+
+# Three approaches to analysing topological systems
+
+
+```python
+MoocVideo("wiHPQlEha6g", src_location='1.2summary')
+```
+
+
+```python
+MoocDiscussion('Questions', 'Bulkedge correspondence in the Kitaev chain')
+```
diff git a/w1_topointro/w1_assignments.ipynb b/w1_topointro/w1_assignments.ipynb
deleted file mode 100644
index 3d95635..0000000
 a/w1_topointro/w1_assignments.ipynb
+++ /dev/null
@@ 1,199 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Simulations: what about other symmetries"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "So you've made it through the content of the first week. Congratulations!\n",
 "\n",
 "Now let's get our hands dirty. \n",
 "\n",
 "Let's begin by grabbing the notebooks of this week and the extra code we use to run these notebooks over [here](http://tiny.cc/topocm_smc). (Click the [i] button to the left of the folder that you want to copy.)\n",
 "\n",
 "You need to copy the `code` folder and the `w1_topointro` folder. Let's look into what's inside.\n",
 "\n",
 "\n",
 "#### First task: combination of particlehole and timereversal symmetries\n",
 "\n",
 "Look at the notebook about topology of zerodimensional systems, and see how we generate Hamiltonians with a spinful timereversal symmetry\n",
 "\n",
 "$$\n",
 "H = \\sigma_y H^* \\sigma_y.\n",
 "$$\n",
 "\n",
 "Now try to add this time reversal symmetry to a Hamiltonian which also has particlehole symmetry. It is easiest to do in the basis where particlehole symmetry has the form $H = H^*$.\n",
 "What do you think will happen? What will the extra symmetry do to the topological invariant?\n",
 "Test your guess by plotting the spectrum and calculating the Pfaffian invariant.\n",
 "\n",
 "\n",
 "#### Second task: SuSchriefferHeeger (SSH) model\n",
 "\n",
 "Similar to the Kitaev chain, the SSH model is simple a onedimensional model where you can see all the essential aspects of topological systems. Unlike the Kitaev chain it does correspond to a physical system: electrons in a polyacetylene chain.\n",
 "\n",
 "Here's such a chain:\n",
 "\n",
 "![](figures/polyacetylene.png)\n",
 "\n",
 "Due to the dimerization of the chain the unit cell has two atoms and the hoppings have alternating strengths $t_1$ and $t_2$, so that the Hamiltonian is\n",
 "$$H = \\sum_{n=1}^N t_1 \\left2n1\\right\\rangle\\left\\langle 2n\\right+t_2 \\left2n\\right\\rangle \\left\\langle 2n+1\\right + \\textrm{h.c}$$\n",
 "\n",
 "We can choose to start a unit cell from an evennumbered site, so $t_1$ becomes intracell hopping and $t_2$ intercell hopping.\n",
 "\n",
 "\n",
 "Now get the notebook with the Kitaev chain and transform a Kitaev chain into an SSH chain.\n",
 "\n",
 "Now repeat the calculations we've done with Majoranas using SSH chain. Keep $t_1 = 1$ and vary $t_2$.\n",
 "You should see something very similar to what you saw with the Kitaev chain.\n",
 "\n",
 "As you can guess, this is because the chain is topological.\n",
 "Think for a moment: what kind of symmetry protects the states at the edges of the chain.\n",
 "*(Hint: you did encounter this symmetry in our course.)*\n",
 "\n",
 "The particlehole symmetry, is a consequence of a mathematical transformation, and cannot be broken.\n",
 "The symmetry protecting the SSH chain, however, can be broken.\n",
 "Test your guess about the protecting symmetry by adding to your chain a term which breaks this symmetry and checking what it does to the spectrum of a finite chain and to its dispersion (especially as chain goes through a phase transition)."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocSelfAssessment()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Now share your results:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocDiscussion('Labs', 'Toy models simulations')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Review assignment"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "For the first week we have these papers:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "display_html(PreprintReference('1103.0780', \n",
 " description=\"Topological classification is not always applied to Hamiltonians. \"\n",
 " \"Figure out what is the topological quantity in open systems. \"\n",
 " \"See this idea also applied in \"\n",
 " \"http://arxiv.org/abs/1405.6896\"))\n",
 "display_html(PreprintReference('1305.2924', description=\"This is a study of statistical properties \"\n",
 " \"of topological transitions.\"))\n",
 "display_html(PreprintReference('1111.6600', description=\"A toy model may still be useful in practice.\"))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Bonus: Find your own paper to review!\n",
 "\n",
 "Do you know of another paper that fits into the topics of this week, and you think is good?\n",
 "Then you can get bonus points by reviewing that paper instead!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocPeerAssessment()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Reviews\", \"Toy models\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
diff git a/w1_topointro/w1_assignments.md b/w1_topointro/w1_assignments.md
new file mode 100644
index 0000000..5e04a75
 /dev/null
+++ b/w1_topointro/w1_assignments.md
@@ 0,0 +1,104 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+```
+
+# Simulations: what about other symmetries
+
+So you've made it through the content of the first week. Congratulations!
+
+Now let's get our hands dirty.
+
+Let's begin by grabbing the notebooks of this week and the extra code we use to run these notebooks over [here](http://tiny.cc/topocm_smc). (Click the [i] button to the left of the folder that you want to copy.)
+
+You need to copy the `code` folder and the `w1_topointro` folder. Let's look into what's inside.
+
+
+#### First task: combination of particlehole and timereversal symmetries
+
+Look at the notebook about topology of zerodimensional systems, and see how we generate Hamiltonians with a spinful timereversal symmetry
+
+$$
+H = \sigma_y H^* \sigma_y.
+$$
+
+Now try to add this time reversal symmetry to a Hamiltonian which also has particlehole symmetry. It is easiest to do in the basis where particlehole symmetry has the form $H = H^*$.
+What do you think will happen? What will the extra symmetry do to the topological invariant?
+Test your guess by plotting the spectrum and calculating the Pfaffian invariant.
+
+
+#### Second task: SuSchriefferHeeger (SSH) model
+
+Similar to the Kitaev chain, the SSH model is simple a onedimensional model where you can see all the essential aspects of topological systems. Unlike the Kitaev chain it does correspond to a physical system: electrons in a polyacetylene chain.
+
+Here's such a chain:
+
+![](figures/polyacetylene.png)
+
+Due to the dimerization of the chain the unit cell has two atoms and the hoppings have alternating strengths $t_1$ and $t_2$, so that the Hamiltonian is
+$$H = \sum_{n=1}^N t_1 \left2n1\right\rangle\left\langle 2n\right+t_2 \left2n\right\rangle \left\langle 2n+1\right + \textrm{h.c}$$
+
+We can choose to start a unit cell from an evennumbered site, so $t_1$ becomes intracell hopping and $t_2$ intercell hopping.
+
+
+Now get the notebook with the Kitaev chain and transform a Kitaev chain into an SSH chain.
+
+Now repeat the calculations we've done with Majoranas using SSH chain. Keep $t_1 = 1$ and vary $t_2$.
+You should see something very similar to what you saw with the Kitaev chain.
+
+As you can guess, this is because the chain is topological.
+Think for a moment: what kind of symmetry protects the states at the edges of the chain.
+*(Hint: you did encounter this symmetry in our course.)*
+
+The particlehole symmetry, is a consequence of a mathematical transformation, and cannot be broken.
+The symmetry protecting the SSH chain, however, can be broken.
+Test your guess about the protecting symmetry by adding to your chain a term which breaks this symmetry and checking what it does to the spectrum of a finite chain and to its dispersion (especially as chain goes through a phase transition).
+
+
+```python
+MoocSelfAssessment()
+```
+
+**Now share your results:**
+
+
+```python
+MoocDiscussion('Labs', 'Toy models simulations')
+```
+
+# Review assignment
+
+For the first week we have these papers:
+
+
+```python
+display_html(PreprintReference('1103.0780',
+ description="Topological classification is not always applied to Hamiltonians. "
+ "Figure out what is the topological quantity in open systems. "
+ "See this idea also applied in "
+ "http://arxiv.org/abs/1405.6896"))
+display_html(PreprintReference('1305.2924', description="This is a study of statistical properties "
+ "of topological transitions."))
+display_html(PreprintReference('1111.6600', description="A toy model may still be useful in practice."))
+```
+
+### Bonus: Find your own paper to review!
+
+Do you know of another paper that fits into the topics of this week, and you think is good?
+Then you can get bonus points by reviewing that paper instead!
+
+
+```python
+MoocPeerAssessment()
+```
+
+**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**
+
+
+```python
+MoocDiscussion("Reviews", "Toy models")
+```
diff git a/w2_majorana/Peierls.ipynb b/w2_majorana/Peierls.ipynb
deleted file mode 100644
index ee1efcf..0000000
 a/w2_majorana/Peierls.ipynb
+++ /dev/null
@@ 1,54 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "# This first cell will be removed by the converter."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Tightbinding models in a magnetic field: Peierls substitution"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "To understand how the vector potential enters a tightbinding model by the socalled Pierels substitution, let us remind ourselves that the gaugeinvariance of the Schrodinger equation requires us to transform the wavefunction amplitude or equivalently the creation operator of an electron at a site as $$c_j^\\dagger \\rightarrow c_j^\\dagger e^{i\\frac{e}{\\hbar c}\\Lambda(\\bf r_j)},$$ \n",
 "where $\\Lambda(\\bf r)$ generates the gauge transformation of the vector potential $\\bf A(\\bf r)\\rightarrow \\bf A(\\bf r)+\\bf\\nabla A(\\bf r)$. If there is no magnetic field then the vector potential can locally be set to $\\bf A=0$ by an appropriate gauge choice of $\\bf \\Lambda$. The hopping term in the absence of a vector potential is written as $H_t=t_{jl}c_j^\\dagger c_l+h.c$, which must gauge transform to $$H_t=t_{jl} e^{i\\frac{e}{\\hbar c}(\\Lambda(\\bf r_j)\\Lambda(\\bf r_l))}c_j^\\dagger c_l+h.c=t_{jl} e^{i\\frac{e}{\\hbar c}(\\int_{\\bf r_l}^{\\bf r_j} d\\bf r'\\cdot\\bf A(\\bf r')}c_j^\\dagger c_l+h.c.$$ While this expression is derived for zero magnetic field, by choosing the integration path to be the shortest distance over nearest neighbor bond, this expression is used to include magnetic fields in lattice models. This is referred to as the Peierls substitution for lattices.\n",
 "\n",
 "\n",
 "If we put our topological nanowire in a ring (as with the AharonovBohm effect) with a junction (as in the figure) and concentrate the magnetic field in the center of the ring, the vector potential $\\bf A$ is constrained by the magnetic flux $\\Phi$ as $$\\oint d\\bf {r'\\cdot\\bf A(\\bf r')}=\\int d^2\\bf {r'\\bf \\nabla\\times \\bf A(\\bf r')}=\\Phi.$$ \n",
 "Choosing a gauge for the vector potential so that it vanishes everywhere except in the junction the hopping phase $\\theta$ for the junction i.e. $H_t=t_{N,1}e^{i\\theta}c_N^\\dagger c_1+h.c.$ is written as $$\\theta=\\int_{\\bf r_l}^{\\bf r_j} d\\bf r'\\cdot\\bf A(\\bf r')=\\pi \\Phi/\\Phi_0,$$ where $\\Phi_0=hc/2e$ is the superconducting flux quantum. "
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
diff git a/w2_majorana/Peierls.md b/w2_majorana/Peierls.md
new file mode 100644
index 0000000..cce5b92
 /dev/null
+++ b/w2_majorana/Peierls.md
@@ 0,0 +1,14 @@
+
+
+```python
+# This first cell will be removed by the converter.
+```
+
+# Tightbinding models in a magnetic field: Peierls substitution
+
+To understand how the vector potential enters a tightbinding model by the socalled Pierels substitution, let us remind ourselves that the gaugeinvariance of the Schrodinger equation requires us to transform the wavefunction amplitude or equivalently the creation operator of an electron at a site as $$c_j^\dagger \rightarrow c_j^\dagger e^{i\frac{e}{\hbar c}\Lambda(\bf r_j)},$$
+where $\Lambda(\bf r)$ generates the gauge transformation of the vector potential $\bf A(\bf r)\rightarrow \bf A(\bf r)+\bf\nabla A(\bf r)$. If there is no magnetic field then the vector potential can locally be set to $\bf A=0$ by an appropriate gauge choice of $\bf \Lambda$. The hopping term in the absence of a vector potential is written as $H_t=t_{jl}c_j^\dagger c_l+h.c$, which must gauge transform to $$H_t=t_{jl} e^{i\frac{e}{\hbar c}(\Lambda(\bf r_j)\Lambda(\bf r_l))}c_j^\dagger c_l+h.c=t_{jl} e^{i\frac{e}{\hbar c}(\int_{\bf r_l}^{\bf r_j} d\bf r'\cdot\bf A(\bf r')}c_j^\dagger c_l+h.c.$$ While this expression is derived for zero magnetic field, by choosing the integration path to be the shortest distance over nearest neighbor bond, this expression is used to include magnetic fields in lattice models. This is referred to as the Peierls substitution for lattices.
+
+
+If we put our topological nanowire in a ring (as with the AharonovBohm effect) with a junction (as in the figure) and concentrate the magnetic field in the center of the ring, the vector potential $\bf A$ is constrained by the magnetic flux $\Phi$ as $$\oint d\bf {r'\cdot\bf A(\bf r')}=\int d^2\bf {r'\bf \nabla\times \bf A(\bf r')}=\Phi.$$
+Choosing a gauge for the vector potential so that it vanishes everywhere except in the junction the hopping phase $\theta$ for the junction i.e. $H_t=t_{N,1}e^{i\theta}c_N^\dagger c_1+h.c.$ is written as $$\theta=\int_{\bf r_l}^{\bf r_j} d\bf r'\cdot\bf A(\bf r')=\pi \Phi/\Phi_0,$$ where $\Phi_0=hc/2e$ is the superconducting flux quantum.
diff git a/w2_majorana/braiding.ipynb b/w2_majorana/braiding.ipynb
deleted file mode 100644
index 8be83aa..0000000
 a/w2_majorana/braiding.ipynb
+++ /dev/null
@@ 1,328 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Braiding of Majoranas"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"Ndf2Z84g1R0\", src_location=\"2.3intro\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Majorana zero modes in nanowire networks"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As you just heard in the video, the goal of this lecture is to compute the quantum statistics of Majorana zero modes. In order to do this, we will have in mind a nanowire network where Majorana modes can be exchanged in space, like this one:\n",
 "\n",
 "![](figures/nanowire_network.svg)\n",
 "\n",
 "In the drawing, you can see a nanowire with many Tshaped junctions in between several Majorana zero modes (which is why we call it a network). We will not worry about the microscopic description of the nanowire network, which will differ in irrelevant ways from similar structures in alternative platforms for Majoranas (we'll learn about those later, in week 7). Just to fix the ideas, you can imagine that the system can be effectively described by the Kitaev chain toymodel, and that the Majoranas are at the positions of domain walls where the gap changes sign, as you saw in the first week of the course.\n",
 "\n",
 "The only thing that distinguishes the Majorana zero modes is their position in the network. They have no other “flavour” that would allow us to characterize them. They are identical to each other, just like all electrons are identical to each other. If we exchanged two Majoranas in space, the system after the exchange would look exactly the same as it looked before the exchange.\n",
 "\n",
 ">It is very interesting to ask what is the behaviour of the quantum state $\\left\\Psi\\right\\rangle$ of a system of identical particles under the exchange of two of the particles. You already know that for bosons and fermions $\\left\\Psi\\right\\rangle\\,\\to\\,\\pm\\left\\Psi\\right\\rangle$. To see what happens in the case of Majoranas, we first have to learn how to write down the quantum state $\\left\\Psi\\right\\rangle$ corresponding to a set of Majoranas like the one sketched above.\n",
 "\n",
 "\n",
 "## The Hilbert space of a set of Majoranas\n",
 "\n",
 "From now on, it is important to keep in mind that by considering only the states corresponding to the Majorana zero modes, we are neglecting the existence of the states that live in the bulk. As mentioned in the video, we assume that the energy spectrum looks like this:\n",
 "\n",
 "![](figures/gs_manifold.svg)\n",
 "\n",
 "Based on your knowledge of the Kitaev chain, this assumption should sound reasonable to you. Because you have several Majoranas, there will be several states all at zero energy, forming a “ground state manifold”.\n",
 "\n",
 "\n",
 "Let's now explore more in detail the ground state manifold defined by this degenerate sets of states.\n",
 "\n",
 "\n",
 "In the drawing you see six Majoranas, that is three pairs, but let's consider here the more general case of $N$ pairs. It might appear that since the $\\gamma_n$s don't appear in the Hamiltonian, there is a degenerate quantum state for each of the $2N$ values of $n$. However, just as Majorana modes appear in pairs, they can be assigned quantum states only in pairs.\n",
 "\n",
 ">To assign quantum states to Majoranas, we can pair the Majoranas and form fermionic modes,\n",
 "$$\n",
 "c^\\dagger_n = \\tfrac{1}{2}(\\gamma_{2n1}+i\\gamma_{2n})\\,,\\\\\n",
 "c_n =\\tfrac{1}{2}(\\gamma_{2n1}i\\gamma_{2n})\\,,\n",
 "$$\n",
 "for $n=1,\\dots, N$. Using this notation, we have chosen to pair neighboring Majoranas into a fermionic mode. We have now a set of $N$ fermionic modes with corresponding creation and annihilation operators. Every mode can be empty or it can be occupied by a fermion, giving us two possible degenerate quantum states $\\left0\\right\\rangle$ and $\\left1\\right\\rangle$ for each pair of Majoranas.\n",
 "\n",
 "\n",
 "Going back to our sketch, we can represent the situation as follows:\n",
 "\n",
 "![](figures/majoranas_pairing.svg)\n",
 "\n",
 "The coloring of the Majorana modes now makes explicit our choice of how to pair them into fermionic modes. In total, the system above has 8 possible states, corresponding to all the possible combinations of the occupation numbers of the 3 fermionic modes. Generalizing, we will have $2^N$ possible quantum states for $N$ pairs of Majoranas. We can represent each such state with a ket\n",
 "\n",
 "$$\\left s_1, s_2, \\dots, s_N\\right\\rangle\\,,$$\n",
 "\n",
 "where $s_n$ is equal to $0$ if the $n$th fermionic mode is not occupied, and equal to $1$ if it is occupied. These states are a *complete basis* for the Hilbert space of the set of Majorana modes. Note that these basis states are all eigenstates of the operators $P_n \\equiv 12c^\\dagger_n c_n \\equiv i\\gamma_{2n1}\\gamma_{2n}$. For instance, we have that\n",
 "\n",
 "$$ P_1 \\left 0, \\dots \\right\\rangle\\ = (12c^\\dagger_1 c_1)\\left0, \\dots \\right\\rangle= + \\left0, \\dots \\right\\rangle\\,, $$\n",
 "$$ P_1 \\left 1, \\dots \\right\\rangle\\ = (12c^\\dagger_1 c_1)\\left1, \\dots \\right\\rangle=  \\left1, \\dots \\right\\rangle\\,, $$\n",
 "\n",
 "and so on. The operator $P_n$ is the *fermion parity operator* for the pair of Majoranas $\\gamma_{2n1}$ and $\\gamma_{2n}$. At this point it is useful to remind you that different Majorana operators all anticommute with each other. This means that the product of a pair of Majorana operators commutes with the product of a different pair, for instance:\n",
 "\n",
 "$$(\\gamma_1\\gamma_2)(\\gamma_3\\gamma_4) = (\\gamma_3\\gamma_4)(\\gamma_1\\gamma_2)\\,.$$\n",
 "\n",
 "However, if the two pairs share a Majorana, then they do not commute anymore, for instance:\n",
 "\n",
 "$$(\\gamma_1\\gamma_2)(\\gamma_2\\gamma_3) =  (\\gamma_2\\gamma_3)(\\gamma_1\\gamma_2)\\,.$$\n",
 "Of course, the product above can also be simplified: since $\\gamma_2^2=1$, you have that $(\\gamma_1\\gamma_2)(\\gamma_2\\gamma_3)=\\gamma_1\\gamma_3$.\n",
 " All $P_n$'s commute with each other, because they all involve a different pair of Majoranas. \n",
 " \n",
 "> Thus the Hilbert space of states $\\Psi\\rangle$ of a set of $N$ pairs of Majorana modes is spanned by the simultaneous eigenstates $s_1,s_2,\\dots,s_N\\rangle$ of the commuting fermion parity operators $P_n$ and is written as $$\\left\\Psi\\right\\rangle= \\sum_{s_n=0,1} \\alpha_{s_1s_2\\dots s_N}\\,\\left s_1, s_2, \\dots, s_N\\right\\rangle\\, $$\n",
 " with complex coefficients $\\alpha_{s_1s_2\\dots s_N}$. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 " At this point an important consideration is in order. You will remember learning during the first week that, while a superconducting Hamiltonian may not conserve the total number of electrons due to the creation and annihilation of Cooper pairs, the parity of the number of electrons is always conserved. \n",
 "We can obtain the *total fermion parity* by multiplying all the operators $P_n$,\n",
 "\n",
 "$$ P_\\textrm{tot}=P_1\\cdot P_2\\cdot\\, \\dots\\, \\cdot P_N = i^N\\,\\gamma_1\\gamma_2\\dots\\gamma_{2N}\\,.$$\n",
 "\n",
 "The operator $P_\\textrm{tot}$ has eigenvalues $s_1 s_2\\dots s_N=\\pm 1$, depending on whether the total number of occupied fermionic modes is even or odd. Applied to our case, this means that it is only meaningful to consider states $\\left\\Psi\\right\\rangle$ which are *eigenstates* of the operator $P_\\textrm{tot}$, that is\n",
 "\n",
 "$$P_\\textrm{tot}\\left\\Psi\\right\\rangle=\\pm\\left\\Psi\\right\\rangle\\,.$$\n",
 "\n",
 "In particular, linear combinations of states with different total parity are forbidden. You can see this condition as a constraint on the allowed values of the coefficients $\\alpha_{s_1s_2\\dots s_N}$.\n",
 "\n",
 "This consideration only applies to closed systems. It does not apply if we are considering a system which is in contact with a reservoir of electrons, such as a metallic lead, in which case electrons may tunnel in and out of the lead, changing the total parity of the system. Equivalently, it does not apply if we are considering only a part of the total system. You could for instance imagine that, in our sketch, there are more Majorana zero modes in the part of the network which is not drawn explicitly (represented by the dots which “continue” the nanowire). In such a case it is perfectly possible that the *total* network is in, say, a state of even parity, but that the subsystem under consideration is in a superposition of even and odd parity states."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"Consider an isolated system with N=7 pairs of Majoranas, and an even total fermion parity. \"\n",
 " \"What is the ground state degeneracy of the system?\")\n",
 "answers = [\"Trick question  it is not possible to get N=7 pairs of Majorana modes with even parity.\",\n",
 " \"2^7.\",\n",
 " \"2^6.\",\n",
 " \"14\",\n",
 " \"The system has an energy gap, so it cannot be degenerate.\"]\n",
 "explanation = (\"N pairs of Majoranas means a Hilbert space with dimension 2^7, \"\n",
 " \"out of which half have even total parity and half have odd total parity. \"\n",
 " \"So the degeneracy at fixed even parity is 2^6.\")\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=2, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# NonAbelian statistics of Majoranas"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's now imagine that experimentalists are not only able to build such a network, but also to move the position of the domain walls and swap the positions of two Majoranas, for instance by performing the following trajectory:\n",
 "\n",
 "![](figures/nanowire_network_exchange.svg)\n",
 "\n",
 "Let's suppose that the trajectory takes a time $T$. During the trajectory, the system is described by a timedependent Hamiltonian $H(t)$, $0\\leq t \\leq T$. This Hamiltonian contains all the details of the system, such as the positions of the domain walls where the Majoranas are located. Because the final configuration of the system is identical to the initial one, for instance all the domain walls are in the same positions as in the beginning, we have that $H(0)=H(T)$. In other words, we are considering a *closed trajectory* which brings the Hamiltonian back into itself. To ensure that the wavefunction for the system does not leave the ground state manifold of states $\\Psi\\rangle$, we need to change the Hamiltonian $H(t)$ slowly enough to obey the [adiabatic theorem](http://en.wikipedia.org/wiki/Adiabatic_theorem). \n",
 "\n",
 "So let's imagine that we are in the adiabatic limit and that we exchange two Majoranas $\\gamma_n$ and $\\gamma_m$. As usual in quantum mechanics, the initial and final quantum states are connected by a unitary operator $U$ ($U^{1}=U^\\dagger$),\n",
 "\n",
 "$$\\left\\Psi\\right\\rangle \\,\\to\\, U \\left\\Psi\\right\\rangle\\,.$$\n",
 "\n",
 "Because the quantum state $\\left\\Psi\\right\\rangle$ never leaves the ground state manifold, which has $2^N$ states, the operator $U$ can be written a $2^N\\times 2^N$ unitary matrix.\n",
 "\n",
 "We can derive the exact form of $U$ without a direct calculation, which would require knowing $H(t)$, but only based on the following, general considerations. First, the adiabatic exchange of two Majoranas does not change the parity of the number of electrons in the system, so $U$ commutes with the total fermion parity, $[U, P_\\textrm{tot}]=0$. Second, it is reasonable to assume that $U$ only depends on the Majoranas involved in the exchange, or in other words that it is a function of $\\gamma_n$ and $\\gamma_m$, and of no other operator. And because it has to preserve fermion parity, it can only depend on their product, that is on the parity operator $i\\gamma_n\\gamma_m$, which is Hermitian. Finally, the exponential of $i$ times a Hermitian operator is a unitary operator. So, in general $U$ must take the form\n",
 "\n",
 "$$U\\equiv\\exp(\\beta \\gamma_n \\gamma_m) = \\cos(\\beta) + \\gamma_n\\gamma_m \\sin(\\beta)\\,,$$\n",
 "\n",
 "*up to an overall phase*. Here, $\\beta$ is a real coefficient to be determined, and in the last equality we have used the fact that $(\\gamma_n\\gamma_m)^2=1$. To determine $\\beta$, it is convenient to go to the [Heisenberg picture](http://en.wikipedia.org/wiki/Heisenberg_picture) and look at the evolution of the Majorana operators in time. We have that\n",
 "\n",
 "$$\n",
 "\\gamma_n\\,\\to\\, U\\,\\gamma_n\\,U^\\dagger\\,,\\\\\n",
 "\\gamma_m\\,\\to\\, U\\,\\gamma_m\\,U^\\dagger\\,.\n",
 "$$\n",
 "\n",
 "Inserting our guess for $U$ we obtain:\n",
 "\n",
 "$$\n",
 "\\gamma_n\\,\\to\\, \\cos (2\\beta)\\,\\gamma_n  \\sin(2\\beta)\\,\\gamma_m\\,,\\\\\n",
 "\\gamma_m\\,\\to\\, \\cos (2\\beta)\\,\\gamma_m + \\sin(2\\beta)\\,\\gamma_n\\,.\n",
 "$$\n",
 "\n",
 "Now we have to remember that at time $T$ we have completed a closed trajectory, so that the Majorana $\\gamma_n$ is now in the place initially occupied by $\\gamma_m$, and vice versa. This condition leads to the choice $\\beta = \\pm \\pi/4$. It is not strange that we find that both signs are possible  this distinguishes the clockwise and the counterclockwise exchange of the Majoranas. \n",
 "\n",
 ">Thus, we can write the unitary operator that exchanges the Majorana modes $\\gamma_n$ and $\\gamma_m$ in an explicit (and somewhat nontrivial looking!) form as:\n",
 "$$U = \\exp \\left(\\pm\\frac{\\pi}{4}\\gamma_n \\gamma_m\\right) = \\tfrac{1}{\\sqrt{2}}\\left(1\\pm\\gamma_n\\gamma_m\\right)$$\n",
 "\n",
 "\n",
 "To fix our ideas and study the consequences of $U$ more closely, it is convenient to just focus on four Majoranas $\\gamma_1\\,\\gamma_2,\\gamma_3$ and $\\gamma_4$. For this discussion we will assume that counterclockwise exchanges pick the $+$ sign in $U$. Their ground state manifold has four states, which in the notation introduced before we write down as\n",
 "\n",
 "$$\\left00\\right\\rangle, \\left11\\right\\rangle, \\left01\\right\\rangle, \\left10\\right\\rangle\\,,$$\n",
 "\n",
 "where the first digit is the occupation number of the fermionic mode $c^\\dagger_1=\\tfrac{1}{2}(\\gamma_1+i\\gamma_2)$ and the second digit the occupation number of $c^\\dagger_2=\\tfrac{1}{2}(\\gamma_3+i\\gamma_4)$. The most generic possible wave function is a superposition\n",
 "\n",
 "$$\\left\\Psi\\right\\rangle = s_{00}\\left00\\right\\rangle + s_{11} \\left11\\right\\rangle + s_{01} \\left01\\right\\rangle + s_{10} \\left10\\right\\rangle\\,,$$\n",
 "\n",
 "which we can also represent as a vector with four entries, $\\left\\Psi\\right\\rangle = (s_{00}, s_{11}, s_{01}, s_{10})^T$. The operator $U$ at this point can be written as a $4\\times 4$ matrix. In order to do so, you just have to compute the action of a product of Majoranas on the basis states. This a simple but tedious operation, which we skip here. It results in the following matrices for the operators $U_{12}, U_{23}$ and $U_{34}$ exchanging neighboring Majoranas:\n",
 "\n",
 "$$\n",
 "U_{12} = \\exp\\left(\\frac{\\pi}{4}\\gamma_1 \\gamma_2\\right) \\equiv\\begin{pmatrix}\n",
 "e^{i\\pi/4} & 0 & 0 & 0 \\\\0 & e^{i\\pi/4} & 0 &0 \\\\0 & 0& e^{i\\pi/4} &0 \\\\ 0&0& 0& e^{i\\pi/4}\n",
 "\\end{pmatrix}\\,,\n",
 "$$\n",
 "\n",
 "$$\n",
 "U_{23} = \\exp\\left(\\frac{\\pi}{4}\\gamma_2 \\gamma_3\\right) \\equiv\\frac{1}{\\sqrt{2}}\\begin{pmatrix}\n",
 "1 & i & 0 & 0\\\\ i & 1 & 0& 0\\\\ 0& 0& 1 & i\\\\ 0& 0& i & 1\n",
 "\\end{pmatrix}\\,,\n",
 "$$\n",
 "\n",
 "$$\n",
 "U_{34} = \\exp\\left(\\frac{\\pi}{4}\\gamma_3 \\gamma_4\\right) \\equiv\\begin{pmatrix}\n",
 "e^{i\\pi/4} & 0 & 0 & 0\\\\ 0& e^{i\\pi/4} & 0& 0\\\\ 0& 0& e^{i\\pi/4} & 0\\\\ 0& 0& 0& e^{i\\pi/4}\n",
 "\\end{pmatrix}\\,.\n",
 "$$\n",
 "\n",
 "These matrices indeed act in a very nontrivial way on the wave function. For instance, if we start from the state $\\left00\\right\\rangle$ and we exchange $\\gamma_2$ and $\\gamma_3$, we obtain\n",
 "\n",
 "$$\\left00\\right\\rangle\\,\\to\\,U_{23}\\left00\\right\\rangle=\\tfrac{1}{\\sqrt{2}}\\left(\\left00\\right\\ranglei\\left11\\right\\rangle\\right)\\,,$$\n",
 "\n",
 "which is a superposition of states! Hence we have seen explicitly that the effect of the exchange two Majoranas on the wavefunction amounts to much more than just an overall phase, as it happens for bosons and fermions.\n",
 "\n",
 "Let's now try a sequence of two exchanges. In this case, we have to multiply the corresponding $U$s, ordering them from right to the left according to the order of the exchanges. Given that the matrices above are not diagonal, it is not surprising that the order in the product matters a lot. For instance you can check that\n",
 "\n",
 "$$U_{23}U_{12}\\neq U_{12}U_{23}\\,$$\n",
 "\n",
 ">We have just shown that exchanging two Majorana modes leads to a non trivial rotation in the ground state manifold, and that changing the order of the exchanges changes the final result. These properties make Majorana modes **nonAbelian anyons**. The exchange of two nonAbelian anyons is usually called **braiding**, a name which is suggestive of the fact that, when thinking of the trajectories of the different particles, a sequence of exchanges looks like a braid made out of different strands.\n",
 "\n",
 "Finally, you might object to the fact that the network of nanowires drawn in the figures only allows to exchange neighbouring Majoranas, even though our derivation of $U=\\exp(\\pi\\gamma_n\\gamma_m/4)$ seems to hold for any pair of Majoranas. This geometric constraint is not a big problem: by carefully composing many exchanges between neighbours, we can exchange any pair of Majoranas. As an example, you have that $U_{13}\\equiv\\exp\\left(\\pi\\gamma_1 \\gamma_3/4\\right) = U_{12}^\\dagger\\,U^\\dagger_{23}\\,U_{12}$."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"Consider a system with only one pair of Majorana modes, thus with just two degenerate states with different fermion parity. \"\n",
 " \"What happens when we exchange the pair of Majorana modes, starting from a given fermion parity eigenstate?\")\n",
 "answers = [\"The fermion parity of the state flips.\",\n",
 " \"Nothing happens.\",\n",
 " \"The system wavefunction picks up a phase that depends on the fermion parity.\",\n",
 " \"You end up in a superposition of the two states.\"]\n",
 "explanation = (\"The total fermion parity cannot change, \"\n",
 " \"but the two states can pick up a different phase. \"\n",
 " \"This is indeed what happens since the operator $U$ describing the exchange depends on fermion parity.\")\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=2, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Majoranas and quantum computation: basic ideas"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The nonAbelian statistics of Majorana modes is a very special property. Furthermore, it has some practical interest, since it could be used to realize a robust **quantum computer**. (If you are not yet interested in quantum computation, you can skip this part, even though we suggest that you get interested in it! Quantum computation is a huge topic of research, but [this](http://arxiv.org/abs/quantph/9708022) is a good place to start learning.)\n",
 "\n",
 "Let's discuss very briefly how this can be done.\n",
 "\n",
 "First, we can think of our network of nanowires with $2N$ Majoranas as a small computer. The $2^N$ states of the ground state manifold can encode a string of $N$ bits, so it's like having a small *register*. As always in quantum computation, and unlike in a classical computer, the register can be in a superposition of different states. So far, nothing really special about Majoranas.\n",
 "\n",
 "How do we execute an *algorithm* on our register? Simply by exchanging the Majorana modes! Because of the nonAbelian statistics, different sequences of exchanges will yield different algorithms. Of course, to execute an interesting algorithm we may need a lot of Majorana modes and a very very long sequence of exchanges. However, it all begins with the small building blocks, the matrices that you have just studied in detail.\n",
 "\n",
 "You might say that this is just another way to obtain a given unitary operator acting on the wave function. The beautiful thing, though, is that both the state of the register and the algorithms are *topologically protected*. Let's explain what we mean by that.\n",
 "\n",
 "The state of the register is encoded in the fermion parity degrees of freedom, which are shared *nonlocally* by the Majoranas. This means that no local perturbation can change the state of the register and cause *decoherence* of the quantum state. The environment cannot access the information stored in the Majoranas, as long as they are kept far away from each other. The only exception is a change in fermion parity due to the tunnelling of a stray quasiparticle into the system (this is the problem of quasiparticle poisoning, the same that can hinder the detection of the $4\\pi$periodic Josephson effect of Majorana modes, as you heard from Carlo Beenakker). But except from this, the Majoranas are a great *quantum memory*.\n",
 "\n",
 "On the other hand, every step of the algorithm will be extremely accurate because it is given by an exchange of two Majoranas, which corresponds to *exactly* $\\exp(\\pi\\gamma_n\\gamma_m/4)$. When you are in the adiabatic limit, this operator does not depend on any of the details on how the exchange between Majoranas is performed. It does not depend on *how* you move the Majoranas, or on the particular trajectory that $\\gamma_n$ and $\\gamma_m$ followed, or on the timing of the trajectory. So the final result is extremely reliable.\n",
 "\n",
 "These are the basic ideas of **topological quantum computation**. It is incredible that we can find condensed matter systems, such as networks of Majoranas, which are naturally endowed with these characteristics. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Summary"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"V3e9r4S8GHs\", src_location=\"2.3summary\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Questions about what you just learned? Ask them below.**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion('Questions', 'NonAbelian statistics of Majorana modes')"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w2_majorana/braiding.md b/w2_majorana/braiding.md
new file mode 100644
index 0000000..859416b
 /dev/null
+++ b/w2_majorana/braiding.md
@@ 0,0 +1,230 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+```
+
+# Braiding of Majoranas
+
+
+```python
+MoocVideo("Ndf2Z84g1R0", src_location="2.3intro")
+```
+
+# Majorana zero modes in nanowire networks
+
+As you just heard in the video, the goal of this lecture is to compute the quantum statistics of Majorana zero modes. In order to do this, we will have in mind a nanowire network where Majorana modes can be exchanged in space, like this one:
+
+![](figures/nanowire_network.svg)
+
+In the drawing, you can see a nanowire with many Tshaped junctions in between several Majorana zero modes (which is why we call it a network). We will not worry about the microscopic description of the nanowire network, which will differ in irrelevant ways from similar structures in alternative platforms for Majoranas (we'll learn about those later, in week 7). Just to fix the ideas, you can imagine that the system can be effectively described by the Kitaev chain toymodel, and that the Majoranas are at the positions of domain walls where the gap changes sign, as you saw in the first week of the course.
+
+The only thing that distinguishes the Majorana zero modes is their position in the network. They have no other “flavour” that would allow us to characterize them. They are identical to each other, just like all electrons are identical to each other. If we exchanged two Majoranas in space, the system after the exchange would look exactly the same as it looked before the exchange.
+
+>It is very interesting to ask what is the behaviour of the quantum state $\left\Psi\right\rangle$ of a system of identical particles under the exchange of two of the particles. You already know that for bosons and fermions $\left\Psi\right\rangle\,\to\,\pm\left\Psi\right\rangle$. To see what happens in the case of Majoranas, we first have to learn how to write down the quantum state $\left\Psi\right\rangle$ corresponding to a set of Majoranas like the one sketched above.
+
+
+## The Hilbert space of a set of Majoranas
+
+From now on, it is important to keep in mind that by considering only the states corresponding to the Majorana zero modes, we are neglecting the existence of the states that live in the bulk. As mentioned in the video, we assume that the energy spectrum looks like this:
+
+![](figures/gs_manifold.svg)
+
+Based on your knowledge of the Kitaev chain, this assumption should sound reasonable to you. Because you have several Majoranas, there will be several states all at zero energy, forming a “ground state manifold”.
+
+
+Let's now explore more in detail the ground state manifold defined by this degenerate sets of states.
+
+
+In the drawing you see six Majoranas, that is three pairs, but let's consider here the more general case of $N$ pairs. It might appear that since the $\gamma_n$s don't appear in the Hamiltonian, there is a degenerate quantum state for each of the $2N$ values of $n$. However, just as Majorana modes appear in pairs, they can be assigned quantum states only in pairs.
+
+>To assign quantum states to Majoranas, we can pair the Majoranas and form fermionic modes,
+$$
+c^\dagger_n = \tfrac{1}{2}(\gamma_{2n1}+i\gamma_{2n})\,,\\
+c_n =\tfrac{1}{2}(\gamma_{2n1}i\gamma_{2n})\,,
+$$
+for $n=1,\dots, N$. Using this notation, we have chosen to pair neighboring Majoranas into a fermionic mode. We have now a set of $N$ fermionic modes with corresponding creation and annihilation operators. Every mode can be empty or it can be occupied by a fermion, giving us two possible degenerate quantum states $\left0\right\rangle$ and $\left1\right\rangle$ for each pair of Majoranas.
+
+
+Going back to our sketch, we can represent the situation as follows:
+
+![](figures/majoranas_pairing.svg)
+
+The coloring of the Majorana modes now makes explicit our choice of how to pair them into fermionic modes. In total, the system above has 8 possible states, corresponding to all the possible combinations of the occupation numbers of the 3 fermionic modes. Generalizing, we will have $2^N$ possible quantum states for $N$ pairs of Majoranas. We can represent each such state with a ket
+
+$$\left s_1, s_2, \dots, s_N\right\rangle\,,$$
+
+where $s_n$ is equal to $0$ if the $n$th fermionic mode is not occupied, and equal to $1$ if it is occupied. These states are a *complete basis* for the Hilbert space of the set of Majorana modes. Note that these basis states are all eigenstates of the operators $P_n \equiv 12c^\dagger_n c_n \equiv i\gamma_{2n1}\gamma_{2n}$. For instance, we have that
+
+$$ P_1 \left 0, \dots \right\rangle\ = (12c^\dagger_1 c_1)\left0, \dots \right\rangle= + \left0, \dots \right\rangle\,, $$
+$$ P_1 \left 1, \dots \right\rangle\ = (12c^\dagger_1 c_1)\left1, \dots \right\rangle=  \left1, \dots \right\rangle\,, $$
+
+and so on. The operator $P_n$ is the *fermion parity operator* for the pair of Majoranas $\gamma_{2n1}$ and $\gamma_{2n}$. At this point it is useful to remind you that different Majorana operators all anticommute with each other. This means that the product of a pair of Majorana operators commutes with the product of a different pair, for instance:
+
+$$(\gamma_1\gamma_2)(\gamma_3\gamma_4) = (\gamma_3\gamma_4)(\gamma_1\gamma_2)\,.$$
+
+However, if the two pairs share a Majorana, then they do not commute anymore, for instance:
+
+$$(\gamma_1\gamma_2)(\gamma_2\gamma_3) =  (\gamma_2\gamma_3)(\gamma_1\gamma_2)\,.$$
+Of course, the product above can also be simplified: since $\gamma_2^2=1$, you have that $(\gamma_1\gamma_2)(\gamma_2\gamma_3)=\gamma_1\gamma_3$.
+ All $P_n$'s commute with each other, because they all involve a different pair of Majoranas.
+
+> Thus the Hilbert space of states $\Psi\rangle$ of a set of $N$ pairs of Majorana modes is spanned by the simultaneous eigenstates $s_1,s_2,\dots,s_N\rangle$ of the commuting fermion parity operators $P_n$ and is written as $$\left\Psi\right\rangle= \sum_{s_n=0,1} \alpha_{s_1s_2\dots s_N}\,\left s_1, s_2, \dots, s_N\right\rangle\, $$
+ with complex coefficients $\alpha_{s_1s_2\dots s_N}$.
+
+ At this point an important consideration is in order. You will remember learning during the first week that, while a superconducting Hamiltonian may not conserve the total number of electrons due to the creation and annihilation of Cooper pairs, the parity of the number of electrons is always conserved.
+We can obtain the *total fermion parity* by multiplying all the operators $P_n$,
+
+$$ P_\textrm{tot}=P_1\cdot P_2\cdot\, \dots\, \cdot P_N = i^N\,\gamma_1\gamma_2\dots\gamma_{2N}\,.$$
+
+The operator $P_\textrm{tot}$ has eigenvalues $s_1 s_2\dots s_N=\pm 1$, depending on whether the total number of occupied fermionic modes is even or odd. Applied to our case, this means that it is only meaningful to consider states $\left\Psi\right\rangle$ which are *eigenstates* of the operator $P_\textrm{tot}$, that is
+
+$$P_\textrm{tot}\left\Psi\right\rangle=\pm\left\Psi\right\rangle\,.$$
+
+In particular, linear combinations of states with different total parity are forbidden. You can see this condition as a constraint on the allowed values of the coefficients $\alpha_{s_1s_2\dots s_N}$.
+
+This consideration only applies to closed systems. It does not apply if we are considering a system which is in contact with a reservoir of electrons, such as a metallic lead, in which case electrons may tunnel in and out of the lead, changing the total parity of the system. Equivalently, it does not apply if we are considering only a part of the total system. You could for instance imagine that, in our sketch, there are more Majorana zero modes in the part of the network which is not drawn explicitly (represented by the dots which “continue” the nanowire). In such a case it is perfectly possible that the *total* network is in, say, a state of even parity, but that the subsystem under consideration is in a superposition of even and odd parity states.
+
+
+```python
+question = ("Consider an isolated system with N=7 pairs of Majoranas, and an even total fermion parity. "
+ "What is the ground state degeneracy of the system?")
+answers = ["Trick question  it is not possible to get N=7 pairs of Majorana modes with even parity.",
+ "2^7.",
+ "2^6.",
+ "14",
+ "The system has an energy gap, so it cannot be degenerate."]
+explanation = ("N pairs of Majoranas means a Hilbert space with dimension 2^7, "
+ "out of which half have even total parity and half have odd total parity. "
+ "So the degeneracy at fixed even parity is 2^6.")
+MoocMultipleChoiceAssessment(question, answers, correct_answer=2, explanation=explanation)
+```
+
+# NonAbelian statistics of Majoranas
+
+Let's now imagine that experimentalists are not only able to build such a network, but also to move the position of the domain walls and swap the positions of two Majoranas, for instance by performing the following trajectory:
+
+![](figures/nanowire_network_exchange.svg)
+
+Let's suppose that the trajectory takes a time $T$. During the trajectory, the system is described by a timedependent Hamiltonian $H(t)$, $0\leq t \leq T$. This Hamiltonian contains all the details of the system, such as the positions of the domain walls where the Majoranas are located. Because the final configuration of the system is identical to the initial one, for instance all the domain walls are in the same positions as in the beginning, we have that $H(0)=H(T)$. In other words, we are considering a *closed trajectory* which brings the Hamiltonian back into itself. To ensure that the wavefunction for the system does not leave the ground state manifold of states $\Psi\rangle$, we need to change the Hamiltonian $H(t)$ slowly enough to obey the [adiabatic theorem](http://en.wikipedia.org/wiki/Adiabatic_theorem).
+
+So let's imagine that we are in the adiabatic limit and that we exchange two Majoranas $\gamma_n$ and $\gamma_m$. As usual in quantum mechanics, the initial and final quantum states are connected by a unitary operator $U$ ($U^{1}=U^\dagger$),
+
+$$\left\Psi\right\rangle \,\to\, U \left\Psi\right\rangle\,.$$
+
+Because the quantum state $\left\Psi\right\rangle$ never leaves the ground state manifold, which has $2^N$ states, the operator $U$ can be written a $2^N\times 2^N$ unitary matrix.
+
+We can derive the exact form of $U$ without a direct calculation, which would require knowing $H(t)$, but only based on the following, general considerations. First, the adiabatic exchange of two Majoranas does not change the parity of the number of electrons in the system, so $U$ commutes with the total fermion parity, $[U, P_\textrm{tot}]=0$. Second, it is reasonable to assume that $U$ only depends on the Majoranas involved in the exchange, or in other words that it is a function of $\gamma_n$ and $\gamma_m$, and of no other operator. And because it has to preserve fermion parity, it can only depend on their product, that is on the parity operator $i\gamma_n\gamma_m$, which is Hermitian. Finally, the exponential of $i$ times a Hermitian operator is a unitary operator. So, in general $U$ must take the form
+
+$$U\equiv\exp(\beta \gamma_n \gamma_m) = \cos(\beta) + \gamma_n\gamma_m \sin(\beta)\,,$$
+
+*up to an overall phase*. Here, $\beta$ is a real coefficient to be determined, and in the last equality we have used the fact that $(\gamma_n\gamma_m)^2=1$. To determine $\beta$, it is convenient to go to the [Heisenberg picture](http://en.wikipedia.org/wiki/Heisenberg_picture) and look at the evolution of the Majorana operators in time. We have that
+
+$$
+\gamma_n\,\to\, U\,\gamma_n\,U^\dagger\,,\\
+\gamma_m\,\to\, U\,\gamma_m\,U^\dagger\,.
+$$
+
+Inserting our guess for $U$ we obtain:
+
+$$
+\gamma_n\,\to\, \cos (2\beta)\,\gamma_n  \sin(2\beta)\,\gamma_m\,,\\
+\gamma_m\,\to\, \cos (2\beta)\,\gamma_m + \sin(2\beta)\,\gamma_n\,.
+$$
+
+Now we have to remember that at time $T$ we have completed a closed trajectory, so that the Majorana $\gamma_n$ is now in the place initially occupied by $\gamma_m$, and vice versa. This condition leads to the choice $\beta = \pm \pi/4$. It is not strange that we find that both signs are possible  this distinguishes the clockwise and the counterclockwise exchange of the Majoranas.
+
+>Thus, we can write the unitary operator that exchanges the Majorana modes $\gamma_n$ and $\gamma_m$ in an explicit (and somewhat nontrivial looking!) form as:
+$$U = \exp \left(\pm\frac{\pi}{4}\gamma_n \gamma_m\right) = \tfrac{1}{\sqrt{2}}\left(1\pm\gamma_n\gamma_m\right)$$
+
+
+To fix our ideas and study the consequences of $U$ more closely, it is convenient to just focus on four Majoranas $\gamma_1\,\gamma_2,\gamma_3$ and $\gamma_4$. For this discussion we will assume that counterclockwise exchanges pick the $+$ sign in $U$. Their ground state manifold has four states, which in the notation introduced before we write down as
+
+$$\left00\right\rangle, \left11\right\rangle, \left01\right\rangle, \left10\right\rangle\,,$$
+
+where the first digit is the occupation number of the fermionic mode $c^\dagger_1=\tfrac{1}{2}(\gamma_1+i\gamma_2)$ and the second digit the occupation number of $c^\dagger_2=\tfrac{1}{2}(\gamma_3+i\gamma_4)$. The most generic possible wave function is a superposition
+
+$$\left\Psi\right\rangle = s_{00}\left00\right\rangle + s_{11} \left11\right\rangle + s_{01} \left01\right\rangle + s_{10} \left10\right\rangle\,,$$
+
+which we can also represent as a vector with four entries, $\left\Psi\right\rangle = (s_{00}, s_{11}, s_{01}, s_{10})^T$. The operator $U$ at this point can be written as a $4\times 4$ matrix. In order to do so, you just have to compute the action of a product of Majoranas on the basis states. This a simple but tedious operation, which we skip here. It results in the following matrices for the operators $U_{12}, U_{23}$ and $U_{34}$ exchanging neighboring Majoranas:
+
+$$
+U_{12} = \exp\left(\frac{\pi}{4}\gamma_1 \gamma_2\right) \equiv\begin{pmatrix}
+e^{i\pi/4} & 0 & 0 & 0 \\0 & e^{i\pi/4} & 0 &0 \\0 & 0& e^{i\pi/4} &0 \\ 0&0& 0& e^{i\pi/4}
+\end{pmatrix}\,,
+$$
+
+$$
+U_{23} = \exp\left(\frac{\pi}{4}\gamma_2 \gamma_3\right) \equiv\frac{1}{\sqrt{2}}\begin{pmatrix}
+1 & i & 0 & 0\\ i & 1 & 0& 0\\ 0& 0& 1 & i\\ 0& 0& i & 1
+\end{pmatrix}\,,
+$$
+
+$$
+U_{34} = \exp\left(\frac{\pi}{4}\gamma_3 \gamma_4\right) \equiv\begin{pmatrix}
+e^{i\pi/4} & 0 & 0 & 0\\ 0& e^{i\pi/4} & 0& 0\\ 0& 0& e^{i\pi/4} & 0\\ 0& 0& 0& e^{i\pi/4}
+\end{pmatrix}\,.
+$$
+
+These matrices indeed act in a very nontrivial way on the wave function. For instance, if we start from the state $\left00\right\rangle$ and we exchange $\gamma_2$ and $\gamma_3$, we obtain
+
+$$\left00\right\rangle\,\to\,U_{23}\left00\right\rangle=\tfrac{1}{\sqrt{2}}\left(\left00\right\ranglei\left11\right\rangle\right)\,,$$
+
+which is a superposition of states! Hence we have seen explicitly that the effect of the exchange two Majoranas on the wavefunction amounts to much more than just an overall phase, as it happens for bosons and fermions.
+
+Let's now try a sequence of two exchanges. In this case, we have to multiply the corresponding $U$s, ordering them from right to the left according to the order of the exchanges. Given that the matrices above are not diagonal, it is not surprising that the order in the product matters a lot. For instance you can check that
+
+$$U_{23}U_{12}\neq U_{12}U_{23}\,$$
+
+>We have just shown that exchanging two Majorana modes leads to a non trivial rotation in the ground state manifold, and that changing the order of the exchanges changes the final result. These properties make Majorana modes **nonAbelian anyons**. The exchange of two nonAbelian anyons is usually called **braiding**, a name which is suggestive of the fact that, when thinking of the trajectories of the different particles, a sequence of exchanges looks like a braid made out of different strands.
+
+Finally, you might object to the fact that the network of nanowires drawn in the figures only allows to exchange neighbouring Majoranas, even though our derivation of $U=\exp(\pi\gamma_n\gamma_m/4)$ seems to hold for any pair of Majoranas. This geometric constraint is not a big problem: by carefully composing many exchanges between neighbours, we can exchange any pair of Majoranas. As an example, you have that $U_{13}\equiv\exp\left(\pi\gamma_1 \gamma_3/4\right) = U_{12}^\dagger\,U^\dagger_{23}\,U_{12}$.
+
+
+```python
+question = ("Consider a system with only one pair of Majorana modes, thus with just two degenerate states with different fermion parity. "
+ "What happens when we exchange the pair of Majorana modes, starting from a given fermion parity eigenstate?")
+answers = ["The fermion parity of the state flips.",
+ "Nothing happens.",
+ "The system wavefunction picks up a phase that depends on the fermion parity.",
+ "You end up in a superposition of the two states."]
+explanation = ("The total fermion parity cannot change, "
+ "but the two states can pick up a different phase. "
+ "This is indeed what happens since the operator $U$ describing the exchange depends on fermion parity.")
+MoocMultipleChoiceAssessment(question, answers, correct_answer=2, explanation=explanation)
+```
+
+# Majoranas and quantum computation: basic ideas
+
+The nonAbelian statistics of Majorana modes is a very special property. Furthermore, it has some practical interest, since it could be used to realize a robust **quantum computer**. (If you are not yet interested in quantum computation, you can skip this part, even though we suggest that you get interested in it! Quantum computation is a huge topic of research, but [this](http://arxiv.org/abs/quantph/9708022) is a good place to start learning.)
+
+Let's discuss very briefly how this can be done.
+
+First, we can think of our network of nanowires with $2N$ Majoranas as a small computer. The $2^N$ states of the ground state manifold can encode a string of $N$ bits, so it's like having a small *register*. As always in quantum computation, and unlike in a classical computer, the register can be in a superposition of different states. So far, nothing really special about Majoranas.
+
+How do we execute an *algorithm* on our register? Simply by exchanging the Majorana modes! Because of the nonAbelian statistics, different sequences of exchanges will yield different algorithms. Of course, to execute an interesting algorithm we may need a lot of Majorana modes and a very very long sequence of exchanges. However, it all begins with the small building blocks, the matrices that you have just studied in detail.
+
+You might say that this is just another way to obtain a given unitary operator acting on the wave function. The beautiful thing, though, is that both the state of the register and the algorithms are *topologically protected*. Let's explain what we mean by that.
+
+The state of the register is encoded in the fermion parity degrees of freedom, which are shared *nonlocally* by the Majoranas. This means that no local perturbation can change the state of the register and cause *decoherence* of the quantum state. The environment cannot access the information stored in the Majoranas, as long as they are kept far away from each other. The only exception is a change in fermion parity due to the tunnelling of a stray quasiparticle into the system (this is the problem of quasiparticle poisoning, the same that can hinder the detection of the $4\pi$periodic Josephson effect of Majorana modes, as you heard from Carlo Beenakker). But except from this, the Majoranas are a great *quantum memory*.
+
+On the other hand, every step of the algorithm will be extremely accurate because it is given by an exchange of two Majoranas, which corresponds to *exactly* $\exp(\pi\gamma_n\gamma_m/4)$. When you are in the adiabatic limit, this operator does not depend on any of the details on how the exchange between Majoranas is performed. It does not depend on *how* you move the Majoranas, or on the particular trajectory that $\gamma_n$ and $\gamma_m$ followed, or on the timing of the trajectory. So the final result is extremely reliable.
+
+These are the basic ideas of **topological quantum computation**. It is incredible that we can find condensed matter systems, such as networks of Majoranas, which are naturally endowed with these characteristics.
+
+# Summary
+
+
+```python
+MoocVideo("V3e9r4S8GHs", src_location="2.3summary")
+```
+
+**Questions about what you just learned? Ask them below.**
+
+
+```python
+MoocDiscussion('Questions', 'NonAbelian statistics of Majorana modes')
+```
diff git a/w2_majorana/nanowire.ipynb b/w2_majorana/nanowire.ipynb
deleted file mode 100644
index 0fcf93f..0000000
 a/w2_majorana/nanowire.ipynb
+++ /dev/null
@@ 1,604 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "%output size=110\n",
 "from holoviews.core.options import Cycle\n",
 "\n",
 "def nanowire_chain():\n",
 " lat = kwant.lattice.chain()\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))\n",
 "\n",
 " def onsite(onsite, p):\n",
 " return (2 * p.t  p.mu) * pauli.szs0 + p.B * pauli.s0sz + p.delta * pauli.sxs0\n",
 "\n",
 " syst[lat(0)] = onsite\n",
 "\n",
 " def hop(site1, site2, p):\n",
 " return p.t * pauli.szs0  .5j * p.alpha * pauli.szsx\n",
 "\n",
 " syst[kwant.HoppingKind((1,), lat)] = hop\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def spinful_kitaev_chain():\n",
 " lat = kwant.lattice.chain()\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))\n",
 "\n",
 " def onsite(site, p):\n",
 " return (2 * p.t  p.mu) * pauli.szs0 + p.B * pauli.szsz\n",
 "\n",
 " syst[lat(0)] = onsite\n",
 "\n",
 " def hop(site1, site2, p):\n",
 " return p.t * pauli.szs0  1j * p.delta * pauli.sys0\n",
 "\n",
 " syst[kwant.HoppingKind((1,), lat)] = hop\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def find_gap(syst, p, resolution=1e4):\n",
 " \"\"\"Find gap in a system by doing a binary search in energy.\"\"\"\n",
 "\n",
 " # This tells us if there are modes at a certain energy.\n",
 " if len(syst.modes(energy=0, args=[p])[0].momenta):\n",
 " return 0\n",
 "\n",
 " gap = step = min(abs(kwant.physics.Bands(syst, args=[p])(k=0))) / 2\n",
 " while step > resolution:\n",
 " step /= 2\n",
 " if len(syst.modes(gap, args=[p])[0].momenta):\n",
 " gap = step\n",
 " else:\n",
 " gap += step\n",
 "\n",
 " return gap\n",
 "\n",
 "\n",
 "def spinorbit_band_gap(syst, mu, t, delta, Bs):\n",
 " syst = syst.finalized()\n",
 " alphas = [0.0, 0.1, 0.2, 0.3]\n",
 " p = SimpleNamespace(mu=mu, t=t, delta=delta)\n",
 "\n",
 " def gap(syst, p, alpha, B):\n",
 " p.alpha = alpha\n",
 " p.B = B\n",
 " return find_gap(syst, p)\n",
 "\n",
 " gaps = [gap(syst, p, alpha, B) for alpha in alphas for B in Bs]\n",
 " gaps = np.reshape(gaps, (len(alphas), 1))\n",
 " dims = {'kdims': [r'$B$'], 'vdims': ['Band gap']}\n",
 " B_crit = holoviews.VLine(np.sqrt(p.delta**2 + p.mu**2))\n",
 " plot = [holoviews.Curve((Bs, gaps[i]), label=r'$\\alpha={}$'.format(\n",
 " alphas[i]), **dims) * B_crit for i, alpha in enumerate(alphas)]\n",
 " title = r'$\\Delta={:.2}$, $\\mu={:.2}$'.format(p.delta, p.mu)\n",
 " style = {'xticks': [0, 0.1, 0.2, 0.3], 'yticks': [0, 0.05, 0.1], 'fig_size': 150}\n",
 " plot = holoviews.Overlay(plot)\n",
 " return plot(plot=style)\n",
 "\n",
 "\n",
 "def title(p):\n",
 " try:\n",
 " title = r\"$\\alpha={:.2}$, $\\mu={:.2}$, $B={:.2}$, $\\Delta={:.2}$\"\n",
 " title = title.format(p.alpha, p.mu, p.B, p.delta)\n",
 " except AttributeError:\n",
 " title = r\"$\\mu={:.2}$, $B={:.2}$, $\\Delta={:.2}$\"\n",
 " title = title.format(p.mu, p.B, p.delta)\n",
 " return title\n",
 "\n",
 "style = {'k_x': np.linspace(1, 1, 101),\n",
 " 'xdim': r'$k$',\n",
 " 'ydim': r'$E/t$',\n",
 " 'xticks': [1, 0, 1],\n",
 " 'yticks': [1, 0, 1],\n",
 " 'xlims': [1, 1],\n",
 " 'ylims': [1.5, 1.5],\n",
 " 'title': title}"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# From Kitaev model to an experiment"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We have a special guest to begin this week's lecture, Yuval Oreg from the Weizmann Institute in Rehovot."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"GQLfs4i22ms\", src_location=\"2.1intro\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Small parameters"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We are now all set to make Majoranas in a real system. Or at least to invent a way to make Majoranas in a real system.\n",
 "\n",
 "The way we approach this problem is by considering the Kitaev chain a 'skeleton', and 'dressing' it with real physics phenomena until it becomes real. \n",
 "\n",
 "> Interestingly, this is not at all how the condensed matter community came to this model. \n",
 "> Instead, the path to it was from complex to simple. The whole story started from what we'll consider in the very end of the course, fractional particles.\n",
 "\n",
 "> Then it was simplified to topological superconductors (that still do not exist in nature, as far as we know).\n",
 "> Majoranas were then predicted to exist (week 7) in a combination of a 3D topological insulator (week 6), which was then simplified to a twodimensional topological insulator (week 5), and only after a few more simplification steps, the nanowire model was developed."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "So once again, here is our 'skeleton', the Kitaev model Hamiltonian written in momentum space:\n",
 "\n",
 "$$H_{Kitaev} = (2 t \\cos k \\mu) \\tau_z + 2 \\Delta \\tau_y \\sin k.$$\n",
 "\n",
 "The model seems OK for a start, because it has some superconducting pairing $\\Delta$ and some normal dispersion given by terms proportional to $\\mu$ and $t$.\n",
 "\n",
 "Before we proceed further, let's understand the relation between these parameters.\n",
 "\n",
 "First of all, we want to make a controllable system, so that we can tweak its parameters. That means that we need a **semiconductor**. In semiconductors the electron density is very low, so that the chemical potential is near the bottom of the band. This makes it easier to define $\\mu$ with respect to the bottom of the band:\n",
 "\n",
 "$$\\mu \\rightarrow \\mu  2t.$$\n",
 "\n",
 "Now the transition between trivial and nontrivial states happens when $\\mu = 0$.\n",
 "\n",
 "Of course semiconductors are never additionally superconducting. Luckily this is easy for us to resolve. We just paste a superconductor and semiconductor together into a hybrid structure, and let the superconductor induce superconductivity in the semiconductor. Making such a hybrid is extremely challenging from the material science point of view, but it's definitely not our problem for now.\n",
 "\n",
 "The next thing we should consider is that $\\mu$ will always stay small compared to the bandwidth, so $\\mu \\ll 2t$. The same holds for superconducting pairing: $\\Delta \\ll t$. This is because superconductivity is a very weak effect compared to the kinetic energy of electrons. These two inequalities combined mean that we can expand the $\\cos k$ term and only work with the continuum limit of the Kitaev model:\n",
 "\n",
 "$$H = (k^2/2m  \\mu) \\tau_z + 2 \\Delta \\tau_y k.$$\n",
 "\n",
 "The effective electron mass $m$ is just the coefficient of the expansion. Let's take a look at the band structure in this regime, both in the topological regime and in the trivial regime:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "syst = spinful_kitaev_chain()\n",
 "p1 = SimpleNamespace(t=1.0, delta=0.1, mu=0.3, B=0.0, alpha=0.0)\n",
 "p2 = SimpleNamespace(t=1.0, delta=0.1, mu=0.3, B=0.0, alpha=0.0)\n",
 "\n",
 "(spectrum(syst, p1, **style).relabel('Trivial bandstructure') +\n",
 " spectrum(syst, p2, **style).relabel('Topological bandstructure'))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# The need for spin"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Still, there is one obvious thing missing from the model, namely electron spin. This model works with some hypothetical spinless fermions, that do not really exist. So to make the model physical, we need to remember that every single particle has spin, and the Hamiltonian has some action in spin space, described by the Pauli matrices $\\sigma$.\n",
 "\n",
 "The simplest thing which we can do is to just add the spin as an extra degeneracy, that is to multiply every term in the Hamiltonian by $\\sigma_0$. Obviously this doesn't change the spectrum, and a zero energy solution stays a zero energy solution."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Just kidding, this would be very bad! The problem about adding spin is that the whole point of a Kitaev chain is to create *unpaired* Majorana modes. If we add an extra spin degeneracy to these Majoranas, the edge of our chain will host two Majoranas, or in other words one regular fermion finetuned to zero energy.\n",
 "\n",
 "What's the correct way of introducing spin then? We still need to add it. Let's add spin such that the Kitaev chain corresponding to one spin species is topologically trivial, and the Kitaev chain corresponding to the other spin species nontrivial. We know that the chemical potential $\\mu$ controls whether a Kitaev chain is topological or trivial, so if say spin up has $\\mu > 0$ and spin down $\\mu < 0$, we're back in business.\n",
 "\n",
 "We achieve this by adding Zeeman coupling of the spin to an external magnetic field:\n",
 "\n",
 "$$H = (k^2/2m  \\mu  B \\sigma_z) \\tau_z + 2 \\Delta \\tau_y k.$$\n",
 "\n",
 "Whenever the Zeeman energy $B$ is larger than $\\mu$ we have one Majorana fermion at the end of the chain.\n",
 "\n",
 "Let's look at what happens with the dispersion as we increase the magnetic field from zero to a value larger than $\\mu$."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "syst = spinful_kitaev_chain()\n",
 "p = SimpleNamespace(t=1.0, delta=0.1, mu=0.3, B=None)\n",
 "Bs = np.linspace(0, 0.4, 10)\n",
 "holoviews.HoloMap({p.B: spectrum(syst, p, **style) for p.B in Bs}, kdims=[r'$B$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We now see that we resolved the first problem:\n",
 "\n",
 "> A high enough **Zeeman splitting** allows to separate the different spins.\n",
 "> Then we can make one spin species trivial, while the other one is topological and hosts Majoranas."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Realistic superconducting pairing"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The next part for us to worry about is the superconductor.\n",
 "\n",
 "Something that you probably saw in the Kitaev chain Hamiltonian is that the superconducting pairing $\\Delta$ has a peculiar form. It pairs electrons from *neighboring* sites, and not those from the same site. In momentum space this means that the superconducting pairing is proportional to $\\Delta k$.\n",
 "\n",
 "Of course, in a Kitaev chain the superconducting pairing cannot couple two electrons from the same site since there is just one particle per site!\n",
 "\n",
 "Real world superconductors are different. Most of them, and specifically all the common superconductors like $Al$, $Nb$, $Pb$, $Sn$ have $s$wave pairing. This means that the pairing has no momentum dependence, and is local in real space. The Kitaev chain pairing is proportional to the first power of momentum and so it is a $p$wave pairing.\n",
 "\n",
 "[High temperature superconductors](https://en.wikipedia.org/wiki/Hightemperature_superconductivity) like cuprates or pnictides do have a momentumdependent pairing, but it's yet another type ($d$wave, or a more exotic $s\\pm$wave).\n",
 "\n",
 "So if we want to invent a way to make Majoranas, we will need to use $s$wave pairing. And then, as you should remember from the previous week, due to the fermionic statistics the pairing function should be antisymmetric. In a Kitaev chain the antisymmetry is due to the real space structure of the pairing, but in an $s$wave superconductor, the antisymmetry of the pairing should arise due to its spin structure.\n",
 "\n",
 "This leaves only one option. All the $s$wave superconductors are spinsinglet:\n",
 "\n",
 "$$H_{pair} = \\Delta(c_\\uparrow c_\\downarrow  c_\\downarrow c_\\uparrow) + \\text{h.c.}$$\n",
 "\n",
 "This means that now we need to modify the pairing, but before that we'll need to do one other important thing."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Important and useful basis change."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "When you see BogoliubovdeGennes Hamiltonians in the literature, you will find them written in two different bases.\n",
 "One variant is the one which we introduced last week:\n",
 "\n",
 "$$\n",
 "H_\\textrm{BdG} = \\begin{pmatrix} H & \\Delta \\\\ \\Delta^* & H^* \\end{pmatrix}.\n",
 "$$\n",
 "\n",
 "It has the particlehole symmetry $H_\\textrm{BdG} =  \\tau_x H^*_\\textrm{BdG} \\tau_x$. In this basis, the $s$wave pairing is proportional to $\\sigma_y$.\n",
 "\n",
 "However for systems with complicated spin and orbital structure, there is a different basis which makes the bookkeeping much easier.\n",
 "\n",
 "If we have a timereversal symmetry operator $\\mathcal{T} = U \\mathcal{K}$, we can apply the unitary transformation $U$ to the holes, so that in the new basis we get the BogoliubovdeGennes Hamiltonian\n",
 "\n",
 "$$\n",
 "H_\\textrm{BdG} = \\begin{pmatrix} H & \\Delta' \\\\ \\Delta'^\\dagger & \\mathcal{T} H \\mathcal{T}^{1}\\end{pmatrix},\n",
 "$$\n",
 "\n",
 "with $\\Delta' = \\Delta U^\\dagger$.\n",
 "\n",
 "Why is this basis useful?\n",
 "\n",
 "* First of all, because in this new basis the $s$wave pairing is a unit matrix regardless of system we consider.\n",
 "* Second, because it's easy to get the Hamiltonian of holes. We take the Hamiltonian for electrons, and change the signs of all terms that respect timereversal symmetry, but not for those that break it, such as the term proportional to the magnetic field $B$. So if the electrons have a Hamiltonian $H(B)$, the Hamiltonian of the holes just becomes $H(B)$.\n",
 "\n",
 "There is one disadvantage. The particlehole symmetry now becomes more complicated. For our system with only one orbital and spin it is $\\mathcal{P} = \\sigma_y \\tau_y \\mathcal{K}$. But, let us tell you, the advantages are worth it."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# swave superconductor with magnetic field"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's look at how our chain looks once we change the superconducting coupling to be $s$wave. The Zeeman field (or anything of magnetic origin) changes sign under timereversal symmetry. \n",
 "\n",
 "This means that the Zeeman field has the same form for electrons and for holes in the new basis, and the full Hamiltonian is now:\n",
 "\n",
 "$$\n",
 "H_\\textrm{BdG} = (k^2/2m  \\mu)\\tau_z + B \\sigma_z + \\Delta \\tau_x.\n",
 "$$\n",
 "\n",
 "This Hamiltonian is easy to diagonalize since every term only has either a $\\tau$ matrix or a $\\sigma$ matrix. At $k=0$ it has 4 levels with energies $E = \\pm B \\pm \\sqrt{\\mu^2 + \\Delta^2}$.\n",
 "\n",
 "We can use this expression to track the crossings. We also know that when $B=0$ the system is trivial due to spin degeneracy.\n",
 "Together this means that we expect the system to be nontrivial (and will have a negative Pfaffian invariant) when\n",
 "\n",
 "$$ B^2 > \\Delta^2 + \\mu^2.$$\n",
 "\n",
 "Are we now done? Not quite."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Problem with singlets"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "A singlet superconductor has an important property: Since electrons are created in singlets, the total spin of every excitation is conserved. Zeeman field conserves the spin in $z$direction, so together every single state of our system has to have a definite spin, *including the Majoranas*.\n",
 "\n",
 "And that is a big problem. Majoranas are their own particlehole partners, and that means that they cannot have any spin (energy, charge, or any other observable property at all).\n",
 "\n",
 "So does this now mean that we \"broke\" the bulkedge correspondence? Let's look at the band structure (tweak the Zeeman energy):"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "syst = nanowire_chain()\n",
 "p = SimpleNamespace(t=1.0, mu=0.0, delta=0.1, alpha=0.0, B=None)\n",
 "Bs = np.linspace(0, 0.4, 10)\n",
 "holoviews.HoloMap({p.B: spectrum(syst, p, **style) for p.B in Bs}, kdims=[r'$B$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Of course we didn't break bulkedge correspondence. Majoranas in our system would have to have a spin, which isn't possible. That in turn means that they cannot appear, and that means that the system cannot be gapped.\n",
 "\n",
 "We can also approach this differently. From all the spin Pauli matrices, only $\\sigma_z$ appears in the Hamiltonian, so there's a conservation law. The two bands that cross at zero energy in the band structure above belong to opposite spin bands, and so cannot be coupled.\n",
 "\n",
 "Now we need to solve this final problem before we are done."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# How to open the gap?"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The final stretch is straightforward.\n",
 "\n",
 "We know that there is no gap because of conservation of one of the spin projections, so we need to break the spin conservation.\n",
 "\n",
 "If we don't want to create an inhomogeneous magnetic field, we have to use a different term that couples to spin. That term is spinorbit interaction. In it's [simplest form](http://en.wikipedia.org/wiki/Rashba_effect) this interaction appears in our wire as\n",
 "\n",
 "$$H_{SO} = \\alpha \\sigma_y k,$$\n",
 "\n",
 "so it is like a Zeeman field pointing in $y$direction with a strength proportional to the particle momentum. Note that this term is invariant under time reversal symmetry (both $\\sigma_y$ and $k$ change sign). So now we have our final Hamiltonian:\n",
 "\n",
 "$$\n",
 "H_\\textrm{wire} = (k^2/2m + \\alpha \\sigma_y k  \\mu)\\tau_z + B \\sigma_z + \\Delta \\tau_x.\n",
 "$$"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "At $k = 0$, spinorbit coupling vanishes, so it has no effect on the system being topologically trivial or nontrivial.\n",
 "\n",
 "Let's now check that it does what we want, namely open the gap at a finite momentum:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "syst = nanowire_chain()\n",
 "p = SimpleNamespace(t=1.0, mu=0.1, delta=0.1, B=0.2, alpha=None)\n",
 "alphas = np.linspace(0, 0.4, 10)\n",
 "holoviews.HoloMap({p.alpha: spectrum(syst, p, **style) for p.alpha in alphas}, kdims=[r'$\\alpha$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Yep, it does :)\n",
 "\n",
 "An important remark: You might now think that since spinorbit interaction depends on spin, it makes the magnetic field unnecessary. This is not true: Since spinorbit interaction preserves timereversal symmetry, in the absence of a magnetic field the energy spectrum of the model would have a *Kramers degeneracy*, as you learned last week. To get one unpaired Majorana mode per edge and not two, we need to break Kramers degeneracy and therefore break timereversal symmetry. So the combination of both Zeeman field and spinorbit coupling is needed."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Putting everything together"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's now rest for a moment and reflect on what we have done.\n",
 "\n",
 "We started from a toy model, which has a very special feature. Then one by one we fixed the parts of the model that we found unrealistic and ended up with a new system. It still has a relatively simple Hamiltonian, but already gives hope of being realizable in a lab.\n",
 "\n",
 "Now try to guess: how many papers were written studying this exact model? The exact number is hard to obtain, but the count is in the hundreds!\n",
 "\n",
 "Despite the model being very simple and the fact that it can be written in one line, it has four independent parameters already in our simplest formulation. Let's enumerate the parameters once again:\n",
 "\n",
 "* The chemical potential $\\mu$, which sets the overall electron density in the wire.\n",
 "* The induced superconducting gap $\\Delta$, which is required to make particlehole symmetry play a role.\n",
 "* The spinorbit coupling $\\alpha$, which breaks spin conservation.\n",
 "* The Zeeman field $B$, which breaks Kramers degeneracy."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We need to control every single parameter out of these 4 to create Majoranas (and there are even more). This is why the task of creating Majoranas is extremely challenging.\n",
 "\n",
 "As a final point in our story, let's see how the four parameters work together in determining how large the gap in our system is.\n",
 "\n",
 "Obviously, this is the key parameter that we care about when creating Majoranas.\n",
 "The smaller the gap, the worse the protection of Majoranas, and the more we need to worry about the effects of finite temperature.\n",
 "\n",
 "Let's calculate the gap as a function of all of the relevant parameters."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "%%opts Curve (color=Cycle(values=['r', 'g', 'b', 'y']))\n",
 "%%opts Overlay [show_legend=True legend_position='top']\n",
 "\n",
 "syst = nanowire_chain()\n",
 "Bs = np.linspace(0, 0.3, 71)\n",
 "mus = np.linspace(0.05, 0.15, 5)\n",
 "holoviews.HoloMap({mu: spinorbit_band_gap(syst, mu, 1.0, 0.1, Bs) for mu in mus}, kdims=[r'$\\mu$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Here the vertical line denotes the critical value of the Zeeman field at which the wire becomes topological.\n",
 "\n",
 "Let's summarize our observations:\n",
 "\n",
 "* So we see that the closer $\\mu$ is to 0, the lower $B$ is required to reach the topological regime.\n",
 "* After reaching the topologically nontrivial regime, the gap slowly grows as we go away from the transition region, and after reaching its peak value, it starts dropping.\n",
 "* Finally, we see that the higher the spinorbit coupling, the larger the optimal gap in the topological regime.\n",
 "\n",
 "We finish our investigation of this model for now with a final simple picture of the band structure of our system."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "syst = nanowire_chain()\n",
 "p = SimpleNamespace(t=1.0, B=0.07, delta=0.025, alpha=0.8, mu=None)\n",
 "mus = np.linspace(0.18, 0.22, 10)\n",
 "holoviews.HoloMap({p.mu: spectrum(syst, p, **style) for p.mu in mus}, kdims=[r'$\\mu$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "When $\\mu$ is very negative we see two split electron bands at positive energy corresponding to two spin orientations.\n",
 "\n",
 "The lower of these two bands has a characteristic double minimum due to spinorbit coupling.\n",
 "\n",
 "As we increase $\\mu$, the bands move down in energy, until they couple with the hole bands at $E=0$. This only happens due to the combination of superconductivity and spinorbit coupling.\n",
 "\n",
 "At $k=0$ the spinorbit coupling is ineffective, so the electron and hole bands pass through each other, changing the system first from trivial to topological and then back.\n",
 "\n",
 "The nonmonotonous behavior of the gap versus $B$ that we saw earlier is a consequence of this complicated band structure: There are different values of momenta where the dispersion has local minima. When we are close to the phase transition, $k=0$ defines the gap, while for large $B$, it is the gap at finite momentum that becomes smallest."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"What happens if we align the magnetic field $B$ along the $y$direction instead of the $z$direction?\")\n",
 "answers = [\"Then we do not need spinorbit coupling anymore in order to get Majoranas.\",\n",
 " \"Then the spin projection along the $y$ direction is conserved, so we can't get Majoranas.\",\n",
 " \"It's impossible, because a magnetic field can only be applied along $z$.\",\n",
 " \"Then the spinorbit term is automatically modified to point along the $z$ direction, so nothing really changes.\"]\n",
 "explanation = (\"If both the magnetic field and the spin orbit coupling point in the $y$ direction, \" +\n",
 " \"then the Hamiltonian commutes with $\\sigma_y$, and spin projection along $y$ is a good quantum number. \" +\n",
 " \"So we are back to the problem that a gap at finite momentum does not open, \" +\n",
 " \"and we do not get a topological phase supporting Majoranas.\")\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Outlook"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"MsFyJBAMFLI\", src_location=\"2.1summary\")"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Questions\", \"Majoranas in nanowires\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w2_majorana/nanowire.md b/w2_majorana/nanowire.md
new file mode 100644
index 0000000..dadc6f7
 /dev/null
+++ b/w2_majorana/nanowire.md
@@ 0,0 +1,396 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+%output size=110
+from holoviews.core.options import Cycle
+
+def nanowire_chain():
+ lat = kwant.lattice.chain()
+ syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))
+
+ def onsite(onsite, p):
+ return (2 * p.t  p.mu) * pauli.szs0 + p.B * pauli.s0sz + p.delta * pauli.sxs0
+
+ syst[lat(0)] = onsite
+
+ def hop(site1, site2, p):
+ return p.t * pauli.szs0  .5j * p.alpha * pauli.szsx
+
+ syst[kwant.HoppingKind((1,), lat)] = hop
+
+ return syst
+
+
+def spinful_kitaev_chain():
+ lat = kwant.lattice.chain()
+ syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))
+
+ def onsite(site, p):
+ return (2 * p.t  p.mu) * pauli.szs0 + p.B * pauli.szsz
+
+ syst[lat(0)] = onsite
+
+ def hop(site1, site2, p):
+ return p.t * pauli.szs0  1j * p.delta * pauli.sys0
+
+ syst[kwant.HoppingKind((1,), lat)] = hop
+
+ return syst
+
+
+def find_gap(syst, p, resolution=1e4):
+ """Find gap in a system by doing a binary search in energy."""
+
+ # This tells us if there are modes at a certain energy.
+ if len(syst.modes(energy=0, args=[p])[0].momenta):
+ return 0
+
+ gap = step = min(abs(kwant.physics.Bands(syst, args=[p])(k=0))) / 2
+ while step > resolution:
+ step /= 2
+ if len(syst.modes(gap, args=[p])[0].momenta):
+ gap = step
+ else:
+ gap += step
+
+ return gap
+
+
+def spinorbit_band_gap(syst, mu, t, delta, Bs):
+ syst = syst.finalized()
+ alphas = [0.0, 0.1, 0.2, 0.3]
+ p = SimpleNamespace(mu=mu, t=t, delta=delta)
+
+ def gap(syst, p, alpha, B):
+ p.alpha = alpha
+ p.B = B
+ return find_gap(syst, p)
+
+ gaps = [gap(syst, p, alpha, B) for alpha in alphas for B in Bs]
+ gaps = np.reshape(gaps, (len(alphas), 1))
+ dims = {'kdims': [r'$B$'], 'vdims': ['Band gap']}
+ B_crit = holoviews.VLine(np.sqrt(p.delta**2 + p.mu**2))
+ plot = [holoviews.Curve((Bs, gaps[i]), label=r'$\alpha={}$'.format(
+ alphas[i]), **dims) * B_crit for i, alpha in enumerate(alphas)]
+ title = r'$\Delta={:.2}$, $\mu={:.2}$'.format(p.delta, p.mu)
+ style = {'xticks': [0, 0.1, 0.2, 0.3], 'yticks': [0, 0.05, 0.1], 'fig_size': 150}
+ plot = holoviews.Overlay(plot)
+ return plot(plot=style)
+
+
+def title(p):
+ try:
+ title = r"$\alpha={:.2}$, $\mu={:.2}$, $B={:.2}$, $\Delta={:.2}$"
+ title = title.format(p.alpha, p.mu, p.B, p.delta)
+ except AttributeError:
+ title = r"$\mu={:.2}$, $B={:.2}$, $\Delta={:.2}$"
+ title = title.format(p.mu, p.B, p.delta)
+ return title
+
+style = {'k_x': np.linspace(1, 1, 101),
+ 'xdim': r'$k$',
+ 'ydim': r'$E/t$',
+ 'xticks': [1, 0, 1],
+ 'yticks': [1, 0, 1],
+ 'xlims': [1, 1],
+ 'ylims': [1.5, 1.5],
+ 'title': title}
+```
+
+# From Kitaev model to an experiment
+
+We have a special guest to begin this week's lecture, Yuval Oreg from the Weizmann Institute in Rehovot.
+
+
+```python
+MoocVideo("GQLfs4i22ms", src_location="2.1intro")
+```
+
+# Small parameters
+
+We are now all set to make Majoranas in a real system. Or at least to invent a way to make Majoranas in a real system.
+
+The way we approach this problem is by considering the Kitaev chain a 'skeleton', and 'dressing' it with real physics phenomena until it becomes real.
+
+> Interestingly, this is not at all how the condensed matter community came to this model.
+> Instead, the path to it was from complex to simple. The whole story started from what we'll consider in the very end of the course, fractional particles.
+
+> Then it was simplified to topological superconductors (that still do not exist in nature, as far as we know).
+> Majoranas were then predicted to exist (week 7) in a combination of a 3D topological insulator (week 6), which was then simplified to a twodimensional topological insulator (week 5), and only after a few more simplification steps, the nanowire model was developed.
+
+So once again, here is our 'skeleton', the Kitaev model Hamiltonian written in momentum space:
+
+$$H_{Kitaev} = (2 t \cos k \mu) \tau_z + 2 \Delta \tau_y \sin k.$$
+
+The model seems OK for a start, because it has some superconducting pairing $\Delta$ and some normal dispersion given by terms proportional to $\mu$ and $t$.
+
+Before we proceed further, let's understand the relation between these parameters.
+
+First of all, we want to make a controllable system, so that we can tweak its parameters. That means that we need a **semiconductor**. In semiconductors the electron density is very low, so that the chemical potential is near the bottom of the band. This makes it easier to define $\mu$ with respect to the bottom of the band:
+
+$$\mu \rightarrow \mu  2t.$$
+
+Now the transition between trivial and nontrivial states happens when $\mu = 0$.
+
+Of course semiconductors are never additionally superconducting. Luckily this is easy for us to resolve. We just paste a superconductor and semiconductor together into a hybrid structure, and let the superconductor induce superconductivity in the semiconductor. Making such a hybrid is extremely challenging from the material science point of view, but it's definitely not our problem for now.
+
+The next thing we should consider is that $\mu$ will always stay small compared to the bandwidth, so $\mu \ll 2t$. The same holds for superconducting pairing: $\Delta \ll t$. This is because superconductivity is a very weak effect compared to the kinetic energy of electrons. These two inequalities combined mean that we can expand the $\cos k$ term and only work with the continuum limit of the Kitaev model:
+
+$$H = (k^2/2m  \mu) \tau_z + 2 \Delta \tau_y k.$$
+
+The effective electron mass $m$ is just the coefficient of the expansion. Let's take a look at the band structure in this regime, both in the topological regime and in the trivial regime:
+
+
+```python
+syst = spinful_kitaev_chain()
+p1 = SimpleNamespace(t=1.0, delta=0.1, mu=0.3, B=0.0, alpha=0.0)
+p2 = SimpleNamespace(t=1.0, delta=0.1, mu=0.3, B=0.0, alpha=0.0)
+
+(spectrum(syst, p1, **style).relabel('Trivial bandstructure') +
+ spectrum(syst, p2, **style).relabel('Topological bandstructure'))
+```
+
+# The need for spin
+
+Still, there is one obvious thing missing from the model, namely electron spin. This model works with some hypothetical spinless fermions, that do not really exist. So to make the model physical, we need to remember that every single particle has spin, and the Hamiltonian has some action in spin space, described by the Pauli matrices $\sigma$.
+
+The simplest thing which we can do is to just add the spin as an extra degeneracy, that is to multiply every term in the Hamiltonian by $\sigma_0$. Obviously this doesn't change the spectrum, and a zero energy solution stays a zero energy solution.
+
+Just kidding, this would be very bad! The problem about adding spin is that the whole point of a Kitaev chain is to create *unpaired* Majorana modes. If we add an extra spin degeneracy to these Majoranas, the edge of our chain will host two Majoranas, or in other words one regular fermion finetuned to zero energy.
+
+What's the correct way of introducing spin then? We still need to add it. Let's add spin such that the Kitaev chain corresponding to one spin species is topologically trivial, and the Kitaev chain corresponding to the other spin species nontrivial. We know that the chemical potential $\mu$ controls whether a Kitaev chain is topological or trivial, so if say spin up has $\mu > 0$ and spin down $\mu < 0$, we're back in business.
+
+We achieve this by adding Zeeman coupling of the spin to an external magnetic field:
+
+$$H = (k^2/2m  \mu  B \sigma_z) \tau_z + 2 \Delta \tau_y k.$$
+
+Whenever the Zeeman energy $B$ is larger than $\mu$ we have one Majorana fermion at the end of the chain.
+
+Let's look at what happens with the dispersion as we increase the magnetic field from zero to a value larger than $\mu$.
+
+
+```python
+syst = spinful_kitaev_chain()
+p = SimpleNamespace(t=1.0, delta=0.1, mu=0.3, B=None)
+Bs = np.linspace(0, 0.4, 10)
+holoviews.HoloMap({p.B: spectrum(syst, p, **style) for p.B in Bs}, kdims=[r'$B$'])
+```
+
+We now see that we resolved the first problem:
+
+> A high enough **Zeeman splitting** allows to separate the different spins.
+> Then we can make one spin species trivial, while the other one is topological and hosts Majoranas.
+
+# Realistic superconducting pairing
+
+The next part for us to worry about is the superconductor.
+
+Something that you probably saw in the Kitaev chain Hamiltonian is that the superconducting pairing $\Delta$ has a peculiar form. It pairs electrons from *neighboring* sites, and not those from the same site. In momentum space this means that the superconducting pairing is proportional to $\Delta k$.
+
+Of course, in a Kitaev chain the superconducting pairing cannot couple two electrons from the same site since there is just one particle per site!
+
+Real world superconductors are different. Most of them, and specifically all the common superconductors like $Al$, $Nb$, $Pb$, $Sn$ have $s$wave pairing. This means that the pairing has no momentum dependence, and is local in real space. The Kitaev chain pairing is proportional to the first power of momentum and so it is a $p$wave pairing.
+
+[High temperature superconductors](https://en.wikipedia.org/wiki/Hightemperature_superconductivity) like cuprates or pnictides do have a momentumdependent pairing, but it's yet another type ($d$wave, or a more exotic $s\pm$wave).
+
+So if we want to invent a way to make Majoranas, we will need to use $s$wave pairing. And then, as you should remember from the previous week, due to the fermionic statistics the pairing function should be antisymmetric. In a Kitaev chain the antisymmetry is due to the real space structure of the pairing, but in an $s$wave superconductor, the antisymmetry of the pairing should arise due to its spin structure.
+
+This leaves only one option. All the $s$wave superconductors are spinsinglet:
+
+$$H_{pair} = \Delta(c_\uparrow c_\downarrow  c_\downarrow c_\uparrow) + \text{h.c.}$$
+
+This means that now we need to modify the pairing, but before that we'll need to do one other important thing.
+
+### Important and useful basis change.
+
+When you see BogoliubovdeGennes Hamiltonians in the literature, you will find them written in two different bases.
+One variant is the one which we introduced last week:
+
+$$
+H_\textrm{BdG} = \begin{pmatrix} H & \Delta \\ \Delta^* & H^* \end{pmatrix}.
+$$
+
+It has the particlehole symmetry $H_\textrm{BdG} =  \tau_x H^*_\textrm{BdG} \tau_x$. In this basis, the $s$wave pairing is proportional to $\sigma_y$.
+
+However for systems with complicated spin and orbital structure, there is a different basis which makes the bookkeeping much easier.
+
+If we have a timereversal symmetry operator $\mathcal{T} = U \mathcal{K}$, we can apply the unitary transformation $U$ to the holes, so that in the new basis we get the BogoliubovdeGennes Hamiltonian
+
+$$
+H_\textrm{BdG} = \begin{pmatrix} H & \Delta' \\ \Delta'^\dagger & \mathcal{T} H \mathcal{T}^{1}\end{pmatrix},
+$$
+
+with $\Delta' = \Delta U^\dagger$.
+
+Why is this basis useful?
+
+* First of all, because in this new basis the $s$wave pairing is a unit matrix regardless of system we consider.
+* Second, because it's easy to get the Hamiltonian of holes. We take the Hamiltonian for electrons, and change the signs of all terms that respect timereversal symmetry, but not for those that break it, such as the term proportional to the magnetic field $B$. So if the electrons have a Hamiltonian $H(B)$, the Hamiltonian of the holes just becomes $H(B)$.
+
+There is one disadvantage. The particlehole symmetry now becomes more complicated. For our system with only one orbital and spin it is $\mathcal{P} = \sigma_y \tau_y \mathcal{K}$. But, let us tell you, the advantages are worth it.
+
+# swave superconductor with magnetic field
+
+Let's look at how our chain looks once we change the superconducting coupling to be $s$wave. The Zeeman field (or anything of magnetic origin) changes sign under timereversal symmetry.
+
+This means that the Zeeman field has the same form for electrons and for holes in the new basis, and the full Hamiltonian is now:
+
+$$
+H_\textrm{BdG} = (k^2/2m  \mu)\tau_z + B \sigma_z + \Delta \tau_x.
+$$
+
+This Hamiltonian is easy to diagonalize since every term only has either a $\tau$ matrix or a $\sigma$ matrix. At $k=0$ it has 4 levels with energies $E = \pm B \pm \sqrt{\mu^2 + \Delta^2}$.
+
+We can use this expression to track the crossings. We also know that when $B=0$ the system is trivial due to spin degeneracy.
+Together this means that we expect the system to be nontrivial (and will have a negative Pfaffian invariant) when
+
+$$ B^2 > \Delta^2 + \mu^2.$$
+
+Are we now done? Not quite.
+
+### Problem with singlets
+
+A singlet superconductor has an important property: Since electrons are created in singlets, the total spin of every excitation is conserved. Zeeman field conserves the spin in $z$direction, so together every single state of our system has to have a definite spin, *including the Majoranas*.
+
+And that is a big problem. Majoranas are their own particlehole partners, and that means that they cannot have any spin (energy, charge, or any other observable property at all).
+
+So does this now mean that we "broke" the bulkedge correspondence? Let's look at the band structure (tweak the Zeeman energy):
+
+
+```python
+syst = nanowire_chain()
+p = SimpleNamespace(t=1.0, mu=0.0, delta=0.1, alpha=0.0, B=None)
+Bs = np.linspace(0, 0.4, 10)
+holoviews.HoloMap({p.B: spectrum(syst, p, **style) for p.B in Bs}, kdims=[r'$B$'])
+```
+
+Of course we didn't break bulkedge correspondence. Majoranas in our system would have to have a spin, which isn't possible. That in turn means that they cannot appear, and that means that the system cannot be gapped.
+
+We can also approach this differently. From all the spin Pauli matrices, only $\sigma_z$ appears in the Hamiltonian, so there's a conservation law. The two bands that cross at zero energy in the band structure above belong to opposite spin bands, and so cannot be coupled.
+
+Now we need to solve this final problem before we are done.
+
+# How to open the gap?
+
+The final stretch is straightforward.
+
+We know that there is no gap because of conservation of one of the spin projections, so we need to break the spin conservation.
+
+If we don't want to create an inhomogeneous magnetic field, we have to use a different term that couples to spin. That term is spinorbit interaction. In it's [simplest form](http://en.wikipedia.org/wiki/Rashba_effect) this interaction appears in our wire as
+
+$$H_{SO} = \alpha \sigma_y k,$$
+
+so it is like a Zeeman field pointing in $y$direction with a strength proportional to the particle momentum. Note that this term is invariant under time reversal symmetry (both $\sigma_y$ and $k$ change sign). So now we have our final Hamiltonian:
+
+$$
+H_\textrm{wire} = (k^2/2m + \alpha \sigma_y k  \mu)\tau_z + B \sigma_z + \Delta \tau_x.
+$$
+
+At $k = 0$, spinorbit coupling vanishes, so it has no effect on the system being topologically trivial or nontrivial.
+
+Let's now check that it does what we want, namely open the gap at a finite momentum:
+
+
+```python
+syst = nanowire_chain()
+p = SimpleNamespace(t=1.0, mu=0.1, delta=0.1, B=0.2, alpha=None)
+alphas = np.linspace(0, 0.4, 10)
+holoviews.HoloMap({p.alpha: spectrum(syst, p, **style) for p.alpha in alphas}, kdims=[r'$\alpha$'])
+```
+
+Yep, it does :)
+
+An important remark: You might now think that since spinorbit interaction depends on spin, it makes the magnetic field unnecessary. This is not true: Since spinorbit interaction preserves timereversal symmetry, in the absence of a magnetic field the energy spectrum of the model would have a *Kramers degeneracy*, as you learned last week. To get one unpaired Majorana mode per edge and not two, we need to break Kramers degeneracy and therefore break timereversal symmetry. So the combination of both Zeeman field and spinorbit coupling is needed.
+
+# Putting everything together
+
+Let's now rest for a moment and reflect on what we have done.
+
+We started from a toy model, which has a very special feature. Then one by one we fixed the parts of the model that we found unrealistic and ended up with a new system. It still has a relatively simple Hamiltonian, but already gives hope of being realizable in a lab.
+
+Now try to guess: how many papers were written studying this exact model? The exact number is hard to obtain, but the count is in the hundreds!
+
+Despite the model being very simple and the fact that it can be written in one line, it has four independent parameters already in our simplest formulation. Let's enumerate the parameters once again:
+
+* The chemical potential $\mu$, which sets the overall electron density in the wire.
+* The induced superconducting gap $\Delta$, which is required to make particlehole symmetry play a role.
+* The spinorbit coupling $\alpha$, which breaks spin conservation.
+* The Zeeman field $B$, which breaks Kramers degeneracy.
+
+We need to control every single parameter out of these 4 to create Majoranas (and there are even more). This is why the task of creating Majoranas is extremely challenging.
+
+As a final point in our story, let's see how the four parameters work together in determining how large the gap in our system is.
+
+Obviously, this is the key parameter that we care about when creating Majoranas.
+The smaller the gap, the worse the protection of Majoranas, and the more we need to worry about the effects of finite temperature.
+
+Let's calculate the gap as a function of all of the relevant parameters.
+
+
+```python
+%%opts Curve (color=Cycle(values=['r', 'g', 'b', 'y']))
+%%opts Overlay [show_legend=True legend_position='top']
+
+syst = nanowire_chain()
+Bs = np.linspace(0, 0.3, 71)
+mus = np.linspace(0.05, 0.15, 5)
+holoviews.HoloMap({mu: spinorbit_band_gap(syst, mu, 1.0, 0.1, Bs) for mu in mus}, kdims=[r'$\mu$'])
+```
+
+Here the vertical line denotes the critical value of the Zeeman field at which the wire becomes topological.
+
+Let's summarize our observations:
+
+* So we see that the closer $\mu$ is to 0, the lower $B$ is required to reach the topological regime.
+* After reaching the topologically nontrivial regime, the gap slowly grows as we go away from the transition region, and after reaching its peak value, it starts dropping.
+* Finally, we see that the higher the spinorbit coupling, the larger the optimal gap in the topological regime.
+
+We finish our investigation of this model for now with a final simple picture of the band structure of our system.
+
+
+```python
+syst = nanowire_chain()
+p = SimpleNamespace(t=1.0, B=0.07, delta=0.025, alpha=0.8, mu=None)
+mus = np.linspace(0.18, 0.22, 10)
+holoviews.HoloMap({p.mu: spectrum(syst, p, **style) for p.mu in mus}, kdims=[r'$\mu$'])
+```
+
+When $\mu$ is very negative we see two split electron bands at positive energy corresponding to two spin orientations.
+
+The lower of these two bands has a characteristic double minimum due to spinorbit coupling.
+
+As we increase $\mu$, the bands move down in energy, until they couple with the hole bands at $E=0$. This only happens due to the combination of superconductivity and spinorbit coupling.
+
+At $k=0$ the spinorbit coupling is ineffective, so the electron and hole bands pass through each other, changing the system first from trivial to topological and then back.
+
+The nonmonotonous behavior of the gap versus $B$ that we saw earlier is a consequence of this complicated band structure: There are different values of momenta where the dispersion has local minima. When we are close to the phase transition, $k=0$ defines the gap, while for large $B$, it is the gap at finite momentum that becomes smallest.
+
+
+```python
+question = ("What happens if we align the magnetic field $B$ along the $y$direction instead of the $z$direction?")
+answers = ["Then we do not need spinorbit coupling anymore in order to get Majoranas.",
+ "Then the spin projection along the $y$ direction is conserved, so we can't get Majoranas.",
+ "It's impossible, because a magnetic field can only be applied along $z$.",
+ "Then the spinorbit term is automatically modified to point along the $z$ direction, so nothing really changes."]
+explanation = ("If both the magnetic field and the spin orbit coupling point in the $y$ direction, " +
+ "then the Hamiltonian commutes with $\sigma_y$, and spin projection along $y$ is a good quantum number. " +
+ "So we are back to the problem that a gap at finite momentum does not open, " +
+ "and we do not get a topological phase supporting Majoranas.")
+MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)
+```
+
+# Outlook
+
+
+```python
+MoocVideo("MsFyJBAMFLI", src_location="2.1summary")
+```
+
+
+```python
+MoocDiscussion("Questions", "Majoranas in nanowires")
+```
diff git a/w2_majorana/signatures.ipynb b/w2_majorana/signatures.ipynb
deleted file mode 100644
index 4d7c437..0000000
 a/w2_majorana/signatures.ipynb
+++ /dev/null
@@ 1,654 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "\n",
 "dims = SimpleNamespace(G=holoviews.Dimension(r'$G/G_0$'),\n",
 " V_bias=holoviews.Dimension('$V_{bias}$'),\n",
 " phi=holoviews.Dimension(r'$\\Phi/\\Phi_0$'))\n",
 "\n",
 "\n",
 "def make_system_spectroscopy():\n",
 "\n",
 " # We apply a magnetic field in all parts of the system\n",
 " def onsite_sc(site, p):\n",
 " return (2 * p.t  p.mu_sc) * pauli.s0sz + p.Ez * pauli.sxs0 + p.delta * pauli.s0sx\n",
 "\n",
 " def onsite_normal(site, p):\n",
 " return (2 * p.t  p.mu_l) * pauli.s0sz + p.Ez * pauli.sxs0\n",
 "\n",
 " def onsite_barrier(site, p):\n",
 " return (2 * p.t  p.mu_l + p.Vbarrier) * pauli.s0sz + p.Ez * pauli.sxs0\n",
 "\n",
 " # The hopping is the same in all subsystems. There is normal hopping and\n",
 " # spin orbit interaction.\n",
 " def hop(site1, site2, p):\n",
 " return p.t * pauli.s0sz + 1j * p.alpha * pauli.sysz\n",
 "\n",
 " lat = kwant.lattice.chain(norbs=4)\n",
 " syst = kwant.Builder()\n",
 "\n",
 " # The first subsystem just consists of the tunnel barrier (one site with a\n",
 " # potential)\n",
 " syst[lat(0)] = onsite_barrier\n",
 "\n",
 " # The second subsystem is a normal lead\n",
 " # The translational symmetry makes it semiinfinite.\n",
 " lead1 = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs), conservation_law=pauli.s0sz) \n",
 " # Define a unit cell (in this case the unit cell consists of a single site)\n",
 " lead1[lat(0)] = onsite_normal\n",
 " # Define the hopping between unitcells\n",
 " lead1[lat(1), lat(0)] = hop\n",
 "\n",
 " # The third subsystem is a superconducting lead. A Majorana bound state\n",
 " # can arise at the edge of this system.\n",
 " lead2 = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs)) \n",
 " # Again: Define a unit cell\n",
 " lead2[lat(0)] = onsite_sc\n",
 " # Again define hopping between unit cells\n",
 " lead2[lat(1), lat(0)] = hop\n",
 "\n",
 " # Create a connection between the first subsystem (the tunnel barrier, system name: syst)\n",
 " # and the other two subsystems (the normal and the superconducting lead)\n",
 " syst.attach_lead(lead1)\n",
 " syst.attach_lead(lead2)\n",
 "\n",
 " syst = syst.finalized()\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def nanowire_chain(L=None, periodic=False):\n",
 " lat = kwant.lattice.chain()\n",
 "\n",
 " if L is None:\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))\n",
 " L = 1\n",
 " else:\n",
 " syst = kwant.Builder()\n",
 "\n",
 " def onsite(onsite, p):\n",
 " return (2 * p.t  p.mu) * pauli.szs0 + p.B * pauli.s0sz + p.delta * pauli.sxs0\n",
 "\n",
 " for x in range(L):\n",
 " syst[lat(x)] = onsite\n",
 "\n",
 " def hop(site1, site2, p):\n",
 " return p.t * pauli.szs0  .5j * p.alpha * pauli.szsx\n",
 "\n",
 " def hopping_with_flux(site1, site2, p):\n",
 " phase = np.exp(1j * p.flux / 2)\n",
 " phase_factors = np.kron(np.diag([phase, phase.conj()]), pauli.s0)\n",
 " return 0.7 * phase_factors @ hop(site1, site1, p)\n",
 "\n",
 " syst[kwant.HoppingKind((1,), lat)] = hop\n",
 "\n",
 " if periodic:\n",
 " syst[lat(0), lat(L  1)] = hopping_with_flux\n",
 " return syst\n",
 "\n",
 "\n",
 "def tunnel_spectroscopy(syst, p, Es):\n",
 " def Andreev_cond(E):\n",
 " sm = kwant.smatrix(syst, energy=E, args=[p])\n",
 " # (i, j) means we call for block j of lead i in the scattering matrix.\n",
 " # The normal lead is i = 0 here, where block j = 0 corresponds to electrons\n",
 " # and block j = 1 holes.\n",
 " return (sm.submatrix((0, 0), (0, 0)).shape[0] \n",
 " sm.transmission((0, 0), (0, 0)) +\n",
 " sm.transmission((0, 1), (0, 0)))\n",
 " Gs = [Andreev_cond(E) for E in Es]\n",
 " return np.array(Gs)\n",
 "\n",
 "\n",
 "def plot_spectroscopy(Vbarrier):\n",
 " syst = make_system_spectroscopy()\n",
 " Es = np.linspace(0.15, 0.15, 101)\n",
 " p = SimpleNamespace(t=1, mu_l=0.5, mu_sc=0, alpha=0.15,\n",
 " delta=0.1, Vbarrier=Vbarrier)\n",
 "\n",
 " # Trivial, because the magnetic field is zero (third argument)\n",
 " p.Ez = 0\n",
 " Gs_trivial = tunnel_spectroscopy(syst, p, Es)\n",
 "\n",
 " # Nontrivial\n",
 " p.Ez = 0.25\n",
 " Gs_topological = tunnel_spectroscopy(syst, p, Es)\n",
 " kdims = [dims.V_bias, dims.G]\n",
 " plot = holoviews.Path((Es, Gs_trivial), kdims=kdims, label='trivial')(style={'color': 'k'})\n",
 " plot *= holoviews.Path((Es, Gs_topological), kdims=kdims, label='topological')(style={'color': 'r'})\n",
 " style_overlay = {'xticks': [0.1, 0.0, 0.1], \n",
 " 'yticks': [0.0, 0.5, 1.0, 1.5, 2.0],\n",
 " 'show_legend':True, \n",
 " 'legend_position': 'top',\n",
 " 'fig_size':150}\n",
 " style_path = {'show_legend':True}\n",
 " return plot(plot={'Overlay': style_overlay, 'Path': style_path})\n",
 "\n",
 "\n",
 "def nanowire_spectrum(trivial=False):\n",
 " B = 0.2 if trivial else 1.0\n",
 " p = SimpleNamespace(mu=0.4, t=1.0, alpha=0.2, delta=0.1, B=B)\n",
 " syst = nanowire_chain(L=100, periodic=True).finalized()\n",
 "\n",
 " def energy(flux):\n",
 " p.flux = flux\n",
 " H = syst.hamiltonian_submatrix(args=[p])\n",
 " return np.linalg.eigvalsh(H)\n",
 "\n",
 " fluxes = np.linspace(0, 4 * np.pi, 51)\n",
 " spectrum = np.array([energy(flux) for flux in fluxes])\n",
 "\n",
 " # Find the two subgap states.\n",
 " if not trivial:\n",
 " N = spectrum.shape[1] // 2\n",
 " non_trivial = np.where((fluxes > np.pi) & (fluxes < 3 * np.pi))\n",
 " spectrum[non_trivial, N  1: N + 1] = spectrum[non_trivial, N: N  2: 1].copy()\n",
 "\n",
 " return fluxes, spectrum\n",
 "\n",
 "\n",
 "def plot_spectrum_nanowire(fluxes, spectrum, ylim=[0.2, 0.2]):\n",
 " N = spectrum.shape[1] // 2\n",
 " kdims = [dims.phi, '$E$']\n",
 " plot = holoviews.Path((fluxes, spectrum), kdims=kdims)(style={'color': 'k', 'alpha': 0.4})\n",
 " plot *= holoviews.Path((fluxes, spectrum[:, N  1]), kdims=kdims)(style={'color': 'r'})\n",
 " plot *= holoviews.Path((fluxes, spectrum[:, N]), kdims=kdims)(style={'color': 'k'})\n",
 " ticks = {'xticks': [(0, '0'), (2 * np.pi, '1'), (4 * np.pi, '2')]}\n",
 " return plot[:, 0.11:0.11](plot=ticks)\n",
 "\n",
 "\n",
 "def plot_gse_sc_nanowire(fluxes, spectrum):\n",
 " N = spectrum.shape[1] // 2\n",
 " energy_gs = np.sum(spectrum[:, :N], axis=1)\n",
 " energy_gs = np.max(energy_gs)\n",
 " current = np.diff(energy_gs) * len(energy_gs)\n",
 "\n",
 " xdim = dims.phi\n",
 " ydim = r'$E_{tot}(\\Phi)$'\n",
 " \n",
 " ticks = {'xticks': [(0, '0'), (2 * np.pi, '1'), (4 * np.pi, '2')]}\n",
 " plot = holoviews.Path((fluxes, energy_gs), kdims=[\n",
 " xdim, ydim], label='Energy')(plot=ticks)\n",
 " ydim = r'$I(\\Phi)$'\n",
 " plot += holoviews.Path(((fluxes[1:] + fluxes[:1]) / 2, current),\n",
 " kdims=[xdim, ydim], label='Current')(plot=ticks)\n",
 " return plot\n"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# How to detect Majoranas"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Our second guest lecturer for this week is Carlo Beenakker, from Leiden University."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"WAhNblNbadA\", src_location=\"2.2intro\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Andreev reflection"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "To understand how conductance through a Majorana works, we first have to learn how charge is transferred from a metallic lead to a superconductor. In general this transfer takes place via a mechanism known as Andreev reflection. Before we discuss the conductance signatures of a Majorana zero mode, it is useful to learn what Andreev reflection is.\n",
 "\n",
 "Let's consider the following very simple circuit with two electrodes:\n",
 "\n",
 "![](figures/ns_interface.svg)\n",
 "\n",
 "One electrode is a normal metal, the other a superconductor, and they are kept at a voltage difference $V$. At the interface between the normal metal and the superconductor (in short, NS interface) there is a barrier. We are particularly interested in the case when the voltage difference is very small compared to the energy gap in the superconductor, $eV < \\Delta$, where $e$ is the charge of the electron.\n",
 "\n",
 "What happens when electrons arrive at the interface with superconductor? The superconductor has no states available up to an energy $\\Delta$ around the Fermi level, and the voltage is not enough to provide for this energy difference. How can a current develop?"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "To understand this, let's look more closely at an electron arriving at the interface with the superconductor. There are two possible processes that can take place, *normal reflection* and *Andreev reflection*. In normal reflection, the electron is simply reflected at the interface with the superconductor:\n",
 "\n",
 "![](figures/normal_reflection.svg)\n",
 "\n",
 "With normal reflection, there is no net charge transfer from the left electrode to the right electrode. Hence this process does not contribute any net current. Normal reflection obviously doesn't even require a superconductor and would take place also if the right electrode was normal."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Andreev reflection, instead, is unique to the NS interface. In Andreev reflection, an electron is converted to a hole by the superconductor, and a Cooper pair is created in the superconductor.\n",
 "\n",
 "![](figures/andreev_reflection.svg)\n",
 "\n",
 "You can see that a net charge of $2e$ is transferred from the left to the right electrode, and at low voltages Andreev reflection is the only process responsible for the electrical current.\n",
 "\n",
 "Above the superconducting gap, $eV > \\Delta$ transmission of an incident electron into the superconductor also contributes to the current."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You can also think of Andreev *reflection* as a *transmission* problem. Because of the presence of the superconductor, both electrons and holes participate in the transfer of charge in the normal metal lead. Conceptually, you can imagine to separate the left lead into two leads, one only carrying electrons and one only carrying holes. These two leads are connected by the superconductor, which converts incoming electrons in the first lead into outgoing holes in the second lead, and viceversa:\n",
 "\n",
 "![](figures/andreev_as_transmission.svg)\n",
 "\n",
 "With this picture, you can understand that Andreev reflection is very similar to the problem of transmission through a double barrier."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's call $r_{eh}$ the amplitude for Andreev reflection. Its absolute value squared, $\\leftr_{eh}\\right^2$, is the probability that an incoming electron from the normal metal is Andreev reflected as a hole. Once we know $r_{eh}$, we can compute the conductance $G(V)$, which relates the current $I$ that develops as a response to a small voltage $V$, $G(V) = dI/dV$. The conductance is given by the following formula:\n",
 "\n",
 "$$G(V)=2G_0r_{eh}^2.$$\n",
 "\n",
 "We will not derive this equation, since it can be understood intuitively. The conductance is proportional to the probability $r_{eh}^2$ of Andreev reflection, since we know that at low voltages this is the only process that transfers electric charge from the left to the right electrode.\n",
 "\n",
 "The factor of $2$ is due to each Andreev reflection transferring a charge of a Cooper pair, $2e$. Finally, $G_0=e^2/h$ is the **conductance quantum**, the fundamental proportionality constant which relates currents to voltages."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Andreev reflection off a Majorana zero mode"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Now that we understand a conventional NS interface, let's see what happens if our superconductor is topological:\n",
 "\n",
 "![](figures/ns_majorana_interface.svg)\n",
 "\n",
 "You can imagine that the superconducting electrode is now a nanowire in the topological phase, like the one you have just studied. Because the superconductor is topological, there is a Majorana mode at the NS interface, whose wave function will “leak” a bit into the normal metal, through the barrier. Of course, there will be also a second Majorana mode, but we place it far enough from the NS interface, so that it does not have a role in the transport. Does the Majorana zero mode at the interface change the Andreev reflection properties?\n",
 "\n",
 "Yes, and in a rather drastic way. Going back to the picture of Andreev reflection as a transmission process through a double barrier, the crucial difference is that the Majorana mode now appears as a bound state between the two barriers:\n",
 "\n",
 "![](figures/resonant_transmission_through_majorana.svg)\n",
 "\n",
 "In the double barrier problem in quantum mechanics, you can have **resonant** transmission in the presence of a bound state. This means that the probability $\\leftr_{eh}\\right^2$ to pass through the barriers is dramatically enhanced if the energy of the incident electron matches the energy of the bound state. In our case, the energy of the incident electron is $V$, and the energy of the bound state, the Majorana mode, is zero. So the presence of the Majorana mode leads to a **resonant peak** in the conductance of the NS interface at $V=0$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Quantization of the Majorana resonance"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Seeing the resonant peak is the most direct way we know to measure the presence of a Majorana zero mode.\n",
 "\n",
 "However, the presence of a resonance associated with Majorana modes is not uniquely topological, because tunneling into any low energy bound state produces resonance.\n",
 "\n",
 "Is there anything in particular which distinguishes the Majorana resonance from any other resonance?\n",
 "\n",
 "Let's just look at what happens if we compare conductance of an NS interface in the cases when S is trivial and nontrivial, and see how the conductance changes as we alter the tunnel barrier strength."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "holoviews.HoloMap({V: plot_spectroscopy(V) for V in np.arange(1, 4.25, 0.25)}, kdims=[r'$V_{barrier}$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We see a very robust and persistent characteristic:\n",
 "the peak height of the Majorana resonance is quantized to the value of $2G_0$, independent of the strength of the voltage barrier. From the formula above, this means that if a Majorana is present we have $\\leftr_{eh}\\right^2=1$, that is we have **perfect Andreev reflection**.\n",
 "\n",
 "To understand why it is robust, we need to go beyond drawing cartoon figures."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Reflection matrix of a normal metalsuperconductor interface\n",
 "\n",
 "Quantummechanically, we can describe transport through the NS interface as a scattering problem. An incoming wave function $\\Psi_\\textrm{in}$ propagates in the left electrode, until it is reflected back at the interface with the superconductor, turning into an outgoing wave function $\\Psi_\\textrm{out}$. Because of the presence of the superconductor, both the incoming and outgoing states can be electrons $\\Psi_e$ or holes $\\Psi_h$. At **zero energy**, they are related to each other by particlehole symmetry:\n",
 "\n",
 "$$\\Psi_e(E) = \\mathcal{P}\\,\\Psi_h(E)\\,$$\n",
 "\n",
 "The reflection enforces a linear relation between incoming and ingoing waves:\n",
 "\n",
 "$$\\Psi_\\textrm{out} = r(V) \\,\\Psi_\\textrm{in}\\,$$\n",
 "\n",
 "$$r(V)=\\left(\\begin{array}{cc}r_{ee}&r_{eh}\\\\r_{he}&r_{hh}\\end{array}\\right).$$\n",
 "\n",
 "The matrix $r$ is known as the **reflection matrix**. Its complex elements are the amplitudes of normal and Andreev reflection of an incoming electron  $r_{ee}$ and $r_{eh}$  and normal and Andreev reflection of an incoming hole  $r_{hh}$ and $r_{he}$. (For brevity we don't write out explicitly that each of those depends on $V$.)\n",
 "\n",
 "If there is more than one incoming electron state (in our case there are two due to spin), all 4 elements of $r$ become matrices themselves. They then describe scattering between all the possible incoming and outgoing states.\n",
 "\n",
 "Because for $eV\\ll \\Delta$ there are no propagating waves in the superconductor, the reflection process which relates $\\Psi_\\textrm{out}$ and $\\Psi_\\textrm{in}$ is unitary, $r^\\dagger r=1$. This implies that\n",
 "\n",
 "$$\\leftr_{ee}\\right^2+\\leftr_{eh}\\right^2 = \\leftr_{he}\\right^2+\\leftr_{hh}\\right^2 = 1\\,.$$\n",
 "\n",
 "This is the mathematical way of saying that an electron (or hole) arriving at the interface has no alternatives other than being normalreflected or Andreevreflected.\n",
 "\n",
 "Can we add any other constraint to $r$, that might help to distinguish any characteristic of the Majorana mode? Just like we did last week, let's try to study $r$ using symmetry and topology. Our circuit involves a superconductor, so we must have particlehole symmetry in the problem.\n",
 "\n",
 "In order to derive $r$ explicitly we could start directly from the Bogoliubovde Gennes Hamiltonian of the NS system, and solve it for an energy $V$. This is a lot of work, which we won't do, but knowing this fact we can understand the consequences of particlehole symmetry for $r$.\n",
 "\n",
 "First, particlehole symmetry exchanges electrons and hole components of the wave function, so it involves a Pauli matrix $\\tau_x$ acting on $\\Psi_\\textrm{in}$ or $\\Psi_\\textrm{out}$. Second, it is an antiunitary symmetry, so it involves complex conjugation. Third, it changes the sign of the energy so it sends $V$ into $V$. Hence we arrive at the following symmetry for the reflection matrix:\n",
 "\n",
 "$$\\tau_x r^*(V) \\tau_x = r(V)\\,.$$\n",
 "\n",
 "Together with unitarity, particlehole symmetry imposes that the conductance is symmetric around zero voltage, $G(V)=G(V)$. In the most interesting point, $V=0$ we have:\n",
 "\n",
 "$$ \\tau_x r^*_0 \\tau_x = r_0 \\,.$$\n",
 "\n",
 "where we defined $r_0\\equiv r(V=0)$. So much for the impact of symmetry on $r$. What about topology?"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Topological invariant of the reflection matrix"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The Majorana zero mode is the consequence of a topological phase in the topological superconductor, and its presence is dictated by the bulkboundary correspondence. Can we find any consequence of this fact in $r_0$? It turns out that reflection matrices $r$ with particlehole symmetry are also topological in their own way. Their topological invariant is \n",
 "\n",
 "$$Q = \\det\\,r_0\\,.$$\n",
 "\n",
 "Again, we will not *derive* this equation, but rather convince ourselves this expression is correct.\n",
 "\n",
 "First of all, the determinant of a unitary matrix such as $r_0$ is always a complex number with unit norm, so $\\left\\det\\,r_0\\,\\right=1$. Second, because of particlehole symmetry, the determinant is real: $\\det r_0 = \\det\\, (\\tau_x r^*_0\\,\\tau_x) = \\det\\,r_0^*\\,=(\\det\\,r_0)^*$. Hence, $\\det\\,r_0\\,= \\pm 1$. This is quite promising! Two possible discrete values, just like the Pfaffian invariant of the Kitaev chain.\n",
 "\n",
 "Because it is just dictated by unitarity and particlehole symmetry, the determinant of $r_0$ cannot change from $+1$ to $1$ under a change of the properties of the NS interface. For instance, you can vary the height of the potential barrier at the interface, but this cannot affect the determinant of $r_0$.\n",
 "\n",
 "The only way to make the determinant change sign is to close the bulk gap in the superconducting electrode. If the gap goes to zero, then it is not true that an incoming electron coming from the normal metal can only be normalreflected or Andreevreflected. It can also just enter the superconducting electrode as an electron. Hence the reflection matrix no longer contains all the possible processes taking place at the interface, and it won't be unitary anymore. This allows the determinant to change sign. We conclude that $Q=\\det\\,r$ is a good topological invariant.\n",
 "\n",
 "Explicitly, we have that\n",
 "\n",
 "$$Q=r_{ee}^2r_{eh}^2\\equiv\\pm 1\\,.$$\n",
 "\n",
 "We already saw that unitarity requires that $r_{ee}^2+r_{eh}^2=1$. There are only two possibilities for both conditions to be true: either $r_{ee}=1$ (**perfect normal reflection**) or $r_{eh}=1$ (**perfect Andreev reflection**). The situation cannot change without a phase transition. Thus the quantized conductance of the Majorana mode is topologically robust in this case, and in fact survives past the tunneling limit. "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (\"Imagine we replace the superconducting electrode with an insulating material, \"\n",
 " \"and imagine that at the interface with the normal metal there is a bound state. \"\n",
 " \"How is the current through the interface different with respect \"\n",
 " \"to that through an NS interface with a Majorana?\")\n",
 "answers = [\"It is not quantized but still nonzero.\",\n",
 " \"It is zero because there cannot be Andreev reflection without a superconductor.\",\n",
 " \"It is not symmetric in voltage but it is still nonzero.\",\n",
 " \"It has a resonance peak whose width is independent of the barrier strength.\"]\n",
 "explanation = (\"A current requires an exit path for the charge. \"\n",
 " \"No current can flow through the insulator, since there are no excitations at the Fermi level in an insulator. \"\n",
 " \"A superconductor is also gapped with respect to excitations, but is different than a normal insulator. \"\n",
 " \"It has a condensate of Cooper pairs, so a current can develop thanks to Andreev reflection at the interface.\")\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Fluxinduced fermion parity switch in topological superconductors"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "How do we probe the Pfaffian topological invariant of a topological superconductor directly? Last week, we introduced a thoughtexperiment where we probed the bulkedge correspondence of Majorana modes by changing the sign of the hopping across a bond. The nontrivial value of the topological invariant results in a fermion parity switch as a result of the change in sign of the hopping $t$ across the junction i.e. \n",
 "\n",
 "$$t\\rightarrow t.$$\n",
 "\n",
 "It turns out that the sign change in the hopping across the junction might also be obtained by introducing a magnetic flux through the superconducting ring (similar to the [AharonovBohm effect](http://en.wikipedia.org/wiki/AharonovBohm_effect)). The role of the special bond is now played by a Josephson junction, which is just an insulating barrier interrupting the ring, as in the following sketch:\n",
 "\n",
 "![](figures/josephson_majorana_ring.svg)\n",
 "\n",
 "How does the magnetic flux enter the Hamiltonian? By following the usual argument for introducing magnetic fields into lattice Hamiltonians using [Peierls substitution](http://topocondmat.org/w2_majorana/Peierls.html), the flux $\\Phi$ can be accounted for simply by changing the phase of the hopping across the junction in the ring:\n",
 "\n",
 "$$t\\,\\to\\,t\\,\\exp (i\\phi/2).$$\n",
 "\n",
 "Here, $\\phi = 2\\pi\\Phi/\\Phi_0$ is usually called the **superconducting phase difference** across the junction, and $\\Phi_0=2e/h$ is the **superconducting flux quantum**. Notice that when $\\Phi=\\Phi_0$ the hopping changes sign: $t \\,\\to\\, \\exp (i\\pi) t = t$, exactly as we had last week!\n",
 "\n",
 "> Thus, the introduction of a flux quantum $\\Phi=\\Phi_0$, changes the sign of the hopping $t\\rightarrow t e^{i\\phi}=t$, which as discussed last week changes the fermion parity of the ground state for topological superconductors. This fermion parity switch is related to a pair of Majorana modes coupled at the junction (as in the figure above).\n",
 "\n",
 "To see how this happens explicitly, let's look at the spectrum of a topological superconducting ring as a function of flux, obtained using our nanowire model:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "fluxes, spectrum = nanowire_spectrum()\n",
 "plot_spectrum_nanowire(fluxes, spectrum)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Staring at the spectrum we see that, lo and behold, the fermion parity switch appears, around $\\Phi=\\Phi_0/2$. Can we measure this fermion parity switch in our superconducting ring?"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Detecting the fermion parity switch using the Josephson effect"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The change in fermion parity of the ground state can be detected using the socalled [Josephson effect](http://en.wikipedia.org/wiki/Josephson_effect). The Josephson current can be computed from the expectation value of the derivative of the energy operator with respect to flux,\n",
 "\n",
 "$$I(\\Phi)=\\frac{1}{2}\\frac{d E_\\textrm{tot}(\\Phi)}{d \\Phi},$$\n",
 "\n",
 "where $E_\\textrm{tot}(\\Phi)=\\left\\langle H_{BdG}(\\Phi)\\right\\rangle$ is the total energy of the system corresponding to the BdG Hamiltonian $H_{BdG}(\\Phi)$. \n",
 "\n",
 ">The key idea to detecting the ground state fermion parity switch is to note that changing the flux $\\Phi$ adiabatically cannot change the fermion parity of the system. If you start with the system in the ground state and advance the magnetic flux from $\\Phi$ to $\\Phi+\\Phi_0$, you end up in an excited state, because in the meantime the fermion parity has changed. To go back to the initial ground state with the same fermion parity, you need to advance $\\Phi$ by $2\\Phi_0$.\n",
 "\n",
 "Note that this argument relies on the absence of a reservoir of electrons, such as a metallic lead. In this case, when the two levels cross at zero energy and the ground state fermion parity changes, there is no electron that can enter or leave the system. \n",
 "\n",
 "The fermion parity switch, together with fermion parity conservation of the ring, result in the energy $E_\\textrm{tot}(\\Phi)$ and the corresponding current (that can be measured) showing a $2\\Phi_0$ periodicity in $\\Phi$  that is, a $4\\pi$ periodicity in $\\phi$:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "fluxes, spectrum = nanowire_spectrum()\n",
 "plot_gse_sc_nanowire(fluxes, spectrum)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "At this point you might wonder, what is so unique about the $2\\Phi_0$ periodicity of the Josephson effect?\n",
 "\n",
 "To answer this question, we need to review an alternative way of thinking about the Josephson effect in terms of just connecting a pair of superconductors by a junction without having to wrap the superconductor in a ring. In this case, the hopping phase $\\phi$ (which we also referred to as the *superconducting phase*) that appeared in the tunneling term proportional to $t e^{i\\phi/2}$ can be eliminated by shifting the fermion operators on one side of the junction by a phase i.e. $c^\\dagger\\rightarrow c^\\dagger e^{i\\phi/2}$. For superconducting systems, this transformation has the interesting effect of changing the superconducting phase on one side of the junction as \n",
 "\n",
 "$$\\Delta\\rightarrow \\Delta e^{i\\phi}.$$ \n",
 "\n",
 "Now you see why $\\phi$ was referred to as *superconducting phase* in the first place. After this transformation (also called a gauge transformation) $\\phi$ really becomes the complex phase of the superconducting term proportional to $\\Delta$.\n",
 "\n",
 "> But this also tells you one more thing  following the gauge transformation the Hamiltonian $H_{BdG}$ only depends on $\\phi$ through the term $\\Delta e^{i\\phi}$, so one expects the energy to be $2\\pi$ periodic in $\\phi$. This leads to the conventional wisdom that the Josephson effect is $2\\pi$periodic (or equivalently $\\Phi_0$periodic in the case of a ring). \n",
 "\n",
 "As seen from the plots below, this is exactly what happens in the nontopological phase. In this case, when we look at the energy spectrum, no fermion parity switches appear:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "fluxes, spectrum = nanowire_spectrum(trivial=True)\n",
 "plot_spectrum_nanowire(fluxes, spectrum, ylim=[0.11, 0.11])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In turn, this means that energy and current are periodic with period $\\Phi_0$:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "fluxes, spectrum = nanowire_spectrum(trivial=True)\n",
 "plot_gse_sc_nanowire(fluxes, spectrum)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "At this point, you might be a little worried about how the topological superconductor managed to get around this *conventional wisdom*. The answer is subtle, and relies on the implicit assumption of the ground state fermion parity of the junction being fixed as one changes $\\phi$. Topological superconductors violate this assumption and therefore can create the $4\\pi$ periodic (or fractional) Josephson effect. "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (\"Suppose that in your topological nanowire junction, positive energy quasiparticles can escape \"\n",
 " \"into a reservoir very quickly, making the junction always relax to the ground state. \"\n",
 " \"How would this affect the periodicity of the Josephson effect?\")\n",
 "answers = [\"It would make the periodicity random because of the quasiparticles jumping around randomly.\",\n",
 " \"If the system can always relax to the ground state, the current would have a period of $\\Phi_0$ (hence $2\\pi)$.\",\n",
 " \"Since the Josephson effect is topologically protected, these processes have no effect on the periodicity.\",\n",
 " \"The period becomes $\\Phi_0/2$ because it is easier for the quasiparticles to jump out at this value of the flux.\"]\n",
 "explanation = (\"A particle tunneling out means that the fermion parity of the ground state changes. \"\n",
 " \"Hence the lowest between the red and black energy levels is always occupied, and both energy and current \"\n",
 " \"turn out to have a period $\\Phi_0$.\")\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Summary"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"sSacO5RpW5A\", src_location=\"2.2summary\")"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocDiscussion('Questions', 'Signatures of Majorana modes')"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w2_majorana/signatures.md b/w2_majorana/signatures.md
new file mode 100644
index 0000000..8f5a805
 /dev/null
+++ b/w2_majorana/signatures.md
@@ 0,0 +1,440 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+
+dims = SimpleNamespace(G=holoviews.Dimension(r'$G/G_0$'),
+ V_bias=holoviews.Dimension('$V_{bias}$'),
+ phi=holoviews.Dimension(r'$\Phi/\Phi_0$'))
+
+
+def make_system_spectroscopy():
+
+ # We apply a magnetic field in all parts of the system
+ def onsite_sc(site, p):
+ return (2 * p.t  p.mu_sc) * pauli.s0sz + p.Ez * pauli.sxs0 + p.delta * pauli.s0sx
+
+ def onsite_normal(site, p):
+ return (2 * p.t  p.mu_l) * pauli.s0sz + p.Ez * pauli.sxs0
+
+ def onsite_barrier(site, p):
+ return (2 * p.t  p.mu_l + p.Vbarrier) * pauli.s0sz + p.Ez * pauli.sxs0
+
+ # The hopping is the same in all subsystems. There is normal hopping and
+ # spin orbit interaction.
+ def hop(site1, site2, p):
+ return p.t * pauli.s0sz + 1j * p.alpha * pauli.sysz
+
+ lat = kwant.lattice.chain(norbs=4)
+ syst = kwant.Builder()
+
+ # The first subsystem just consists of the tunnel barrier (one site with a
+ # potential)
+ syst[lat(0)] = onsite_barrier
+
+ # The second subsystem is a normal lead
+ # The translational symmetry makes it semiinfinite.
+ lead1 = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs), conservation_law=pauli.s0sz)
+ # Define a unit cell (in this case the unit cell consists of a single site)
+ lead1[lat(0)] = onsite_normal
+ # Define the hopping between unitcells
+ lead1[lat(1), lat(0)] = hop
+
+ # The third subsystem is a superconducting lead. A Majorana bound state
+ # can arise at the edge of this system.
+ lead2 = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))
+ # Again: Define a unit cell
+ lead2[lat(0)] = onsite_sc
+ # Again define hopping between unit cells
+ lead2[lat(1), lat(0)] = hop
+
+ # Create a connection between the first subsystem (the tunnel barrier, system name: syst)
+ # and the other two subsystems (the normal and the superconducting lead)
+ syst.attach_lead(lead1)
+ syst.attach_lead(lead2)
+
+ syst = syst.finalized()
+
+ return syst
+
+
+def nanowire_chain(L=None, periodic=False):
+ lat = kwant.lattice.chain()
+
+ if L is None:
+ syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))
+ L = 1
+ else:
+ syst = kwant.Builder()
+
+ def onsite(onsite, p):
+ return (2 * p.t  p.mu) * pauli.szs0 + p.B * pauli.s0sz + p.delta * pauli.sxs0
+
+ for x in range(L):
+ syst[lat(x)] = onsite
+
+ def hop(site1, site2, p):
+ return p.t * pauli.szs0  .5j * p.alpha * pauli.szsx
+
+ def hopping_with_flux(site1, site2, p):
+ phase = np.exp(1j * p.flux / 2)
+ phase_factors = np.kron(np.diag([phase, phase.conj()]), pauli.s0)
+ return 0.7 * phase_factors @ hop(site1, site1, p)
+
+ syst[kwant.HoppingKind((1,), lat)] = hop
+
+ if periodic:
+ syst[lat(0), lat(L  1)] = hopping_with_flux
+ return syst
+
+
+def tunnel_spectroscopy(syst, p, Es):
+ def Andreev_cond(E):
+ sm = kwant.smatrix(syst, energy=E, args=[p])
+ # (i, j) means we call for block j of lead i in the scattering matrix.
+ # The normal lead is i = 0 here, where block j = 0 corresponds to electrons
+ # and block j = 1 holes.
+ return (sm.submatrix((0, 0), (0, 0)).shape[0] 
+ sm.transmission((0, 0), (0, 0)) +
+ sm.transmission((0, 1), (0, 0)))
+ Gs = [Andreev_cond(E) for E in Es]
+ return np.array(Gs)
+
+
+def plot_spectroscopy(Vbarrier):
+ syst = make_system_spectroscopy()
+ Es = np.linspace(0.15, 0.15, 101)
+ p = SimpleNamespace(t=1, mu_l=0.5, mu_sc=0, alpha=0.15,
+ delta=0.1, Vbarrier=Vbarrier)
+
+ # Trivial, because the magnetic field is zero (third argument)
+ p.Ez = 0
+ Gs_trivial = tunnel_spectroscopy(syst, p, Es)
+
+ # Nontrivial
+ p.Ez = 0.25
+ Gs_topological = tunnel_spectroscopy(syst, p, Es)
+ kdims = [dims.V_bias, dims.G]
+ plot = holoviews.Path((Es, Gs_trivial), kdims=kdims, label='trivial')(style={'color': 'k'})
+ plot *= holoviews.Path((Es, Gs_topological), kdims=kdims, label='topological')(style={'color': 'r'})
+ style_overlay = {'xticks': [0.1, 0.0, 0.1],
+ 'yticks': [0.0, 0.5, 1.0, 1.5, 2.0],
+ 'show_legend':True,
+ 'legend_position': 'top',
+ 'fig_size':150}
+ style_path = {'show_legend':True}
+ return plot(plot={'Overlay': style_overlay, 'Path': style_path})
+
+
+def nanowire_spectrum(trivial=False):
+ B = 0.2 if trivial else 1.0
+ p = SimpleNamespace(mu=0.4, t=1.0, alpha=0.2, delta=0.1, B=B)
+ syst = nanowire_chain(L=100, periodic=True).finalized()
+
+ def energy(flux):
+ p.flux = flux
+ H = syst.hamiltonian_submatrix(args=[p])
+ return np.linalg.eigvalsh(H)
+
+ fluxes = np.linspace(0, 4 * np.pi, 51)
+ spectrum = np.array([energy(flux) for flux in fluxes])
+
+ # Find the two subgap states.
+ if not trivial:
+ N = spectrum.shape[1] // 2
+ non_trivial = np.where((fluxes > np.pi) & (fluxes < 3 * np.pi))
+ spectrum[non_trivial, N  1: N + 1] = spectrum[non_trivial, N: N  2: 1].copy()
+
+ return fluxes, spectrum
+
+
+def plot_spectrum_nanowire(fluxes, spectrum, ylim=[0.2, 0.2]):
+ N = spectrum.shape[1] // 2
+ kdims = [dims.phi, '$E$']
+ plot = holoviews.Path((fluxes, spectrum), kdims=kdims)(style={'color': 'k', 'alpha': 0.4})
+ plot *= holoviews.Path((fluxes, spectrum[:, N  1]), kdims=kdims)(style={'color': 'r'})
+ plot *= holoviews.Path((fluxes, spectrum[:, N]), kdims=kdims)(style={'color': 'k'})
+ ticks = {'xticks': [(0, '0'), (2 * np.pi, '1'), (4 * np.pi, '2')]}
+ return plot[:, 0.11:0.11](plot=ticks)
+
+
+def plot_gse_sc_nanowire(fluxes, spectrum):
+ N = spectrum.shape[1] // 2
+ energy_gs = np.sum(spectrum[:, :N], axis=1)
+ energy_gs = np.max(energy_gs)
+ current = np.diff(energy_gs) * len(energy_gs)
+
+ xdim = dims.phi
+ ydim = r'$E_{tot}(\Phi)$'
+
+ ticks = {'xticks': [(0, '0'), (2 * np.pi, '1'), (4 * np.pi, '2')]}
+ plot = holoviews.Path((fluxes, energy_gs), kdims=[
+ xdim, ydim], label='Energy')(plot=ticks)
+ ydim = r'$I(\Phi)$'
+ plot += holoviews.Path(((fluxes[1:] + fluxes[:1]) / 2, current),
+ kdims=[xdim, ydim], label='Current')(plot=ticks)
+ return plot
+
+```
+
+# How to detect Majoranas
+
+Our second guest lecturer for this week is Carlo Beenakker, from Leiden University.
+
+
+```python
+MoocVideo("WAhNblNbadA", src_location="2.2intro")
+```
+
+# Andreev reflection
+
+To understand how conductance through a Majorana works, we first have to learn how charge is transferred from a metallic lead to a superconductor. In general this transfer takes place via a mechanism known as Andreev reflection. Before we discuss the conductance signatures of a Majorana zero mode, it is useful to learn what Andreev reflection is.
+
+Let's consider the following very simple circuit with two electrodes:
+
+![](figures/ns_interface.svg)
+
+One electrode is a normal metal, the other a superconductor, and they are kept at a voltage difference $V$. At the interface between the normal metal and the superconductor (in short, NS interface) there is a barrier. We are particularly interested in the case when the voltage difference is very small compared to the energy gap in the superconductor, $eV < \Delta$, where $e$ is the charge of the electron.
+
+What happens when electrons arrive at the interface with superconductor? The superconductor has no states available up to an energy $\Delta$ around the Fermi level, and the voltage is not enough to provide for this energy difference. How can a current develop?
+
+To understand this, let's look more closely at an electron arriving at the interface with the superconductor. There are two possible processes that can take place, *normal reflection* and *Andreev reflection*. In normal reflection, the electron is simply reflected at the interface with the superconductor:
+
+![](figures/normal_reflection.svg)
+
+With normal reflection, there is no net charge transfer from the left electrode to the right electrode. Hence this process does not contribute any net current. Normal reflection obviously doesn't even require a superconductor and would take place also if the right electrode was normal.
+
+Andreev reflection, instead, is unique to the NS interface. In Andreev reflection, an electron is converted to a hole by the superconductor, and a Cooper pair is created in the superconductor.
+
+![](figures/andreev_reflection.svg)
+
+You can see that a net charge of $2e$ is transferred from the left to the right electrode, and at low voltages Andreev reflection is the only process responsible for the electrical current.
+
+Above the superconducting gap, $eV > \Delta$ transmission of an incident electron into the superconductor also contributes to the current.
+
+You can also think of Andreev *reflection* as a *transmission* problem. Because of the presence of the superconductor, both electrons and holes participate in the transfer of charge in the normal metal lead. Conceptually, you can imagine to separate the left lead into two leads, one only carrying electrons and one only carrying holes. These two leads are connected by the superconductor, which converts incoming electrons in the first lead into outgoing holes in the second lead, and viceversa:
+
+![](figures/andreev_as_transmission.svg)
+
+With this picture, you can understand that Andreev reflection is very similar to the problem of transmission through a double barrier.
+
+Let's call $r_{eh}$ the amplitude for Andreev reflection. Its absolute value squared, $\leftr_{eh}\right^2$, is the probability that an incoming electron from the normal metal is Andreev reflected as a hole. Once we know $r_{eh}$, we can compute the conductance $G(V)$, which relates the current $I$ that develops as a response to a small voltage $V$, $G(V) = dI/dV$. The conductance is given by the following formula:
+
+$$G(V)=2G_0r_{eh}^2.$$
+
+We will not derive this equation, since it can be understood intuitively. The conductance is proportional to the probability $r_{eh}^2$ of Andreev reflection, since we know that at low voltages this is the only process that transfers electric charge from the left to the right electrode.
+
+The factor of $2$ is due to each Andreev reflection transferring a charge of a Cooper pair, $2e$. Finally, $G_0=e^2/h$ is the **conductance quantum**, the fundamental proportionality constant which relates currents to voltages.
+
+# Andreev reflection off a Majorana zero mode
+
+Now that we understand a conventional NS interface, let's see what happens if our superconductor is topological:
+
+![](figures/ns_majorana_interface.svg)
+
+You can imagine that the superconducting electrode is now a nanowire in the topological phase, like the one you have just studied. Because the superconductor is topological, there is a Majorana mode at the NS interface, whose wave function will “leak” a bit into the normal metal, through the barrier. Of course, there will be also a second Majorana mode, but we place it far enough from the NS interface, so that it does not have a role in the transport. Does the Majorana zero mode at the interface change the Andreev reflection properties?
+
+Yes, and in a rather drastic way. Going back to the picture of Andreev reflection as a transmission process through a double barrier, the crucial difference is that the Majorana mode now appears as a bound state between the two barriers:
+
+![](figures/resonant_transmission_through_majorana.svg)
+
+In the double barrier problem in quantum mechanics, you can have **resonant** transmission in the presence of a bound state. This means that the probability $\leftr_{eh}\right^2$ to pass through the barriers is dramatically enhanced if the energy of the incident electron matches the energy of the bound state. In our case, the energy of the incident electron is $V$, and the energy of the bound state, the Majorana mode, is zero. So the presence of the Majorana mode leads to a **resonant peak** in the conductance of the NS interface at $V=0$.
+
+# Quantization of the Majorana resonance
+
+Seeing the resonant peak is the most direct way we know to measure the presence of a Majorana zero mode.
+
+However, the presence of a resonance associated with Majorana modes is not uniquely topological, because tunneling into any low energy bound state produces resonance.
+
+Is there anything in particular which distinguishes the Majorana resonance from any other resonance?
+
+Let's just look at what happens if we compare conductance of an NS interface in the cases when S is trivial and nontrivial, and see how the conductance changes as we alter the tunnel barrier strength.
+
+
+```python
+holoviews.HoloMap({V: plot_spectroscopy(V) for V in np.arange(1, 4.25, 0.25)}, kdims=[r'$V_{barrier}$'])
+```
+
+We see a very robust and persistent characteristic:
+the peak height of the Majorana resonance is quantized to the value of $2G_0$, independent of the strength of the voltage barrier. From the formula above, this means that if a Majorana is present we have $\leftr_{eh}\right^2=1$, that is we have **perfect Andreev reflection**.
+
+To understand why it is robust, we need to go beyond drawing cartoon figures.
+
+## Reflection matrix of a normal metalsuperconductor interface
+
+Quantummechanically, we can describe transport through the NS interface as a scattering problem. An incoming wave function $\Psi_\textrm{in}$ propagates in the left electrode, until it is reflected back at the interface with the superconductor, turning into an outgoing wave function $\Psi_\textrm{out}$. Because of the presence of the superconductor, both the incoming and outgoing states can be electrons $\Psi_e$ or holes $\Psi_h$. At **zero energy**, they are related to each other by particlehole symmetry:
+
+$$\Psi_e(E) = \mathcal{P}\,\Psi_h(E)\,$$
+
+The reflection enforces a linear relation between incoming and ingoing waves:
+
+$$\Psi_\textrm{out} = r(V) \,\Psi_\textrm{in}\,$$
+
+$$r(V)=\left(\begin{array}{cc}r_{ee}&r_{eh}\\r_{he}&r_{hh}\end{array}\right).$$
+
+The matrix $r$ is known as the **reflection matrix**. Its complex elements are the amplitudes of normal and Andreev reflection of an incoming electron  $r_{ee}$ and $r_{eh}$  and normal and Andreev reflection of an incoming hole  $r_{hh}$ and $r_{he}$. (For brevity we don't write out explicitly that each of those depends on $V$.)
+
+If there is more than one incoming electron state (in our case there are two due to spin), all 4 elements of $r$ become matrices themselves. They then describe scattering between all the possible incoming and outgoing states.
+
+Because for $eV\ll \Delta$ there are no propagating waves in the superconductor, the reflection process which relates $\Psi_\textrm{out}$ and $\Psi_\textrm{in}$ is unitary, $r^\dagger r=1$. This implies that
+
+$$\leftr_{ee}\right^2+\leftr_{eh}\right^2 = \leftr_{he}\right^2+\leftr_{hh}\right^2 = 1\,.$$
+
+This is the mathematical way of saying that an electron (or hole) arriving at the interface has no alternatives other than being normalreflected or Andreevreflected.
+
+Can we add any other constraint to $r$, that might help to distinguish any characteristic of the Majorana mode? Just like we did last week, let's try to study $r$ using symmetry and topology. Our circuit involves a superconductor, so we must have particlehole symmetry in the problem.
+
+In order to derive $r$ explicitly we could start directly from the Bogoliubovde Gennes Hamiltonian of the NS system, and solve it for an energy $V$. This is a lot of work, which we won't do, but knowing this fact we can understand the consequences of particlehole symmetry for $r$.
+
+First, particlehole symmetry exchanges electrons and hole components of the wave function, so it involves a Pauli matrix $\tau_x$ acting on $\Psi_\textrm{in}$ or $\Psi_\textrm{out}$. Second, it is an antiunitary symmetry, so it involves complex conjugation. Third, it changes the sign of the energy so it sends $V$ into $V$. Hence we arrive at the following symmetry for the reflection matrix:
+
+$$\tau_x r^*(V) \tau_x = r(V)\,.$$
+
+Together with unitarity, particlehole symmetry imposes that the conductance is symmetric around zero voltage, $G(V)=G(V)$. In the most interesting point, $V=0$ we have:
+
+$$ \tau_x r^*_0 \tau_x = r_0 \,.$$
+
+where we defined $r_0\equiv r(V=0)$. So much for the impact of symmetry on $r$. What about topology?
+
+# Topological invariant of the reflection matrix
+
+The Majorana zero mode is the consequence of a topological phase in the topological superconductor, and its presence is dictated by the bulkboundary correspondence. Can we find any consequence of this fact in $r_0$? It turns out that reflection matrices $r$ with particlehole symmetry are also topological in their own way. Their topological invariant is
+
+$$Q = \det\,r_0\,.$$
+
+Again, we will not *derive* this equation, but rather convince ourselves this expression is correct.
+
+First of all, the determinant of a unitary matrix such as $r_0$ is always a complex number with unit norm, so $\left\det\,r_0\,\right=1$. Second, because of particlehole symmetry, the determinant is real: $\det r_0 = \det\, (\tau_x r^*_0\,\tau_x) = \det\,r_0^*\,=(\det\,r_0)^*$. Hence, $\det\,r_0\,= \pm 1$. This is quite promising! Two possible discrete values, just like the Pfaffian invariant of the Kitaev chain.
+
+Because it is just dictated by unitarity and particlehole symmetry, the determinant of $r_0$ cannot change from $+1$ to $1$ under a change of the properties of the NS interface. For instance, you can vary the height of the potential barrier at the interface, but this cannot affect the determinant of $r_0$.
+
+The only way to make the determinant change sign is to close the bulk gap in the superconducting electrode. If the gap goes to zero, then it is not true that an incoming electron coming from the normal metal can only be normalreflected or Andreevreflected. It can also just enter the superconducting electrode as an electron. Hence the reflection matrix no longer contains all the possible processes taking place at the interface, and it won't be unitary anymore. This allows the determinant to change sign. We conclude that $Q=\det\,r$ is a good topological invariant.
+
+Explicitly, we have that
+
+$$Q=r_{ee}^2r_{eh}^2\equiv\pm 1\,.$$
+
+We already saw that unitarity requires that $r_{ee}^2+r_{eh}^2=1$. There are only two possibilities for both conditions to be true: either $r_{ee}=1$ (**perfect normal reflection**) or $r_{eh}=1$ (**perfect Andreev reflection**). The situation cannot change without a phase transition. Thus the quantized conductance of the Majorana mode is topologically robust in this case, and in fact survives past the tunneling limit.
+
+
+```python
+question = ("Imagine we replace the superconducting electrode with an insulating material, "
+ "and imagine that at the interface with the normal metal there is a bound state. "
+ "How is the current through the interface different with respect "
+ "to that through an NS interface with a Majorana?")
+answers = ["It is not quantized but still nonzero.",
+ "It is zero because there cannot be Andreev reflection without a superconductor.",
+ "It is not symmetric in voltage but it is still nonzero.",
+ "It has a resonance peak whose width is independent of the barrier strength."]
+explanation = ("A current requires an exit path for the charge. "
+ "No current can flow through the insulator, since there are no excitations at the Fermi level in an insulator. "
+ "A superconductor is also gapped with respect to excitations, but is different than a normal insulator. "
+ "It has a condensate of Cooper pairs, so a current can develop thanks to Andreev reflection at the interface.")
+MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)
+```
+
+# Fluxinduced fermion parity switch in topological superconductors
+
+How do we probe the Pfaffian topological invariant of a topological superconductor directly? Last week, we introduced a thoughtexperiment where we probed the bulkedge correspondence of Majorana modes by changing the sign of the hopping across a bond. The nontrivial value of the topological invariant results in a fermion parity switch as a result of the change in sign of the hopping $t$ across the junction i.e.
+
+$$t\rightarrow t.$$
+
+It turns out that the sign change in the hopping across the junction might also be obtained by introducing a magnetic flux through the superconducting ring (similar to the [AharonovBohm effect](http://en.wikipedia.org/wiki/AharonovBohm_effect)). The role of the special bond is now played by a Josephson junction, which is just an insulating barrier interrupting the ring, as in the following sketch:
+
+![](figures/josephson_majorana_ring.svg)
+
+How does the magnetic flux enter the Hamiltonian? By following the usual argument for introducing magnetic fields into lattice Hamiltonians using [Peierls substitution](http://topocondmat.org/w2_majorana/Peierls.html), the flux $\Phi$ can be accounted for simply by changing the phase of the hopping across the junction in the ring:
+
+$$t\,\to\,t\,\exp (i\phi/2).$$
+
+Here, $\phi = 2\pi\Phi/\Phi_0$ is usually called the **superconducting phase difference** across the junction, and $\Phi_0=2e/h$ is the **superconducting flux quantum**. Notice that when $\Phi=\Phi_0$ the hopping changes sign: $t \,\to\, \exp (i\pi) t = t$, exactly as we had last week!
+
+> Thus, the introduction of a flux quantum $\Phi=\Phi_0$, changes the sign of the hopping $t\rightarrow t e^{i\phi}=t$, which as discussed last week changes the fermion parity of the ground state for topological superconductors. This fermion parity switch is related to a pair of Majorana modes coupled at the junction (as in the figure above).
+
+To see how this happens explicitly, let's look at the spectrum of a topological superconducting ring as a function of flux, obtained using our nanowire model:
+
+
+```python
+fluxes, spectrum = nanowire_spectrum()
+plot_spectrum_nanowire(fluxes, spectrum)
+```
+
+Staring at the spectrum we see that, lo and behold, the fermion parity switch appears, around $\Phi=\Phi_0/2$. Can we measure this fermion parity switch in our superconducting ring?
+
+# Detecting the fermion parity switch using the Josephson effect
+
+The change in fermion parity of the ground state can be detected using the socalled [Josephson effect](http://en.wikipedia.org/wiki/Josephson_effect). The Josephson current can be computed from the expectation value of the derivative of the energy operator with respect to flux,
+
+$$I(\Phi)=\frac{1}{2}\frac{d E_\textrm{tot}(\Phi)}{d \Phi},$$
+
+where $E_\textrm{tot}(\Phi)=\left\langle H_{BdG}(\Phi)\right\rangle$ is the total energy of the system corresponding to the BdG Hamiltonian $H_{BdG}(\Phi)$.
+
+>The key idea to detecting the ground state fermion parity switch is to note that changing the flux $\Phi$ adiabatically cannot change the fermion parity of the system. If you start with the system in the ground state and advance the magnetic flux from $\Phi$ to $\Phi+\Phi_0$, you end up in an excited state, because in the meantime the fermion parity has changed. To go back to the initial ground state with the same fermion parity, you need to advance $\Phi$ by $2\Phi_0$.
+
+Note that this argument relies on the absence of a reservoir of electrons, such as a metallic lead. In this case, when the two levels cross at zero energy and the ground state fermion parity changes, there is no electron that can enter or leave the system.
+
+The fermion parity switch, together with fermion parity conservation of the ring, result in the energy $E_\textrm{tot}(\Phi)$ and the corresponding current (that can be measured) showing a $2\Phi_0$ periodicity in $\Phi$  that is, a $4\pi$ periodicity in $\phi$:
+
+
+```python
+fluxes, spectrum = nanowire_spectrum()
+plot_gse_sc_nanowire(fluxes, spectrum)
+```
+
+At this point you might wonder, what is so unique about the $2\Phi_0$ periodicity of the Josephson effect?
+
+To answer this question, we need to review an alternative way of thinking about the Josephson effect in terms of just connecting a pair of superconductors by a junction without having to wrap the superconductor in a ring. In this case, the hopping phase $\phi$ (which we also referred to as the *superconducting phase*) that appeared in the tunneling term proportional to $t e^{i\phi/2}$ can be eliminated by shifting the fermion operators on one side of the junction by a phase i.e. $c^\dagger\rightarrow c^\dagger e^{i\phi/2}$. For superconducting systems, this transformation has the interesting effect of changing the superconducting phase on one side of the junction as
+
+$$\Delta\rightarrow \Delta e^{i\phi}.$$
+
+Now you see why $\phi$ was referred to as *superconducting phase* in the first place. After this transformation (also called a gauge transformation) $\phi$ really becomes the complex phase of the superconducting term proportional to $\Delta$.
+
+> But this also tells you one more thing  following the gauge transformation the Hamiltonian $H_{BdG}$ only depends on $\phi$ through the term $\Delta e^{i\phi}$, so one expects the energy to be $2\pi$ periodic in $\phi$. This leads to the conventional wisdom that the Josephson effect is $2\pi$periodic (or equivalently $\Phi_0$periodic in the case of a ring).
+
+As seen from the plots below, this is exactly what happens in the nontopological phase. In this case, when we look at the energy spectrum, no fermion parity switches appear:
+
+
+```python
+fluxes, spectrum = nanowire_spectrum(trivial=True)
+plot_spectrum_nanowire(fluxes, spectrum, ylim=[0.11, 0.11])
+```
+
+In turn, this means that energy and current are periodic with period $\Phi_0$:
+
+
+```python
+fluxes, spectrum = nanowire_spectrum(trivial=True)
+plot_gse_sc_nanowire(fluxes, spectrum)
+```
+
+At this point, you might be a little worried about how the topological superconductor managed to get around this *conventional wisdom*. The answer is subtle, and relies on the implicit assumption of the ground state fermion parity of the junction being fixed as one changes $\phi$. Topological superconductors violate this assumption and therefore can create the $4\pi$ periodic (or fractional) Josephson effect.
+
+
+```python
+question = ("Suppose that in your topological nanowire junction, positive energy quasiparticles can escape "
+ "into a reservoir very quickly, making the junction always relax to the ground state. "
+ "How would this affect the periodicity of the Josephson effect?")
+answers = ["It would make the periodicity random because of the quasiparticles jumping around randomly.",
+ "If the system can always relax to the ground state, the current would have a period of $\Phi_0$ (hence $2\pi)$.",
+ "Since the Josephson effect is topologically protected, these processes have no effect on the periodicity.",
+ "The period becomes $\Phi_0/2$ because it is easier for the quasiparticles to jump out at this value of the flux."]
+explanation = ("A particle tunneling out means that the fermion parity of the ground state changes. "
+ "Hence the lowest between the red and black energy levels is always occupied, and both energy and current "
+ "turn out to have a period $\Phi_0$.")
+MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)
+```
+
+# Summary
+
+
+```python
+MoocVideo("sSacO5RpW5A", src_location="2.2summary")
+```
+
+
+```python
+MoocDiscussion('Questions', 'Signatures of Majorana modes')
+```
diff git a/w2_majorana/w2_assignments.ipynb b/w2_majorana/w2_assignments.ipynb
deleted file mode 100644
index a679483..0000000
 a/w2_majorana/w2_assignments.ipynb
+++ /dev/null
@@ 1,179 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Simulation: tweaking the nanowire"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We have two choices for your coding assignments of this week. Consider the task complete when you finish one of the two.\n",
 "\n",
 "This is especially true since both of the assignments constitute a complete paper :)\n",
 "\n",
 "As usual, start by grabbing the notebooks of this week (`w2_majorana`). They are once again over [here](http://tiny.cc/topocm_smc).\n",
 "\n",
 "## Tilted magnetic field\n",
 "\n",
 "Explore what happens when we change one the important knobs of the nanowire model, the external magnetic field. We studied what happens when $B$ is pointing along the $z$ direction. However, what happens when the magnetic field is tilted?\n",
 "\n",
 "Generalize the Hamiltonian of the nanowire to the case of a magnetic field with three components $B_x, B_y, B_z$. How do the new terms look like?\n",
 "\n",
 "Go into the `nanowire` notebook. Modify the `nanowire_chain` function to include the magnetic field pointing in general direction.\n",
 "Plot the band structure for different field directions, and compare to the original case of having only $B_z$. What changes?\n",
 "\n",
 "Compare your results with what you find over here:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "display_html(PreprintReference('1403.4464'))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## From $4\\pi$ to $2\\pi$.\n",
 "\n",
 "Now let's switch to the signatures of Majoranas. The code for these is in the `signatures` notebook.\n",
 "\n",
 "How does the $4\\pi$periodic Josephson effect disapper? We argued that we cannot just remove a single crossing. Also periodicity isn't a continuous variable and cannot just change. So what is happening?\n",
 "\n",
 "Study the spectrum of a superconducting ring as a function of magnetic field, as you make a transition between the trivial and the topological regimes.\n",
 "\n",
 "What do you see? Compare your results with the paper below."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "PreprintReference(\"1210.3237\")"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocSelfAssessment(due=5*7, review_due=6*7)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion('Labs', 'Majorana nanowire')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Review assignment"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As we mentioned, there are really hundreds of papers that use the models and concepts that we used in the lecture.\n",
 "\n",
 "Here is a small selection of the ones that you may find interesting."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "display_html(PreprintReference('1204.2792',\n",
 " description=\"Welcome to the real world.\"))\n",
 "\n",
 "display_html(PreprintReference('1101.5795',\n",
 " description=\"Majorana conductance with many modes.\"))\n",
 "\n",
 "display_html(PreprintReference('1006.4395',\n",
 " description=\"To play a nice melody, you just need a keyboard. \"\n",
 " \"This paper first showed how Majoranas in wire networks can be moved around\"))\n",
 "\n",
 "display_html(PreprintReference('1008.0629', description=\"Real nanowires are more complicated.\"))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Bonus: Find your own paper to review!\n",
 "\n",
 "Do you know of another paper that fits into the topics of this week, and you think is good?\n",
 "Then you can get bonus points by reviewing that paper instead!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocPeerAssessment(due=5*7, review_due=6*7)"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Reviews\", \"Majoranas\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w2_majorana/w2_assignments.md b/w2_majorana/w2_assignments.md
new file mode 100644
index 0000000..5c1e293
 /dev/null
+++ b/w2_majorana/w2_assignments.md
@@ 0,0 +1,93 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+```
+
+# Simulation: tweaking the nanowire
+
+We have two choices for your coding assignments of this week. Consider the task complete when you finish one of the two.
+
+This is especially true since both of the assignments constitute a complete paper :)
+
+As usual, start by grabbing the notebooks of this week (`w2_majorana`). They are once again over [here](http://tiny.cc/topocm_smc).
+
+## Tilted magnetic field
+
+Explore what happens when we change one the important knobs of the nanowire model, the external magnetic field. We studied what happens when $B$ is pointing along the $z$ direction. However, what happens when the magnetic field is tilted?
+
+Generalize the Hamiltonian of the nanowire to the case of a magnetic field with three components $B_x, B_y, B_z$. How do the new terms look like?
+
+Go into the `nanowire` notebook. Modify the `nanowire_chain` function to include the magnetic field pointing in general direction.
+Plot the band structure for different field directions, and compare to the original case of having only $B_z$. What changes?
+
+Compare your results with what you find over here:
+
+
+```python
+display_html(PreprintReference('1403.4464'))
+```
+
+## From $4\pi$ to $2\pi$.
+
+Now let's switch to the signatures of Majoranas. The code for these is in the `signatures` notebook.
+
+How does the $4\pi$periodic Josephson effect disapper? We argued that we cannot just remove a single crossing. Also periodicity isn't a continuous variable and cannot just change. So what is happening?
+
+Study the spectrum of a superconducting ring as a function of magnetic field, as you make a transition between the trivial and the topological regimes.
+
+What do you see? Compare your results with the paper below.
+
+
+```python
+PreprintReference("1210.3237")
+```
+
+
+```python
+MoocSelfAssessment(due=5*7, review_due=6*7)
+```
+
+
+```python
+MoocDiscussion('Labs', 'Majorana nanowire')
+```
+
+# Review assignment
+
+As we mentioned, there are really hundreds of papers that use the models and concepts that we used in the lecture.
+
+Here is a small selection of the ones that you may find interesting.
+
+
+```python
+display_html(PreprintReference('1204.2792',
+ description="Welcome to the real world."))
+
+display_html(PreprintReference('1101.5795',
+ description="Majorana conductance with many modes."))
+
+display_html(PreprintReference('1006.4395',
+ description="To play a nice melody, you just need a keyboard. "
+ "This paper first showed how Majoranas in wire networks can be moved around"))
+
+display_html(PreprintReference('1008.0629', description="Real nanowires are more complicated."))
+```
+
+### Bonus: Find your own paper to review!
+
+Do you know of another paper that fits into the topics of this week, and you think is good?
+Then you can get bonus points by reviewing that paper instead!
+
+
+```python
+MoocPeerAssessment(due=5*7, review_due=6*7)
+```
+
+
+```python
+MoocDiscussion("Reviews", "Majoranas")
+```
diff git a/w3_pump_QHE/Laughlinargument.ipynb b/w3_pump_QHE/Laughlinargument.ipynb
deleted file mode 100644
index 5df4be6..0000000
 a/w3_pump_QHE/Laughlinargument.ipynb
+++ /dev/null
@@ 1,756 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "%output size = 150\n",
 "\n",
 "\n",
 "def qhe_corbino(r_out=100, r_in=65, w_lead=10):\n",
 " \"\"\"Create corbino disk. \n",
 "\n",
 " Square lattice, one orbital per site.\n",
 " Returns kwant system.\n",
 "\n",
 " Arguments required in onsite/hoppings: \n",
 " t, mu, mu_lead, B, phi\n",
 " \"\"\"\n",
 " # ring shape\n",
 " def ring(pos):\n",
 " (x, y) = pos\n",
 " rsq = x ** 2 + y ** 2\n",
 " return (r_in ** 2 < rsq < r_out ** 2)\n",
 "\n",
 " # Onsite and hoppings\n",
 " def onsite(site, p):\n",
 " (x, y) = site.pos\n",
 " return 4 * p.t  p.mu\n",
 "\n",
 " def crosses_branchcut(hop):\n",
 " x1, y1 = hop[0].pos\n",
 " x2, y2 = hop[1].pos\n",
 " return y1 < 0 and x1 > 0.5 and x2 < 0.5\n",
 "\n",
 " def hopping(site1, site2, p):\n",
 " x1, y1 = site1.pos\n",
 " x2, y2 = site2.pos\n",
 " # Check for correctness!\n",
 " return p.t * np.exp(0.5j * p.B * (x1  x2) * (y1 + y2))\n",
 "\n",
 " def branchcut_hopping(site1, site2, p):\n",
 " return hopping(site1, site2, p) * np.exp(1j * p.phi)\n",
 "\n",
 " # Building system\n",
 " lat = kwant.lattice.square()\n",
 " syst = kwant.Builder()\n",
 "\n",
 " syst[lat.shape(ring, (0, r_in + 1))] = onsite\n",
 " syst[lat.neighbors()] = hopping\n",
 "\n",
 " # adding special hoppings\n",
 " def hops_across_cut(syst):\n",
 " for hop in kwant.builder.HoppingKind((1, 0), lat, lat)(syst):\n",
 " if crosses_branchcut(hop):\n",
 " yield hop\n",
 " syst[hops_across_cut] = branchcut_hopping\n",
 "\n",
 " # Attaching leads\n",
 " sym_lead = kwant.TranslationalSymmetry((1, 0))\n",
 " lead = kwant.Builder(sym_lead)\n",
 "\n",
 " def lead_shape(pos):\n",
 " (x, y) = pos\n",
 " return (w_lead / 2 < y < w_lead / 2)\n",
 "\n",
 " lead[lat.shape(lead_shape, (0, 0))] = lambda site, p: 4 * p.t  p.mu_lead\n",
 " lead[lat.neighbors()] = lambda site1, site2, p: p.t\n",
 "\n",
 " #### Attach the leads and return the system. ####\n",
 " syst.attach_lead(lead)\n",
 " syst.attach_lead(lead, origin=lat(0, 0))\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def total_charge(value_array):\n",
 " determinants = [np.linalg.det(s) for s in value_array]\n",
 " charge = np.cumsum(np.angle(determinants / np.roll(determinants, 1)))\n",
 " return charge / (2 * np.pi)\n",
 "\n",
 "\n",
 "def qhe_ribbon(W, periodic=False):\n",
 " \"\"\" Creates ribbon system\n",
 "\n",
 " If we have periodic boundary conditions, the flux through a single \n",
 " unit cell is quantized.\n",
 " \"\"\"\n",
 " W = 2 * (W // 2)\n",
 "\n",
 " def ribbon_shape(pos):\n",
 " (x, y) = pos\n",
 " return (W / 2 <= y <= W / 2)\n",
 "\n",
 " def onsite(site, p):\n",
 " (x, y) = site.pos\n",
 " return 4 * p.t  p.mu\n",
 "\n",
 " def hopping(site1, site2, p):\n",
 " x1, y1 = site1.pos\n",
 " x2, y2 = site2.pos\n",
 " return p.t * np.exp(0.5j * p.B * (x1  x2) * (y1 + y2))\n",
 "\n",
 " def hopping_periodic(site1, site2, p):\n",
 " x1, y1 = site1.pos\n",
 " x2, y2 = site2.pos\n",
 " return p.t * np.exp(1j * np.pi / (W + 1) * np.round((W + 1) * p.B / (2 * np.pi)) * (x1  x2) * (y1 + y2))\n",
 "\n",
 " lat = kwant.lattice.square()\n",
 " sym_syst = kwant.TranslationalSymmetry((1, 0))\n",
 " syst = kwant.Builder(sym_syst)\n",
 "\n",
 " syst[lat.shape(ribbon_shape, (0, 0))] = onsite\n",
 "\n",
 " if periodic:\n",
 " syst[lat.neighbors()] = hopping_periodic\n",
 " syst[lat(0,  W / 2), lat(0, + W / 2)] = hopping_periodic\n",
 " else:\n",
 " syst[lat.neighbors()] = hopping\n",
 "\n",
 " return syst\n",
 "\n",
 "# Quantum hall bar codes\n",
 "\n",
 "\n",
 "def qhe_hall_bar(L=50, W=10, w_lead=10, w_vert_lead=None):\n",
 " \"\"\"Create a hall bar system. \n",
 "\n",
 " Square lattice, one orbital per site.\n",
 " Returns kwant system.\n",
 "\n",
 " Arguments required in onsite/hoppings: \n",
 " t, mu, mu_lead\n",
 " \"\"\"\n",
 "\n",
 " L = 2 * (L // 2)\n",
 " W = 2 * (W // 2)\n",
 " w_lead = 2 * (w_lead // 2)\n",
 " if w_vert_lead is None:\n",
 " w_vert_lead = w_lead\n",
 " else:\n",
 " w_vert_lead = 2 * (w_vert_lead // 2)\n",
 "\n",
 " # bar shape\n",
 " def bar(pos):\n",
 " (x, y) = pos\n",
 " return (x >= L / 2 and x <= L / 2) and (y >= W / 2 and y <= W / 2)\n",
 "\n",
 " # Onsite and hoppings\n",
 " def onsite(site, p):\n",
 " (x, y) = site.pos\n",
 " return 4 * p.t  p.mu\n",
 "\n",
 " def hopping_Ax(site1, site2, p):\n",
 " x1, y1 = site1.pos\n",
 " x2, y2 = site2.pos\n",
 " return p.t * np.exp(0.5j * p.B * (x1 + x2) * (y1  y2))\n",
 "\n",
 " def make_lead_hop_y(x0):\n",
 " def hopping_Ay(site1, site2, p):\n",
 " x1, y1 = site1.pos\n",
 " x2, y2 = site2.pos\n",
 " return p.t * np.exp(1j * p.B * x0 * (y1  y2))\n",
 " return hopping_Ay\n",
 "\n",
 " def lead_hop_vert(site1, site2, p):\n",
 " return p.t\n",
 "\n",
 " # Building system\n",
 " lat = kwant.lattice.square()\n",
 " syst = kwant.Builder()\n",
 "\n",
 " syst[lat.shape(bar, (0, 0))] = onsite\n",
 " syst[lat.neighbors()] = hopping_Ax\n",
 "\n",
 " # Attaching leads\n",
 " sym_lead = kwant.TranslationalSymmetry((1, 0))\n",
 " lead = kwant.Builder(sym_lead)\n",
 "\n",
 " def lead_shape(pos):\n",
 " (x, y) = pos\n",
 " return (w_lead / 2 <= y <= w_lead / 2)\n",
 "\n",
 " lead_onsite = lambda site, p: 4 * p.t  p.mu_lead\n",
 "\n",
 " sym_lead_vertical = kwant.TranslationalSymmetry((0, 1))\n",
 " lead_vertical1 = kwant.Builder(sym_lead_vertical)\n",
 " lead_vertical2 = kwant.Builder(sym_lead_vertical)\n",
 "\n",
 " def lead_shape_vertical1(pos):\n",
 " (x, y) = pos\n",
 " return (L / 4  w_vert_lead / 2 <= x <= L / 4 + w_vert_lead / 2)\n",
 "\n",
 " def lead_shape_vertical2(pos):\n",
 " (x, y) = pos\n",
 " return (+L / 4  w_vert_lead / 2 <= x <= +L / 4 + w_vert_lead / 2)\n",
 "\n",
 " lead_vertical1[lat.shape(lead_shape_vertical1, (L / 4, 0))] = lead_onsite\n",
 " lead_vertical1[lat.neighbors()] = lead_hop_vert\n",
 " lead_vertical2[lat.shape(lead_shape_vertical2, (L / 4, 0))] = lead_onsite\n",
 " lead_vertical2[lat.neighbors()] = lead_hop_vert\n",
 "\n",
 " syst.attach_lead(lead_vertical1)\n",
 " syst.attach_lead(lead_vertical2)\n",
 "\n",
 " syst.attach_lead(lead_vertical1.reversed())\n",
 " syst.attach_lead(lead_vertical2.reversed())\n",
 "\n",
 " lead[lat.shape(lead_shape, (1, 0))] = lead_onsite\n",
 " lead[lat.neighbors()] = make_lead_hop_y(L / 2)\n",
 "\n",
 " syst.attach_lead(lead)\n",
 "\n",
 " lead = kwant.Builder(sym_lead)\n",
 " lead[lat.shape(lead_shape, (1, 0))] = lead_onsite\n",
 " lead[lat.neighbors()] = make_lead_hop_y(L / 2)\n",
 "\n",
 " syst.attach_lead(lead.reversed())\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def calculate_sigmas(G):\n",
 " # reduce by one dimension G > G[temp, temp]\n",
 " temp = [0, 1, 3, 4, 5]\n",
 " G = G[temp, :]\n",
 " G = G[:, temp]\n",
 " # invert R = G^1\n",
 " # find out whether it is a numpy object\n",
 " r = np.linalg.inv(G)\n",
 " # Voltages follow: V = R I[temp]\n",
 " V = r @ np.array([0, 0, 0, 1, 1])\n",
 " # Completely solved the six terminal system.\n",
 " # Consider the 2x2 conductance now: Use I = sigma U\n",
 " E_x = V[1]  V[0]\n",
 " E_y = V[1]  V[3]\n",
 " # formula above\n",
 " sigma_xx = E_x / (E_x**2 + E_y**2)\n",
 " sigma_xy = E_y / (E_x**2 + E_y**2)\n",
 " return sigma_xx, sigma_xy\n",
 "\n",
 "\n",
 "def plot_pumping(syst, p):\n",
 " p.mu_lead = p.mu\n",
 " phis = np.linspace(0, 2 * np.pi, 40)\n",
 " syst = syst.finalized()\n",
 " rs = [kwant.smatrix(syst, energy=0.0, args=[p]).submatrix(1, 1) for p.phi in phis]\n",
 " charges = total_charge(rs)\n",
 " style = {'xticks': [0, 1], 'yticks': [0, 1, 2, 3], 'aspect': 'square'}\n",
 " kdims = ['$\\phi/2\\pi$', '$q_{pump}$']\n",
 " title = '$\\mu = {:.2}$, $\\sigma_H = {:} \\cdot e^2/h$'.format(p.mu, int(round(charges[1])))\n",
 " return holoviews.Path((phis / (2 * np.pi), charges), kdims=kdims, label=title)(plot=style)[:, 0:3.1]\n"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## We present an argument for the robustness of the quantum hall effect for electrons: Laughlin argument\n",
 "* Observation of Quantum Hall\n",
 "* Quantized Hall conductance from pumping: Laughlin argument\n",
 "* Landau levels: microscopic model for the quantum hall effect"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Introduction"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Ady Stern from the Weizmann Institute of Science will introduce the quantum Hall effect.\n",
 "\n",
 "Ady thanks Dr. Dan Arav and Gil Novik from the School of Media Studies of the\n",
 "College of Management  Academic Studies for their help in preparing the videos."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"QC3tQT7MD00\", src_location='3.2intro', res='360')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# The Hall effect"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We now move on to the quantum Hall effect, the mother of all topological effects in condensed matter physics.\n",
 "\n",
 "But let's start from the classical [Hall effect](http://en.wikipedia.org/wiki/Hall_effect), the famous phenomenon by which a current flows perpendicular to an applied voltage, or vice versa a voltage develops perpendicular to a flowing current.\n",
 "\n",
 "How does one get a Hall effect? The key is to break timereversal symmetry. A flowing current breaks timereversal symmetry, while an electric field doesn't. Hence, any system with a Hall effect must somehow break timereversal symmetry.\n",
 "\n",
 "But wait a minute, you might catch me and ask, what about a normal electric current flowing parallel to an electric field? This is what happens in a metal on a regular basis, and a metal does not break timereversal symmetry.\n",
 "\n",
 "The key difference there is that such a longitudinal current breaks timereversal through energy dissipation, which turns into heat that breaks timereversal by the second law of thermodynamics. A Hall current is special in that it is **dissipationless**. We can drive a Hall current without wasting any energy because the current flows perpendicular to the voltage gradient.\n",
 "\n",
 "> Thus to get a Hall effect we must somehow break timereversal symmetry. We will examine the simplest way to achieve this, an external magnetic field."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## How to measure the Hall effect\n",
 "\n",
 "Let's consider a two dimensional gas of electrons immersed in a strong, perpendicular magnetic field. In particular, we take the following geometry, which is called a Hall bar and is routinely used in experiments:\n",
 "\n",
 "![](figures/hall_bar.svg)\n",
 "\n",
 "The electron gas is contacted by six electrodes, numbered in the figure. We can use this Hall bar geometry setup to measure the transport characteristics of the gas, as follows.\n",
 "\n",
 "The transport characteristics are tabulated using the 4 components $\\sigma_{xx},\\sigma_{yy},\\sigma_{xy}$ and $\\sigma_{yx}$ of the socalled conductivity tensor. Once we know the conductivity tensor, we can use it to calculate how the current density $\\mathbf{j} = (j_x,j_y)$ flows in response to the electric field $\\mathbf{E} = (E_x,E_y)$ in the metal, through the equation \n",
 "\n",
 "$$j_\\alpha=\\sum_\\beta \\sigma_{\\alpha\\beta}E_{\\beta}.$$\n",
 "\n",
 "By inverting this set of relations between current densities and electric field, we obtain the resistivities $\\rho_{xx}, \\rho_{xy}, \\dots$, which are more often reported in experimental data. Also, in twodimensional systems there is no real difference between conductance and conductivity (or resistance and resistivity)  they have the same physical units. So the terms are somehow interchangeable.\n",
 "\n",
 "The way to use the Hall bar device is to drive a current $I$ along the $x$ direction, so that there is a current density $j_x=(I/W)$ where $W$ is the width of the sample. There is no current density in the perpendicular direction.\n",
 "\n",
 "We can measure the electric field using the Hall bar geometry from the voltage drops between the probes with voltages $V_{1,2,3,4}$.\n",
 "We can then measure the $x$component of the electric field from the longitudinal voltage drop $V_L\\sim (V_1V_2)$ or $(V_3V_4)$ according to the averaged equation "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "$$E_x \\equiv \\frac{V_1+V_3V_2V_4}{2L}.$$\n",
 "\n",
 "Similarly, we can measure the $y$component of the electric field from the Hall voltage $V_H=(V_1V_3)$ or $(V_2V_4)$. Specifically we can calculate the electric field as: \n",
 "\n",
 "$$E_y \\equiv \\frac{V_1+V_2V_4V_3}{2W}.$$\n",
 "\n",
 "\n",
 "The Hall bar can only measure the conductance completely for isotropic or rotationally invariant systems. If we rotate the system by 90 degrees we can transform $x\\rightarrow y$ and $y\\rightarrow x$. So we expect $\\sigma_{xx}=\\sigma_{yy}=\\sigma_L$, the longitudinal conductance. If we apply this same rotation transformation we conclude that $\\sigma_{xy}=\\sigma_{yx}=\\sigma_H$, the *Hall conductance*. \n",
 "\n",
 "So with rotational invariance the 4 component conductance tensor has only 2 independent components i.e. the longitudinal and Hall conductance. We can calculate these using the two electric fields $E_{x,y}$ that we measure using the Hall bar. \n",
 "To do this, we solve the set of equations $j_y=\\sigma_L E_y  \\sigma_H E_x=0$ and $j_x=\\sigma_L E_x+\\sigma_H E_y$ to obtain $\\sigma_{L,H}$. We obtain the Hall conductance\n",
 "\n",
 "$$\\sigma_H=\\frac{j_x E_y}{E_x^2+E_y^2}.$$"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# The classical Hall effect is a linear effect"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's now try to obtain an alternative expression for the Hall conductance $\\sigma_H$ of our Hall bar. In general we expect the electric and magnetic fields present in our Hall bar to apply a force to the electrons, and increase their velocity. \n",
 "\n",
 "Instead of solving the problem directly, let us make the ansatz that the electrons enter a state, which is obtained from the usual electron ground state by doing a Galilean transformation to a reference frame moving with velocity $\\bf{v}$ with respect to the original reference frame.\n",
 "\n",
 "Since the average velocity of the electrons is $\\bf v$ in the original reference frame, the average force on the electrons is \n",
 "\n",
 "$${\\bf F}= e\\,(\\mathbf{E}+\\mathbf{v}\\times \\mathbf{B}).$$\n",
 "\n",
 "If we want to be a steady state then $\\bf F=0$, which means that ${\\bf v}= (\\mathbf{E}\\times \\mathbf{B})/B^2$. Since the electrons move with an average velocity $\\bf v$, and if $n$ denotes the electron density, we can easily guess that the current density is ${\\bf j}=n e {\\bf v}=(n e/ B) \\,(\\mathbf{E}\\times \\mathbf{z})$.\n",
 "\n",
 "> Comparing with the previous subsection, we can thus conclude that simply based on Galilean invariance, an electron gas in a magnetic field must have a Hall conductance that is given by \n",
 "\n",
 "$$\\sigma_H=n e B^{1}.$$\n",
 "\n",
 "This relation, which says that $\\sigma_H\\propto n$, is extremely general in the sense that it does not depend on how the electrons interact with each other or anything else. It is referred to as the Streda relation. If we define the socalled \"filling factor\" as $\\nu=n h/ e B$ the Hall conductance can be written as a multiple of the quantum of conductance as $\\sigma_H=\\nu \\frac{e^2}{h}$.\n",
 "\n",
 "As you already heard from Ady Stern in the intro video, people have measured the Hall conductance of this exact system to incredible precision. At relatively high density, the Hall conductance of this system behaves itself accordingly and scales linearly with gate voltage, which is tuned to control the density. At low filling factors, one would expect many nonidealities like disorder and interaction to break the Galilean invariance based argument and lead to a Hall conductance $\\sigma_H$ that varies from sample to sample and depends on disorder. "
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = \"What is the longitudinal conductance for the ideal electron gas in a magnetic field?\"\n",
 "answers = [\"Infinity since there are no impurities in the system.\",\n",
 " \"Finite and inversely proportional to the magnetic field like the Hall conductance.\",\n",
 " \"Finite and proportional to density but independent of magnetic field.\",\n",
 " \"Zero since current is perpendicular to electric field.\"\n",
 " ]\n",
 "explanation = \"As we saw the velocity is related to the crossproduct of the electric and magnetic field.\"\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=3, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# The quantum Hall effect: experimental data"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Instead, a completely unexpected result was measured for the first time by Klaus von Klitzing. Typical experimental data looks like this (taken from M.E. Suddards, A. Baumgartner, M. Henini and C. J. Mellor, [New J. Phys. 14 083015](http://iopscience.iop.org/13672630/14/8/083015)):\n",
 "\n",
 "![](figures/QHE.png)\n",
 "\n",
 "> As the average density is varied, the Hall conductance $\\sigma_H$ appears to form plateaus at integer filling fractions $\\nu=1,2,3,\\dots$. These plateaus are incredibly sample independent and occur at the same value in many other materials. At the same time, the longitudinal conductivity appears to vanish except at the transition points between the plateaus. This is the integer \"Quantum Hall effect\". "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "This setup is easy to try to reproduce numerically, but there's one complication:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "syst = qhe_hall_bar(L=60, W=100, w_lead=90, w_vert_lead=28).finalized()\n",
 "p = SimpleNamespace(t=1.0, mu=0.3, mu_lead=0.3, B=None)\n",
 "Bs = np.linspace(0.02, 0.15, 200)\n",
 "num_leads = len(syst.leads)\n",
 "def G(syst, p):\n",
 " smatrix = kwant.smatrix(syst, args=[p])\n",
 " G = [[smatrix.transmission(i, j) for i in range(num_leads)] for j in range(num_leads)]\n",
 " G = np.diag(np.sum(G, axis=0))\n",
 " return calculate_sigmas(G)\n",
 "\n",
 "sigmasxx, sigmasxy = np.array([G(syst, p) for p.B in Bs]).T\n",
 "\n",
 "kdims = [r'$B^{1} [a.u.]$', '$\\sigma_{xx}, \\sigma_{xy}\\,[e^2/h]$']\n",
 "plot_xx = holoviews.Path((1/Bs, sigmasxx), label=r'$\\sigma_{xx}$', kdims=kdims)(style={'color': 'k'})\n",
 "plot_xy = holoviews.Path((1/Bs, sigmasxy), label=r'$\\sigma_{xy}$', kdims=kdims)(style={'color': 'r'})\n",
 "\n",
 "(plot_xx * plot_xy)(plot={'xticks': 0, 'yticks': list(range(8))})"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Numerical systems are so good that the longitudinal conductivity always stays low even at the transition.\n",
 "\n",
 "But other than that small problem everything works just the same."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Quantized Hall conductance from pumping: Laughlin argument"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Why is the quantized Hall conductance $\\sigma_H$ so robust and independent of system details? Clearly there must be a topological argument at play.\n",
 "\n",
 "Soon after the experimental discovery, Laughlin came up with an elegant argument that mapped the Hall conductance problem to a topological pumping problem and in the process explained the robustness. Let us go through this argument.\n",
 "\n",
 "## The Corbino geometry\n",
 "\n",
 "To start with, we imagine doing the Hall measurement in a system cut out as an annulus, which is referred to as the Corbino disk:\n",
 "\n",
 "![](figures/corbino_flux.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We will also try to do the experiment in reverse i.e. apply an electric field along the circumference of the disk and measure the current $I$ in the radial direction, as shown in the figure. The radial current is easy to measure  we just measure the amount of charge $\\Delta Q$ transferred between the inner and outer edges of the Corbino geometry and obtain the radial current $I=\\Delta Q/\\Delta T$, where $\\Delta T$ is the time over which this is done.\n",
 "\n",
 "But how do we apply an electric field in the tangential direction? The easiest way to do this is to apply a timedependent magnetic field in the centre of the disc and use the Faraday effect. \n",
 "\n",
 "We can calculate the electric field from the changing magnetic field using Faraday's law as $\\oint d{\\bf{r}\\cdot\\bf{E}}=\\partial_t \\Phi$, where $\\Phi$ is the magnetic flux resulting from the field in the center of the disk. Assuming that the electric field depends only on the radius $R$ we find that the resulting tangential electric field is given by\n",
 "\n",
 "$$E(R,t)=\\frac{1}{2\\pi R}\\,\\partial_t \\Phi.$$ \n",
 "\n",
 "Given $I$, we can also calculate the other component of the measurement of the Hall conductance $\\sigma_H$ i.e. the radial current density $j=I/(2\\pi R)$ at the same radius $R$ as we calculated the electric field. \n",
 "\n",
 "Now that we know both the circumferential electric field and also the radial current density, the Hall conductance can be measured easily in this geometry as \n",
 "\n",
 "$$\\sigma_H=\\frac{j}{E(r,t)}=\\frac{I}{\\partial_t \\Phi}.$$\n",
 "\n",
 "You might worry that we were a bit simplistic and ignored the longitudinal conductance in this geometry. We could measure the longitudinal conductivity by applying a voltage difference between the inner and outer edges and measuring the resulting radial current $I$. For the remainder of this discussion, we assume that the longitudinal conductivity vanishes as is observed experimentally."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Laughlin pump\n",
 "\n",
 "We are now ready to present the pumping argument to explain why the low temperature Hall effect is quantized.\n",
 "\n",
 "To do this, we change the magnetic field in the center of the Corbino disc so that the flux changes by $\\Delta \\Phi=\\Phi_0=h/e$, i.e. a **flux quantum** over the time $\\Delta T$. (Note that this flux quantum is only half of the superconducting flux quantum that we were using last week. That's because now the current is being carried by electrons and not Cooper pairs. It is customary to use the same symbol $\\Phi_0$ for both, since they often appear in different contexts). Assuming that we have a system with Hall conductance $\\sigma_H$, we obtain the charge transferred as \n",
 "\n",
 "$$\\Delta Q=I \\Delta T=\\sigma_H\\, \\Delta T\\, \\partial_t\\Phi =\\sigma_H\\,\\Delta\\Phi=\\sigma_H\\, \\frac{h}{e}.$$\n",
 "\n",
 "Writing $\\sigma_H=\\nu e^2/h$, we obtain $\\Delta Q=\\nu e$. Since the longitudinal conductance $\\sigma_L=0$, we expect the system to be gapped in the bulk of the disc and we expect the entire charge transfer $\\Delta Q$ to occur between the edges.\n",
 "\n",
 ">Since the flux $\\Phi$ in the center is a flux quantum $\\Phi_0$, the wave functions of the electrons all return to being the same as at $\\Phi=0$. Therefore only an integer number of charges $\\Delta Q=n e$ can be pumped between the edges. This is Laughlin's argument for why the Hall conductance must be quantized as\n",
 "\n",
 "$$\\sigma_{xy}=n e^2/h.$$\n",
 "\n",
 "What you notice at this point is that we basically have a pump similar to the last unit.\n",
 "\n",
 "Here an integer number of charges is pumped from one edge to the other as the flux $\\Phi$ is increased by $\\Phi_0$. As one sees below, one can simulate electrons in a Corbino geometry and check that indeed an integer number of charges is pumped between the edges as the flux $\\Phi$ is changed by $\\Phi_0$.\n",
 "\n"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "W = 20\n",
 "p = SimpleNamespace(t=1, B=2*np.pi/(W+1), phi=None, mu=None)\n",
 "syst = qhe_corbino(r_out=2*W, r_in=20, w_lead=10)\n",
 "mus = np.linspace(0.4, 1.4, 11)\n",
 "holoviews.HoloMap({p.mu: plot_pumping(syst, p) for p.mu in mus}, kdims=[r'$\\mu$'])"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"Experimentally the quantum Hall conductance jumps  what does this mean about the \"\n",
 " \"robustness of the Laughlin pumping argument?\")\n",
 "answers = [\"The Laughlin argument breaks down because it assumes specific values of the magnetic field.\",\n",
 " \"The Laughlin argument assumes there is no longitudinal conductivity.\",\n",
 " \"The Hall conductance is not a topological invariant since it changes.\",\n",
 " \"The flux in the corbino geometry was changed by a value that was not a multiple of the flux quantum.\"\n",
 " ]\n",
 "explanation = (\"The key ingredient in the Laughlin argument was that there is no states at the fermi level in \"\n",
 " \"the bulk which is equivalent to no longitudinal conductivity\")\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Landau levels: a microscopic model for the quantum hall effect"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The general argument so far is great in that it applies to virtually any complicated electron system with interactions and in a real material, but we would probably feel better if we could calculate the Hall conductance directly for some simple system. So let us try to do this for the simplest case of electrons in a magnetic field.\n",
 "\n",
 "For starters, let us forget about the Corbino disk and just ask what do quantum mechanical electrons do in a magnetic field. \n",
 "\n",
 "## Landau levels on the back of an envelope\n",
 "\n",
 "We know what classical electrons do in a perpendicular magnetic field: They go around in *cyclotron orbits*, because of the Lorentz force. The cyclotron radius in a magnetic field of strength $B$ for an electron with velocity $v$ is $r_c = mv/eB$. An electron performing a cyclotron orbit at velocity $v$ has angular momentum $L=mvr_c=eB r^2_c$. In quantum mechanics, however, only orbits with a quantized angular momentum $L=n\\hbar$ will be allowed. From the equality $r^2_c = n\\hbar/eB$ one obtains that only some discrete values are allowed for the radius, $r_n = \\sqrt{n} l_B$, where $l_B = \\sqrt{\\hbar/eB}$ is called the magnetic length.\n",
 "\n",
 "All cyclotron orbits, independent of the radius, circle at the same frequency $\\omega_c=eB/m$. The energy of the electron in this quantized orbit is equal to $L\\omega_c = n\\hbar\\omega_c$. So the energy spectrum really looks like that of a harmonic oscillator. All the energy levels are also shifted up from zero energy by the zeropoint motion of the harmonic oscillator, $\\hbar\\omega_c/2$. We finally obtain that the allowed energy levels are\n",
 "\n",
 "$$E_n = \\hbar \\omega_c \\,\\left(n+\\tfrac{1}{2}\\right)\\,.$$\n",
 "\n",
 "These quantized energy levels of electrons in a magnetic field are called **Landau levels**.\n",
 "\n",
 "You can put many electrons in the same Landau level: one for every flux quantum of the magnetic flux passing through the system. Therefore Landau levels have a huge degeneracy, proportional to the area of the sample.\n",
 "\n",
 "\n",
 "## Landau levels from the Hamiltonian\n",
 "\n",
 "Now that we know the answer in advance, we can solve the Schrödinger equation for electrons in a magnetic field without stress. It will still be important to understand the quantum Hall effect in a bit more detail. The Hamiltonian is\n",
 "\n",
 "$$H=(\\textbf{p}e \\textbf{ A})^2.$$ \n",
 "\n",
 "The vector potential $\\bf{A}$ depends on position, which makes this Hamiltonian complicated to solve in general. For a uniform magnetic field, we can make our life easier by choosing a Landau gauge \n",
 "\n",
 "$$\\textbf{A}(x,y)=\\hat{\\textbf{x}}B y ,$$ \n",
 "\n",
 "where the vector potential does not depend on $x$. In this gauge, the entire Hamiltonian is translationally invariant along the $x$ direction, and therefore commutes with the corresponding momentum $p_x$. This allows us to choose $p_x=\\hbar k$ as a good quantum number, and our two dimensional Hamiltonian reduces to a one dimensional one:\n",
 "\n",
 "$$H(k)=p_y^2+(\\hbar ke B y)^2.$$\n",
 "\n",
 "Apart from a shift of the $y$ coordinate by $y_0(k)=\\hbar k/eB$, this is exactly the Hamiltonian of a simple harmonic oscillator! Its eigenvalues are the Landau levels, which are independent of $k$. The corresponding wave functions are those of the harmonic oscillator along the $y$ direction, and plane waves with momentum $k$ along the $x$ direction. In the $y$ direction, they are localized in space within a length $\\sim l_B$.\n",
 "\n",
 "This gives us another way to understand the quantized Hall conductance for ideal two dimensional electron gases.\n",
 "\n",
 "Now, the electron energies are quantized in Landau levels, and if $n$ Landau levels are filled at a given chemical potential, the filling factor is $\\nu=n$. The Streda formula then predicts the Hall conductance as $\\sigma_H=\\nu e^2/h=n e^2/h$. The longitudinal conductivity must vanish since the gapped system does not allow dissipation of energy in the bulk."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Flux pumping of electrons in a Hall cylinder"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We can now see explicitly how the Laughlin pumping argument works, starting from the microscopic description of electrons in terms of Landau levels. Starting from the formulas we derived, it is a little difficult to do so in the Corbino geometry, which has an angular symmetry rather than a translational symmetry. It is very easy if we consider the Laughlin pump for electrons in a cylinder:\n",
 "\n",
 "![](figures/hall_cylinder.svg)\n",
 "\n",
 "In fact the cylinder drawn above and the Corbino disk are completely equivalent  you can imagine deforming one into the other. The advantage of the cylinder is that we get to keep our $(x, y)$ coordinates. The Hall cylinder that we considered for Laughlin's argument is in fact equivalent to a ribbon in the $(x, y)$ plane, with periodic boundary conditions $x\\equiv x+L$ in the $x$ direction ($L$ is the circumference of the cylinder).\n",
 "The periodic boundary conditions along the $x$ direction discretize the allowed values of $k$ as $k=2\\pi n/L$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "For the Laughlin pumping argument, we need to introduce a flux through the cylinder. Using Stokes' theorem, we know that the line integral of the vector potential around the cylinder must be equal to the flux passing through it, $\\oint \\textbf{dr}\\cdot\\textbf{A(r)}=\\Phi$. So we can introduce a flux through the cylinder by choosing our vector potential $\\bf{A}$ as \n",
 "\n",
 "$$\\textbf{A}(x,y)=(B y +\\Phi/L)\\,\\hat{\\textbf{x}}\\,,$$ \n",
 "\n",
 "very similar to the previous calculation. The resulting Hamiltonian for the states labeled by $n$ is \n",
 "\n",
 "$$H=p_y^2+\\left(\\frac{\\hbar 2\\pi n}{L}e B y\\frac{e\\Phi}{L}\\right)^2\\,.$$\n",
 "\n",
 "\n",
 "Comparing the above equation to the quantum harmonic oscillator, we see that the harmonic oscillator levels \n",
 "must be centered at \n",
 "\n",
 "$$y_0(n) = \\left(n\\frac{\\Phi}{\\Phi_0}\\right)\\frac{h}{e B L}\\,.$$\n",
 "\n",
 ">We see from this that the Landau level wavefunctions are centered around a discrete set of rings at $y_0(n)$ on the cylinder axis that are labelled by the integer $n$. As $\\Phi$ is increased we see that the centers $y_0$ move so that after one flux quantum $\\Delta\\Phi=\\Phi_0=h/e$ all the electrons have moved down by one step along $y$, i.e. $n \\rightarrow n1$. If $n$ Landau levels are filled then a total charge of $\\Delta Q=n e$ will be transferred between the edges, in exact accordance with the Laughlin argument."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We can now look again at the Laughlin pump, monitoring at the same time the Landau levels. You can see that the total pumped charge jumps in integer steps each time a Landau level passes through the Fermi level."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "kwargs = {'ylims': [1.1, 1.1],\n",
 " 'xticks': 0,\n",
 " 'yticks': [1, 0, 1],\n",
 " 'xdim': r'$k$',\n",
 " 'ydim': r'$E$',\n",
 " 'k_x': np.linspace(np.pi, np.pi, 101),\n",
 " 'title': lambda p: \"Landau levels\"}\n",
 "W = 20\n",
 "p = SimpleNamespace(t=1, B=2*np.pi/(W+1), phi=None, mu=None)\n",
 "syst = qhe_corbino(r_out=2*W, r_in=20, w_lead=10)\n",
 "sys1 = qhe_ribbon(W, True)\n",
 "HLine = holoviews.HLine(0)(style={'linestyle': '', 'color': 'r'})\n",
 "mus = np.linspace(0.4, 1.4, 11)\n",
 "hm1 = holoviews.HoloMap({p.mu: plot_pumping(syst, p) for p.mu in mus}, kdims=[r'$\\mu$'])\n",
 "hm2 = holoviews.HoloMap({p.mu: spectrum(sys1, p, **kwargs) for p.mu in mus}, kdims=[r'$\\mu$'])\n",
 "hm1 + hm2 * HLine"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"Consider a cylinder of height $W$, circumference $L$, subject to a magnetic field $B$, \"\n",
 " \"and with 2 Landau levels filled. \"\n",
 " \"Approximately, how many electrons does it contain?\")\n",
 "answers = [\"$2.\\,$\",\n",
 " \"$2 W/L\\,.$\",\n",
 " \"$2 B WL / \\Phi_0\\, $.\",\n",
 " \"$ B L^2/\\Phi_0\\,$.\"]\n",
 "explanation = \"Based on the form of the Hamiltonian, $y$ goes from $0$ to $W$ and therefore $n$ goes from 0 to $B W L/\\Phi_0$.\"\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=2, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Summary"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"2u8_2isyi7o\", src_location='3.2summary', res='360')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Questions about what you learned? Ask them below**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Questions\", \"Laughlin argument\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w3_pump_QHE/Laughlinargument.md b/w3_pump_QHE/Laughlinargument.md
new file mode 100644
index 0000000..a07e354
 /dev/null
+++ b/w3_pump_QHE/Laughlinargument.md
@@ 0,0 +1,569 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+%output size = 150
+
+
+def qhe_corbino(r_out=100, r_in=65, w_lead=10):
+ """Create corbino disk.
+
+ Square lattice, one orbital per site.
+ Returns kwant system.
+
+ Arguments required in onsite/hoppings:
+ t, mu, mu_lead, B, phi
+ """
+ # ring shape
+ def ring(pos):
+ (x, y) = pos
+ rsq = x ** 2 + y ** 2
+ return (r_in ** 2 < rsq < r_out ** 2)
+
+ # Onsite and hoppings
+ def onsite(site, p):
+ (x, y) = site.pos
+ return 4 * p.t  p.mu
+
+ def crosses_branchcut(hop):
+ x1, y1 = hop[0].pos
+ x2, y2 = hop[1].pos
+ return y1 < 0 and x1 > 0.5 and x2 < 0.5
+
+ def hopping(site1, site2, p):
+ x1, y1 = site1.pos
+ x2, y2 = site2.pos
+ # Check for correctness!
+ return p.t * np.exp(0.5j * p.B * (x1  x2) * (y1 + y2))
+
+ def branchcut_hopping(site1, site2, p):
+ return hopping(site1, site2, p) * np.exp(1j * p.phi)
+
+ # Building system
+ lat = kwant.lattice.square()
+ syst = kwant.Builder()
+
+ syst[lat.shape(ring, (0, r_in + 1))] = onsite
+ syst[lat.neighbors()] = hopping
+
+ # adding special hoppings
+ def hops_across_cut(syst):
+ for hop in kwant.builder.HoppingKind((1, 0), lat, lat)(syst):
+ if crosses_branchcut(hop):
+ yield hop
+ syst[hops_across_cut] = branchcut_hopping
+
+ # Attaching leads
+ sym_lead = kwant.TranslationalSymmetry((1, 0))
+ lead = kwant.Builder(sym_lead)
+
+ def lead_shape(pos):
+ (x, y) = pos
+ return (w_lead / 2 < y < w_lead / 2)
+
+ lead[lat.shape(lead_shape, (0, 0))] = lambda site, p: 4 * p.t  p.mu_lead
+ lead[lat.neighbors()] = lambda site1, site2, p: p.t
+
+ #### Attach the leads and return the system. ####
+ syst.attach_lead(lead)
+ syst.attach_lead(lead, origin=lat(0, 0))
+
+ return syst
+
+
+def total_charge(value_array):
+ determinants = [np.linalg.det(s) for s in value_array]
+ charge = np.cumsum(np.angle(determinants / np.roll(determinants, 1)))
+ return charge / (2 * np.pi)
+
+
+def qhe_ribbon(W, periodic=False):
+ """ Creates ribbon system
+
+ If we have periodic boundary conditions, the flux through a single
+ unit cell is quantized.
+ """
+ W = 2 * (W // 2)
+
+ def ribbon_shape(pos):
+ (x, y) = pos
+ return (W / 2 <= y <= W / 2)
+
+ def onsite(site, p):
+ (x, y) = site.pos
+ return 4 * p.t  p.mu
+
+ def hopping(site1, site2, p):
+ x1, y1 = site1.pos
+ x2, y2 = site2.pos
+ return p.t * np.exp(0.5j * p.B * (x1  x2) * (y1 + y2))
+
+ def hopping_periodic(site1, site2, p):
+ x1, y1 = site1.pos
+ x2, y2 = site2.pos
+ return p.t * np.exp(1j * np.pi / (W + 1) * np.round((W + 1) * p.B / (2 * np.pi)) * (x1  x2) * (y1 + y2))
+
+ lat = kwant.lattice.square()
+ sym_syst = kwant.TranslationalSymmetry((1, 0))
+ syst = kwant.Builder(sym_syst)
+
+ syst[lat.shape(ribbon_shape, (0, 0))] = onsite
+
+ if periodic:
+ syst[lat.neighbors()] = hopping_periodic
+ syst[lat(0,  W / 2), lat(0, + W / 2)] = hopping_periodic
+ else:
+ syst[lat.neighbors()] = hopping
+
+ return syst
+
+# Quantum hall bar codes
+
+
+def qhe_hall_bar(L=50, W=10, w_lead=10, w_vert_lead=None):
+ """Create a hall bar system.
+
+ Square lattice, one orbital per site.
+ Returns kwant system.
+
+ Arguments required in onsite/hoppings:
+ t, mu, mu_lead
+ """
+
+ L = 2 * (L // 2)
+ W = 2 * (W // 2)
+ w_lead = 2 * (w_lead // 2)
+ if w_vert_lead is None:
+ w_vert_lead = w_lead
+ else:
+ w_vert_lead = 2 * (w_vert_lead // 2)
+
+ # bar shape
+ def bar(pos):
+ (x, y) = pos
+ return (x >= L / 2 and x <= L / 2) and (y >= W / 2 and y <= W / 2)
+
+ # Onsite and hoppings
+ def onsite(site, p):
+ (x, y) = site.pos
+ return 4 * p.t  p.mu
+
+ def hopping_Ax(site1, site2, p):
+ x1, y1 = site1.pos
+ x2, y2 = site2.pos
+ return p.t * np.exp(0.5j * p.B * (x1 + x2) * (y1  y2))
+
+ def make_lead_hop_y(x0):
+ def hopping_Ay(site1, site2, p):
+ x1, y1 = site1.pos
+ x2, y2 = site2.pos
+ return p.t * np.exp(1j * p.B * x0 * (y1  y2))
+ return hopping_Ay
+
+ def lead_hop_vert(site1, site2, p):
+ return p.t
+
+ # Building system
+ lat = kwant.lattice.square()
+ syst = kwant.Builder()
+
+ syst[lat.shape(bar, (0, 0))] = onsite
+ syst[lat.neighbors()] = hopping_Ax
+
+ # Attaching leads
+ sym_lead = kwant.TranslationalSymmetry((1, 0))
+ lead = kwant.Builder(sym_lead)
+
+ def lead_shape(pos):
+ (x, y) = pos
+ return (w_lead / 2 <= y <= w_lead / 2)
+
+ lead_onsite = lambda site, p: 4 * p.t  p.mu_lead
+
+ sym_lead_vertical = kwant.TranslationalSymmetry((0, 1))
+ lead_vertical1 = kwant.Builder(sym_lead_vertical)
+ lead_vertical2 = kwant.Builder(sym_lead_vertical)
+
+ def lead_shape_vertical1(pos):
+ (x, y) = pos
+ return (L / 4  w_vert_lead / 2 <= x <= L / 4 + w_vert_lead / 2)
+
+ def lead_shape_vertical2(pos):
+ (x, y) = pos
+ return (+L / 4  w_vert_lead / 2 <= x <= +L / 4 + w_vert_lead / 2)
+
+ lead_vertical1[lat.shape(lead_shape_vertical1, (L / 4, 0))] = lead_onsite
+ lead_vertical1[lat.neighbors()] = lead_hop_vert
+ lead_vertical2[lat.shape(lead_shape_vertical2, (L / 4, 0))] = lead_onsite
+ lead_vertical2[lat.neighbors()] = lead_hop_vert
+
+ syst.attach_lead(lead_vertical1)
+ syst.attach_lead(lead_vertical2)
+
+ syst.attach_lead(lead_vertical1.reversed())
+ syst.attach_lead(lead_vertical2.reversed())
+
+ lead[lat.shape(lead_shape, (1, 0))] = lead_onsite
+ lead[lat.neighbors()] = make_lead_hop_y(L / 2)
+
+ syst.attach_lead(lead)
+
+ lead = kwant.Builder(sym_lead)
+ lead[lat.shape(lead_shape, (1, 0))] = lead_onsite
+ lead[lat.neighbors()] = make_lead_hop_y(L / 2)
+
+ syst.attach_lead(lead.reversed())
+
+ return syst
+
+
+def calculate_sigmas(G):
+ # reduce by one dimension G > G[temp, temp]
+ temp = [0, 1, 3, 4, 5]
+ G = G[temp, :]
+ G = G[:, temp]
+ # invert R = G^1
+ # find out whether it is a numpy object
+ r = np.linalg.inv(G)
+ # Voltages follow: V = R I[temp]
+ V = r @ np.array([0, 0, 0, 1, 1])
+ # Completely solved the six terminal system.
+ # Consider the 2x2 conductance now: Use I = sigma U
+ E_x = V[1]  V[0]
+ E_y = V[1]  V[3]
+ # formula above
+ sigma_xx = E_x / (E_x**2 + E_y**2)
+ sigma_xy = E_y / (E_x**2 + E_y**2)
+ return sigma_xx, sigma_xy
+
+
+def plot_pumping(syst, p):
+ p.mu_lead = p.mu
+ phis = np.linspace(0, 2 * np.pi, 40)
+ syst = syst.finalized()
+ rs = [kwant.smatrix(syst, energy=0.0, args=[p]).submatrix(1, 1) for p.phi in phis]
+ charges = total_charge(rs)
+ style = {'xticks': [0, 1], 'yticks': [0, 1, 2, 3], 'aspect': 'square'}
+ kdims = ['$\phi/2\pi$', '$q_{pump}$']
+ title = '$\mu = {:.2}$, $\sigma_H = {:} \cdot e^2/h$'.format(p.mu, int(round(charges[1])))
+ return holoviews.Path((phis / (2 * np.pi), charges), kdims=kdims, label=title)(plot=style)[:, 0:3.1]
+
+```
+
+## We present an argument for the robustness of the quantum hall effect for electrons: Laughlin argument
+* Observation of Quantum Hall
+* Quantized Hall conductance from pumping: Laughlin argument
+* Landau levels: microscopic model for the quantum hall effect
+
+# Introduction
+
+Ady Stern from the Weizmann Institute of Science will introduce the quantum Hall effect.
+
+Ady thanks Dr. Dan Arav and Gil Novik from the School of Media Studies of the
+College of Management  Academic Studies for their help in preparing the videos.
+
+
+```python
+MoocVideo("QC3tQT7MD00", src_location='3.2intro', res='360')
+```
+
+# The Hall effect
+
+We now move on to the quantum Hall effect, the mother of all topological effects in condensed matter physics.
+
+But let's start from the classical [Hall effect](http://en.wikipedia.org/wiki/Hall_effect), the famous phenomenon by which a current flows perpendicular to an applied voltage, or vice versa a voltage develops perpendicular to a flowing current.
+
+How does one get a Hall effect? The key is to break timereversal symmetry. A flowing current breaks timereversal symmetry, while an electric field doesn't. Hence, any system with a Hall effect must somehow break timereversal symmetry.
+
+But wait a minute, you might catch me and ask, what about a normal electric current flowing parallel to an electric field? This is what happens in a metal on a regular basis, and a metal does not break timereversal symmetry.
+
+The key difference there is that such a longitudinal current breaks timereversal through energy dissipation, which turns into heat that breaks timereversal by the second law of thermodynamics. A Hall current is special in that it is **dissipationless**. We can drive a Hall current without wasting any energy because the current flows perpendicular to the voltage gradient.
+
+> Thus to get a Hall effect we must somehow break timereversal symmetry. We will examine the simplest way to achieve this, an external magnetic field.
+
+## How to measure the Hall effect
+
+Let's consider a two dimensional gas of electrons immersed in a strong, perpendicular magnetic field. In particular, we take the following geometry, which is called a Hall bar and is routinely used in experiments:
+
+![](figures/hall_bar.svg)
+
+The electron gas is contacted by six electrodes, numbered in the figure. We can use this Hall bar geometry setup to measure the transport characteristics of the gas, as follows.
+
+The transport characteristics are tabulated using the 4 components $\sigma_{xx},\sigma_{yy},\sigma_{xy}$ and $\sigma_{yx}$ of the socalled conductivity tensor. Once we know the conductivity tensor, we can use it to calculate how the current density $\mathbf{j} = (j_x,j_y)$ flows in response to the electric field $\mathbf{E} = (E_x,E_y)$ in the metal, through the equation
+
+$$j_\alpha=\sum_\beta \sigma_{\alpha\beta}E_{\beta}.$$
+
+By inverting this set of relations between current densities and electric field, we obtain the resistivities $\rho_{xx}, \rho_{xy}, \dots$, which are more often reported in experimental data. Also, in twodimensional systems there is no real difference between conductance and conductivity (or resistance and resistivity)  they have the same physical units. So the terms are somehow interchangeable.
+
+The way to use the Hall bar device is to drive a current $I$ along the $x$ direction, so that there is a current density $j_x=(I/W)$ where $W$ is the width of the sample. There is no current density in the perpendicular direction.
+
+We can measure the electric field using the Hall bar geometry from the voltage drops between the probes with voltages $V_{1,2,3,4}$.
+We can then measure the $x$component of the electric field from the longitudinal voltage drop $V_L\sim (V_1V_2)$ or $(V_3V_4)$ according to the averaged equation
+
+$$E_x \equiv \frac{V_1+V_3V_2V_4}{2L}.$$
+
+Similarly, we can measure the $y$component of the electric field from the Hall voltage $V_H=(V_1V_3)$ or $(V_2V_4)$. Specifically we can calculate the electric field as:
+
+$$E_y \equiv \frac{V_1+V_2V_4V_3}{2W}.$$
+
+
+The Hall bar can only measure the conductance completely for isotropic or rotationally invariant systems. If we rotate the system by 90 degrees we can transform $x\rightarrow y$ and $y\rightarrow x$. So we expect $\sigma_{xx}=\sigma_{yy}=\sigma_L$, the longitudinal conductance. If we apply this same rotation transformation we conclude that $\sigma_{xy}=\sigma_{yx}=\sigma_H$, the *Hall conductance*.
+
+So with rotational invariance the 4 component conductance tensor has only 2 independent components i.e. the longitudinal and Hall conductance. We can calculate these using the two electric fields $E_{x,y}$ that we measure using the Hall bar.
+To do this, we solve the set of equations $j_y=\sigma_L E_y  \sigma_H E_x=0$ and $j_x=\sigma_L E_x+\sigma_H E_y$ to obtain $\sigma_{L,H}$. We obtain the Hall conductance
+
+$$\sigma_H=\frac{j_x E_y}{E_x^2+E_y^2}.$$
+
+# The classical Hall effect is a linear effect
+
+Let's now try to obtain an alternative expression for the Hall conductance $\sigma_H$ of our Hall bar. In general we expect the electric and magnetic fields present in our Hall bar to apply a force to the electrons, and increase their velocity.
+
+Instead of solving the problem directly, let us make the ansatz that the electrons enter a state, which is obtained from the usual electron ground state by doing a Galilean transformation to a reference frame moving with velocity $\bf{v}$ with respect to the original reference frame.
+
+Since the average velocity of the electrons is $\bf v$ in the original reference frame, the average force on the electrons is
+
+$${\bf F}= e\,(\mathbf{E}+\mathbf{v}\times \mathbf{B}).$$
+
+If we want to be a steady state then $\bf F=0$, which means that ${\bf v}= (\mathbf{E}\times \mathbf{B})/B^2$. Since the electrons move with an average velocity $\bf v$, and if $n$ denotes the electron density, we can easily guess that the current density is ${\bf j}=n e {\bf v}=(n e/ B) \,(\mathbf{E}\times \mathbf{z})$.
+
+> Comparing with the previous subsection, we can thus conclude that simply based on Galilean invariance, an electron gas in a magnetic field must have a Hall conductance that is given by
+
+$$\sigma_H=n e B^{1}.$$
+
+This relation, which says that $\sigma_H\propto n$, is extremely general in the sense that it does not depend on how the electrons interact with each other or anything else. It is referred to as the Streda relation. If we define the socalled "filling factor" as $\nu=n h/ e B$ the Hall conductance can be written as a multiple of the quantum of conductance as $\sigma_H=\nu \frac{e^2}{h}$.
+
+As you already heard from Ady Stern in the intro video, people have measured the Hall conductance of this exact system to incredible precision. At relatively high density, the Hall conductance of this system behaves itself accordingly and scales linearly with gate voltage, which is tuned to control the density. At low filling factors, one would expect many nonidealities like disorder and interaction to break the Galilean invariance based argument and lead to a Hall conductance $\sigma_H$ that varies from sample to sample and depends on disorder.
+
+
+```python
+question = "What is the longitudinal conductance for the ideal electron gas in a magnetic field?"
+answers = ["Infinity since there are no impurities in the system.",
+ "Finite and inversely proportional to the magnetic field like the Hall conductance.",
+ "Finite and proportional to density but independent of magnetic field.",
+ "Zero since current is perpendicular to electric field."
+ ]
+explanation = "As we saw the velocity is related to the crossproduct of the electric and magnetic field."
+MoocMultipleChoiceAssessment(question, answers, correct_answer=3, explanation=explanation)
+```
+
+# The quantum Hall effect: experimental data
+
+Instead, a completely unexpected result was measured for the first time by Klaus von Klitzing. Typical experimental data looks like this (taken from M.E. Suddards, A. Baumgartner, M. Henini and C. J. Mellor, [New J. Phys. 14 083015](http://iopscience.iop.org/13672630/14/8/083015)):
+
+![](figures/QHE.png)
+
+> As the average density is varied, the Hall conductance $\sigma_H$ appears to form plateaus at integer filling fractions $\nu=1,2,3,\dots$. These plateaus are incredibly sample independent and occur at the same value in many other materials. At the same time, the longitudinal conductivity appears to vanish except at the transition points between the plateaus. This is the integer "Quantum Hall effect".
+
+This setup is easy to try to reproduce numerically, but there's one complication:
+
+
+```python
+syst = qhe_hall_bar(L=60, W=100, w_lead=90, w_vert_lead=28).finalized()
+p = SimpleNamespace(t=1.0, mu=0.3, mu_lead=0.3, B=None)
+Bs = np.linspace(0.02, 0.15, 200)
+num_leads = len(syst.leads)
+def G(syst, p):
+ smatrix = kwant.smatrix(syst, args=[p])
+ G = [[smatrix.transmission(i, j) for i in range(num_leads)] for j in range(num_leads)]
+ G = np.diag(np.sum(G, axis=0))
+ return calculate_sigmas(G)
+
+sigmasxx, sigmasxy = np.array([G(syst, p) for p.B in Bs]).T
+
+kdims = [r'$B^{1} [a.u.]$', '$\sigma_{xx}, \sigma_{xy}\,[e^2/h]$']
+plot_xx = holoviews.Path((1/Bs, sigmasxx), label=r'$\sigma_{xx}$', kdims=kdims)(style={'color': 'k'})
+plot_xy = holoviews.Path((1/Bs, sigmasxy), label=r'$\sigma_{xy}$', kdims=kdims)(style={'color': 'r'})
+
+(plot_xx * plot_xy)(plot={'xticks': 0, 'yticks': list(range(8))})
+```
+
+Numerical systems are so good that the longitudinal conductivity always stays low even at the transition.
+
+But other than that small problem everything works just the same.
+
+# Quantized Hall conductance from pumping: Laughlin argument
+
+Why is the quantized Hall conductance $\sigma_H$ so robust and independent of system details? Clearly there must be a topological argument at play.
+
+Soon after the experimental discovery, Laughlin came up with an elegant argument that mapped the Hall conductance problem to a topological pumping problem and in the process explained the robustness. Let us go through this argument.
+
+## The Corbino geometry
+
+To start with, we imagine doing the Hall measurement in a system cut out as an annulus, which is referred to as the Corbino disk:
+
+![](figures/corbino_flux.svg)
+
+We will also try to do the experiment in reverse i.e. apply an electric field along the circumference of the disk and measure the current $I$ in the radial direction, as shown in the figure. The radial current is easy to measure  we just measure the amount of charge $\Delta Q$ transferred between the inner and outer edges of the Corbino geometry and obtain the radial current $I=\Delta Q/\Delta T$, where $\Delta T$ is the time over which this is done.
+
+But how do we apply an electric field in the tangential direction? The easiest way to do this is to apply a timedependent magnetic field in the centre of the disc and use the Faraday effect.
+
+We can calculate the electric field from the changing magnetic field using Faraday's law as $\oint d{\bf{r}\cdot\bf{E}}=\partial_t \Phi$, where $\Phi$ is the magnetic flux resulting from the field in the center of the disk. Assuming that the electric field depends only on the radius $R$ we find that the resulting tangential electric field is given by
+
+$$E(R,t)=\frac{1}{2\pi R}\,\partial_t \Phi.$$
+
+Given $I$, we can also calculate the other component of the measurement of the Hall conductance $\sigma_H$ i.e. the radial current density $j=I/(2\pi R)$ at the same radius $R$ as we calculated the electric field.
+
+Now that we know both the circumferential electric field and also the radial current density, the Hall conductance can be measured easily in this geometry as
+
+$$\sigma_H=\frac{j}{E(r,t)}=\frac{I}{\partial_t \Phi}.$$
+
+You might worry that we were a bit simplistic and ignored the longitudinal conductance in this geometry. We could measure the longitudinal conductivity by applying a voltage difference between the inner and outer edges and measuring the resulting radial current $I$. For the remainder of this discussion, we assume that the longitudinal conductivity vanishes as is observed experimentally.
+
+## Laughlin pump
+
+We are now ready to present the pumping argument to explain why the low temperature Hall effect is quantized.
+
+To do this, we change the magnetic field in the center of the Corbino disc so that the flux changes by $\Delta \Phi=\Phi_0=h/e$, i.e. a **flux quantum** over the time $\Delta T$. (Note that this flux quantum is only half of the superconducting flux quantum that we were using last week. That's because now the current is being carried by electrons and not Cooper pairs. It is customary to use the same symbol $\Phi_0$ for both, since they often appear in different contexts). Assuming that we have a system with Hall conductance $\sigma_H$, we obtain the charge transferred as
+
+$$\Delta Q=I \Delta T=\sigma_H\, \Delta T\, \partial_t\Phi =\sigma_H\,\Delta\Phi=\sigma_H\, \frac{h}{e}.$$
+
+Writing $\sigma_H=\nu e^2/h$, we obtain $\Delta Q=\nu e$. Since the longitudinal conductance $\sigma_L=0$, we expect the system to be gapped in the bulk of the disc and we expect the entire charge transfer $\Delta Q$ to occur between the edges.
+
+>Since the flux $\Phi$ in the center is a flux quantum $\Phi_0$, the wave functions of the electrons all return to being the same as at $\Phi=0$. Therefore only an integer number of charges $\Delta Q=n e$ can be pumped between the edges. This is Laughlin's argument for why the Hall conductance must be quantized as
+
+$$\sigma_{xy}=n e^2/h.$$
+
+What you notice at this point is that we basically have a pump similar to the last unit.
+
+Here an integer number of charges is pumped from one edge to the other as the flux $\Phi$ is increased by $\Phi_0$. As one sees below, one can simulate electrons in a Corbino geometry and check that indeed an integer number of charges is pumped between the edges as the flux $\Phi$ is changed by $\Phi_0$.
+
+
+
+
+```python
+W = 20
+p = SimpleNamespace(t=1, B=2*np.pi/(W+1), phi=None, mu=None)
+syst = qhe_corbino(r_out=2*W, r_in=20, w_lead=10)
+mus = np.linspace(0.4, 1.4, 11)
+holoviews.HoloMap({p.mu: plot_pumping(syst, p) for p.mu in mus}, kdims=[r'$\mu$'])
+```
+
+
+```python
+question = ("Experimentally the quantum Hall conductance jumps  what does this mean about the "
+ "robustness of the Laughlin pumping argument?")
+answers = ["The Laughlin argument breaks down because it assumes specific values of the magnetic field.",
+ "The Laughlin argument assumes there is no longitudinal conductivity.",
+ "The Hall conductance is not a topological invariant since it changes.",
+ "The flux in the corbino geometry was changed by a value that was not a multiple of the flux quantum."
+ ]
+explanation = ("The key ingredient in the Laughlin argument was that there is no states at the fermi level in "
+ "the bulk which is equivalent to no longitudinal conductivity")
+MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)
+```
+
+# Landau levels: a microscopic model for the quantum hall effect
+
+The general argument so far is great in that it applies to virtually any complicated electron system with interactions and in a real material, but we would probably feel better if we could calculate the Hall conductance directly for some simple system. So let us try to do this for the simplest case of electrons in a magnetic field.
+
+For starters, let us forget about the Corbino disk and just ask what do quantum mechanical electrons do in a magnetic field.
+
+## Landau levels on the back of an envelope
+
+We know what classical electrons do in a perpendicular magnetic field: They go around in *cyclotron orbits*, because of the Lorentz force. The cyclotron radius in a magnetic field of strength $B$ for an electron with velocity $v$ is $r_c = mv/eB$. An electron performing a cyclotron orbit at velocity $v$ has angular momentum $L=mvr_c=eB r^2_c$. In quantum mechanics, however, only orbits with a quantized angular momentum $L=n\hbar$ will be allowed. From the equality $r^2_c = n\hbar/eB$ one obtains that only some discrete values are allowed for the radius, $r_n = \sqrt{n} l_B$, where $l_B = \sqrt{\hbar/eB}$ is called the magnetic length.
+
+All cyclotron orbits, independent of the radius, circle at the same frequency $\omega_c=eB/m$. The energy of the electron in this quantized orbit is equal to $L\omega_c = n\hbar\omega_c$. So the energy spectrum really looks like that of a harmonic oscillator. All the energy levels are also shifted up from zero energy by the zeropoint motion of the harmonic oscillator, $\hbar\omega_c/2$. We finally obtain that the allowed energy levels are
+
+$$E_n = \hbar \omega_c \,\left(n+\tfrac{1}{2}\right)\,.$$
+
+These quantized energy levels of electrons in a magnetic field are called **Landau levels**.
+
+You can put many electrons in the same Landau level: one for every flux quantum of the magnetic flux passing through the system. Therefore Landau levels have a huge degeneracy, proportional to the area of the sample.
+
+
+## Landau levels from the Hamiltonian
+
+Now that we know the answer in advance, we can solve the Schrödinger equation for electrons in a magnetic field without stress. It will still be important to understand the quantum Hall effect in a bit more detail. The Hamiltonian is
+
+$$H=(\textbf{p}e \textbf{ A})^2.$$
+
+The vector potential $\bf{A}$ depends on position, which makes this Hamiltonian complicated to solve in general. For a uniform magnetic field, we can make our life easier by choosing a Landau gauge
+
+$$\textbf{A}(x,y)=\hat{\textbf{x}}B y ,$$
+
+where the vector potential does not depend on $x$. In this gauge, the entire Hamiltonian is translationally invariant along the $x$ direction, and therefore commutes with the corresponding momentum $p_x$. This allows us to choose $p_x=\hbar k$ as a good quantum number, and our two dimensional Hamiltonian reduces to a one dimensional one:
+
+$$H(k)=p_y^2+(\hbar ke B y)^2.$$
+
+Apart from a shift of the $y$ coordinate by $y_0(k)=\hbar k/eB$, this is exactly the Hamiltonian of a simple harmonic oscillator! Its eigenvalues are the Landau levels, which are independent of $k$. The corresponding wave functions are those of the harmonic oscillator along the $y$ direction, and plane waves with momentum $k$ along the $x$ direction. In the $y$ direction, they are localized in space within a length $\sim l_B$.
+
+This gives us another way to understand the quantized Hall conductance for ideal two dimensional electron gases.
+
+Now, the electron energies are quantized in Landau levels, and if $n$ Landau levels are filled at a given chemical potential, the filling factor is $\nu=n$. The Streda formula then predicts the Hall conductance as $\sigma_H=\nu e^2/h=n e^2/h$. The longitudinal conductivity must vanish since the gapped system does not allow dissipation of energy in the bulk.
+
+# Flux pumping of electrons in a Hall cylinder
+
+We can now see explicitly how the Laughlin pumping argument works, starting from the microscopic description of electrons in terms of Landau levels. Starting from the formulas we derived, it is a little difficult to do so in the Corbino geometry, which has an angular symmetry rather than a translational symmetry. It is very easy if we consider the Laughlin pump for electrons in a cylinder:
+
+![](figures/hall_cylinder.svg)
+
+In fact the cylinder drawn above and the Corbino disk are completely equivalent  you can imagine deforming one into the other. The advantage of the cylinder is that we get to keep our $(x, y)$ coordinates. The Hall cylinder that we considered for Laughlin's argument is in fact equivalent to a ribbon in the $(x, y)$ plane, with periodic boundary conditions $x\equiv x+L$ in the $x$ direction ($L$ is the circumference of the cylinder).
+The periodic boundary conditions along the $x$ direction discretize the allowed values of $k$ as $k=2\pi n/L$.
+
+For the Laughlin pumping argument, we need to introduce a flux through the cylinder. Using Stokes' theorem, we know that the line integral of the vector potential around the cylinder must be equal to the flux passing through it, $\oint \textbf{dr}\cdot\textbf{A(r)}=\Phi$. So we can introduce a flux through the cylinder by choosing our vector potential $\bf{A}$ as
+
+$$\textbf{A}(x,y)=(B y +\Phi/L)\,\hat{\textbf{x}}\,,$$
+
+very similar to the previous calculation. The resulting Hamiltonian for the states labeled by $n$ is
+
+$$H=p_y^2+\left(\frac{\hbar 2\pi n}{L}e B y\frac{e\Phi}{L}\right)^2\,.$$
+
+
+Comparing the above equation to the quantum harmonic oscillator, we see that the harmonic oscillator levels
+must be centered at
+
+$$y_0(n) = \left(n\frac{\Phi}{\Phi_0}\right)\frac{h}{e B L}\,.$$
+
+>We see from this that the Landau level wavefunctions are centered around a discrete set of rings at $y_0(n)$ on the cylinder axis that are labelled by the integer $n$. As $\Phi$ is increased we see that the centers $y_0$ move so that after one flux quantum $\Delta\Phi=\Phi_0=h/e$ all the electrons have moved down by one step along $y$, i.e. $n \rightarrow n1$. If $n$ Landau levels are filled then a total charge of $\Delta Q=n e$ will be transferred between the edges, in exact accordance with the Laughlin argument.
+
+We can now look again at the Laughlin pump, monitoring at the same time the Landau levels. You can see that the total pumped charge jumps in integer steps each time a Landau level passes through the Fermi level.
+
+
+```python
+kwargs = {'ylims': [1.1, 1.1],
+ 'xticks': 0,
+ 'yticks': [1, 0, 1],
+ 'xdim': r'$k$',
+ 'ydim': r'$E$',
+ 'k_x': np.linspace(np.pi, np.pi, 101),
+ 'title': lambda p: "Landau levels"}
+W = 20
+p = SimpleNamespace(t=1, B=2*np.pi/(W+1), phi=None, mu=None)
+syst = qhe_corbino(r_out=2*W, r_in=20, w_lead=10)
+sys1 = qhe_ribbon(W, True)
+HLine = holoviews.HLine(0)(style={'linestyle': '', 'color': 'r'})
+mus = np.linspace(0.4, 1.4, 11)
+hm1 = holoviews.HoloMap({p.mu: plot_pumping(syst, p) for p.mu in mus}, kdims=[r'$\mu$'])
+hm2 = holoviews.HoloMap({p.mu: spectrum(sys1, p, **kwargs) for p.mu in mus}, kdims=[r'$\mu$'])
+hm1 + hm2 * HLine
+```
+
+
+```python
+question = ("Consider a cylinder of height $W$, circumference $L$, subject to a magnetic field $B$, "
+ "and with 2 Landau levels filled. "
+ "Approximately, how many electrons does it contain?")
+answers = ["$2.\,$",
+ "$2 W/L\,.$",
+ "$2 B WL / \Phi_0\, $.",
+ "$ B L^2/\Phi_0\,$."]
+explanation = "Based on the form of the Hamiltonian, $y$ goes from $0$ to $W$ and therefore $n$ goes from 0 to $B W L/\Phi_0$."
+MoocMultipleChoiceAssessment(question, answers, correct_answer=2, explanation=explanation)
+```
+
+# Summary
+
+
+```python
+MoocVideo("2u8_2isyi7o", src_location='3.2summary', res='360')
+```
+
+**Questions about what you learned? Ask them below**
+
+
+```python
+MoocDiscussion("Questions", "Laughlin argument")
+```
diff git a/w3_pump_QHE/QHEedgestates.ipynb b/w3_pump_QHE/QHEedgestates.ipynb
deleted file mode 100644
index 41d659e..0000000
 a/w3_pump_QHE/QHEedgestates.ipynb
+++ /dev/null
@@ 1,588 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "%output size=150\n",
 "pi_ticks = [(np.pi, r'$\\pi$'), (0, '0'), (np.pi, r'$\\pi$')]\n",
 "\n",
 "def qhe_hall_bar(L=50, W=10, w_lead=10, w_vert_lead=None):\n",
 " \"\"\"Create a hall bar system. \n",
 "\n",
 " Square lattice, one orbital per site.\n",
 " Returns finalized kwant system.\n",
 "\n",
 " Arguments required in onsite/hoppings: \n",
 " t, mu, mu_lead\n",
 " \"\"\"\n",
 " L = 2 * (L // 2)\n",
 " W = 2 * (W // 2)\n",
 " w_lead = 2 * (w_lead // 2)\n",
 " if w_vert_lead is None:\n",
 " w_vert_lead = w_lead\n",
 " else:\n",
 " w_vert_lead = 2 * (w_vert_lead // 2)\n",
 "\n",
 " # bar shape\n",
 " def bar(pos):\n",
 " (x, y) = pos\n",
 " return (x >= L / 2 and x <= L / 2) and (y >= W / 2 and y <= W / 2)\n",
 "\n",
 " # Onsite and hoppings\n",
 " def onsite(site, p):\n",
 " (x, y) = site.pos\n",
 " return 4 * p.t  p.mu\n",
 "\n",
 " def hopping_Ax(site1, site2, p):\n",
 " xt, yt = site1.pos\n",
 " xs, ys = site2.pos\n",
 " return p.t * np.exp(0.5j * p.B * (xt + xs) * (yt  ys))\n",
 "\n",
 " def make_lead_hop_y(x0):\n",
 " def hopping_Ay(site1, site2, p):\n",
 " xt, yt = site1.pos\n",
 " xs, ys = site2.pos\n",
 " return p.t * np.exp(1j * p.B * x0 * (yt  ys))\n",
 " return hopping_Ay\n",
 "\n",
 " def lead_hop_vert(site1, site2, p):\n",
 " return p.t\n",
 "\n",
 " # Building system\n",
 " lat = kwant.lattice.square()\n",
 " syst = kwant.Builder()\n",
 "\n",
 " syst[lat.shape(bar, (0, 0))] = onsite\n",
 " syst[lat.neighbors()] = hopping_Ax\n",
 "\n",
 " # Attaching leads\n",
 " sym_lead = kwant.TranslationalSymmetry((1, 0))\n",
 " lead = kwant.Builder(sym_lead)\n",
 "\n",
 " def lead_shape(pos):\n",
 " (x, y) = pos\n",
 " return (w_lead / 2 <= y <= w_lead / 2)\n",
 "\n",
 " lead_onsite = lambda site, p: 4 * p.t  p.mu_lead\n",
 "\n",
 " sym_lead_vertical = kwant.TranslationalSymmetry((0, 1))\n",
 " lead_vertical1 = kwant.Builder(sym_lead_vertical)\n",
 " lead_vertical2 = kwant.Builder(sym_lead_vertical)\n",
 "\n",
 " def lead_shape_vertical1(pos):\n",
 " (x, y) = pos\n",
 " return (L / 4  w_vert_lead / 2 <= x <= L / 4 + w_vert_lead / 2)\n",
 "\n",
 " def lead_shape_vertical2(pos):\n",
 " (x, y) = pos\n",
 " return (+L / 4  w_vert_lead / 2 <= x <= +L / 4 + w_vert_lead / 2)\n",
 "\n",
 " lead_vertical1[lat.shape(lead_shape_vertical1, (L / 4, 0))] = lead_onsite\n",
 " lead_vertical1[lat.neighbors()] = lead_hop_vert\n",
 " lead_vertical2[lat.shape(lead_shape_vertical2, (L / 4, 0))] = lead_onsite\n",
 " lead_vertical2[lat.neighbors()] = lead_hop_vert\n",
 "\n",
 " syst.attach_lead(lead_vertical1)\n",
 " syst.attach_lead(lead_vertical2)\n",
 "\n",
 " syst.attach_lead(lead_vertical1.reversed())\n",
 " syst.attach_lead(lead_vertical2.reversed())\n",
 "\n",
 " lead[lat.shape(lead_shape, (1, 0))] = lead_onsite\n",
 " lead[lat.neighbors()] = make_lead_hop_y(L / 2)\n",
 "\n",
 " syst.attach_lead(lead)\n",
 "\n",
 " lead = kwant.Builder(sym_lead)\n",
 " lead[lat.shape(lead_shape, (1, 0))] = lead_onsite\n",
 " lead[lat.neighbors()] = make_lead_hop_y(L / 2)\n",
 "\n",
 " syst.attach_lead(lead.reversed())\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def qhe_ribbon(W, periodic=False):\n",
 " \"\"\" Creates a ribbon with magnetic field through it.\n",
 "\n",
 " If we have periodic boundary conditions, the flux through a single \n",
 " unit cell is quantized.\n",
 " \"\"\"\n",
 " W = 2 * (W // 2)\n",
 "\n",
 " def ribbon_shape(pos):\n",
 " (x, y) = pos\n",
 " return (W / 2 <= y <= W / 2)\n",
 "\n",
 " def onsite(site, p):\n",
 " (x, y) = site.pos\n",
 " return 4 * p.t  p.mu\n",
 "\n",
 " def hopping(site1, site2, p):\n",
 " xt, yt = site1.pos\n",
 " xs, ys = site2.pos\n",
 " return p.t * np.exp(0.5j * p.B * (xt  xs) * (yt + ys))\n",
 "\n",
 " def hopping_periodic(site1, site2, p):\n",
 " xt, yt = site1.pos\n",
 " xs, ys = site2.pos\n",
 " return p.t * np.exp(0.5j * int(p.B) * 2 * np.pi / (W + 1) * (xt  xs) * (yt + ys))\n",
 "\n",
 " lat = kwant.lattice.square()\n",
 " sym_syst = kwant.TranslationalSymmetry((1, 0))\n",
 " syst = kwant.Builder(sym_syst)\n",
 "\n",
 " syst[lat.shape(ribbon_shape, (0, 0))] = onsite\n",
 "\n",
 " if periodic:\n",
 " syst[lat.neighbors()] = hopping_periodic\n",
 " syst[lat(0,  W / 2), lat(0, + W / 2)] = hopping_periodic\n",
 " else:\n",
 " syst[lat.neighbors()] = hopping\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def qhe_corbino(r_out=100, r_in=65, w_lead=10):\n",
 " \"\"\"Create corbino disk. \n",
 "\n",
 " Square lattice, one orbital per site.\n",
 " Returns kwant system.\n",
 "\n",
 " Arguments required in onsite/hoppings: \n",
 " t, mu, mu_lead, B, phi\n",
 " \"\"\"\n",
 " # ring shape\n",
 " def ring(pos):\n",
 " (x, y) = pos\n",
 " rsq = x ** 2 + y ** 2\n",
 " return (r_in ** 2 < rsq < r_out ** 2)\n",
 "\n",
 " # Onsite and hoppings\n",
 " def onsite(site, p):\n",
 " (x, y) = site.pos\n",
 " return 4 * p.t  p.mu\n",
 "\n",
 " def crosses_branchcut(hop):\n",
 " xt, yt = hop[0].pos\n",
 " xs, ys = hop[1].pos\n",
 " return yt < 0 and xt > 0.5 and xs < 0.5\n",
 "\n",
 " def hopping(site1, site2, p):\n",
 " xt, yt = site1.pos\n",
 " xs, ys = site2.pos\n",
 " # Check for correctness!\n",
 " return p.t * np.exp(0.5j * p.B * (xt  xs) * (yt + ys))\n",
 "\n",
 " def branchcut_hopping(site1, site2, p):\n",
 " return hopping(site1, site2, p) * np.exp(1j * p.phi)\n",
 "\n",
 " # Building system\n",
 " lat = kwant.lattice.square()\n",
 " syst = kwant.Builder()\n",
 "\n",
 " syst[lat.shape(ring, (0, r_in + 1))] = onsite\n",
 " syst[lat.neighbors()] = hopping\n",
 "\n",
 " # adding special hoppings\n",
 " def hops_across_cut(syst):\n",
 " for hop in kwant.builder.HoppingKind((1, 0), lat, lat)(syst):\n",
 " if crosses_branchcut(hop):\n",
 " yield hop\n",
 " syst[hops_across_cut] = branchcut_hopping\n",
 "\n",
 " # Attaching leads\n",
 " sym_lead = kwant.TranslationalSymmetry((1, 0))\n",
 " lead = kwant.Builder(sym_lead)\n",
 "\n",
 " def lead_shape(pos):\n",
 " (x, y) = pos\n",
 " return (w_lead / 2 < y < w_lead / 2)\n",
 "\n",
 " lead[lat.shape(lead_shape, (0, 0))] = lambda site, p: 4 * p.t  p.mu_lead\n",
 " lead[lat.neighbors()] = lambda site1, site2, p: p.t\n",
 "\n",
 " # Attach the leads and return the system.\n",
 " syst.attach_lead(lead)\n",
 " syst.attach_lead(lead, origin=lat(0, 0))\n",
 "\n",
 " return syst"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Quantum Hall effect: edge states and quantized Hall conductance\n",
 "\n",
 "* Landau levels in a slowly varying potential: chiral edge states\n",
 "* Chiral anomaly: Bulkedge correspondence of the quantum Hall effect\n",
 "* Hall conductance from edge states\n",
 "* Topological quantum phase transitions and robustness to disorder "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Where do the pumped electrons come from and go to?"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You have just seen that Laughlin's argument explains the quantization of the Hall conductance in terms of a pump which moves electrons through the bulk of a Hall cylinder, from one edge to the other of the cylinder. \n",
 "\n",
 "Compare the situation with the simple electron pump which you studied earlier in the lecture. There, the pump moved electrons from one metallic lead to the other. Clearly the pump worked thanks to the availability of electronic states at the Fermi level in the two metallic leads. Otherwise, it would have no electrons to take and no place to drop them. Without the metallic leads, the pump would be like an empty carousel.\n",
 "\n",
 "When applied to the Hall cylinder, this simple reasoning shows that Laughlin's argument necessarily implies the presence of **electronic states localized at the edges** of the sample.\n",
 "\n",
 "It is in fact very easy to convince ourselves that such states must exist. We just need to think again about the classical trajectory of an electron with velocity $v$ moving in a perpendicular magnetic field $B$. This trajectory is a circular orbit with radius given by the cyclotron radius.\n",
 "\n",
 "What happens to the classical trajectory of an electron when the center of the orbit is too close to the edge of the cylinder, say closer than a cyclotron radius? It is easier drawn than said:\n",
 "\n",
 "![](figures/skipping_orbits.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The electrons cannot exit the sample, and need to bounce back inside. This creates a socalled **skipping orbit**. In a real sample, there will be a confining electrostatic potential which keeps the electrons inside the Hall bar, or cylinder. The combination of a strong magnetic field in the bulk and a confining potential creates trajectories at the edges which are not closed, but travel along the full extent of the edges.\n",
 "\n",
 "> On the lower edge there are only leftmoving states, and on the upper edge only right moving ones. On each edge there are only states moving in one direction, and the direction is opposite for opposite edges. These strange states obtained at the edges are often referred to as **chiral edge states**.\n",
 "\n",
 "The chirality of the edges is determined by the orientation of the magnetic field (out of the plane vs. into the plane), and it would be reversed at both edges if the magnetic field were reversed.\n",
 "\n",
 "The cartoon above is purely based on classical physics, and needs to be supplemented with quantum considerations before it can give quantitative predictions. We will soon see that the quantum version of the cartoon above can give an explanation of the quantized Hall effect, complementary to Laughlin's argument.\n",
 "\n",
 "But before we move on to that, we should realize that the picture above is in fact a manifestation of the **bulkboundary correspondence**. Chiral edge states could not exist without the bulk of the quantum Hall sample."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# A closer look at the chiral edge states"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "So let's look at the edges of a Hall system in more detail. Let's think about the ribbon geometry, that we used when we discussed the Laughlin pump in a Hall cylinder. This time, we will take into account explicitly that the ribbon has a finite width $W$ in the $y$ direction.\n",
 "\n",
 "In practice, in order to confine the electrons in this region there must be a potential barrier $V(y)$, which has to be added to the Hamiltonian:\n",
 "\n",
 "$$H=p_y^2+(\\hbar ke B y\\Phi)^2\\,+V(y).$$\n",
 "\n",
 "\n",
 "Let's recall that $k=2\\pi n/L$ because of periodic boundary conditions over $x$. We do not really care about the particular shape of the potential. Generically, it will be very flat in the middle of the ribbon and very steep right at its boundaries:"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/confining_potential.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "How does the potential affect the energy eigenvalues of $H$? In the bulk of the ribbon, away from the edges, the potential is flat, so we can safely set $V(y)=0$ there. In the bulk, we still get flat Landau levels, with energy $E$ independent of $k$. These are the states corresponding to the cyclotron orbits in the classical sketch shown above.\n",
 "\n",
 "But let's now move closer to the edges. That is, let's consider states which are centered at a position $y_0 = \\hbar c k/eB$ which is not more than a few magnetic lengths away from the edges. These states are very sensitive to the confining potential, so their energies will be affected. The precise form of the spectrum is not universal and depends on the particular shape of $V(y)$. In general, however, we expect the energy $E(y_0)$ to increase by an amount proportional to $V(y_0)$ with respect to the original Landau level.\n",
 "\n",
 "Because $y_0$ is proportional to $k$, this means the states close to the edge will acquire a dependence on $k$. Let's see if this is true, by plotting $E(k)$ for our ribbon:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "p = SimpleNamespace(t=1, mu=0.5, B=0.15)\n",
 "syst = qhe_ribbon(W=20)\n",
 "\n",
 "kwargs = {'k_x': np.linspace(np.pi, np.pi, 101),\n",
 " 'xdim': r'$k$',\n",
 " 'ydim': r'$E$',\n",
 " 'xticks': pi_ticks,\n",
 " 'yticks': 3,\n",
 " 'ylims': [0.5, 0.5]}\n",
 " \n",
 "spectrum(syst, p, **kwargs) * holoviews.HLine(0)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You can see that, as a consequence of this bending of the Landau levels, even if the Fermi level is placed in the middle of a bulk gap as in the figure, there are states crossing it. We can associate the levels at negative $k$ with states localized at the bottom edge of the ribbon, and those at positive $k$ with states localized at the top edge. For each edge, there are as many edge states as there are filled Landau levels in the bulk of the system.\n",
 "\n",
 "The particular shape of the dispersion $E(k)$ will depend on the details of the confining potential (which in this case was an infinite square well). However, close to the Fermi level we can always approximate the dispersion $E(k)$ of the edge states as a straight line. We then obtain, for each edge state, a linear relation between energy and momentum,\n",
 "\n",
 "$$E = \\hbar v (kk_F).$$\n",
 "\n",
 "Here $k_F$ is the Fermi momentum, which in the case of our ribbon is equal to $k_F = 2\\pi N / L$, with $N$ the number of electrons in the system.\n",
 "\n",
 "Because the slope of the potential is just the local electric field $\\mathcal{E}_y=\\partial_y V(y)$ perpendicular to the edge of the sample, the velocity $v$ of the edge states can be simply interpreted as the [drift velocity](http://en.wikipedia.org/wiki/Guiding_center) of a skipping state,\n",
 "\n",
 "$$v = \\mathcal{E}_y/B\\,.$$\n",
 "\n",
 "The velocity is opposite at the two edges because the local electric field $\\mathcal{E}$ created by the confining potential always points towards the interior of the sample."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "An important thing to note is that the presence of edge states does not depend in any way on the particular shape of the sample as well. You can cut a quantum Hall system in any way you want, but as long as it has edges, it will have edge states. To demonstrate this, let's take a “picture” of the edge states by plotting the local density of states at the Fermi level in a Hall bar."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "p = SimpleNamespace(t=1, mu = 0.6, mu_lead=0.6, B=0.15, phi=0.0)\n",
 "syst = qhe_hall_bar(L=200, W=100).finalized()\n",
 "ldos = kwant.ldos(syst, energy=0.0, args=[p])\n",
 "\n",
 "fig = plt.figure(figsize=[20,20])\n",
 "ax = fig.add_subplot(1,2,1)\n",
 "ax.axis('off')\n",
 "kwant.plotter.map(syst, ldos, num_lead_cells=20, colorbar=False, ax=ax);"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The local density of states beautifully reveals the presence of edge states in the sample. You can see that each filled Landau level produces a maximum in the density of states, which goes all around the edges of the sample. In this case, our simulation had two filled Landau levels in the bulk."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"In the plot above, which edge state moves faster, the one closer to the edge or the one further away ?\")\n",
 "answers = [\"They go at the same velocity.\",\n",
 " \"The one more towards the bulk, because it is not slowed by the confining potential.\",\n",
 " \"The one closer to the edge, because the local electric field there is stronger.\",\n",
 " \"One cannot tell, because it depends on microscopic details.\"]\n",
 "explanation = (\"The drift velocity is given by the ratio of the local electric field and the magnetic field. \"\n",
 " \"The slope of the confinement potential increases sharply at the edge, hence the local electric field \"\n",
 " \"is stronger there.\")\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=2, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# The harmless anomaly of the chiral edges"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The chiral edge states can be described in such simple terms, that you might doubt the fact that they cannot exist without a bulk. After all, couldn't we just build a theory of a single chiral edge state, neglecting the bulk of the quantum Hall system and the existence of the other edge? Can't a truly onedimensional system just show the same behavior of the chiral edge state of the quantum Hall effect?\n",
 "\n",
 "Let's consider the equation $E=\\hbar v (kk_F)$ which describes these chiral states. We can imagine that a constant electric field $\\mathcal{E}$ can be applied along the edge, pallel to the momentum $k$. (In the Hall cylinder, this can be done by threading a timedependent flux through the cylinder, as you have seen in the previous part of the lecture).\n",
 "\n",
 "The momentum $k$ changes according to the equation $\\hbar \\dot{k} = e\\mathcal{E}$. After a time $t$, the energy of a state with momentum $k$ has changed to $\\hbar v (k  k_F  e\\mathcal{E}t/\\hbar)$. This increase corresponds to a timedependent shift of the Fermi momentum, $k_F\\,\\to\\,k_F + e\\mathcal{E}t/\\hbar$. Recall that $k_F = 2\\pi N/L$ where $N$ is the number of electrons, so the rate of change of $k_F$ gives\n",
 "\n",
 "$$\\dot{N} = \\mathcal{E}L/\\Phi_0,$$\n",
 "\n",
 "with $\\Phi_0=h/e$ a flux quantum! Since the number of electrons is changing, **charge is not conserved**. In particular, after a time such that $\\mathcal{E}L t = \\Phi_0$, it seems that exactly one electron has popped out of nowhere at the edge."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "At this point, you should understand what's happening. This is just how the Laughlin pump manifests itself if you only look at one edge. The number of electrons at one edge can increase, because electrons are being depleted from the other edge (which is not included in our “theory”) and pumped through the bulk until they appear.\n",
 "\n",
 "> This property of the edge is referred to as the **chiral anomaly**. The chiral anomaly tells us that we cannot have a consistent theory for a chiral edge state without a bulk, which at the same time conserves electric charge. Chiral edge states, or anything else that exhibits a chiral anomaly, are an example of the bulk edge correspondence, since they can only appear at the edge of a two dimensional system and never in isolation.\n",
 "\n",
 "We called the anomaly “harmless” since the nonconservation of charge at the edge has a very simple explanation when the rest of the system is included in the picture. If you ever encounter other “anomalous” theories, it might well be a sign that the system under consideration is only the edge of something else!"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Quantization of Hall Conductance from edge states"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "To conclude our case about chiral edge states, we will now show that both signatures of the quantum Hall effect can be explained solely in terms of the edge states, as long as the interactions between electrons are neglected. In principle, this exercise can be done in any of the sample geometries that you have seen so far: the 6terminal Hall bar, the Hall cylinder, and the Corbino geometry. We will choose the last one for the sake of convenience.\n",
 "\n",
 "So let's take again our Corbino disk immersed in an external magnetic field. With respect to last time, we now apply a small voltage difference $V$ between the edges, and there is no flux passing through in the middle of the Corbino disk."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/corbino_voltage.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In this new drawing, we have also added arrows to indicate that we now know that each edge of the Corbino supports one chiral state. We cannot resist the temptation of showing you another beautiful plot of the local density of states, showing edge states in the Corbino geometry:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "W = 60\n",
 "p = SimpleNamespace(t=1, mu=0.9, mu_lead=0.9, B=0.15, phi=0.0)\n",
 "syst = qhe_corbino(2*W, W).finalized()\n",
 "ldos = kwant.ldos(syst, energy=0.0, args=[p])\n",
 "fig = plt.figure(figsize=[15, 15])\n",
 "ax = fig.add_subplot(1,2,1)\n",
 "ax.axis('off')\n",
 "kwant.plotter.map(syst, ldos, num_lead_cells=20, colorbar=False, ax=ax)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Note how the local density of states for each edge state oscillates between maxima and minima. This is because the edge state wave functions are standing waves which go all around the Corbino disk.\n",
 "\n",
 "But back to the point. We want to consider the case when the system is in equilibrium, and we ask what are the currents that flow in the system as a consequence of the small applied voltage $V$.\n",
 "\n",
 "First, $V$ does not determine the presence of a current *between the edges*. Even though electrons can be injected in the edges, these are separated by the bulk of the system, where due to the position of the Fermi level there are no states available to carry a current. Furthermore, there is no timedependent flux being threaded through the Corbino disk, so the Laughlin pump is not in motion. Since there is no charge transfer at all in the direction parallel to the applied voltage, we have that the longitudinal conductance $\\sigma_L=0$.\n",
 "\n",
 "However, what is the current $I_\\circlearrowleft$ flowing *around* the ring? Because such a current would flow *orthogonally* with respect to the applied voltage, it is associated with the Hall conductance, $I_\\circlearrowleft= \\sigma_H V$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's first consider the case $V=0$. The Fermi level is then the same at both edges. There are as many electrons going around the ring clockwise on the outer edge, as there are going around counterclockwise on the inner edge. In this case there is no net current flowing around the ring.\n",
 "\n",
 "A small voltage difference $V$ creates a small imbalance in the electron population between the edges. There will be, say, more electrons running counterclockwise on the inner edge than running clockwise on the outer edge. So we do expect a net current flowing around the ring.\n",
 "\n",
 "Let's compute the intensity of the current, it's quite simple."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Every chiral edge state is a *transport channel* for the current. Now, the defining property of chiral edge states is that they only allow electrons to travel along the edge in one direction. Electrons have no chance to reverse their velocity, or in other words no chance to *backscatter*. This means that chiral edge states are perfect transport channels to carry a current, so they have the highest conductance possible. Quantum mechanics limits the maximum conductance that a single transport channel can have to the value $G_0=e^2/h$, which is the conductance quantum you already met last week. With $n$ of these channels, we obtain precisely\n",
 "\n",
 "$$I_\\circlearrowleft = n \\,\\frac{e^2}{h} V\\,.$$\n",
 "\n",
 "\n",
 "> Thus, the relevant electromagnetic responses, namely the longitudinal and Hall conductivities $\\sigma_L=0$ and $\\sigma_H=ne^2/h$, can both be derived directly by only considering the chiral edge states."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"At which energy did we set the Fermi level in the density of states plot for the Corbino disk?\")\n",
 "answers = [\"It is impossible to answer on the base of the plot alone, because it depends on the voltages applied to the leads.\",\n",
 " \"Exactly at the same energy as the third Landau level.\",\n",
 " \"Between the second and the third Landau levels.\",\n",
 " \"Between the third and the fourth Landau levels.\"]\n",
 "explanation = (\"There are three edge states visible in the figure. \"\n",
 " \"Hence there are three filled Landau levels in the bulk, \" \n",
 " \"so the Fermi level lies somewhere above the third, but below the fourth Landau level.\")\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=3, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Important things to know about edge states"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The physical picture that we presented this week is very simple, and it is also somewhat simplified.\n",
 "\n",
 "In the summary video of this week, Bert Halperin from Harvard University will discuss how disorder and interactions enter in the description of the quantum Hall effect, and where the electric current is really carried. In 1982, Bert was the [first to understand](http://sites.fas.harvard.edu/~phys191r/References/e3/halperin1982.pdf) that the quantum Hall effect could be explained by the existence of chiral edge states, so we are very happy that you can learn the story directly from him."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"rQs12cSieE\", src_location='3.3summary')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Questions about what you just learned? Ask them below!**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Questions\", \"Chiral edge states\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w3_pump_QHE/QHEedgestates.md b/w3_pump_QHE/QHEedgestates.md
new file mode 100644
index 0000000..48daaed
 /dev/null
+++ b/w3_pump_QHE/QHEedgestates.md
@@ 0,0 +1,412 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+%output size=150
+pi_ticks = [(np.pi, r'$\pi$'), (0, '0'), (np.pi, r'$\pi$')]
+
+def qhe_hall_bar(L=50, W=10, w_lead=10, w_vert_lead=None):
+ """Create a hall bar system.
+
+ Square lattice, one orbital per site.
+ Returns finalized kwant system.
+
+ Arguments required in onsite/hoppings:
+ t, mu, mu_lead
+ """
+ L = 2 * (L // 2)
+ W = 2 * (W // 2)
+ w_lead = 2 * (w_lead // 2)
+ if w_vert_lead is None:
+ w_vert_lead = w_lead
+ else:
+ w_vert_lead = 2 * (w_vert_lead // 2)
+
+ # bar shape
+ def bar(pos):
+ (x, y) = pos
+ return (x >= L / 2 and x <= L / 2) and (y >= W / 2 and y <= W / 2)
+
+ # Onsite and hoppings
+ def onsite(site, p):
+ (x, y) = site.pos
+ return 4 * p.t  p.mu
+
+ def hopping_Ax(site1, site2, p):
+ xt, yt = site1.pos
+ xs, ys = site2.pos
+ return p.t * np.exp(0.5j * p.B * (xt + xs) * (yt  ys))
+
+ def make_lead_hop_y(x0):
+ def hopping_Ay(site1, site2, p):
+ xt, yt = site1.pos
+ xs, ys = site2.pos
+ return p.t * np.exp(1j * p.B * x0 * (yt  ys))
+ return hopping_Ay
+
+ def lead_hop_vert(site1, site2, p):
+ return p.t
+
+ # Building system
+ lat = kwant.lattice.square()
+ syst = kwant.Builder()
+
+ syst[lat.shape(bar, (0, 0))] = onsite
+ syst[lat.neighbors()] = hopping_Ax
+
+ # Attaching leads
+ sym_lead = kwant.TranslationalSymmetry((1, 0))
+ lead = kwant.Builder(sym_lead)
+
+ def lead_shape(pos):
+ (x, y) = pos
+ return (w_lead / 2 <= y <= w_lead / 2)
+
+ lead_onsite = lambda site, p: 4 * p.t  p.mu_lead
+
+ sym_lead_vertical = kwant.TranslationalSymmetry((0, 1))
+ lead_vertical1 = kwant.Builder(sym_lead_vertical)
+ lead_vertical2 = kwant.Builder(sym_lead_vertical)
+
+ def lead_shape_vertical1(pos):
+ (x, y) = pos
+ return (L / 4  w_vert_lead / 2 <= x <= L / 4 + w_vert_lead / 2)
+
+ def lead_shape_vertical2(pos):
+ (x, y) = pos
+ return (+L / 4  w_vert_lead / 2 <= x <= +L / 4 + w_vert_lead / 2)
+
+ lead_vertical1[lat.shape(lead_shape_vertical1, (L / 4, 0))] = lead_onsite
+ lead_vertical1[lat.neighbors()] = lead_hop_vert
+ lead_vertical2[lat.shape(lead_shape_vertical2, (L / 4, 0))] = lead_onsite
+ lead_vertical2[lat.neighbors()] = lead_hop_vert
+
+ syst.attach_lead(lead_vertical1)
+ syst.attach_lead(lead_vertical2)
+
+ syst.attach_lead(lead_vertical1.reversed())
+ syst.attach_lead(lead_vertical2.reversed())
+
+ lead[lat.shape(lead_shape, (1, 0))] = lead_onsite
+ lead[lat.neighbors()] = make_lead_hop_y(L / 2)
+
+ syst.attach_lead(lead)
+
+ lead = kwant.Builder(sym_lead)
+ lead[lat.shape(lead_shape, (1, 0))] = lead_onsite
+ lead[lat.neighbors()] = make_lead_hop_y(L / 2)
+
+ syst.attach_lead(lead.reversed())
+
+ return syst
+
+
+def qhe_ribbon(W, periodic=False):
+ """ Creates a ribbon with magnetic field through it.
+
+ If we have periodic boundary conditions, the flux through a single
+ unit cell is quantized.
+ """
+ W = 2 * (W // 2)
+
+ def ribbon_shape(pos):
+ (x, y) = pos
+ return (W / 2 <= y <= W / 2)
+
+ def onsite(site, p):
+ (x, y) = site.pos
+ return 4 * p.t  p.mu
+
+ def hopping(site1, site2, p):
+ xt, yt = site1.pos
+ xs, ys = site2.pos
+ return p.t * np.exp(0.5j * p.B * (xt  xs) * (yt + ys))
+
+ def hopping_periodic(site1, site2, p):
+ xt, yt = site1.pos
+ xs, ys = site2.pos
+ return p.t * np.exp(0.5j * int(p.B) * 2 * np.pi / (W + 1) * (xt  xs) * (yt + ys))
+
+ lat = kwant.lattice.square()
+ sym_syst = kwant.TranslationalSymmetry((1, 0))
+ syst = kwant.Builder(sym_syst)
+
+ syst[lat.shape(ribbon_shape, (0, 0))] = onsite
+
+ if periodic:
+ syst[lat.neighbors()] = hopping_periodic
+ syst[lat(0,  W / 2), lat(0, + W / 2)] = hopping_periodic
+ else:
+ syst[lat.neighbors()] = hopping
+
+ return syst
+
+
+def qhe_corbino(r_out=100, r_in=65, w_lead=10):
+ """Create corbino disk.
+
+ Square lattice, one orbital per site.
+ Returns kwant system.
+
+ Arguments required in onsite/hoppings:
+ t, mu, mu_lead, B, phi
+ """
+ # ring shape
+ def ring(pos):
+ (x, y) = pos
+ rsq = x ** 2 + y ** 2
+ return (r_in ** 2 < rsq < r_out ** 2)
+
+ # Onsite and hoppings
+ def onsite(site, p):
+ (x, y) = site.pos
+ return 4 * p.t  p.mu
+
+ def crosses_branchcut(hop):
+ xt, yt = hop[0].pos
+ xs, ys = hop[1].pos
+ return yt < 0 and xt > 0.5 and xs < 0.5
+
+ def hopping(site1, site2, p):
+ xt, yt = site1.pos
+ xs, ys = site2.pos
+ # Check for correctness!
+ return p.t * np.exp(0.5j * p.B * (xt  xs) * (yt + ys))
+
+ def branchcut_hopping(site1, site2, p):
+ return hopping(site1, site2, p) * np.exp(1j * p.phi)
+
+ # Building system
+ lat = kwant.lattice.square()
+ syst = kwant.Builder()
+
+ syst[lat.shape(ring, (0, r_in + 1))] = onsite
+ syst[lat.neighbors()] = hopping
+
+ # adding special hoppings
+ def hops_across_cut(syst):
+ for hop in kwant.builder.HoppingKind((1, 0), lat, lat)(syst):
+ if crosses_branchcut(hop):
+ yield hop
+ syst[hops_across_cut] = branchcut_hopping
+
+ # Attaching leads
+ sym_lead = kwant.TranslationalSymmetry((1, 0))
+ lead = kwant.Builder(sym_lead)
+
+ def lead_shape(pos):
+ (x, y) = pos
+ return (w_lead / 2 < y < w_lead / 2)
+
+ lead[lat.shape(lead_shape, (0, 0))] = lambda site, p: 4 * p.t  p.mu_lead
+ lead[lat.neighbors()] = lambda site1, site2, p: p.t
+
+ # Attach the leads and return the system.
+ syst.attach_lead(lead)
+ syst.attach_lead(lead, origin=lat(0, 0))
+
+ return syst
+```
+
+## Quantum Hall effect: edge states and quantized Hall conductance
+
+* Landau levels in a slowly varying potential: chiral edge states
+* Chiral anomaly: Bulkedge correspondence of the quantum Hall effect
+* Hall conductance from edge states
+* Topological quantum phase transitions and robustness to disorder
+
+# Where do the pumped electrons come from and go to?
+
+You have just seen that Laughlin's argument explains the quantization of the Hall conductance in terms of a pump which moves electrons through the bulk of a Hall cylinder, from one edge to the other of the cylinder.
+
+Compare the situation with the simple electron pump which you studied earlier in the lecture. There, the pump moved electrons from one metallic lead to the other. Clearly the pump worked thanks to the availability of electronic states at the Fermi level in the two metallic leads. Otherwise, it would have no electrons to take and no place to drop them. Without the metallic leads, the pump would be like an empty carousel.
+
+When applied to the Hall cylinder, this simple reasoning shows that Laughlin's argument necessarily implies the presence of **electronic states localized at the edges** of the sample.
+
+It is in fact very easy to convince ourselves that such states must exist. We just need to think again about the classical trajectory of an electron with velocity $v$ moving in a perpendicular magnetic field $B$. This trajectory is a circular orbit with radius given by the cyclotron radius.
+
+What happens to the classical trajectory of an electron when the center of the orbit is too close to the edge of the cylinder, say closer than a cyclotron radius? It is easier drawn than said:
+
+![](figures/skipping_orbits.svg)
+
+The electrons cannot exit the sample, and need to bounce back inside. This creates a socalled **skipping orbit**. In a real sample, there will be a confining electrostatic potential which keeps the electrons inside the Hall bar, or cylinder. The combination of a strong magnetic field in the bulk and a confining potential creates trajectories at the edges which are not closed, but travel along the full extent of the edges.
+
+> On the lower edge there are only leftmoving states, and on the upper edge only right moving ones. On each edge there are only states moving in one direction, and the direction is opposite for opposite edges. These strange states obtained at the edges are often referred to as **chiral edge states**.
+
+The chirality of the edges is determined by the orientation of the magnetic field (out of the plane vs. into the plane), and it would be reversed at both edges if the magnetic field were reversed.
+
+The cartoon above is purely based on classical physics, and needs to be supplemented with quantum considerations before it can give quantitative predictions. We will soon see that the quantum version of the cartoon above can give an explanation of the quantized Hall effect, complementary to Laughlin's argument.
+
+But before we move on to that, we should realize that the picture above is in fact a manifestation of the **bulkboundary correspondence**. Chiral edge states could not exist without the bulk of the quantum Hall sample.
+
+# A closer look at the chiral edge states
+
+So let's look at the edges of a Hall system in more detail. Let's think about the ribbon geometry, that we used when we discussed the Laughlin pump in a Hall cylinder. This time, we will take into account explicitly that the ribbon has a finite width $W$ in the $y$ direction.
+
+In practice, in order to confine the electrons in this region there must be a potential barrier $V(y)$, which has to be added to the Hamiltonian:
+
+$$H=p_y^2+(\hbar ke B y\Phi)^2\,+V(y).$$
+
+
+Let's recall that $k=2\pi n/L$ because of periodic boundary conditions over $x$. We do not really care about the particular shape of the potential. Generically, it will be very flat in the middle of the ribbon and very steep right at its boundaries:
+
+![](figures/confining_potential.svg)
+
+How does the potential affect the energy eigenvalues of $H$? In the bulk of the ribbon, away from the edges, the potential is flat, so we can safely set $V(y)=0$ there. In the bulk, we still get flat Landau levels, with energy $E$ independent of $k$. These are the states corresponding to the cyclotron orbits in the classical sketch shown above.
+
+But let's now move closer to the edges. That is, let's consider states which are centered at a position $y_0 = \hbar c k/eB$ which is not more than a few magnetic lengths away from the edges. These states are very sensitive to the confining potential, so their energies will be affected. The precise form of the spectrum is not universal and depends on the particular shape of $V(y)$. In general, however, we expect the energy $E(y_0)$ to increase by an amount proportional to $V(y_0)$ with respect to the original Landau level.
+
+Because $y_0$ is proportional to $k$, this means the states close to the edge will acquire a dependence on $k$. Let's see if this is true, by plotting $E(k)$ for our ribbon:
+
+
+```python
+p = SimpleNamespace(t=1, mu=0.5, B=0.15)
+syst = qhe_ribbon(W=20)
+
+kwargs = {'k_x': np.linspace(np.pi, np.pi, 101),
+ 'xdim': r'$k$',
+ 'ydim': r'$E$',
+ 'xticks': pi_ticks,
+ 'yticks': 3,
+ 'ylims': [0.5, 0.5]}
+
+spectrum(syst, p, **kwargs) * holoviews.HLine(0)
+```
+
+You can see that, as a consequence of this bending of the Landau levels, even if the Fermi level is placed in the middle of a bulk gap as in the figure, there are states crossing it. We can associate the levels at negative $k$ with states localized at the bottom edge of the ribbon, and those at positive $k$ with states localized at the top edge. For each edge, there are as many edge states as there are filled Landau levels in the bulk of the system.
+
+The particular shape of the dispersion $E(k)$ will depend on the details of the confining potential (which in this case was an infinite square well). However, close to the Fermi level we can always approximate the dispersion $E(k)$ of the edge states as a straight line. We then obtain, for each edge state, a linear relation between energy and momentum,
+
+$$E = \hbar v (kk_F).$$
+
+Here $k_F$ is the Fermi momentum, which in the case of our ribbon is equal to $k_F = 2\pi N / L$, with $N$ the number of electrons in the system.
+
+Because the slope of the potential is just the local electric field $\mathcal{E}_y=\partial_y V(y)$ perpendicular to the edge of the sample, the velocity $v$ of the edge states can be simply interpreted as the [drift velocity](http://en.wikipedia.org/wiki/Guiding_center) of a skipping state,
+
+$$v = \mathcal{E}_y/B\,.$$
+
+The velocity is opposite at the two edges because the local electric field $\mathcal{E}$ created by the confining potential always points towards the interior of the sample.
+
+An important thing to note is that the presence of edge states does not depend in any way on the particular shape of the sample as well. You can cut a quantum Hall system in any way you want, but as long as it has edges, it will have edge states. To demonstrate this, let's take a “picture” of the edge states by plotting the local density of states at the Fermi level in a Hall bar.
+
+
+```python
+p = SimpleNamespace(t=1, mu = 0.6, mu_lead=0.6, B=0.15, phi=0.0)
+syst = qhe_hall_bar(L=200, W=100).finalized()
+ldos = kwant.ldos(syst, energy=0.0, args=[p])
+
+fig = plt.figure(figsize=[20,20])
+ax = fig.add_subplot(1,2,1)
+ax.axis('off')
+kwant.plotter.map(syst, ldos, num_lead_cells=20, colorbar=False, ax=ax);
+```
+
+The local density of states beautifully reveals the presence of edge states in the sample. You can see that each filled Landau level produces a maximum in the density of states, which goes all around the edges of the sample. In this case, our simulation had two filled Landau levels in the bulk.
+
+
+```python
+question = ("In the plot above, which edge state moves faster, the one closer to the edge or the one further away ?")
+answers = ["They go at the same velocity.",
+ "The one more towards the bulk, because it is not slowed by the confining potential.",
+ "The one closer to the edge, because the local electric field there is stronger.",
+ "One cannot tell, because it depends on microscopic details."]
+explanation = ("The drift velocity is given by the ratio of the local electric field and the magnetic field. "
+ "The slope of the confinement potential increases sharply at the edge, hence the local electric field "
+ "is stronger there.")
+MoocMultipleChoiceAssessment(question, answers, correct_answer=2, explanation=explanation)
+```
+
+# The harmless anomaly of the chiral edges
+
+The chiral edge states can be described in such simple terms, that you might doubt the fact that they cannot exist without a bulk. After all, couldn't we just build a theory of a single chiral edge state, neglecting the bulk of the quantum Hall system and the existence of the other edge? Can't a truly onedimensional system just show the same behavior of the chiral edge state of the quantum Hall effect?
+
+Let's consider the equation $E=\hbar v (kk_F)$ which describes these chiral states. We can imagine that a constant electric field $\mathcal{E}$ can be applied along the edge, pallel to the momentum $k$. (In the Hall cylinder, this can be done by threading a timedependent flux through the cylinder, as you have seen in the previous part of the lecture).
+
+The momentum $k$ changes according to the equation $\hbar \dot{k} = e\mathcal{E}$. After a time $t$, the energy of a state with momentum $k$ has changed to $\hbar v (k  k_F  e\mathcal{E}t/\hbar)$. This increase corresponds to a timedependent shift of the Fermi momentum, $k_F\,\to\,k_F + e\mathcal{E}t/\hbar$. Recall that $k_F = 2\pi N/L$ where $N$ is the number of electrons, so the rate of change of $k_F$ gives
+
+$$\dot{N} = \mathcal{E}L/\Phi_0,$$
+
+with $\Phi_0=h/e$ a flux quantum! Since the number of electrons is changing, **charge is not conserved**. In particular, after a time such that $\mathcal{E}L t = \Phi_0$, it seems that exactly one electron has popped out of nowhere at the edge.
+
+At this point, you should understand what's happening. This is just how the Laughlin pump manifests itself if you only look at one edge. The number of electrons at one edge can increase, because electrons are being depleted from the other edge (which is not included in our “theory”) and pumped through the bulk until they appear.
+
+> This property of the edge is referred to as the **chiral anomaly**. The chiral anomaly tells us that we cannot have a consistent theory for a chiral edge state without a bulk, which at the same time conserves electric charge. Chiral edge states, or anything else that exhibits a chiral anomaly, are an example of the bulk edge correspondence, since they can only appear at the edge of a two dimensional system and never in isolation.
+
+We called the anomaly “harmless” since the nonconservation of charge at the edge has a very simple explanation when the rest of the system is included in the picture. If you ever encounter other “anomalous” theories, it might well be a sign that the system under consideration is only the edge of something else!
+
+# Quantization of Hall Conductance from edge states
+
+To conclude our case about chiral edge states, we will now show that both signatures of the quantum Hall effect can be explained solely in terms of the edge states, as long as the interactions between electrons are neglected. In principle, this exercise can be done in any of the sample geometries that you have seen so far: the 6terminal Hall bar, the Hall cylinder, and the Corbino geometry. We will choose the last one for the sake of convenience.
+
+So let's take again our Corbino disk immersed in an external magnetic field. With respect to last time, we now apply a small voltage difference $V$ between the edges, and there is no flux passing through in the middle of the Corbino disk.
+
+![](figures/corbino_voltage.svg)
+
+In this new drawing, we have also added arrows to indicate that we now know that each edge of the Corbino supports one chiral state. We cannot resist the temptation of showing you another beautiful plot of the local density of states, showing edge states in the Corbino geometry:
+
+
+```python
+W = 60
+p = SimpleNamespace(t=1, mu=0.9, mu_lead=0.9, B=0.15, phi=0.0)
+syst = qhe_corbino(2*W, W).finalized()
+ldos = kwant.ldos(syst, energy=0.0, args=[p])
+fig = plt.figure(figsize=[15, 15])
+ax = fig.add_subplot(1,2,1)
+ax.axis('off')
+kwant.plotter.map(syst, ldos, num_lead_cells=20, colorbar=False, ax=ax)
+```
+
+Note how the local density of states for each edge state oscillates between maxima and minima. This is because the edge state wave functions are standing waves which go all around the Corbino disk.
+
+But back to the point. We want to consider the case when the system is in equilibrium, and we ask what are the currents that flow in the system as a consequence of the small applied voltage $V$.
+
+First, $V$ does not determine the presence of a current *between the edges*. Even though electrons can be injected in the edges, these are separated by the bulk of the system, where due to the position of the Fermi level there are no states available to carry a current. Furthermore, there is no timedependent flux being threaded through the Corbino disk, so the Laughlin pump is not in motion. Since there is no charge transfer at all in the direction parallel to the applied voltage, we have that the longitudinal conductance $\sigma_L=0$.
+
+However, what is the current $I_\circlearrowleft$ flowing *around* the ring? Because such a current would flow *orthogonally* with respect to the applied voltage, it is associated with the Hall conductance, $I_\circlearrowleft= \sigma_H V$.
+
+Let's first consider the case $V=0$. The Fermi level is then the same at both edges. There are as many electrons going around the ring clockwise on the outer edge, as there are going around counterclockwise on the inner edge. In this case there is no net current flowing around the ring.
+
+A small voltage difference $V$ creates a small imbalance in the electron population between the edges. There will be, say, more electrons running counterclockwise on the inner edge than running clockwise on the outer edge. So we do expect a net current flowing around the ring.
+
+Let's compute the intensity of the current, it's quite simple.
+
+Every chiral edge state is a *transport channel* for the current. Now, the defining property of chiral edge states is that they only allow electrons to travel along the edge in one direction. Electrons have no chance to reverse their velocity, or in other words no chance to *backscatter*. This means that chiral edge states are perfect transport channels to carry a current, so they have the highest conductance possible. Quantum mechanics limits the maximum conductance that a single transport channel can have to the value $G_0=e^2/h$, which is the conductance quantum you already met last week. With $n$ of these channels, we obtain precisely
+
+$$I_\circlearrowleft = n \,\frac{e^2}{h} V\,.$$
+
+
+> Thus, the relevant electromagnetic responses, namely the longitudinal and Hall conductivities $\sigma_L=0$ and $\sigma_H=ne^2/h$, can both be derived directly by only considering the chiral edge states.
+
+
+```python
+question = ("At which energy did we set the Fermi level in the density of states plot for the Corbino disk?")
+answers = ["It is impossible to answer on the base of the plot alone, because it depends on the voltages applied to the leads.",
+ "Exactly at the same energy as the third Landau level.",
+ "Between the second and the third Landau levels.",
+ "Between the third and the fourth Landau levels."]
+explanation = ("There are three edge states visible in the figure. "
+ "Hence there are three filled Landau levels in the bulk, "
+ "so the Fermi level lies somewhere above the third, but below the fourth Landau level.")
+MoocMultipleChoiceAssessment(question, answers, correct_answer=3, explanation=explanation)
+```
+
+# Important things to know about edge states
+
+The physical picture that we presented this week is very simple, and it is also somewhat simplified.
+
+In the summary video of this week, Bert Halperin from Harvard University will discuss how disorder and interactions enter in the description of the quantum Hall effect, and where the electric current is really carried. In 1982, Bert was the [first to understand](http://sites.fas.harvard.edu/~phys191r/References/e3/halperin1982.pdf) that the quantum Hall effect could be explained by the existence of chiral edge states, so we are very happy that you can learn the story directly from him.
+
+
+```python
+MoocVideo("rQs12cSieE", src_location='3.3summary')
+```
+
+**Questions about what you just learned? Ask them below!**
+
+
+```python
+MoocDiscussion("Questions", "Chiral edge states")
+```
diff git a/w3_pump_QHE/pumps.ipynb b/w3_pump_QHE/pumps.ipynb
deleted file mode 100644
index 9fcd038..0000000
 a/w3_pump_QHE/pumps.ipynb
+++ /dev/null
@@ 1,684 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "from holoviews.core.options import Cycle\n",
 "%output size=120\n",
 "pi_ticks = [(np.pi, r'$\\pi$'), (0, '0'), (np.pi, r'$\\pi$')]\n",
 "\n",
 "\n",
 "def ts_modulated_wire(L=50):\n",
 " \"\"\"Create an infinite wire with a periodic potential\n",
 "\n",
 " Chain lattice, one orbital per site.\n",
 " Returns kwant system.\n",
 "\n",
 " Arguments required in onsite/hoppings: \n",
 " t, mu, mu_lead, A, phase\n",
 "\n",
 " The period of the potential is 2*pi/L.\n",
 " \"\"\"\n",
 " omega = 2 * np.pi / L\n",
 "\n",
 " def onsite(site, p):\n",
 " x = site.pos[0]\n",
 " return 2 * p.t  p.mu + p.A * (np.cos(omega * x + p.phase) + 1)\n",
 "\n",
 " def hopping(site1, site2, p):\n",
 " return p.t\n",
 "\n",
 " sym_lead = kwant.TranslationalSymmetry([L])\n",
 "\n",
 " lat = kwant.lattice.chain()\n",
 " syst = kwant.Builder(sym_lead)\n",
 "\n",
 " syst[(lat(x) for x in range(L))] = onsite\n",
 " syst[lat.neighbors()] = hopping\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def modulated_wire(L=50, dL=10):\n",
 " \"\"\"Create a pump. \n",
 "\n",
 " Chain lattice, one orbital per site.\n",
 " Returns kwant system.\n",
 "\n",
 " L is the length of the pump,\n",
 " dL is the length of the clean regions next to the pump,\n",
 " useful for demonstration purposes.\n",
 "\n",
 " Arguments required in onsite/hoppings: \n",
 " t, mu, mu_lead, A, omega, phase\n",
 " \"\"\"\n",
 " def onsite(site, p):\n",
 " x = site.pos[0]\n",
 " return 2 * p.t  p.mu + p.A * (np.cos(p.omega * x + p.phase) + 1)\n",
 "\n",
 " lead_onsite = lambda site, p: 2 * p.t  p.mu_lead\n",
 "\n",
 " def hopping(site1, site2, p):\n",
 " return p.t\n",
 "\n",
 " lat = kwant.lattice.chain()\n",
 " syst = kwant.Builder()\n",
 "\n",
 " syst[(lat(x) for x in range(L))] = onsite\n",
 " syst[lat.neighbors()] = hopping\n",
 "\n",
 " sym_lead = kwant.TranslationalSymmetry([1])\n",
 " lead = kwant.Builder(sym_lead)\n",
 " lead[lat(0)] = lead_onsite\n",
 " lead[lat.neighbors()] = hopping\n",
 "\n",
 " syst.attach_lead(lead)\n",
 " syst.attach_lead(lead.reversed())\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def total_charge(value_array):\n",
 " \"\"\"Calculate the pumped charge from the list of reflection matrices.\"\"\"\n",
 " determinants = [np.linalg.det(r) for r in value_array]\n",
 " charge = np.cumsum(np.angle(np.roll(determinants, 1) / determinants))\n",
 " charge = charge  charge[0]\n",
 " return charge / (2 * np.pi)\n"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Thouless pumps"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Dganit Meidan from Ben Gurion University will introduce Thouless pumps,."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"gKZK9IGY9wo\", src_location='3.1intro', res='360')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Hamiltonians with parameters"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Previously, when studying the topology of systems supporting Majoranas (both the Kitaev chain and the nanowire), we were able to calculate topological properties by studying the bulk Hamiltonian $H(k)$.\n",
 "\n",
 "There are two points of view on this Hamiltonian. We could either consider it a Hamiltonian of an infinite system with momentum conservation\n",
 "\n",
 "$$H = H(k) k\\rangle\\langle k,$$\n",
 "\n",
 "or we could equivalently study a finite system with only a small number of degrees of freedom (corresponding to a single unit cell), and a Hamiltonian which depends on some continuous periodic parameter $k$.\n",
 "\n",
 "Of course, without specifying that $k$ is the real space momentum, there is no meaning in bulkedge correspondence (since the edge is an edge in real space), but the topological properties are still welldefined."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Sometimes we want to know how a physical system changes if we slowly vary some parameters of the system, for example a bias voltage or a magnetic field. Because the parameters change with time, the Hamiltonian becomes timedependent, namely\n",
 "\n",
 "$$H = H(t).$$\n",
 "\n",
 "The slow [adiabatic](https://en.wikipedia.org/wiki/Adiabatic_theorem) change of parameters ensures that if the system was initially in the ground state, it will stay in the ground state, so that the topological properties are useful.\n",
 "\n",
 "A further requirement for topology to be useful is the *periodicity* of time evolution:\n",
 "\n",
 "$$H(t) = H(t+T).$$\n",
 "\n",
 "The period can even go to $\\infty$, in which case $H(\\infty) = H(+\\infty)$. The reasons for the requirement of periodicity are somewhat abstract. If the Hamiltonian has parameters, we're studying the topology of a *mapping* from the space of parameter values to the space of all possible gapped Hamiltonians. This mapping has nontrivial topological properties only if the space of parameter values is compact.\n",
 "\n",
 "For us, this simply means that the Hamiltonian has to be periodic in time."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Of course, if we want systems with bulkedge correspondence, then in addition to $t$ our Hamiltonian must still depend on the real space coordinate, or the momentum $k$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Quantum pumps"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In the image below (source: Chambers's Encyclopedia, 1875, via Wikipedia) you see a very simple periodic timedependent system, an Archimedes screw pump."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/Archimedes_screw.jpg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The changes to the system are clearly periodic, and the pump works the same no matter how slowly we use it (that is, change the parameters), so it is an adiabatic tool.\n",
 "\n",
 "What about a quantum analog of this pump? Turns out it is just as simple as you would think.\n",
 "\n",
 "Let's take a onedimensional region, coupled to two electrodes on both sides, and apply a strong sineshaped confining potential in this region. As we move the confining potential, we drag the electrons captured in it.\n",
 "\n",
 "So our system now looks like this:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "# Plot of the potential in the pumping system as a function of coordinate.\n",
 "# Some part of the leads is shown with a constant potential.\n",
 "# Regions with E < 0 should be shaded to emulate Fermi sea.\n",
 "A = 0.6\n",
 "L = 10\n",
 "lamb = (10 / 5.3) / (2 * np.pi)\n",
 "mu = 0.4\n",
 "mu_lead = 0.8\n",
 "\n",
 "\n",
 "def f(x):\n",
 " if x < 0.0:\n",
 " return mu_lead\n",
 " if x >= 0.0 and x <= L:\n",
 " return mu + A * (1.0  np.cos(x / lamb))\n",
 " if x > L:\n",
 " return mu_lead\n",
 "\n",
 "x = np.linspace(5, 15, 1000)\n",
 "y = [f(i) for i in x]\n",
 "\n",
 "plt.figure(figsize=(6, 4))\n",
 "plt.plot(x, y, 'k', lw=1.2)\n",
 "\n",
 "plt.xlim(2.5, 12.5)\n",
 "plt.ylim(2, 2)\n",
 "\n",
 "y = [i if i <= 0 else 0 for i in y]\n",
 "plt.fill_between(x, y, 0, color='r', where=np.array(y) <\n",
 " 0.0, alpha=0.5, edgecolor='k', lw='1.5')\n",
 "\n",
 "plt.arrow(2.0, 1.25, 5, 0, head_width=0.15, head_length=1.0, fc='k', ec='k')\n",
 "\n",
 "plt.xlabel('$x$')\n",
 "plt.ylabel('$U(x)$')\n",
 "plt.xticks([])\n",
 "plt.yticks([])\n",
 "plt.show()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "It is described by the Hamiltonian\n",
 "\n",
 "$$H(t) = \\frac{k^2}{2m} + A [1  \\cos(x/\\lambda + 2\\pi t/T)].$$\n",
 "\n",
 "As we discussed, if we change $t$ very slowly, the solution will not depend on how fast $t$ varies.\n",
 "\n",
 "When $A \\gg 1 /m \\lambda^2$ the confining potential is strong, and additionally if the chemical potential $\\mu \\ll A$, the states bound in the separate minima of the potential have very small overlap.\n",
 "\n",
 "The potential near the bottom of each minimum is approximately quadratic, so the Hamiltonian is that of a simple Harmonic oscillator. This gives us discrete levels of the electrons with energies $E_n = (n + \\tfrac{1}{2})\\omega_c$, with $\\omega_c = \\sqrt{A/m\\lambda^2}$ the oscillator frequency.\n",
 "\n",
 "We can quickly check how continuous bands in the wire become discrete evenly spaced bands as we increase $A$:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "p = SimpleNamespace(t=1, mu=0.0, phase=0.0, A=None)\n",
 "syst = ts_modulated_wire(L=17)\n",
 "\n",
 "def title(p):\n",
 " return \"Band structure, $A={:.2}$\".format(p.A)\n",
 "\n",
 "kwargs = {'ylims': [0.2, 1.3],\n",
 " 'xticks': pi_ticks,\n",
 " 'yticks': [0, 0.5, 1.0],\n",
 " 'xdim': r'$k$',\n",
 " 'ydim': r'$E$',\n",
 " 'k_x': np.linspace(np.pi, np.pi, 101),\n",
 " 'title': title}\n",
 "\n",
 "\n",
 "holoviews.HoloMap({p.A: spectrum(syst, p, **kwargs) for p.A in np.linspace(0, 0.8, 10)}, kdims=[r'$A$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "So unless $\\mu = E_n$ for some $n$, each minimum of the potential contains an integer number of electrons $N$.\n",
 "\n",
 "Electron wave functions from neighboring potential minima do not overlap, so when we change the potential by one time period, we move exactly $N$ electrons."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "question = \"Why are some levels in the band structure flat while some are not?\"\n",
 "answers = [\"The flat levels are the ones whose energies are not sensitive to the offset of confining potential.\",\n",
 " \"Destructive interference of the wave functions in neighboring minima suppresses the dispersion.\",\n",
 " \"The flat levels are localized deep in the potential minima, \"\n",
 " \"so the bandwidth is exponentially small.\",\n",
 " \"The flat levels correspond to filled states, and the rest to empty states.\"]\n",
 "explanation = (\"The dispersion of the bands in a perodic potential appears \"\n",
 " \"when the wave functions from neighboring minima overlap.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=2, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Quantization of pumped charge"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As we already learned, integers are important, and they could indicate that something topological is happening.\n",
 "\n",
 "At this point we should ask ourselves these questions: Is the number of electrons $N$ pumped per cycle topological, or can we pump any continuous amount of charge? How important is it that the potential well of the pump is deep?"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Thought experiment\n",
 "\n",
 "To simplify the counting let's \"dry out\" the pump: We can define a procedure that empties the middle region, and pushes $n_L$ extra electrons to the left and $n_R$ electrons to the right.\n",
 "\n",
 "For example, we can do this:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "# Same plot as above, but now with an extra rectangular barrier in the\n",
 "# middle, and with arrows both ways showing that the barrier widens.\n",
 "\n",
 "# Plot of the potential in the pumping system as a function of coordinate.\n",
 "# Some part of the leads is shown with a constant potential.\n",
 "# Regions with E < 0 should be shaded to emulate Fermi sea.\n",
 "\n",
 "# Plot of the potential in the pumping system as a function of coordinate.\n",
 "# Some part of the leads is shown with a constant potential.\n",
 "# Regions with E < 0 should be shaded to emulate Fermi sea.\n",
 "A = 0.6\n",
 "L = 10\n",
 "lamb = (10 / 5.3) / (2 * np.pi)\n",
 "mu = 0.4\n",
 "mu_lead = 0.8\n",
 "a = 4.5\n",
 "b = 6.5\n",
 "top = 1.2\n",
 "\n",
 "\n",
 "def f(x):\n",
 " if x < 0.0:\n",
 " return mu_lead\n",
 " if x >= 0.0 and x <= a:\n",
 " return mu + A * (1.0  np.cos(x / lamb))\n",
 " if x > a and x < b:\n",
 " return top\n",
 " if x >= b and x <= L:\n",
 " return mu + A * (1.0  np.cos(x / lamb))\n",
 " if x > L:\n",
 " return mu_lead\n",
 "\n",
 "\n",
 "x = np.linspace(5, 15, 1000)\n",
 "y = [f(i) for i in x]\n",
 "\n",
 "plt.figure(figsize=(6, 4))\n",
 "plt.plot(x, y, 'k', lw=1.2)\n",
 "plt.xlim(2.5, 12.5)\n",
 "plt.ylim(2, 2)\n",
 "y = [i if i <= 0 else 0 for i in y]\n",
 "plt.fill_between(x, y, 0, color='r', where=np.array(y) <\n",
 " 0.0, alpha=0.5, edgecolor='k', lw='1.5')\n",
 "plt.arrow(a, 1.05, 1, 0, head_width=0.1, head_length=0.4, fc='k', ec='k')\n",
 "plt.arrow(b, 1.05, +1, 0, head_width=0.1, head_length=0.4, fc='k', ec='k')\n",
 "plt.xlabel('$x$')\n",
 "plt.ylabel('$U(x)$')\n",
 "plt.xticks([])\n",
 "plt.yticks([])\n",
 "plt.show()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "A reverse of this procedure does the reverse of course, so it reduces the number of charges on the left and right sides.\n",
 "\n",
 "Now here comes the trick:\n",
 "\n",
 "1. When the middle region is emptied, the two sides are completely disconnected, and so the number of electrons on either side must be integer for every eigenstate of the Hamiltonian.\n",
 "\n",
 "2. Next, if we performed the manipulation adiabatically, then if we start in an eigenstate of the Hamiltonian, we will also end in an eigenstate of the Hamiltonian. This is a consequence of the adiabatic theorem.\n",
 "\n",
 "3. In light of 1. and 2., we conclude that in the process of drying the middle out, we pumped an integer number of charges.\n",
 "\n",
 "4. Finally, adiabatic manipulation is only possible if the Hamiltonian stays gapped at all times.\n",
 "\n",
 "Bonus: In our argument we didn't use the shape or the strength of the potential, so it applies universally to any possible pump."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "So without doing any calculations, we can conclude that:\n",
 "\n",
 "> The number of electrons pumped per cycle of a quantum pump is an integer as long as\n",
 "> the bulk of the pump is gapped. Therefore it is a **topological invariant**."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Counting electrons through reflection."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The expression for the pumped charge in terms of the bulk Hamiltonian $H(k, t)$ is complicated.\n",
 "\n",
 "It's an integral over both $k$ and $t$, called a **Chern number** or in other sources a TKNN integer. Its complexity is beyond the scope of our course, but is extremely important, so we will have to study it... next week.\n",
 "\n",
 "There is a much simpler way to calculate the same quantity using scattering formalism. From the previous two weeks, recall that we may infer the presence or absence of Majoranas at an end of a system by calculating either $Q = \\textrm{sign}[\\textrm{Pf}\\,H(0)\\,\\textrm{Pf}\\,H(\\pi)]$ or $Q=\\textrm{sign}\\det r$, where $r$ is the reflection matrix from one end of the Majorana wire."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In order to derive the scattering expression, we need to understand how the pumped charge manifests in the reflection matrix.\n",
 "\n",
 "Let's start from the case when there's just one mode in the reservoir. We'll count the charge pumped by making the reservoir finite but very large.\n",
 "\n",
 "Now all the levels in the reservoir are quantized, and are standing waves, so they are equal weight superpositions of waves going to the left $\\psi_L$ and to the right $\\psi_R$,\n",
 "\n",
 "$$\n",
 "\\psi_n = \\psi_L(x) + \\psi_R(x) \\propto \\exp(ik_n x) + \\exp(ik_n x + i\\phi),\n",
 "$$\n",
 "\n",
 "where the wave number $k_n$ is of course a function of energy. The relative phase shift $\\phi$ is necessary to satisfy the boundary condition at $x=0$, where $\\psi_L = r \\psi_R$, and so $\\exp(i \\phi) = r$. The energies of the levels are determined by requiring that the phases of $\\psi_L$ and $\\psi_R$ also match at $x = L$.\n",
 "\n",
 "Now, what happens when we pump one extra charge into the reservoir? All the energy levels are shifted up by one, that is $E_n \\rightarrow E_{n+1}$, and accordingly the wave functions also change $\\psi_n \\rightarrow \\psi_{n+1}$.\n",
 "\n",
 "> We conclude that the charge can only be pumped as the reflection phase $\\phi$ advances by $2\\pi$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "It's very easy to generalize our argument to many modes. For that we just need to sum all of the reflection phase shifts, which means we need to look at the phase of $\\det r$.\n",
 "\n",
 "We conclude that there's a very compact relation between charge $dq$ pumped by an infinitesimal change of an external parameter and the change in reflection matrix $dr$:\n",
 "\n",
 "$$\n",
 "dq = \\frac{d \\log \\det r}{2\\pi i} = \\operatorname{Tr}\\frac{r^\\dagger dr }{ 2 \\pi i}.\n",
 "$$\n",
 "\n",
 "While we derived this relation only for the case when all incoming particles reflect, and $r$ is unitary, written in form of trace it also holds if there is transmission.[¹](https://arxiv.org/abs/condmat/9808347)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's check if this expression holds to our expectations. If $r=1$, this is just the number of times the phase of $\\det r$ winds around zero, and it is certainly an integer, as we expected."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Applying the topological invariant"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We're left with a simple exercise.\n",
 "\n",
 "We know now how to calculate the pumped charge during one cycle, so let's just see how it works in practice.\n",
 "\n",
 "The scattering problem in 1D can be solved quickly, so let's calculate the pumped charge as a function of time for different values of the chemical potential in the pump."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "%%opts Path.Q (color=Cycle(values=['r', 'g', 'b', 'y']))\n",
 "%%opts HLine (color=Cycle(values=['r', 'g', 'b', 'y']) linestyle='')\n",
 "\n",
 "def plot_charge(mu):\n",
 " energy = 0.0\n",
 " phases = np.linspace(0, 2*np.pi, 100)\n",
 " p = SimpleNamespace(t=1, mu=mu, mu_lead=mu, A=0.6, omega= .3)\n",
 " syst = modulated_wire(L=100).finalized()\n",
 " rs = [kwant.smatrix(syst, energy, args=[p]).submatrix(0, 0) for p.phase in phases]\n",
 " wn = total_charge(rs)\n",
 " title = '$\\mu={:.2}$'.format(mu)\n",
 " kdims = [r'$t/T$', r'$q/e$']\n",
 " plot = holoviews.Path((phases / (2 * np.pi), wn), kdims=kdims, label=title, group='Q')\n",
 " return plot[:, 0.5:3.5](plot={'xticks': [0, 1], 'yticks': [0, 1, 2, 3]})\n",
 "\n",
 "\n",
 "kwargs = {'ylims': [0.2, 1.3],\n",
 " 'xticks': pi_ticks,\n",
 " 'yticks': [0, 0.5, 1.0],\n",
 " 'xdim': r'$k$',\n",
 " 'ydim': r'$E$',\n",
 " 'k_x': np.linspace(np.pi, np.pi, 101),\n",
 " 'title': lambda p: \"Band structure, $A={:.2}$\".format(p.A)}\n",
 "\n",
 "p = SimpleNamespace(t=1, mu=0.0, phase=0.0, A=0.6)\n",
 "syst = ts_modulated_wire(L=17)\n",
 "mus = [0.1, 0.3, 0.6, 0.9]\n",
 "HLines = holoviews.Overlay([holoviews.HLine(mu) for mu in mus])\n",
 "spectrum(syst, p, **kwargs) * HLines + holoviews.Overlay([plot_charge(mu) for mu in mus]).relabel('Pumped charge')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In the left plot, we show the band structure, where the different colors correspond to different chemical potentials. The right plot shows the corresponding pumped charge. During the pumping cycle the charge may change, and the relation between the offset $\\phi$ of the potential isn't always linear. However we see that after a full cycle, the pumped charge exactly matches the number of filled levels in a single potential well."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As a final mental exercise about pumps, let's think about what happens if we disconnect the leads and consider the spectrum of a closed system.\n",
 "\n",
 "As the periodic potential moves, it tries to increase the energies of all the states at the right of the system and reduce the energy of all the states to the left (that's what pumping does after all).\n",
 "\n",
 "So there should be states crossing the bulk band gap. Let's see if it's true."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "p = SimpleNamespace(t=1, mu=0.0, mu_lead=0, A=0.6, omega=0.3, phase=None)\n",
 "syst = modulated_wire(L=110).finalized()\n",
 "phases = np.linspace(0, 2*np.pi, 251)\n",
 "en = [np.linalg.eigvalsh(syst.hamiltonian_submatrix(args=[p])) for p.phase in phases]\n",
 "en = np.array(en)\n",
 "ticks = {'xticks': [0, 1], 'yticks': [0, 0.5, 1]}\n",
 "kdims = [r'$t/T$', r'$E$']\n",
 "holoviews.Path((phases / (2*np.pi), en), kdims=kdims)[:, 0:1.2](plot=ticks)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Indeed, the levels in the bulk stay flat and have a high degeneracy, but we see that there are also single levels that get pushed across the gap. Since the bulk is homogeneous, these states have to be localized at the edge.\n",
 "\n",
 "Of course, since we have a finite system, the charge cannot be pumped forever from one end into the other. So the pumping breaks down when you see the edge states crossing the bulk bands. At these moments the charge can flow back through the bulk."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "question = (\"What happens to the dependence of the reflection phase shift on time if we \"\n",
 " \"remove one of the reservoirs and leave the other one?\")\n",
 "answers = [\"It becomes constant.\",\n",
 " \"For most of the cycle it stays the same, but there appear \"\n",
 " \"sharp jumps such that the total winding becomes zero.\",\n",
 " \"Nothing changes, since the two ends of the pump are \"\n",
 " \"far apart from each other, and the pump is not conducting.\",\n",
 " \"The reflection phase gets a new time dependence with zero winding, unrelated to the original one.\"]\n",
 "explanation = (\"The total pumped charge must become equal to zero since there's nowhere to place the charge, but \"\n",
 " \"since the pump is insulating, the phase cannot change \"\n",
 " \"for most of the cycle unless a sharp resonance appears\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Quantized charge and scattering invariant"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"6lXRAZ7hv7E\", src_location='3.1summary', res='360')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Questions about what you learned? Ask them below**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocDiscussion('Questions', 'Quantum pumps')"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
diff git a/w3_pump_QHE/pumps.md b/w3_pump_QHE/pumps.md
new file mode 100644
index 0000000..08cd2e4
 /dev/null
+++ b/w3_pump_QHE/pumps.md
@@ 0,0 +1,450 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+from holoviews.core.options import Cycle
+%output size=120
+pi_ticks = [(np.pi, r'$\pi$'), (0, '0'), (np.pi, r'$\pi$')]
+
+
+def ts_modulated_wire(L=50):
+ """Create an infinite wire with a periodic potential
+
+ Chain lattice, one orbital per site.
+ Returns kwant system.
+
+ Arguments required in onsite/hoppings:
+ t, mu, mu_lead, A, phase
+
+ The period of the potential is 2*pi/L.
+ """
+ omega = 2 * np.pi / L
+
+ def onsite(site, p):
+ x = site.pos[0]
+ return 2 * p.t  p.mu + p.A * (np.cos(omega * x + p.phase) + 1)
+
+ def hopping(site1, site2, p):
+ return p.t
+
+ sym_lead = kwant.TranslationalSymmetry([L])
+
+ lat = kwant.lattice.chain()
+ syst = kwant.Builder(sym_lead)
+
+ syst[(lat(x) for x in range(L))] = onsite
+ syst[lat.neighbors()] = hopping
+
+ return syst
+
+
+def modulated_wire(L=50, dL=10):
+ """Create a pump.
+
+ Chain lattice, one orbital per site.
+ Returns kwant system.
+
+ L is the length of the pump,
+ dL is the length of the clean regions next to the pump,
+ useful for demonstration purposes.
+
+ Arguments required in onsite/hoppings:
+ t, mu, mu_lead, A, omega, phase
+ """
+ def onsite(site, p):
+ x = site.pos[0]
+ return 2 * p.t  p.mu + p.A * (np.cos(p.omega * x + p.phase) + 1)
+
+ lead_onsite = lambda site, p: 2 * p.t  p.mu_lead
+
+ def hopping(site1, site2, p):
+ return p.t
+
+ lat = kwant.lattice.chain()
+ syst = kwant.Builder()
+
+ syst[(lat(x) for x in range(L))] = onsite
+ syst[lat.neighbors()] = hopping
+
+ sym_lead = kwant.TranslationalSymmetry([1])
+ lead = kwant.Builder(sym_lead)
+ lead[lat(0)] = lead_onsite
+ lead[lat.neighbors()] = hopping
+
+ syst.attach_lead(lead)
+ syst.attach_lead(lead.reversed())
+
+ return syst
+
+
+def total_charge(value_array):
+ """Calculate the pumped charge from the list of reflection matrices."""
+ determinants = [np.linalg.det(r) for r in value_array]
+ charge = np.cumsum(np.angle(np.roll(determinants, 1) / determinants))
+ charge = charge  charge[0]
+ return charge / (2 * np.pi)
+
+```
+
+# Thouless pumps
+
+Dganit Meidan from Ben Gurion University will introduce Thouless pumps,.
+
+
+```python
+MoocVideo("gKZK9IGY9wo", src_location='3.1intro', res='360')
+```
+
+# Hamiltonians with parameters
+
+Previously, when studying the topology of systems supporting Majoranas (both the Kitaev chain and the nanowire), we were able to calculate topological properties by studying the bulk Hamiltonian $H(k)$.
+
+There are two points of view on this Hamiltonian. We could either consider it a Hamiltonian of an infinite system with momentum conservation
+
+$$H = H(k) k\rangle\langle k,$$
+
+or we could equivalently study a finite system with only a small number of degrees of freedom (corresponding to a single unit cell), and a Hamiltonian which depends on some continuous periodic parameter $k$.
+
+Of course, without specifying that $k$ is the real space momentum, there is no meaning in bulkedge correspondence (since the edge is an edge in real space), but the topological properties are still welldefined.
+
+Sometimes we want to know how a physical system changes if we slowly vary some parameters of the system, for example a bias voltage or a magnetic field. Because the parameters change with time, the Hamiltonian becomes timedependent, namely
+
+$$H = H(t).$$
+
+The slow [adiabatic](https://en.wikipedia.org/wiki/Adiabatic_theorem) change of parameters ensures that if the system was initially in the ground state, it will stay in the ground state, so that the topological properties are useful.
+
+A further requirement for topology to be useful is the *periodicity* of time evolution:
+
+$$H(t) = H(t+T).$$
+
+The period can even go to $\infty$, in which case $H(\infty) = H(+\infty)$. The reasons for the requirement of periodicity are somewhat abstract. If the Hamiltonian has parameters, we're studying the topology of a *mapping* from the space of parameter values to the space of all possible gapped Hamiltonians. This mapping has nontrivial topological properties only if the space of parameter values is compact.
+
+For us, this simply means that the Hamiltonian has to be periodic in time.
+
+Of course, if we want systems with bulkedge correspondence, then in addition to $t$ our Hamiltonian must still depend on the real space coordinate, or the momentum $k$.
+
+# Quantum pumps
+
+In the image below (source: Chambers's Encyclopedia, 1875, via Wikipedia) you see a very simple periodic timedependent system, an Archimedes screw pump.
+
+![](figures/Archimedes_screw.jpg)
+
+The changes to the system are clearly periodic, and the pump works the same no matter how slowly we use it (that is, change the parameters), so it is an adiabatic tool.
+
+What about a quantum analog of this pump? Turns out it is just as simple as you would think.
+
+Let's take a onedimensional region, coupled to two electrodes on both sides, and apply a strong sineshaped confining potential in this region. As we move the confining potential, we drag the electrons captured in it.
+
+So our system now looks like this:
+
+
+```python
+# Plot of the potential in the pumping system as a function of coordinate.
+# Some part of the leads is shown with a constant potential.
+# Regions with E < 0 should be shaded to emulate Fermi sea.
+A = 0.6
+L = 10
+lamb = (10 / 5.3) / (2 * np.pi)
+mu = 0.4
+mu_lead = 0.8
+
+
+def f(x):
+ if x < 0.0:
+ return mu_lead
+ if x >= 0.0 and x <= L:
+ return mu + A * (1.0  np.cos(x / lamb))
+ if x > L:
+ return mu_lead
+
+x = np.linspace(5, 15, 1000)
+y = [f(i) for i in x]
+
+plt.figure(figsize=(6, 4))
+plt.plot(x, y, 'k', lw=1.2)
+
+plt.xlim(2.5, 12.5)
+plt.ylim(2, 2)
+
+y = [i if i <= 0 else 0 for i in y]
+plt.fill_between(x, y, 0, color='r', where=np.array(y) <
+ 0.0, alpha=0.5, edgecolor='k', lw='1.5')
+
+plt.arrow(2.0, 1.25, 5, 0, head_width=0.15, head_length=1.0, fc='k', ec='k')
+
+plt.xlabel('$x$')
+plt.ylabel('$U(x)$')
+plt.xticks([])
+plt.yticks([])
+plt.show()
+```
+
+It is described by the Hamiltonian
+
+$$H(t) = \frac{k^2}{2m} + A [1  \cos(x/\lambda + 2\pi t/T)].$$
+
+As we discussed, if we change $t$ very slowly, the solution will not depend on how fast $t$ varies.
+
+When $A \gg 1 /m \lambda^2$ the confining potential is strong, and additionally if the chemical potential $\mu \ll A$, the states bound in the separate minima of the potential have very small overlap.
+
+The potential near the bottom of each minimum is approximately quadratic, so the Hamiltonian is that of a simple Harmonic oscillator. This gives us discrete levels of the electrons with energies $E_n = (n + \tfrac{1}{2})\omega_c$, with $\omega_c = \sqrt{A/m\lambda^2}$ the oscillator frequency.
+
+We can quickly check how continuous bands in the wire become discrete evenly spaced bands as we increase $A$:
+
+
+```python
+p = SimpleNamespace(t=1, mu=0.0, phase=0.0, A=None)
+syst = ts_modulated_wire(L=17)
+
+def title(p):
+ return "Band structure, $A={:.2}$".format(p.A)
+
+kwargs = {'ylims': [0.2, 1.3],
+ 'xticks': pi_ticks,
+ 'yticks': [0, 0.5, 1.0],
+ 'xdim': r'$k$',
+ 'ydim': r'$E$',
+ 'k_x': np.linspace(np.pi, np.pi, 101),
+ 'title': title}
+
+
+holoviews.HoloMap({p.A: spectrum(syst, p, **kwargs) for p.A in np.linspace(0, 0.8, 10)}, kdims=[r'$A$'])
+```
+
+So unless $\mu = E_n$ for some $n$, each minimum of the potential contains an integer number of electrons $N$.
+
+Electron wave functions from neighboring potential minima do not overlap, so when we change the potential by one time period, we move exactly $N$ electrons.
+
+
+```python
+question = "Why are some levels in the band structure flat while some are not?"
+answers = ["The flat levels are the ones whose energies are not sensitive to the offset of confining potential.",
+ "Destructive interference of the wave functions in neighboring minima suppresses the dispersion.",
+ "The flat levels are localized deep in the potential minima, "
+ "so the bandwidth is exponentially small.",
+ "The flat levels correspond to filled states, and the rest to empty states."]
+explanation = ("The dispersion of the bands in a perodic potential appears "
+ "when the wave functions from neighboring minima overlap.")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=2, explanation=explanation)
+```
+
+# Quantization of pumped charge
+
+As we already learned, integers are important, and they could indicate that something topological is happening.
+
+At this point we should ask ourselves these questions: Is the number of electrons $N$ pumped per cycle topological, or can we pump any continuous amount of charge? How important is it that the potential well of the pump is deep?
+
+### Thought experiment
+
+To simplify the counting let's "dry out" the pump: We can define a procedure that empties the middle region, and pushes $n_L$ extra electrons to the left and $n_R$ electrons to the right.
+
+For example, we can do this:
+
+
+```python
+# Same plot as above, but now with an extra rectangular barrier in the
+# middle, and with arrows both ways showing that the barrier widens.
+
+# Plot of the potential in the pumping system as a function of coordinate.
+# Some part of the leads is shown with a constant potential.
+# Regions with E < 0 should be shaded to emulate Fermi sea.
+
+# Plot of the potential in the pumping system as a function of coordinate.
+# Some part of the leads is shown with a constant potential.
+# Regions with E < 0 should be shaded to emulate Fermi sea.
+A = 0.6
+L = 10
+lamb = (10 / 5.3) / (2 * np.pi)
+mu = 0.4
+mu_lead = 0.8
+a = 4.5
+b = 6.5
+top = 1.2
+
+
+def f(x):
+ if x < 0.0:
+ return mu_lead
+ if x >= 0.0 and x <= a:
+ return mu + A * (1.0  np.cos(x / lamb))
+ if x > a and x < b:
+ return top
+ if x >= b and x <= L:
+ return mu + A * (1.0  np.cos(x / lamb))
+ if x > L:
+ return mu_lead
+
+
+x = np.linspace(5, 15, 1000)
+y = [f(i) for i in x]
+
+plt.figure(figsize=(6, 4))
+plt.plot(x, y, 'k', lw=1.2)
+plt.xlim(2.5, 12.5)
+plt.ylim(2, 2)
+y = [i if i <= 0 else 0 for i in y]
+plt.fill_between(x, y, 0, color='r', where=np.array(y) <
+ 0.0, alpha=0.5, edgecolor='k', lw='1.5')
+plt.arrow(a, 1.05, 1, 0, head_width=0.1, head_length=0.4, fc='k', ec='k')
+plt.arrow(b, 1.05, +1, 0, head_width=0.1, head_length=0.4, fc='k', ec='k')
+plt.xlabel('$x$')
+plt.ylabel('$U(x)$')
+plt.xticks([])
+plt.yticks([])
+plt.show()
+```
+
+A reverse of this procedure does the reverse of course, so it reduces the number of charges on the left and right sides.
+
+Now here comes the trick:
+
+1. When the middle region is emptied, the two sides are completely disconnected, and so the number of electrons on either side must be integer for every eigenstate of the Hamiltonian.
+
+2. Next, if we performed the manipulation adiabatically, then if we start in an eigenstate of the Hamiltonian, we will also end in an eigenstate of the Hamiltonian. This is a consequence of the adiabatic theorem.
+
+3. In light of 1. and 2., we conclude that in the process of drying the middle out, we pumped an integer number of charges.
+
+4. Finally, adiabatic manipulation is only possible if the Hamiltonian stays gapped at all times.
+
+Bonus: In our argument we didn't use the shape or the strength of the potential, so it applies universally to any possible pump.
+
+So without doing any calculations, we can conclude that:
+
+> The number of electrons pumped per cycle of a quantum pump is an integer as long as
+> the bulk of the pump is gapped. Therefore it is a **topological invariant**.
+
+# Counting electrons through reflection.
+
+The expression for the pumped charge in terms of the bulk Hamiltonian $H(k, t)$ is complicated.
+
+It's an integral over both $k$ and $t$, called a **Chern number** or in other sources a TKNN integer. Its complexity is beyond the scope of our course, but is extremely important, so we will have to study it... next week.
+
+There is a much simpler way to calculate the same quantity using scattering formalism. From the previous two weeks, recall that we may infer the presence or absence of Majoranas at an end of a system by calculating either $Q = \textrm{sign}[\textrm{Pf}\,H(0)\,\textrm{Pf}\,H(\pi)]$ or $Q=\textrm{sign}\det r$, where $r$ is the reflection matrix from one end of the Majorana wire.
+
+In order to derive the scattering expression, we need to understand how the pumped charge manifests in the reflection matrix.
+
+Let's start from the case when there's just one mode in the reservoir. We'll count the charge pumped by making the reservoir finite but very large.
+
+Now all the levels in the reservoir are quantized, and are standing waves, so they are equal weight superpositions of waves going to the left $\psi_L$ and to the right $\psi_R$,
+
+$$
+\psi_n = \psi_L(x) + \psi_R(x) \propto \exp(ik_n x) + \exp(ik_n x + i\phi),
+$$
+
+where the wave number $k_n$ is of course a function of energy. The relative phase shift $\phi$ is necessary to satisfy the boundary condition at $x=0$, where $\psi_L = r \psi_R$, and so $\exp(i \phi) = r$. The energies of the levels are determined by requiring that the phases of $\psi_L$ and $\psi_R$ also match at $x = L$.
+
+Now, what happens when we pump one extra charge into the reservoir? All the energy levels are shifted up by one, that is $E_n \rightarrow E_{n+1}$, and accordingly the wave functions also change $\psi_n \rightarrow \psi_{n+1}$.
+
+> We conclude that the charge can only be pumped as the reflection phase $\phi$ advances by $2\pi$.
+
+It's very easy to generalize our argument to many modes. For that we just need to sum all of the reflection phase shifts, which means we need to look at the phase of $\det r$.
+
+We conclude that there's a very compact relation between charge $dq$ pumped by an infinitesimal change of an external parameter and the change in reflection matrix $dr$:
+
+$$
+dq = \frac{d \log \det r}{2\pi i} = \operatorname{Tr}\frac{r^\dagger dr }{ 2 \pi i}.
+$$
+
+While we derived this relation only for the case when all incoming particles reflect, and $r$ is unitary, written in form of trace it also holds if there is transmission.[¹](https://arxiv.org/abs/condmat/9808347)
+
+Let's check if this expression holds to our expectations. If $r=1$, this is just the number of times the phase of $\det r$ winds around zero, and it is certainly an integer, as we expected.
+
+# Applying the topological invariant
+
+We're left with a simple exercise.
+
+We know now how to calculate the pumped charge during one cycle, so let's just see how it works in practice.
+
+The scattering problem in 1D can be solved quickly, so let's calculate the pumped charge as a function of time for different values of the chemical potential in the pump.
+
+
+```python
+%%opts Path.Q (color=Cycle(values=['r', 'g', 'b', 'y']))
+%%opts HLine (color=Cycle(values=['r', 'g', 'b', 'y']) linestyle='')
+
+def plot_charge(mu):
+ energy = 0.0
+ phases = np.linspace(0, 2*np.pi, 100)
+ p = SimpleNamespace(t=1, mu=mu, mu_lead=mu, A=0.6, omega= .3)
+ syst = modulated_wire(L=100).finalized()
+ rs = [kwant.smatrix(syst, energy, args=[p]).submatrix(0, 0) for p.phase in phases]
+ wn = total_charge(rs)
+ title = '$\mu={:.2}$'.format(mu)
+ kdims = [r'$t/T$', r'$q/e$']
+ plot = holoviews.Path((phases / (2 * np.pi), wn), kdims=kdims, label=title, group='Q')
+ return plot[:, 0.5:3.5](plot={'xticks': [0, 1], 'yticks': [0, 1, 2, 3]})
+
+
+kwargs = {'ylims': [0.2, 1.3],
+ 'xticks': pi_ticks,
+ 'yticks': [0, 0.5, 1.0],
+ 'xdim': r'$k$',
+ 'ydim': r'$E$',
+ 'k_x': np.linspace(np.pi, np.pi, 101),
+ 'title': lambda p: "Band structure, $A={:.2}$".format(p.A)}
+
+p = SimpleNamespace(t=1, mu=0.0, phase=0.0, A=0.6)
+syst = ts_modulated_wire(L=17)
+mus = [0.1, 0.3, 0.6, 0.9]
+HLines = holoviews.Overlay([holoviews.HLine(mu) for mu in mus])
+spectrum(syst, p, **kwargs) * HLines + holoviews.Overlay([plot_charge(mu) for mu in mus]).relabel('Pumped charge')
+```
+
+In the left plot, we show the band structure, where the different colors correspond to different chemical potentials. The right plot shows the corresponding pumped charge. During the pumping cycle the charge may change, and the relation between the offset $\phi$ of the potential isn't always linear. However we see that after a full cycle, the pumped charge exactly matches the number of filled levels in a single potential well.
+
+As a final mental exercise about pumps, let's think about what happens if we disconnect the leads and consider the spectrum of a closed system.
+
+As the periodic potential moves, it tries to increase the energies of all the states at the right of the system and reduce the energy of all the states to the left (that's what pumping does after all).
+
+So there should be states crossing the bulk band gap. Let's see if it's true.
+
+
+```python
+p = SimpleNamespace(t=1, mu=0.0, mu_lead=0, A=0.6, omega=0.3, phase=None)
+syst = modulated_wire(L=110).finalized()
+phases = np.linspace(0, 2*np.pi, 251)
+en = [np.linalg.eigvalsh(syst.hamiltonian_submatrix(args=[p])) for p.phase in phases]
+en = np.array(en)
+ticks = {'xticks': [0, 1], 'yticks': [0, 0.5, 1]}
+kdims = [r'$t/T$', r'$E$']
+holoviews.Path((phases / (2*np.pi), en), kdims=kdims)[:, 0:1.2](plot=ticks)
+```
+
+Indeed, the levels in the bulk stay flat and have a high degeneracy, but we see that there are also single levels that get pushed across the gap. Since the bulk is homogeneous, these states have to be localized at the edge.
+
+Of course, since we have a finite system, the charge cannot be pumped forever from one end into the other. So the pumping breaks down when you see the edge states crossing the bulk bands. At these moments the charge can flow back through the bulk.
+
+
+```python
+question = ("What happens to the dependence of the reflection phase shift on time if we "
+ "remove one of the reservoirs and leave the other one?")
+answers = ["It becomes constant.",
+ "For most of the cycle it stays the same, but there appear "
+ "sharp jumps such that the total winding becomes zero.",
+ "Nothing changes, since the two ends of the pump are "
+ "far apart from each other, and the pump is not conducting.",
+ "The reflection phase gets a new time dependence with zero winding, unrelated to the original one."]
+explanation = ("The total pumped charge must become equal to zero since there's nowhere to place the charge, but "
+ "since the pump is insulating, the phase cannot change "
+ "for most of the cycle unless a sharp resonance appears")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)
+```
+
+# Quantized charge and scattering invariant
+
+
+```python
+MoocVideo("6lXRAZ7hv7E", src_location='3.1summary', res='360')
+```
+
+**Questions about what you learned? Ask them below**
+
+
+```python
+MoocDiscussion('Questions', 'Quantum pumps')
+```
diff git a/w3_pump_QHE/w3_assignments.ipynb b/w3_pump_QHE/w3_assignments.ipynb
deleted file mode 100644
index 9316b99..0000000
 a/w3_pump_QHE/w3_assignments.ipynb
+++ /dev/null
@@ 1,175 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Simulations: Disorder, butterflies, and honeycombs"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As usual, start by grabbing the notebooks of this week (`w3_pump_QHE`). They are once again over [here](http://tiny.cc/topocm_smc).\n",
 "\n",
 "There are really plenty of things that one can study with the quantum Hall effect and pumps. Remember, that you don't need to do everything at once (but of course all of the simulations are quite fun!)\n",
 "\n",
 "### Pumping with disorder\n",
 "\n",
 "Grab the simulations of the Thouless pump, and see what happens to the pump when you add disorder. Try both the winding in a pump with reservoirs attached, and the spectrum of a closed pump. Can you explain what you observe?\n",
 "\n",
 "### Butterfly\n",
 "\n",
 "Take a look at how we calculate numerically the spectrum of Landau levels in the Laughlin argument chapter.\n",
 "We were always careful to only take weak fields so that the flux per unit cell of the tight binding lattice is small.\n",
 "This is done to avoid certain [notorious insects](http://en.wikipedia.org/wiki/Hofstadter%27s_butterfly), but nothing should prevent you from cranking up the magnetic field and seeing this beautiful phenomenon.\n",
 "\n",
 "Plot the spectrum of a quantum Hall layer rolled into a cylinder at a fixed momentum as a function of $B$ as $B$ goes to one flux quantum per unit cell, so in lattice units $B = 2\\pi$. Bonus (requires more work): attach a lead to the cylinder, calculate pumping, and color the butterfly according to the pumped charge.\n",
 "\n",
 "### Graphene\n",
 "\n",
 "Take a look at how to implement a honeycomb lattice in Kwant [tutorials](http://kwantproject.org/doc/1.0/tutorial/tutorial4), and modify the Hall bar from the Laughlin argument notebook to be made of graphene. Observe the famous [unconventional quantum Hall effect](http://arxiv.org/abs/condmat/0602565).\n",
 "\n",
 "Bonus: See what happens to the edge states as you introduce a constriction in the middle of the Hall bar. This is an extremely useful experimental tool used in making quantum Hall interferometers (also check out the density of states using the code from the edge states notebook)."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocSelfAssessment(due=4*7, review_due=5*7)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Now share your results:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocDiscussion('Labs', 'Quantum Hall effect')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Review assignment"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "For the third week we have these papers:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "display_html(PreprintReference('1109.5983', description=\"Topological pumping can be used to characterize quasicrystals too! \"\n",
 " \"Whether this is really unique to quasicrystals is debated though \"\n",
 " \"http://arxiv.org/abs/1307.2577v2\"))\n",
 "display_html(PreprintReference('condmat/0602645', \n",
 " description=\"Quantum Hall effect applies beyond parabolic dispersions with interesting twists. \"\n",
 " \"Figure out what different features arise from other cases. \"))\n",
 "\n",
 "display_html(PreprintReference('1201.4167', description=\"An experiment detecting the interesting consequences of \"\n",
 " \"coexistence of quantum Hall and ferromagnetism in graphene.\"))\n",
 "display_html(PreprintReference('0710.2806', description=\"AharonovBohm interference using quantum hall edge\"\n",
 " \"quasiparticles.\"))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Bonus: Find your own paper to review!\n",
 "\n",
 "Do you know of another paper that fits into the topics of this week, and you think is good?\n",
 "Then you can get bonus points by reviewing that paper instead!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocPeerAssessment(due=4*7, review_due=5*7)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Reviews\", \"Quantum Hall effect\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
diff git a/w3_pump_QHE/w3_assignments.md b/w3_pump_QHE/w3_assignments.md
new file mode 100644
index 0000000..c74fcb5
 /dev/null
+++ b/w3_pump_QHE/w3_assignments.md
@@ 0,0 +1,80 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+```
+
+# Simulations: Disorder, butterflies, and honeycombs
+
+As usual, start by grabbing the notebooks of this week (`w3_pump_QHE`). They are once again over [here](http://tiny.cc/topocm_smc).
+
+There are really plenty of things that one can study with the quantum Hall effect and pumps. Remember, that you don't need to do everything at once (but of course all of the simulations are quite fun!)
+
+### Pumping with disorder
+
+Grab the simulations of the Thouless pump, and see what happens to the pump when you add disorder. Try both the winding in a pump with reservoirs attached, and the spectrum of a closed pump. Can you explain what you observe?
+
+### Butterfly
+
+Take a look at how we calculate numerically the spectrum of Landau levels in the Laughlin argument chapter.
+We were always careful to only take weak fields so that the flux per unit cell of the tight binding lattice is small.
+This is done to avoid certain [notorious insects](http://en.wikipedia.org/wiki/Hofstadter%27s_butterfly), but nothing should prevent you from cranking up the magnetic field and seeing this beautiful phenomenon.
+
+Plot the spectrum of a quantum Hall layer rolled into a cylinder at a fixed momentum as a function of $B$ as $B$ goes to one flux quantum per unit cell, so in lattice units $B = 2\pi$. Bonus (requires more work): attach a lead to the cylinder, calculate pumping, and color the butterfly according to the pumped charge.
+
+### Graphene
+
+Take a look at how to implement a honeycomb lattice in Kwant [tutorials](http://kwantproject.org/doc/1.0/tutorial/tutorial4), and modify the Hall bar from the Laughlin argument notebook to be made of graphene. Observe the famous [unconventional quantum Hall effect](http://arxiv.org/abs/condmat/0602565).
+
+Bonus: See what happens to the edge states as you introduce a constriction in the middle of the Hall bar. This is an extremely useful experimental tool used in making quantum Hall interferometers (also check out the density of states using the code from the edge states notebook).
+
+
+```python
+MoocSelfAssessment(due=4*7, review_due=5*7)
+```
+
+**Now share your results:**
+
+
+```python
+MoocDiscussion('Labs', 'Quantum Hall effect')
+```
+
+# Review assignment
+
+For the third week we have these papers:
+
+
+```python
+display_html(PreprintReference('1109.5983', description="Topological pumping can be used to characterize quasicrystals too! "
+ "Whether this is really unique to quasicrystals is debated though "
+ "http://arxiv.org/abs/1307.2577v2"))
+display_html(PreprintReference('condmat/0602645',
+ description="Quantum Hall effect applies beyond parabolic dispersions with interesting twists. "
+ "Figure out what different features arise from other cases. "))
+
+display_html(PreprintReference('1201.4167', description="An experiment detecting the interesting consequences of "
+ "coexistence of quantum Hall and ferromagnetism in graphene."))
+display_html(PreprintReference('0710.2806', description="AharonovBohm interference using quantum hall edge"
+ "quasiparticles."))
+```
+
+### Bonus: Find your own paper to review!
+
+Do you know of another paper that fits into the topics of this week, and you think is good?
+Then you can get bonus points by reviewing that paper instead!
+
+
+```python
+MoocPeerAssessment(due=4*7, review_due=5*7)
+```
+
+**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**
+
+
+```python
+MoocDiscussion("Reviews", "Quantum Hall effect")
+```
diff git a/w4_haldane/ComputingChern.ipynb b/w4_haldane/ComputingChern.ipynb
deleted file mode 100644
index ecd61c8..0000000
 a/w4_haldane/ComputingChern.ipynb
+++ /dev/null
@@ 1,103 +0,0 @@
{
 "cells": [
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Additional notes on computing Chern number\n",
 "\n",
 "Computing the Chern number from the Berry connection $\\bf{a}(\\bf {k})=i\\langle u(\\bf{k})\\bf{\\nabla}(u(\\bf{k})\\rangle)$ is annoying because one needs to find a gauge where the Bloch wavefunctions $u_n({\\bf k})$ are continuous.\n",
 "\n",
 "On the other hand, the Chern number is really the integral of the Berry curvature \n",
 "\n",
 "$${\\bf{b}(k)}={\\bf\\nabla\\times a(k)}$$ \n",
 "\n",
 "as\n",
 "\n",
 "$$\\Phi=\\oint d^2\\bf{k}\\bf{z}\\cdot \\bf{b}(\\bf{k}).$$"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Numerically it is more convenient to compute the integral $\\Phi$ by breaking them down into small plaquettes. So that \n",
 "\n",
 "$$\\Phi=\\sum_n \\oint_{\\Gamma_n} d^2\\bf{k}\\bf{z}\\cdot \\bf{b}(\\bf{k})=\\sum_n \\oint_{\\Gamma_n} d{\\bf k}\\cdot {\\bf a(k)},$$\n",
 "is broken down into chunks \n",
 "$$\\Phi_n=i\\oint_{\\Gamma_n} d{\\bf k}\\cdot {\\langle u(\\bf{k})\\bf{\\nabla}(u(\\bf{k})\\rangle)}.$$\n",
 "\n",
 "For sufficiently small chunks $\\Phi_n$ is small and one can get away with computing the exponential \n",
 "\n",
 "$$e^{i\\Phi_n}=e^{\\oint_{\\Gamma_n} d{\\bf k}\\cdot {\\langle u(\\bf{k})\\bf{\\nabla}(u(\\bf{k})\\rangle)}}=\\prod_p e^{\\delta{\\bf k}_{n,p}\\cdot {\\langle u(\\bf{k}_{n,p})\\bf{\\nabla}(u(\\bf{k}_{n,p})\\rangle)}}\\approx \\prod_p (1+\\delta k_{n,p}\\langle u(\\bf{k}_{n,p})\\bf{\\nabla}(u(\\bf{k}_{n,p})\\rangle)\\approx \\prod_p \\langle u(\\bf{k}_{n,p})u(\\bf{k}_{n,p+1})\\rangle.$$\n"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The flux on the small plaquette can be computed as \n",
 "\n",
 "$$\\Phi_n=\\textrm{Arg}(\\prod_p \\langle u({\\bf k}_{n,p})u({\\bf k}_{n,p+1})\\rangle).$$\n",
 "\n",
 "What is nice about this product is that it is gauge invariant as can be checked by multiplying each wavefunction $u({\\bf k}_{n,p})\\rangle\\rightarrow e^{i\\varphi({\\bf k}_{n,p})}u({\\bf k}_{n,p})\\rangle$.\n",
 "\n",
 "The nice thing about this expression is that one can also generalize this to multiband systems to calculate the total Chern number so that the contribution from each plaquette \n",
 "\n",
 "$$e^{i\\Phi_n}\\approx \\prod_p\\prod_s \\langle u_s(\\bf{k}_{n,p})u_s(\\bf{k}_{n,p+1})\\rangle=\\prod_p Det[\\langle u_s(\\bf{k}_{n,p})u_s(\\bf{k}_{n,p+1})\\rangle],$$\n",
 "where $s$ labels the band index.\n",
 "\n",
 "What Vanderbilt and coworkers pointed out is that this expression can be written as \n",
 "$$e^{i\\Phi_n}=\\prod_p Det[\\langle u_s(\\bf{k}_{n,p})u_{s'}(\\bf{k}_{n,p+1})\\rangle],$$\n",
 "is related to determinants of a bunch of matrices $\\langle u_s(\\bf{k}_{n,p})u_{s'}(\\bf{k}_{n,p+1})\\rangle$, which in the diagonal basis of eigenstates is nearly diagonal, which takes us back to the previous expression.\n",
 "\n",
 "The main advantage of this expression is that it is actually $U(N)$ invariant for any unitary transformation of the $N$ occupied eigenstates."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Final recipe\n",
 "\n",
 "So the final recipe to compute the Chern number is as follows:\n",
 "\n",
 "* grid up the BZ into small plaquettes labelled by $n$\n",
 "\n",
 "* Compute the flux through each plaquette $$\\Phi_n=Arg[\\prod_p Det[\\langle u_s(\\bf{k}_{n,p})u_{s'}(\\bf{k}_{n,p+1})\\rangle]],$$\n",
 "where ${\\bf k}_{n,p}$ are momenta on the corners of the lattice.\n",
 "\n",
 "* The Chern number is calculated as $$\\nu=(2\\pi)^{1}\\sum_n \\Phi_n.$$"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": false
 },
 "outputs": [],
 "source": []
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
diff git a/w4_haldane/ComputingChern.md b/w4_haldane/ComputingChern.md
new file mode 100644
index 0000000..23c4cc5
 /dev/null
+++ b/w4_haldane/ComputingChern.md
@@ 0,0 +1,51 @@
+
+## Additional notes on computing Chern number
+
+Computing the Chern number from the Berry connection $\bf{a}(\bf {k})=i\langle u(\bf{k})\bf{\nabla}(u(\bf{k})\rangle)$ is annoying because one needs to find a gauge where the Bloch wavefunctions $u_n({\bf k})$ are continuous.
+
+On the other hand, the Chern number is really the integral of the Berry curvature
+
+$${\bf{b}(k)}={\bf\nabla\times a(k)}$$
+
+as
+
+$$\Phi=\oint d^2\bf{k}\bf{z}\cdot \bf{b}(\bf{k}).$$
+
+Numerically it is more convenient to compute the integral $\Phi$ by breaking them down into small plaquettes. So that
+
+$$\Phi=\sum_n \oint_{\Gamma_n} d^2\bf{k}\bf{z}\cdot \bf{b}(\bf{k})=\sum_n \oint_{\Gamma_n} d{\bf k}\cdot {\bf a(k)},$$
+is broken down into chunks
+$$\Phi_n=i\oint_{\Gamma_n} d{\bf k}\cdot {\langle u(\bf{k})\bf{\nabla}(u(\bf{k})\rangle)}.$$
+
+For sufficiently small chunks $\Phi_n$ is small and one can get away with computing the exponential
+
+$$e^{i\Phi_n}=e^{\oint_{\Gamma_n} d{\bf k}\cdot {\langle u(\bf{k})\bf{\nabla}(u(\bf{k})\rangle)}}=\prod_p e^{\delta{\bf k}_{n,p}\cdot {\langle u(\bf{k}_{n,p})\bf{\nabla}(u(\bf{k}_{n,p})\rangle)}}\approx \prod_p (1+\delta k_{n,p}\langle u(\bf{k}_{n,p})\bf{\nabla}(u(\bf{k}_{n,p})\rangle)\approx \prod_p \langle u(\bf{k}_{n,p})u(\bf{k}_{n,p+1})\rangle.$$
+
+
+The flux on the small plaquette can be computed as
+
+$$\Phi_n=\textrm{Arg}(\prod_p \langle u({\bf k}_{n,p})u({\bf k}_{n,p+1})\rangle).$$
+
+What is nice about this product is that it is gauge invariant as can be checked by multiplying each wavefunction $u({\bf k}_{n,p})\rangle\rightarrow e^{i\varphi({\bf k}_{n,p})}u({\bf k}_{n,p})\rangle$.
+
+The nice thing about this expression is that one can also generalize this to multiband systems to calculate the total Chern number so that the contribution from each plaquette
+
+$$e^{i\Phi_n}\approx \prod_p\prod_s \langle u_s(\bf{k}_{n,p})u_s(\bf{k}_{n,p+1})\rangle=\prod_p Det[\langle u_s(\bf{k}_{n,p})u_s(\bf{k}_{n,p+1})\rangle],$$
+where $s$ labels the band index.
+
+What Vanderbilt and coworkers pointed out is that this expression can be written as
+$$e^{i\Phi_n}=\prod_p Det[\langle u_s(\bf{k}_{n,p})u_{s'}(\bf{k}_{n,p+1})\rangle],$$
+is related to determinants of a bunch of matrices $\langle u_s(\bf{k}_{n,p})u_{s'}(\bf{k}_{n,p+1})\rangle$, which in the diagonal basis of eigenstates is nearly diagonal, which takes us back to the previous expression.
+
+The main advantage of this expression is that it is actually $U(N)$ invariant for any unitary transformation of the $N$ occupied eigenstates.
+
+## Final recipe
+
+So the final recipe to compute the Chern number is as follows:
+
+* grid up the BZ into small plaquettes labelled by $n$
+
+* Compute the flux through each plaquette $$\Phi_n=Arg[\prod_p Det[\langle u_s(\bf{k}_{n,p})u_{s'}(\bf{k}_{n,p+1})\rangle]],$$
+where ${\bf k}_{n,p}$ are momenta on the corners of the lattice.
+
+* The Chern number is calculated as $$\nu=(2\pi)^{1}\sum_n \Phi_n.$$
diff git a/w4_haldane/QHE_lattice.ipynb b/w4_haldane/QHE_lattice.ipynb
deleted file mode 100644
index 2d4051a..0000000
 a/w4_haldane/QHE_lattice.ipynb
+++ /dev/null
@@ 1,398 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "%output size=150\n",
 "pi_ticks = [(np.pi, r'$\\pi$'), (0, '0'), (np.pi, r'$\\pi$')]\n",
 "\n",
 "def Qi_Wu_Zhang(w=None):\n",
 " def onsite(site, p):\n",
 " return  p.mu * pauli.sz\n",
 " \n",
 " def hopx(site1, site2, p):\n",
 " return  0.5j * p.delta * pauli.sy  p.t * pauli.sz\n",
 " \n",
 " def hopy(site1, site2, p):\n",
 " return  1j * p.gamma * pauli.sx  p.gamma * pauli.sz \n",
 " \n",
 " lat = kwant.lattice.square()\n",
 "\n",
 " if w == None:\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))\n",
 " syst[lat.shape(lambda pos: True, (0, 0))] = onsite\n",
 " else:\n",
 " def ribbon_shape(pos):\n",
 " return (0 <= pos[1] < w )\n",
 "\n",
 " sym = kwant.TranslationalSymmetry((1, 0))\n",
 " syst = kwant.Builder(sym)\n",
 " syst[lat.shape(ribbon_shape, (0, 0))] = onsite\n",
 "\n",
 " syst[kwant.HoppingKind((1,0), lat)] = hopx\n",
 " syst[kwant.HoppingKind((0,1), lat)] = hopy\n",
 " return syst\n",
 "\n",
 "\n",
 "def title(p):\n",
 " title = r\"$t={:.2}$, $\\mu={:.2}$, $\\Delta={:.2}$, $\\gamma={:.2}$\"\n",
 " title = title.format(p.t, p.mu, p.delta, p.gamma)\n",
 " return title"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Quantum Hall effect on a lattice and the Dirac Hamiltonian\n",
 "* Pairs of chiral edges in a 1D wire\n",
 "* Coupling wires and QHE without field\n",
 "* Dirac equation at the phase transition"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Introduction: stacking wires"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Looking back at the material from the past weeks, you might have the impression that the quantum Hall effect and one dimensional topological superconductors are really different topics, and not connected at all.\n",
 "\n",
 "Xiaoliang Qi from Stanford University will now explain that this is not the case, and will also introduce this week's topic  Chern insulators."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"osKP6x0Ewbo\", src_location=\"4.1intro\")"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Pairs of chiral edges in a 1D wire"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Last week, we started with a phenomenological description of the quantum Hall effect. We learned that one way to get a quantum Hall state is to place electrons in an external magnetic field.\n",
 "\n",
 "However, we still don't have a simple lattice Hamiltonian describing the quantum Hall effect  we'd like to have something like the Kitaev chain model, which was very useful to understand Majoranas in the first two weeks of the course. An added benefit of finding this tight binding model is that it would not need an external magnetic field to exhibit the unique properties of quantum Hall effect.\n",
 "\n",
 "These models exist, and they are referred to as *Chern insulators*. The quantum Hall effect without an external magnetic field is also referred to as the *quantum anomalous Hall effect*. Duncan Haldane, from who we will hear in the next chapter, invented the first model of a Chern insulator now known as *Haldane model*. However, in this chapter, we will use a more natural route that fits better into the context of our course so far."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## General strategy to construct a lattice model for the Quantum Hall Effect\n",
 "\n",
 "What we will do to get a model for a Chern insulator is to follow a \"domino prescription\", as we did to get the Kitaev model in week 1. Our strategy will have two key aspects:\n",
 "\n",
 "* Focusing on the unique property of the quantum Hall edge that cannot exist in isolation from a bulk, and can only be present because of bulkboundary correspondence. For the Kitaev chain, this property was the presence of unpaired Majorana modes. In the quantum Hall effect, it is the chiral edge states.\n",
 "\n",
 "* Finding a lower dimensional building block, from which we can somehow “extract“ in a clever way the exotic object we are interested in. In the Kitaev chain, these were the fermionic sites, which we could think of as a pair of Majorana modes.\n",
 "\n",
 "So we need to find a onedimensional system which can host a pair of chiral edge states. Since they are onedimensional, these states will necessarily be spatially on top of each other, essentially a pair of propagating modes with opposite velocity. Once we have this building block, we can follow the domino prescription: couple the counterpropagating states in pairs, just like we did with Majorana modes. We then end up with a pair of spatially separated chiral edge states, and so a quantum Hall insulator without magnetic field.\n",
 "\n",
 "So our plan is to turn the system on the left into the system on the right:"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/coupled_chains.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Voilà  we have a lattice model for the 2D quantum Hall state!"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Getting a one dimensional wire with a pair of edge states\n",
 "\n",
 "Let's focus on the first essential step of our plan: finding a one dimensional system with a pair of counterpropagating chiral states.\n",
 "\n",
 "You might guess that the easiest way to get a pair of states moving in opposite directions is to take the usual one dimensional single electron Hamiltonian with an effective mass. Such a system has a parabolic dispersion and the low energy excitations at a finite Fermi wavevector $k=\\pm k_F$ move in opposite directions. The catch is that these two states have different momenta, and it is tricky (though not impossible) to deal with momentum conservation when pairing the edges. So we will avoid this approach.\n",
 "\n",
 "The more educated guess we make a model that we have already encountered, the Dirac model $H= \\Delta\\,k\\, \\tau_y$ of the Kitaev chain at the topological phase transition.\n",
 "\n",
 "More specifically, in the first week we wrote the Kitaev Hamiltonian in momentum space as $H(k)=(2 t\\cos{k}+\\mu)\\,\\tau_z+\\Delta \\sin{k}\\tau_y$. At the critical point $\\mu=2t$, we found the Kitaev Hamiltonian to become\n",
 "\n",
 "$$H=2t(\\cos{k}1)\\,\\tau_z+\\Delta\\sin{k}\\,\\tau_y.$$\n",
 "\n",
 "We see that at $k\\approx 0$ we have a pair of states with wave functions the eigenvalues $\\pm 1$ of $\\tau_y$, and with opposite and equal velocities.\n",
 "\n",
 "At this point you might worry that the Kitaev model has superconductivity, and so the $\\tau$ matrices refer to particle and hole degrees of freedom. Indeed, these ingredients should not enter in the description of the quantum Hall effect. But this is not a real issue, because we can just interpret the $\\tau$ matrices as acting in the space of left and rightmovers. This flexibility in interpreting the Hamiltonian terms in different ways, depending on the context, is part of the advantage of thinking in terms of toy models.\n",
 "\n",
 "Finally, before we go on with our plan, keep in mind that considering the phase transition point of a lower dimensional model turns out to be a fairly generic strategy to construct higher dimensional topological models."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"It seems that both a quantum Hall bar and a Kitaev chain can have chiral states. \"\n",
 " \"Apart from the two systems having different dimensionality\"\n",
 " \", what's the fundamental difference between the two cases?\")\n",
 "answers = [\"The quantum Hall edge states go in opposite directions, while the Kitaev states go in the same direction.\",\n",
 " \"The quantum Hall edge states go in the same direction, while the Kitaev states go in opposite directions.\",\n",
 " \"The quantum Hall edges always cross zero energy at zero momentum while the Kitaev states don't.\",\n",
 " (\"The Kitaev chiral states exist only at specific parameter values, \"\n",
 " \"while the quantum Hall edge states don't.\")]\n",
 "explanation = (\"The pair of chiral states in the Kitaev model only exists at \"\n",
 " \"the phase transition point, when the chain becomes gapless. \"\n",
 " \"On the other hand, chiral edge states are a topological property of the quantum Hall state. \"\n",
 " \"They are separated by a gapped bulk which protects them, and they exist for a full range of parameter values.\")\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=3, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# QHE without a magnetic field"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Deriving the model Hamiltonian\n",
 "\n",
 "Let us now couple the wires to get the quantum Hall system as promised. We take a stack of chains all extending along the horizontal $x$ direction, like in the figure above. We stack them one next to the other along the $y$ direction, so that we form a square lattice. If we take a large (ideally infinite) stack of chains we have a truly twodimensional system.\n",
 "\n",
 "Now let us make this formal by first labeling the chains by an index $n_y$, which takes integer values. Let us also replace $k\\rightarrow k_x$ to denote the wavevector along a chain. Hence a single chain has the Hamiltonian $\\left[(2 t\\cos{k_x}+\\mu)\\,\\tau_z+\\Delta \\sin{k_x}\\tau_y\\right]\\,\\otimes\\,\\left\\,n_y\\right\\rangle\\left\\langle n_y\\right$. The projector $\\left\\,n_y\\right\\rangle\\left\\langle n_y\\right$ is needed to single out one chain from the stack. \n",
 "\n",
 "Now all that we have to do is to couple the $\\tau_y=1$ branch of one chain to the $\\tau_y=+1$ branch of a neighboring chain, and we will have a quantum Hall state.\n",
 "\n",
 "A term coupling opposite movers from different chains is $\\left\\,n_y\\right\\rangle\\left\\langle n_y+1\\right\\otimes (\\tau_z+i\\tau_x)$. The first part couples neighboring chains and the matrix $(\\tau_z+i\\tau_x)$ turns a right mover into a left mover, which is what we want. Let's call the strength of this coupling $\\gamma$.\n",
 "\n",
 "To obtain the complete Hamiltonian of the stack of chains we just need to sum over $n_y$, and we obtain\n",
 "\n",
 "$$H=\\sum_{n_y}\\,\\left[(2 t\\cos{k_x}+\\mu)\\tau_z+\\Delta \\sin{k_x}\\tau_y\\right]\\,\\otimes\\,\\left\\,n_y\\right\\rangle\\left\\langle n_y\\right\\,\\,\\gamma\\,\\sum_{n_y}\\,\\left[\\left\\,n_y\\right\\rangle\\left\\langle n_y+1\\right\\otimes (\\tau_z+i\\tau_x)\\,+\\,\\textrm{h.c.}\\right].$$\n",
 "\n",
 "This Hamiltonian should in principle suffice to produce a quantum Hall state."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Gap and edge states\n",
 "\n",
 "Let's first consider a finite number of chains $n_y=1,\\dots,N$. If you tune each chain individually to the point $\\mu = 2t$, it's easy to check that at $k_x \\approx 0$ the above Hamiltonian has one rightmoving edge eigenstate for $n_y=1$ with eigenvalue $\\approx \\Delta \\, k_x$, and a leftmoving edge eigenstate for $n_y=N$ with eigenvalue $\\approx \\Delta\\,k_x$.\n",
 "\n",
 "The next thing we need to check is that these are the only eigenstates close to zero energy. In other words, is the system gapped in the twodimensional bulk? To see this, let's switch to an infinite stack of chains along the $y$ direction. We then have full translational invariance, so we can go to momentum space in the $y$ direction.\n",
 "\n",
 "This leads us to the twodimensional Bloch Hamiltonian \n",
 "\n",
 "$$H(k_x,k_y)=[(2t\\cos{k_x}+\\mu)\\tau_z+\\Delta\\sin{k_x}\\tau_y]2\\gamma\\,[\\cos{k_y}\\tau_z+\\sin{k_y}\\tau_x].$$ \n",
 "\n",
 "Since this Hamiltonian is a sum of three Pauli matrices, the energy spectrum can be written down as \n",
 "\n",
 "$$E(k_x,k_y)=\\pm\\sqrt{\\Delta^2\\sin^2{k_x}+(2\\gamma\\cos{k_y}+\\mu+2t\\cos{k_x}))^2+4\\gamma^2\\sin^2{k_y}}.$$ \n",
 "\n",
 "Aside from special points, this spectrum is gapped, just like we wanted. For instance it is gapped if $\\mu<2t2\\gamma$. If we start from this point and increase the value of $\\mu$, the gap closes at the point $\\mu = 2t2\\gamma$ and then reopens:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "%%output fig='png'\n",
 "p = SimpleNamespace(t=1.0, delta=0.3, gamma=.5, mu=None)\n",
 "syst = Qi_Wu_Zhang()\n",
 "mus = np.linspace(2, 0, 11)\n",
 "holoviews.HoloMap({p.mu: spectrum(syst, p, zticks=[4, 2, 0, 2, 4], title=title)\n",
 " for p.mu in mus}, kdims=[r'$\\mu$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As a check that everything worked, let's look at the dispersion of a ribbon with finite width along the $y$ direction. If there are edge states, we should see a Diraclike crossing around $k_x=0$."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "p = SimpleNamespace(t=1.0, delta=0.3, gamma=0.5, mu=None)\n",
 "syst = Qi_Wu_Zhang(w=15)\n",
 "mus = np.linspace(2, 0, 11)\n",
 "\n",
 "style = {'xdim': r'$k$',\n",
 " 'ydim': r'$E/t$',\n",
 " 'xticks': pi_ticks,\n",
 " 'yticks': [2, 0, 2],\n",
 " 'ylims': [2.2, 2.2],\n",
 " 'title': title}\n",
 "\n",
 "holoviews.HoloMap({p.mu: spectrum(syst, p, **style) for p.mu in mus}, kdims=[r'$\\mu$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We see that the crossing is there, and it disappears when the gap closes. So we can identify the point $\\mu=2t2\\gamma$ as a critical point at which the quantum Hall state becomes topologically trivial.\n",
 "\n",
 "While details such as the bulk spectrum and edge dispersion are different from the case with a magnetic field, the bulkedge correspondence tells us that the edge states are as robust as those of the quantum Hall effect we studied last week."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"How does our lattice model with no magnetic field differ from the original quantum Hall effect?\")\n",
 "answers = [\"Since there is no magnetic field the quantum Hall effect on a lattice preserves time reversal symmetry.\",\n",
 " \"Quantum Hall effect in a magnetic field has Landau levels \"\n",
 " \"that do not disperse in k while they disperse in the lattice.\",\n",
 " \"Quantum Hall effect in the lattice has no chiral edge states, which arise from skipping orbits in a magnetic field.\",\n",
 " \"In a magnetic field the filling fraction is fixed to integer per flux quantum, while in the \"\n",
 " \"lattice the filling fraction per unit cell is arbitrary.\"]\n",
 "explanation = (\"In a lattice one gets a nonconstant bandstructure which forms a Dirac cone near the phase transition.\")\n",
 "MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Dirac equation at the phase transition"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Back in week 1, we saw with the Kitaev chain that the \"domino argument\" led to two distinct phases. The same is true for our model, even though the parameter space is larger than before, with three distinct parameters $\\mu, t, \\gamma$, which we have not explored fully. But let's not worry about establishing the full phase diagram. For now it's more interesting to study the transition point we have found.\n",
 "\n",
 "The two phases around this point are easy to understand. One is the quantum Hall phase with chiral edge states, which was our initial goal. The other one is a topologically trivial phase. The trivial phase can be understood by first taking $\\mu$ very positive and large, and then taking $\\gamma\\to 0$. Then we just have a bunch of gapped 1D chains next to each other without any tunneling between them, a trivial phase with no edge states."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "It is once again useful to write down the effective Hamiltonian near to the transition point at $k_x\\approx 0$ and $k_y\\approx 0$. It is given by a 2D Dirac Hamiltonian:\n",
 "\n",
 "\n",
 "$$H_{\\textrm{Dirac}}=[\\Delta k_x\\tau_y2\\gamma k_y\\tau_x+m\\tau_z],$$ \n"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The combination $m=(\\mu +2t+2\\gamma)$ serves as the 'mass' in this Dirac model. As before, we see that the gapless phase transition point at $m=0$ is described by a massless Dirac Hamiltonian. The phase transition separates the topological from the trivial phase, and the two phases are characterized by a different sign of the mass (in this case $m>0$ in the topological phase and $m<0$ in the trivial phase)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As with Kitaev chains, the Dirac model gives us another way to construct chiral edge states at the domain wall between topological and nontopological phases. Back in week 1, we saw that for a one dimensional Dirac model, a domain wall in the mass $m$ supports a nondegenerate zero mode. Fixing $k_y=0$, we see that the one dimensional Dirac Hamiltonian here is identical to the one we saw in week 1, where the zero mode at the domain wall between $m<0$ and $m>0$ was an eigenstate of $\\tau_x$ with eigenvalue $+1$. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Unlike the onedimensional case, the zero mode is not stationary in the two dimensional case. By adding $2\\gamma k_y\\tau_x$ as a perturbation, we see that the energy of the state increases as \n",
 "\n",
 "$$\\epsilon(k_y)\\approx 2\\gamma k_y\\,,$$\n",
 "\n",
 "so it has a velocity $v=2\\gamma$, the direction of which depends on the sign of $\\gamma$. So we see how we can get the chiral edge modes analytically."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Conclusion"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"CXgAcOOVlag\", src_location='4.1summary')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Questions about what you learned? Ask them below**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion('Questions', 'Chern insulators')"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w4_haldane/QHE_lattice.md b/w4_haldane/QHE_lattice.md
new file mode 100644
index 0000000..0431543
 /dev/null
+++ b/w4_haldane/QHE_lattice.md
@@ 0,0 +1,233 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+%output size=150
+pi_ticks = [(np.pi, r'$\pi$'), (0, '0'), (np.pi, r'$\pi$')]
+
+def Qi_Wu_Zhang(w=None):
+ def onsite(site, p):
+ return  p.mu * pauli.sz
+
+ def hopx(site1, site2, p):
+ return  0.5j * p.delta * pauli.sy  p.t * pauli.sz
+
+ def hopy(site1, site2, p):
+ return  1j * p.gamma * pauli.sx  p.gamma * pauli.sz
+
+ lat = kwant.lattice.square()
+
+ if w == None:
+ syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))
+ syst[lat.shape(lambda pos: True, (0, 0))] = onsite
+ else:
+ def ribbon_shape(pos):
+ return (0 <= pos[1] < w )
+
+ sym = kwant.TranslationalSymmetry((1, 0))
+ syst = kwant.Builder(sym)
+ syst[lat.shape(ribbon_shape, (0, 0))] = onsite
+
+ syst[kwant.HoppingKind((1,0), lat)] = hopx
+ syst[kwant.HoppingKind((0,1), lat)] = hopy
+ return syst
+
+
+def title(p):
+ title = r"$t={:.2}$, $\mu={:.2}$, $\Delta={:.2}$, $\gamma={:.2}$"
+ title = title.format(p.t, p.mu, p.delta, p.gamma)
+ return title
+```
+
+## Quantum Hall effect on a lattice and the Dirac Hamiltonian
+* Pairs of chiral edges in a 1D wire
+* Coupling wires and QHE without field
+* Dirac equation at the phase transition
+
+# Introduction: stacking wires
+
+Looking back at the material from the past weeks, you might have the impression that the quantum Hall effect and one dimensional topological superconductors are really different topics, and not connected at all.
+
+Xiaoliang Qi from Stanford University will now explain that this is not the case, and will also introduce this week's topic  Chern insulators.
+
+
+```python
+MoocVideo("osKP6x0Ewbo", src_location="4.1intro")
+```
+
+# Pairs of chiral edges in a 1D wire
+
+Last week, we started with a phenomenological description of the quantum Hall effect. We learned that one way to get a quantum Hall state is to place electrons in an external magnetic field.
+
+However, we still don't have a simple lattice Hamiltonian describing the quantum Hall effect  we'd like to have something like the Kitaev chain model, which was very useful to understand Majoranas in the first two weeks of the course. An added benefit of finding this tight binding model is that it would not need an external magnetic field to exhibit the unique properties of quantum Hall effect.
+
+These models exist, and they are referred to as *Chern insulators*. The quantum Hall effect without an external magnetic field is also referred to as the *quantum anomalous Hall effect*. Duncan Haldane, from who we will hear in the next chapter, invented the first model of a Chern insulator now known as *Haldane model*. However, in this chapter, we will use a more natural route that fits better into the context of our course so far.
+
+## General strategy to construct a lattice model for the Quantum Hall Effect
+
+What we will do to get a model for a Chern insulator is to follow a "domino prescription", as we did to get the Kitaev model in week 1. Our strategy will have two key aspects:
+
+* Focusing on the unique property of the quantum Hall edge that cannot exist in isolation from a bulk, and can only be present because of bulkboundary correspondence. For the Kitaev chain, this property was the presence of unpaired Majorana modes. In the quantum Hall effect, it is the chiral edge states.
+
+* Finding a lower dimensional building block, from which we can somehow “extract“ in a clever way the exotic object we are interested in. In the Kitaev chain, these were the fermionic sites, which we could think of as a pair of Majorana modes.
+
+So we need to find a onedimensional system which can host a pair of chiral edge states. Since they are onedimensional, these states will necessarily be spatially on top of each other, essentially a pair of propagating modes with opposite velocity. Once we have this building block, we can follow the domino prescription: couple the counterpropagating states in pairs, just like we did with Majorana modes. We then end up with a pair of spatially separated chiral edge states, and so a quantum Hall insulator without magnetic field.
+
+So our plan is to turn the system on the left into the system on the right:
+
+![](figures/coupled_chains.svg)
+
+Voilà  we have a lattice model for the 2D quantum Hall state!
+
+## Getting a one dimensional wire with a pair of edge states
+
+Let's focus on the first essential step of our plan: finding a one dimensional system with a pair of counterpropagating chiral states.
+
+You might guess that the easiest way to get a pair of states moving in opposite directions is to take the usual one dimensional single electron Hamiltonian with an effective mass. Such a system has a parabolic dispersion and the low energy excitations at a finite Fermi wavevector $k=\pm k_F$ move in opposite directions. The catch is that these two states have different momenta, and it is tricky (though not impossible) to deal with momentum conservation when pairing the edges. So we will avoid this approach.
+
+The more educated guess we make a model that we have already encountered, the Dirac model $H= \Delta\,k\, \tau_y$ of the Kitaev chain at the topological phase transition.
+
+More specifically, in the first week we wrote the Kitaev Hamiltonian in momentum space as $H(k)=(2 t\cos{k}+\mu)\,\tau_z+\Delta \sin{k}\tau_y$. At the critical point $\mu=2t$, we found the Kitaev Hamiltonian to become
+
+$$H=2t(\cos{k}1)\,\tau_z+\Delta\sin{k}\,\tau_y.$$
+
+We see that at $k\approx 0$ we have a pair of states with wave functions the eigenvalues $\pm 1$ of $\tau_y$, and with opposite and equal velocities.
+
+At this point you might worry that the Kitaev model has superconductivity, and so the $\tau$ matrices refer to particle and hole degrees of freedom. Indeed, these ingredients should not enter in the description of the quantum Hall effect. But this is not a real issue, because we can just interpret the $\tau$ matrices as acting in the space of left and rightmovers. This flexibility in interpreting the Hamiltonian terms in different ways, depending on the context, is part of the advantage of thinking in terms of toy models.
+
+Finally, before we go on with our plan, keep in mind that considering the phase transition point of a lower dimensional model turns out to be a fairly generic strategy to construct higher dimensional topological models.
+
+
+```python
+question = ("It seems that both a quantum Hall bar and a Kitaev chain can have chiral states. "
+ "Apart from the two systems having different dimensionality"
+ ", what's the fundamental difference between the two cases?")
+answers = ["The quantum Hall edge states go in opposite directions, while the Kitaev states go in the same direction.",
+ "The quantum Hall edge states go in the same direction, while the Kitaev states go in opposite directions.",
+ "The quantum Hall edges always cross zero energy at zero momentum while the Kitaev states don't.",
+ ("The Kitaev chiral states exist only at specific parameter values, "
+ "while the quantum Hall edge states don't.")]
+explanation = ("The pair of chiral states in the Kitaev model only exists at "
+ "the phase transition point, when the chain becomes gapless. "
+ "On the other hand, chiral edge states are a topological property of the quantum Hall state. "
+ "They are separated by a gapped bulk which protects them, and they exist for a full range of parameter values.")
+MoocMultipleChoiceAssessment(question, answers, correct_answer=3, explanation=explanation)
+```
+
+# QHE without a magnetic field
+
+## Deriving the model Hamiltonian
+
+Let us now couple the wires to get the quantum Hall system as promised. We take a stack of chains all extending along the horizontal $x$ direction, like in the figure above. We stack them one next to the other along the $y$ direction, so that we form a square lattice. If we take a large (ideally infinite) stack of chains we have a truly twodimensional system.
+
+Now let us make this formal by first labeling the chains by an index $n_y$, which takes integer values. Let us also replace $k\rightarrow k_x$ to denote the wavevector along a chain. Hence a single chain has the Hamiltonian $\left[(2 t\cos{k_x}+\mu)\,\tau_z+\Delta \sin{k_x}\tau_y\right]\,\otimes\,\left\,n_y\right\rangle\left\langle n_y\right$. The projector $\left\,n_y\right\rangle\left\langle n_y\right$ is needed to single out one chain from the stack.
+
+Now all that we have to do is to couple the $\tau_y=1$ branch of one chain to the $\tau_y=+1$ branch of a neighboring chain, and we will have a quantum Hall state.
+
+A term coupling opposite movers from different chains is $\left\,n_y\right\rangle\left\langle n_y+1\right\otimes (\tau_z+i\tau_x)$. The first part couples neighboring chains and the matrix $(\tau_z+i\tau_x)$ turns a right mover into a left mover, which is what we want. Let's call the strength of this coupling $\gamma$.
+
+To obtain the complete Hamiltonian of the stack of chains we just need to sum over $n_y$, and we obtain
+
+$$H=\sum_{n_y}\,\left[(2 t\cos{k_x}+\mu)\tau_z+\Delta \sin{k_x}\tau_y\right]\,\otimes\,\left\,n_y\right\rangle\left\langle n_y\right\,\,\gamma\,\sum_{n_y}\,\left[\left\,n_y\right\rangle\left\langle n_y+1\right\otimes (\tau_z+i\tau_x)\,+\,\textrm{h.c.}\right].$$
+
+This Hamiltonian should in principle suffice to produce a quantum Hall state.
+
+## Gap and edge states
+
+Let's first consider a finite number of chains $n_y=1,\dots,N$. If you tune each chain individually to the point $\mu = 2t$, it's easy to check that at $k_x \approx 0$ the above Hamiltonian has one rightmoving edge eigenstate for $n_y=1$ with eigenvalue $\approx \Delta \, k_x$, and a leftmoving edge eigenstate for $n_y=N$ with eigenvalue $\approx \Delta\,k_x$.
+
+The next thing we need to check is that these are the only eigenstates close to zero energy. In other words, is the system gapped in the twodimensional bulk? To see this, let's switch to an infinite stack of chains along the $y$ direction. We then have full translational invariance, so we can go to momentum space in the $y$ direction.
+
+This leads us to the twodimensional Bloch Hamiltonian
+
+$$H(k_x,k_y)=[(2t\cos{k_x}+\mu)\tau_z+\Delta\sin{k_x}\tau_y]2\gamma\,[\cos{k_y}\tau_z+\sin{k_y}\tau_x].$$
+
+Since this Hamiltonian is a sum of three Pauli matrices, the energy spectrum can be written down as
+
+$$E(k_x,k_y)=\pm\sqrt{\Delta^2\sin^2{k_x}+(2\gamma\cos{k_y}+\mu+2t\cos{k_x}))^2+4\gamma^2\sin^2{k_y}}.$$
+
+Aside from special points, this spectrum is gapped, just like we wanted. For instance it is gapped if $\mu<2t2\gamma$. If we start from this point and increase the value of $\mu$, the gap closes at the point $\mu = 2t2\gamma$ and then reopens:
+
+
+```python
+%%output fig='png'
+p = SimpleNamespace(t=1.0, delta=0.3, gamma=.5, mu=None)
+syst = Qi_Wu_Zhang()
+mus = np.linspace(2, 0, 11)
+holoviews.HoloMap({p.mu: spectrum(syst, p, zticks=[4, 2, 0, 2, 4], title=title)
+ for p.mu in mus}, kdims=[r'$\mu$'])
+```
+
+As a check that everything worked, let's look at the dispersion of a ribbon with finite width along the $y$ direction. If there are edge states, we should see a Diraclike crossing around $k_x=0$.
+
+
+```python
+p = SimpleNamespace(t=1.0, delta=0.3, gamma=0.5, mu=None)
+syst = Qi_Wu_Zhang(w=15)
+mus = np.linspace(2, 0, 11)
+
+style = {'xdim': r'$k$',
+ 'ydim': r'$E/t$',
+ 'xticks': pi_ticks,
+ 'yticks': [2, 0, 2],
+ 'ylims': [2.2, 2.2],
+ 'title': title}
+
+holoviews.HoloMap({p.mu: spectrum(syst, p, **style) for p.mu in mus}, kdims=[r'$\mu$'])
+```
+
+We see that the crossing is there, and it disappears when the gap closes. So we can identify the point $\mu=2t2\gamma$ as a critical point at which the quantum Hall state becomes topologically trivial.
+
+While details such as the bulk spectrum and edge dispersion are different from the case with a magnetic field, the bulkedge correspondence tells us that the edge states are as robust as those of the quantum Hall effect we studied last week.
+
+
+```python
+question = ("How does our lattice model with no magnetic field differ from the original quantum Hall effect?")
+answers = ["Since there is no magnetic field the quantum Hall effect on a lattice preserves time reversal symmetry.",
+ "Quantum Hall effect in a magnetic field has Landau levels "
+ "that do not disperse in k while they disperse in the lattice.",
+ "Quantum Hall effect in the lattice has no chiral edge states, which arise from skipping orbits in a magnetic field.",
+ "In a magnetic field the filling fraction is fixed to integer per flux quantum, while in the "
+ "lattice the filling fraction per unit cell is arbitrary."]
+explanation = ("In a lattice one gets a nonconstant bandstructure which forms a Dirac cone near the phase transition.")
+MoocMultipleChoiceAssessment(question, answers, correct_answer=1, explanation=explanation)
+```
+
+# Dirac equation at the phase transition
+
+Back in week 1, we saw with the Kitaev chain that the "domino argument" led to two distinct phases. The same is true for our model, even though the parameter space is larger than before, with three distinct parameters $\mu, t, \gamma$, which we have not explored fully. But let's not worry about establishing the full phase diagram. For now it's more interesting to study the transition point we have found.
+
+The two phases around this point are easy to understand. One is the quantum Hall phase with chiral edge states, which was our initial goal. The other one is a topologically trivial phase. The trivial phase can be understood by first taking $\mu$ very positive and large, and then taking $\gamma\to 0$. Then we just have a bunch of gapped 1D chains next to each other without any tunneling between them, a trivial phase with no edge states.
+
+It is once again useful to write down the effective Hamiltonian near to the transition point at $k_x\approx 0$ and $k_y\approx 0$. It is given by a 2D Dirac Hamiltonian:
+
+
+$$H_{\textrm{Dirac}}=[\Delta k_x\tau_y2\gamma k_y\tau_x+m\tau_z],$$
+
+
+The combination $m=(\mu +2t+2\gamma)$ serves as the 'mass' in this Dirac model. As before, we see that the gapless phase transition point at $m=0$ is described by a massless Dirac Hamiltonian. The phase transition separates the topological from the trivial phase, and the two phases are characterized by a different sign of the mass (in this case $m>0$ in the topological phase and $m<0$ in the trivial phase).
+
+As with Kitaev chains, the Dirac model gives us another way to construct chiral edge states at the domain wall between topological and nontopological phases. Back in week 1, we saw that for a one dimensional Dirac model, a domain wall in the mass $m$ supports a nondegenerate zero mode. Fixing $k_y=0$, we see that the one dimensional Dirac Hamiltonian here is identical to the one we saw in week 1, where the zero mode at the domain wall between $m<0$ and $m>0$ was an eigenstate of $\tau_x$ with eigenvalue $+1$.
+
+Unlike the onedimensional case, the zero mode is not stationary in the two dimensional case. By adding $2\gamma k_y\tau_x$ as a perturbation, we see that the energy of the state increases as
+
+$$\epsilon(k_y)\approx 2\gamma k_y\,,$$
+
+so it has a velocity $v=2\gamma$, the direction of which depends on the sign of $\gamma$. So we see how we can get the chiral edge modes analytically.
+
+# Conclusion
+
+
+```python
+MoocVideo("CXgAcOOVlag", src_location='4.1summary')
+```
+
+**Questions about what you learned? Ask them below**
+
+
+```python
+MoocDiscussion('Questions', 'Chern insulators')
+```
diff git a/w4_haldane/haldane_model.ipynb b/w4_haldane/haldane_model.ipynb
deleted file mode 100644
index 9c6b682..0000000
 a/w4_haldane/haldane_model.ipynb
+++ /dev/null
@@ 1,748 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true,
 "scrolled": true
 },
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "import scipy\n",
 "%output size=150 fig='png'\n",
 "pi_ticks = [(np.pi, r'$\\pi$'), (0, '0'), (np.pi, r'$\\pi$')]\n",
 "\n",
 "\n",
 "def haldane(w=20, boundary='zigzag'):\n",
 " def ribbon_shape_zigzag(pos):\n",
 " return (0.5 / np.sqrt(3)  0.1 <= pos[1] < np.sqrt(3) * w / 2 + 0.01)\n",
 "\n",
 " def ribbon_shape_armchair(pos):\n",
 " return (1 <= pos[0] < w)\n",
 "\n",
 " def onsite(site, p):\n",
 " if site.family == a:\n",
 " return p.m\n",
 " else:\n",
 " return p.m\n",
 "\n",
 " def nn_hopping(site1, site2, p):\n",
 " return p.t\n",
 "\n",
 " def nnn_hopping(site1, site2, p):\n",
 " return 1j * p.t_2\n",
 "\n",
 " lat = kwant.lattice.honeycomb()\n",
 " a, b = lat.sublattices\n",
 " nnn_hoppings_a = (((1, 0), a, a), ((0, 1), a, a), ((1, 1), a, a))\n",
 " nnn_hoppings_b = (((1, 0), b, b), ((0, 1), b, b), ((1, 1), b, b))\n",
 "\n",
 " if boundary == 'zigzag':\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry((1, 0)))\n",
 " syst[lat.shape(ribbon_shape_zigzag, (0, 0))] = onsite\n",
 " elif boundary == 'armchair':\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry((0, np.sqrt(3))))\n",
 " syst[lat.shape(ribbon_shape_armchair, (0, 0))] = onsite\n",
 " else:\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs)) \n",
 " syst[lat.shape(lambda pos: True, (0, 0))] = onsite\n",
 " \n",
 " syst[lat.neighbors()] = nn_hopping\n",
 " syst[[kwant.builder.HoppingKind(*hopping) for hopping in nnn_hoppings_a]] = nnn_hopping\n",
 " syst[[kwant.builder.HoppingKind(*hopping) for hopping in nnn_hoppings_b]] = nnn_hopping\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def Qi_Wu_Zhang():\n",
 " def onsite(site, p):\n",
 " return  p.mu * pauli.sz\n",
 " \n",
 " def hopx(site1, site2, p):\n",
 " return  0.5j * p.delta * pauli.sy  p.t * pauli.sz\n",
 " \n",
 " def hopy(site1, site2, p):\n",
 " return  1j * p.gamma * pauli.sx  p.gamma * pauli.sz \n",
 " \n",
 " lat = kwant.lattice.square()\n",
 "\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))\n",
 " syst[lat.shape(lambda pos: True, (0, 0))] = onsite\n",
 " syst[kwant.HoppingKind((1,0), lat)] = hopx\n",
 " syst[kwant.HoppingKind((0,1), lat)] = hopy\n",
 " return syst\n",
 "\n",
 "\n",
 "def berry_curvature(syst, p, ks, num_filled_bands=1):\n",
 " \"\"\"Berry curvature of a system.\n",
 " \n",
 " Parameters:\n",
 " \n",
 " sys : kwant.Builder\n",
 " A 2D infinite system.\n",
 " p : SimpleNamespace\n",
 " The arguments expected by the system.\n",
 " ks : 1D arraylike\n",
 " Values of momentum grid to be used for Berry curvature calculation.\n",
 " num_filled_bands : int\n",
 " The number of filled bands.\n",
 "\n",
 " Returns:\n",
 " \n",
 " bc : 2D array\n",
 " Berry curvature on each square in a `ks x ks` grid.\n",
 " \"\"\"\n",
 " # Calculate an array of eigenvectors.\n",
 " B = np.array(syst.symmetry.periods).T\n",
 " A = B @ np.linalg.inv(B.T @ B)\n",
 "\n",
 " syst = kwant.wraparound.wraparound(syst).finalized()\n",
 "\n",
 " def energy(kx, ky):\n",
 " k = np.array([kx, ky])\n",
 " kx, ky = np.linalg.solve(A, k)\n",
 " H = syst.hamiltonian_submatrix([p, kx, ky], sparse=False)\n",
 " return scipy.linalg.eigh(H)[1]\n",
 " \n",
 " vectors = np.array([[energy(kx, ky)[:, :num_filled_bands] for kx in ks] for ky in ks])\n",
 " \n",
 " # The actual Berry curvature calculation\n",
 " vectors_x = np.roll(vectors, 1, 0)\n",
 " vectors_xy = np.roll(vectors_x, 1, 1)\n",
 " vectors_y = np.roll(vectors, 1, 1)\n",
 "\n",
 " shifted_vecs = [vectors, vectors_x, vectors_xy, vectors_y]\n",
 "\n",
 " v_shape = vectors.shape\n",
 "\n",
 " shifted_vecs = [i.reshape(1, v_shape[2], v_shape[1]) for i in shifted_vecs]\n",
 "\n",
 " dets = np.ones(len(shifted_vecs[0]), dtype=complex)\n",
 " for vec, shifted in zip(shifted_vecs, np.roll(shifted_vecs, 1, 0)):\n",
 " dets *= [np.linalg.det(a.T.conj() @ b) for a, b in zip(vec, shifted)]\n",
 " bc = np.angle(dets).reshape(int(np.sqrt(len(dets))), 1) \n",
 " \n",
 " bc = (bc + np.pi / 2) % (np.pi)  np.pi / 2\n",
 " \n",
 " return bc\n",
 "\n",
 "\n",
 "def plot_berry_curvature(syst, p, ks=None, title=None): \n",
 " if ks is None:\n",
 " ks = np.linspace(np.pi, np.pi, 150, endpoint=False)\n",
 " bc = berry_curvature(syst, p, ks)[1:1,1:1]\n",
 " vmax = max(np.abs(bc).min(), np.abs(bc).max())\n",
 " kwargs = {'bounds': (ks.min(), ks.min(), ks.max(), ks.max()),\n",
 " 'kdims': [r'$k_x$', r'$k_y$']}\n",
 "\n",
 " if callable(title):\n",
 " kwargs['label'] = title(p)\n",
 "\n",
 " plot = {'xticks': pi_ticks, 'yticks': pi_ticks}\n",
 " style = {'clims': [vmax, vmax]}\n",
 " return holoviews.Image(bc, **kwargs)(plot=plot, style=style)\n",
 "\n",
 "\n",
 "def title(p):\n",
 " title = r'$t={:.2}$, $t_2={:.2}$, $M={:.2}$'\n",
 " return title.format(p.t, p.t_2, p.m)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Intro"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Duncan Haldane from Princeton University will teach us about an interesting two dimensional toymodel which he [introduced](http://faculty.washington.edu/cobden/papers/haldane88.pdf) in 1988, and which has become a prototype for the anomalous quantum Hall effect."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"7nVO4uMmdo\", src_location='4.2intro')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We will now study the model in detail, starting from the beginning. Along the way, we will also learn about the Chern number, the bulk topological invariant of a quantum Hall state."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Dirac cones in graphene"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In the last chapter we saw how it is possible to obtain a quantum Hall state by coupling onedimensional systems. At the end, our recipe was to first obtain a Dirac cone, add a mass term to it and finally to make this mass change sign. Following this recipe we were able to obtain chiral edge states without applying an external magnetic field.\n",
 "\n",
 "There is a real (and a very important) twodimensional system which has Dirac cones: [graphene](http://en.wikipedia.org/wiki/Graphene). So in this chapter we will take graphene and make it into a topological system with chiral edge states.\n",
 "\n",
 "Graphene is a single layer of carbon atoms arranged in a honeycomb lattice. It is a triangular lattice with two atoms per unit cell, type $A$ and type $B$, represented by red and blue sites in the figure:\n",
 "\n",
 "![](figures/graphene.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Hence, the wave function in a unit cell can be written as a vector $(\\Psi_A, \\Psi_B)^T$ of amplitudes on the two sites $A$ and $B$. Taking a simple tightbinding model where electrons can hop between neighboring sites with hopping strength $t$, one obtains the Bloch Hamiltonian:\n",
 "\n",
 "$$\n",
 "H_0(\\mathbf{k})= \\begin{pmatrix} 0 & h(\\mathbf{k}) \\\\ h^\\dagger(\\mathbf{k}) & 0 \\end{pmatrix}\\,,\n",
 "$$\n",
 "\n",
 "with $\\mathbf{k}=(k_x, k_y)$ and\n",
 "\n",
 "$$h(\\mathbf{k}) = t_1\\,\\sum_i\\,\\exp\\,\\left(i\\,\\mathbf{k}\\cdot\\mathbf{a}_i\\right)\\,.$$\n",
 "\n",
 "Here $\\mathbf{a}_i$ are the three vectors in the figure, connecting nearest neighbors of the lattice [we set the lattice spacing to one, so that for instance $\\mathbf{a}_1=(1,0)$]. Introducing a set of Pauli matrices $\\sigma$ which act on the sublattice degree of freedom, we can write the Hamiltonian in a compact form as\n",
 "\n",
 "$$H_0(\\mathbf{k}) = t_1\\,\\sum_i\\,\\left[\\sigma_x\\,\\cos(\\mathbf{k}\\cdot\\mathbf{a}_i)\\sigma_y \\,\\sin(\\mathbf{k}\\cdot\\mathbf{a}_i)\\right]\\,.$$\n",
 "\n",
 "The energy spectrum $E(\\mathbf{k}) = \\pm \\,\\lefth(\\mathbf{k})\\right$ gives rise to the famous band structure of graphene, with the two bands touching at the six corners of the Brillouin zone:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "p = SimpleNamespace(t=1.0, t_2=0.0, m=0.0, phi=np.pi/2)\n",
 "syst = haldane(boundary='infinite')\n",
 "k = (4 / 3) * np.linspace(np.pi, np.pi, 150)\n",
 "spectrum(syst, p, k_x=k, k_y=k, title=title)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Only two of these six Dirac cones are really distinct, the ones at $\\mathbf{K}=(2\\pi/3, 2\\pi/3\\sqrt{3})$ and $\\mathbf{K}'=(2\\pi/3, 2\\pi/3\\sqrt{3})$. All the others can be obtained by adding some reciprocal lattice vector to $\\mathbf{K}$ and $\\mathbf{K}'$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Discrete symmetries of graphene"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The symmetries of graphene were discussed intensively in the video, so let's review them.\n",
 "\n",
 "As we already said in our first week, graphene is the prototype of a system with sublattice symmetry, which makes the Hamiltonian block offdiagonal with respect to the two sublattices. The sublattice symmetry reads\n",
 "\n",
 "$$\\sigma_z\\,H_0(\\mathbf{k})\\,\\sigma_z = H_0(\\mathbf{k})\\,.$$\n",
 "\n",
 "Sublattice symmetry is only approximate, and it is consequence of the nearest neighbor tightbinding model. Just like the inversion symmetry mentioned in the video, it protects the Dirac points and needs to be broken in order to open a gap."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In addition to sublattice and inversion symmetry, the honeycomb lattice also has a threefold rotation symmetry around the center of the unit cell. This symmetry is important to make the Dirac cones appear in the first place, but it will not play a role in all that follows.\n",
 "\n",
 "Finally, there is timereversal symmetry, which at the moment is perfectly preserved in our tightbinding model. Since we are not considering the spin degree of freedom of the electrons, the timereversal symmetry operator in real space is just complex conjugation. In momentum space representation, timereversal symmetry reads\n",
 "\n",
 "$$ H_0(\\mathbf{k}) = H_0^*(\\mathbf{k})\\,.$$"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "It's important to note that timereversal symmetry sends $\\mathbf{K}$ into $\\mathbf{K}'$ and therefore it exchanges the two Dirac cones.\n",
 "\n",
 "The product of (approximate) sublattice and timereversal symmetries yields a further discrete symmetry, a particlehole symmetry $\\sigma_z H^*(\\mathbf{k})\\,\\sigma_z = H_0(\\mathbf{k})$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Making graphene topological"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's recall that our goal is to make our graphene sheet enter a quantum Hall state, with chiral edge states. The first necessary step is to make the bulk of the system gapped. \n",
 "\n",
 "How can we open a gap in graphene? The Dirac points are protected by both sublattice (inversion) and timereversal symmetry. So there are many ways we can think of to open an energy gap at $\\mathbf{K}$ and $\\mathbf{K}'$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## First try\n",
 "\n",
 "The easiest way to break sublattice symmetry is to assign an opposite onsite energy $M$ or $M$ to the $A$ or $B$ sites respectively. The Hamiltonian is then given by\n",
 "\n",
 "$$ H_0(\\mathbf{k}) + M\\,\\sigma_z\\,.$$\n",
 "\n",
 "This leads to a gapped spectrum,\n",
 "\n",
 "$$E(\\mathbf{k})=\\pm \\sqrt{\\lefth(\\mathbf{k})\\right^2 + M^2}\\,.$$\n",
 "\n",
 "However, we quickly realize that by doing this we end up in a rather boring situation. Taking the limit $\\leftM\\right \\gg t_1$, we obtain electronic states which are localized in one of the two sublattices $A$ or $B$, independent of the sign of $M$. Most importantly, there is no trace of edge states.\n",
 "\n",
 "It's easy to see why this mass term is hopeless: it preserves timereversal symmetry. And with the timereversal symmetry present, it is definitely impossible to obtain chiral edge states."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Second try\n",
 "\n",
 "There is another, more ingenious way to gap out the Dirac cones in graphene, which is the essence of today's model. It involves adding imaginary secondnearest neighbor hoppings, with the following distinctive pattern:\n",
 "\n",
 "![](figures/haldane_hoppings.svg)\n",
 "\n",
 "With the direction of the arrow, we denote the direction in which the hopping is $+it_2$ (it is $it_2$ in the opposite direction)."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Note the following things about these hoppings:\n",
 "\n",
 "* they are purely imaginary and, furthermore, they all have the same chirality, in the sense that they all follow the orientation of your right hand, if the thumb points out from the screen.\n",
 "* they couple sites of same type: $A$ with $A$ and $B$ with $B$.\n",
 "\n",
 "These characteristics tell us that the new hoppings break both timereversal symmetry and sublattice symmetry. Now the full Hamiltonian becomes\n",
 "\n",
 "$$\n",
 "H(\\mathbf{k}) = H_0(\\mathbf{k})+ M\\sigma_z + 2t_2\\sum_i\\,\\sigma_z\\,\\sin(\\mathbf{k}\\cdot\\mathbf{b}_i)\\,.\n",
 "$$\n",
 "\n",
 "The last term changes sign under timereversal symmetry, breaking it. This is the Hamiltonian of the Haldane model."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's see what happens to the system when these special second neighbor hoppings are turned on:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "p = SimpleNamespace(t=1.0, m=0.2, phi=np.pi/2, t_2=None)\n",
 "syst = haldane(boundary='infinite')\n",
 "k = (4 / 3) * np.linspace(np.pi, np.pi, 101)\n",
 "kwargs = {'k_x': k, 'k_y': k, 'title': title}\n",
 "t_2s = np.linspace(0, 0.10, 11)\n",
 "holoviews.HoloMap({p.t_2: spectrum(syst, p, **kwargs) for p.t_2 in t_2s}, kdims=[r'$t_2$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "When $t_2=0$ and at a finite $M$, the system is in a boring gapped phase, generically without zero energy states. As you heard in the video, there might be zero energy states for some specific termination of the lattice, but these are not particularly interesting.\n",
 "\n",
 "Adding a small $t_2$ initially does not change the situation, but when $t_2$ passes through a value $\\pm M/3\\sqrt{3}$ the gap closes and changes sign. Importantly, the gap closes *only at one of the two Dirac points*: at $\\mathbf{K}'$ for $t_2=M/3\\sqrt{3}$ and at $\\mathbf{K}$ for $t_2=M/3\\sqrt{3}$.\n",
 "\n",
 "And when it does, chiral edge states appear! We can see this by looking at the onedimensional band structure of a ribbon of graphene. To convince you that they are of topological origin, let's look at the bandstructure for ribbons with two different lattice terminations: armchair and zigzag. In a zigzag ribbon, $\\mathbf{K}$ and $\\mathbf{K}'$ correspond to different momenta parallel to the ribbon direction, while in an armchair one they correspond to the same one."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "%%output fig='svg'\n",
 "def ribbon_bandstructure(t_2, boundary):\n",
 " p = SimpleNamespace(t=1.0, t_2=t_2, m=0.2, phi=np.pi/2)\n",
 "\n",
 " if boundary is 'zigzag':\n",
 " syst = haldane(w=20, boundary='zigzag')\n",
 " elif boundary is 'armchair':\n",
 " syst = haldane(w=20, boundary='armchair', )\n",
 " \n",
 " style = {'k_x': np.linspace(np.pi, np.pi, 101),\n",
 " 'xdim': r'$k$',\n",
 " 'ydim': r'$E/t$',\n",
 " 'xticks': pi_ticks,\n",
 " 'yticks': [3, 0, 3],\n",
 " 'ylims': [3.2, 3.2],\n",
 " 'title': title}\n",
 " \n",
 " return spectrum(syst, p, **style)\n",
 "\n",
 "t_2s = np.linspace(0, 0.5, 20)\n",
 "boundaries = ['zigzag', 'armchair']\n",
 "plots = {(t_2, boundary): ribbon_bandstructure(t_2, boundary) for t_2 in t_2s for boundary in boundaries}\n",
 "holoviews.HoloMap(plots, kdims=[r'$t_2$', 'Boundary'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The appearance of edge states means that graphene has entered a topological phase after the gap closing. This phase is akin to the quantum Hall phase  the edge states are of the same kind. However, as Duncan Haldane explained in the introduction, it is realized without a strong magnetic field.\n",
 "\n",
 "As you know, this means we have created a **Chern insulator**. The reason for this name will become obvious in the second part of the lecture."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (\"What happens if we take a Haldane model in the topological phase and turn \"\n",
 " \"on a weak magnetic field?\")\n",
 "\n",
 "answers = [\"Magnetic field introduces Landau levels, which change the number of edge states.\",\n",
 " \"Since the magnetic field is weak, nothing changes as long as it doesn't close the gap\",\n",
 " \"The bulk gap closes and there are no edge states anymore.\",\n",
 " \"The gap doesn't close but the edge states may change direction \"\n",
 " \"of propagation, depending on the sign of magnetic field.\"]\n",
 "\n",
 "explanation = \"Topological robustness is still present, so the number of edge states cannot change unless the gap closes.\"\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Pumping in terms of Berry phase"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Last week we understood the quantum Hall effect in terms of a pumping argument that we attributed to Laughlin.\n",
 "\n",
 "Our pumping argument involved putting our system on a cylinder and adiabatically pumping a magnetic flux $\\Phi$ through the cylinder so that the Hamiltonian returns to itself. The flux enters the Hamiltonian through minimal substitution as $H(\\mathbf{k})\\rightarrow H(\\mathbf{k}+e\\mathbf{A})$ where ${\\bf A}=\\hat{\\mathbf{y}}\\,\\Phi/L$.\n",
 "\n",
 "Thus we can understand the effects of flux pumping on the Hamiltonian in terms of a change in momentum. When the flux is changed by the appropriate number of quanta, the momentum $\\mathbf{k}$ changes by a reciprocal lattice vector and, hence the Bloch Hamiltonian returns to its original value. To simplify the discussion, in the following we will use a square Brillouin zone, with $k_x$ and $k_y$ defined in an interval $[0, 2\\pi]$, but all our arguments also apply for the hexagonal Brillouin zone of graphene."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's imagine the adiabatic timeevolution of an eigenstate $\\left\\psi(\\mathbf{k})\\right\\rangle$ of this Hamiltonian, with energy $E(\\mathbf{k})$, as $\\mathbf{k}$ is changed slowly. Suppose the Hamiltonian is such that $\\left\\psi(\\mathbf{k})\\right\\rangle$ remains nondegenerate as in the case of the Haldane model. We can then adiabatically explore an energy band by moving $\\mathbf{k}$, without the risk of encountering a level crossing. After a while, let's say a time $T$, we bring $\\mathbf{k}$ back to its initial value after going around the entire Brillouin Zone. For instance, we can consider the following closed path $C$, where $k_y$ changes by $2\\pi$ at a fixed $k_x$, starting from $k_y=0$:\n",
 "\n",
 "![](figures/bz_path.svg)\n",
 "\n",
 "We then ask: what is the final quantum state at the time $T$? For a long time people guessed that it would just be given by the initial state $\\left\\psi(k_x, k_y+2\\pi)\\right\\rangle\\equiv\\left\\psi(k_x, k_y)\\right\\rangle$ times the usual phase $\\exp\\left(i \\int_0^T E[\\mathbf{k}(t)]\\,d t\\right)$, which an eigenstate of the Hamiltonian accumulates with time. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "This would be rather boring. Berry instead realized that for a closed loops there is an additional phase $\\gamma$, which in our case may depend on $k_x$:\n",
 "\n",
 "$$\\gamma(C) = \\oint_C\\,\\mathbf{A}(\\mathbf{k})\\,\\cdot d\\mathbf{k}\\,.$$\n",
 "\n",
 "Here, $\\mathbf{A}(\\mathbf{k})=i\\left\\langle\\,\\psi(\\mathbf{k}) \\,\\,\\nabla_\\mathbf{k}\\,\\psi(\\mathbf{k})\\right\\rangle$ is a vector with two complex entries, which are obtained by taking the derivatives of $\\left\\psi(\\mathbf{k})\\right\\rangle$ with respect to $k_x$ and $k_y$ and then taking the inner product with $\\left\\langle\\psi(\\mathbf{k})\\right$. This vector goes by the rather obscure name of Berry connection. In our example, the final quantum state at the end of the cycle is thus\n",
 "\n",
 "$$\\exp\\,\\left[i\\gamma(k_x)\\right]\\,\\exp\\,\\left(i \\int_0^T E[\\mathbf{k}(t)]\\,d t\\right)\\,\\left\\psi(\\mathbf{k})\\right\\rangle\\,.$$"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We have made explicit the fact that $\\gamma$ in our case may depend on $k_x$. We will not derive the formula for the Berry phase, something which can be done directly from the Schrödinger equation, see for instance [here](http://arxiv.org/abs/0907.2021). What is important to know about $\\gamma$ is that it is a **geometric phase**: its value depends on the path $C$ but not on how the path is performed in time, so not on the particular expression for $\\mathbf{k}(t)$. We'll soon see that sometimes it can have an even stronger, topological character. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Flux pumping\n",
 "\n",
 "The phase $\\gamma(k_x)$ must bear information about the charge pumped during an adiabatic cycle over $k_y$. Now we take advantage of pumped charge being invariant as long as the energy gap is preserved. This means that we have the freedom to change the energy dispersion $E(k_x,k_y)$ arbitrarily, as long as we do not close the gap.\n",
 "\n",
 "It is convenient to make the energy dispersion completely flat along the $k_x$ direction for $k_y=0$, analogous to the case of Landau levels. In this way, since at fixed $k_y$ all the wave functions have the same energy, we can choose our initial quantum state to be localized in a single unit cell in the $x$ direction,\n",
 "\n",
 "$$\\left\\psi(n,t=0)\\right\\rangle=\\int_0^{2\\pi} dk_x\\, e^{i k_x n}\\,\\left\\psi(k_x, k_y=0)\\right\\rangle\\,.$$\n",
 "\n",
 "Starting from this state, after one adiabatic cycle we obtain\n",
 "\n",
 "$$\\left\\psi(n,t=T)\\right\\rangle=\\int_0^{2\\pi} dk_x\\, e^{i k_x n}\\,\\exp\\,\\left[i\\gamma(k_x)i\\theta(k_x)\\right]\\,\\left\\psi(k_x, k_y=2\\pi)\\right\\rangle,$$\n",
 "\n",
 "where $\\theta(k_x)=\\int_0^T E[k_x, k_y(t)]\\,d t$ is the dynamical phase. Now we notice something strange. While $\\theta(k_x)$ is a truly periodic function of $k_x$ because $E(k_x)=E(k_x+2\\pi)$, the only restriction on the Berry phase $\\gamma(k_x)$ is to be periodic modulo $2\\pi$. That is, we can have $\\gamma(k_x+2\\pi)=\\gamma(k_x)+2\\pi W$ with $W$ an integer number.\n",
 "\n",
 "Let's try to deform the dispersion along $k_y$ in order to make the combination $\\gamma(k_x)\\theta(k_x)$ as large as possible (just like before, this is allowed as long as we do not close the gap). The best we can do is choose $\\theta(k_x)$ so that \n",
 "\n",
 "$$\\gamma(k_x)\\theta(k_x)=W k_x.$$\n",
 "\n",
 "Plugging this in to the form of the wavefunction we see that \n",
 "\n",
 "$$\\left\\psi(n,t=T)\\right\\rangle=\\int dk_x e^{i k_x (n+W)}\\,\\left\\psi(k_x, k_y=0)\\right\\rangle,$$\n",
 "\n",
 "which means that every wave function is shifted over by $W$ unit cells. Thus the system with the wave functions $\\left\\psi(\\mathbf{k})\\right\\rangle$ pumps $W$ units of charge if the Berry phase satisfies \n",
 "\n",
 "$$\\gamma(k_x+2\\pi)\\gamma(k_x)=2\\pi W.$$\n",
 "\n",
 "> The quantity $W$ is called the **Chern number** and is the topological invariant characterizing the bandstructure of two dimensional quantum Hall systems. Because it is an integer, it cannot be changed by any continuous deformation of the Hamiltonian, provided the gap does not close. The Chern number is in fact the bulk topological invariant for all insulators with broken timereversal symmetry. If $W=0$, we have a topologically trivial insulator with no chiral edge states. If $W=n$ there are $n$ chiral edge states at the boundary of the insulator."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Compact form of the Chern number as Berry curvature"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We did not denote the Berry connection as $\\mathbf{A}(\\mathbf{k})$ just by chance. We picked that letter because this vector reminds us a lot of the vector potential $\\mathbf{A}(\\mathbf{r})$ that is used in electromagnetism.\n",
 "\n",
 "Just like the vector potential, the definition of $\\mathbf{A}(\\mathbf{k})$ depends on a particular choice of the person making the calculation. If you decide to multiply the quantum state by a phase, $\\left\\psi(\\mathbf{k})\\right\\rangle\\,\\to \\exp\\,[i\\lambda(\\mathbf{k})]\\,\\left\\psi(\\mathbf{k})\\right\\rangle$, then you get that the Berry connection transforms as $\\mathbf{A}(\\mathbf{k})\\,\\to\\,\\mathbf{A}(\\mathbf{k})+\\nabla_\\mathbf{k} \\,\\lambda$. However, when you take the integral of $\\mathbf{A}(\\mathbf{k})$ on a closed path, the result is independent of $\\lambda$. That's why the Berry phase is only meaningful for closed paths. \n",
 "\n",
 "Now that we have established an analogy with the vector potential, we cannot avoid the idea of taking the curl of the Berry connection, which is known as the **Berry curvature**:\n",
 "\n",
 "$$\\mathbf{\\Omega}(\\mathbf{k}) = \\nabla_\\mathbf{k} \\times \\mathbf{A}(\\mathbf{k})=i\\left[\\left\\langle \\frac{\\partial \\psi(\\mathbf{k})}{\\partial k_x}\\,\\Bigg\\,\\frac{\\partial\\,\\psi(\\mathbf{k})}{\\partial k_y}\\right\\rangle\\left\\langle \\frac{\\partial \\psi(\\mathbf{k})}{\\partial k_y}\\,\\Bigg\\,\\frac{\\partial\\,\\psi(\\mathbf{k})}{\\partial k_x}\\right\\rangle\\right]\\,.$$\n",
 "\n",
 "The Berry curvature is like a *magnetic field in momentum space*. Just like the magnetic field $\\mathbf{B}(\\mathbf{r})=\\nabla_\\mathbf{r}\\times\\mathbf{A}(\\mathbf{r})$ in electromagnetism, it is a local quantity which does not suffer from the ambiguities of the vector potential (it is gauge independent).\n",
 "\n",
 "The main advantage of introducing the analogy with the magnetic field is that it motivates us to use Stokes theorem. The Brillouin Zone has the shape of a torus. Therefore the curve $k_x=0$ and $k_x=2\\pi$ on the torus bounds the entire Brillouin zone. Using Stokes theorem on this curve we can conclude that \n",
 "\n",
 "$$2\\pi W=\\gamma(2\\pi)\\gamma(0)=\\iint_{\\textrm{BZ}} \\mathbf{\\Omega}(\\mathbf{k})\\,\\cdot\\,d\\mathbf{S}\\,,$$\n",
 "\n",
 "where the integral extends over the entire Brillouin Zone.\n",
 "\n",
 "> As a result of this formalism, we have established two things. First, there is a Chern number which is defined entirely in terms of the momentum space wave functions. Second, the analogy with the magnetic field allows us to obtain an explicit expression for the Chern number in terms of derivatives of the wave functions.\n",
 "\n",
 "Loosely speaking, a situation with a nonzero Chern number is a bit like having a magnetic monopole, because we have a finite flux coming out of a closed surface. Now, you probably know that experimentally a magnetic monopole was never observed. For our Chern number in the Brillouin zone the situation is more exciting, as situations where it is nonzero are realized in nature.\n",
 "\n",
 "To see how this can happen, we first have to understand the following: if there is Berry curvature in the Brillouin zone, what are its sources?"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Gap closings are sources of Berry curvature"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The Berry phase can only be computed if the Hamiltonian has a gap. For a Hamiltonian $H(\\mathbf{k})$ with many bands $E_n(\\mathbf{k})$, this means that we can compute the Chern number only for an isolated band $E_n(\\mathbf{k})$ which does not touch any other band. If there is a band touching, the Berry phase is undefined.\n",
 "\n",
 "Now let's go back to our analogy with electromagnetism. We know that we cannot compute the electric or magnetic flux through a surface if there are electric or magnetic charges sitting exactly on it. That's because the electric or magnetic fields are *not defined* at the points where their sources are."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "This analogy suggests the following: that the sources for Berry flux in momentum space are points where two bands touch, just like the Dirac points at the $\\mathbf{K}$ and $\\mathbf{K}'$ points of the Brillouin zone in graphene.\n",
 "\n",
 "This may sound a bit abstract and confusing: where are these points located? We are used to thinking about sources of flux in real space, not in momentum space. In fact, just like you do with a twodimensional sphere surrounding a charge in threedimensional space, you can think of the Brillouin zone as lying in a threedimensional space, with two directions given by $k_x$ and $k_y$ and the third given by the **magnitude of the energy gap**. \n",
 "\n",
 "The situation is explained by the following sketch, which also gives a bird'seye view of the phase diagram of the Haldane model as a function of the ratio $t_2/M$:\n",
 "\n",
 ""
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "What you see in the sketch above is a schematic illustration of the energy spectrum close to the Dirac points in the Brillouin zone, for some representative values of $t_2/M$ (for simplicity we drew the Brillouin zone as a square and not a hexagon, but that's not essential). The two massless Dirac cones appearing for $t_2=\\pm M/(3\\sqrt{3})$ are the sources of the Berry curvature, which then “spreads“ along the vertical axis, passing through the Brillouin zones of the gapped phases.\n",
 "\n",
 "The $t_2=0$ Brillouin zone is “sandwiched“ between the two gap closings: it has opposite curvature for the two Dirac points, and a total Chern number of zero.\n",
 "\n",
 "The Brillouin zones for $t_2>M/(3\\sqrt{3})$, on the other hand, have Berry curvature with the same sign for both Dirac points, and a total Chern number equal to $\\pm 1$.\n",
 "\n",
 "To see this more clearly, we can compute the Berry curvature numerically and plot it over the whole Brillouin zone as a function of $t_2$:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "p = SimpleNamespace(t=1.0, m=0.2, phi=np.pi/2, t_2=None)\n",
 "syst = haldane(boundary='infinite')\n",
 "kwargs = {'title': title, 'ks': np.linspace(2*np.pi, 2*np.pi, 150, endpoint=False)}\n",
 "t_2s = np.linspace(0.1, 0.1, 11)\n",
 "holoviews.HoloMap({p.t_2: plot_berry_curvature(syst, p, **kwargs) for p.t_2 in t_2s}, kdims=[r'$t_2$'])"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = \"How does timereversal symmetry influence the Berry curvature?\"\n",
 "\n",
 "answers = [\"The Berry curvature breaks timereversal, so it must be zero if timereversal is present.\",\n",
 " \"Time reversal symmetry doesn't constrain Berry curvature at all.\",\n",
 " \"There is no constraint, only the integral of Berry curvature (Chern number) should be zero.\",\n",
 " \"The Berry curvature and momentum change sign under timereversal, so that the Berry curvature \"\n",
 " \"at one momentum becomes opposite to the Berry curvature at opposite momentum.\"]\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=3)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You can see that the Berry curvature is really located around the Dirac points. Around $t_2=0$, the two Dirac points give canceling contributions. After a gap closing however, the contribution of one of the two Dirac points changes sign, so that the two add to $\\pm 1$ instead of canceling each other.\n",
 "\n",
 "From both the plots above, you can also infer that each Dirac point always contributes a Berry curvature equal to $\\pm 1/2$, depending on the sign of the mass in the effective Dirac Hamiltonian. We always obtain an integer number because the number of Dirac points in the Brillouin zone is even. It also implies that when the gap changes sign at a Dirac point, the Chern number changes by exactly one!"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "At the same time it's important to know that the particular distribution of the Berry curvature depends on all the details of the eigenstates of the Hamiltonian, so it changes a lot from model to model. And in fact, it is a special feature of the Haldane model that the Berry curvature is focused around two distinct points in the Brillouin zone.\n",
 "\n",
 "For instance, here is a slider plot for the Berry curvature for the quantum Hall lattice model studied in the previous chapter."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "p = SimpleNamespace(t=1.0, delta=1.0, gamma=0.5, mu=None)\n",
 "syst = Qi_Wu_Zhang()\n",
 "\n",
 "def title_Qi(p):\n",
 " title = r'$t={:.2}$, $\\mu={:.2}$, $\\Delta={:.2}$, $\\gamma={:.2}$'\n",
 " return title.format(p.t, p.mu, p.delta, p.gamma)\n",
 "\n",
 "kwargs = {'title': title_Qi}\n",
 "mus = np.linspace(2, 0, 11)\n",
 "holoviews.HoloMap({p.mu: plot_berry_curvature(syst, p, **kwargs) for p.mu in mus}, kdims=[r'$\\mu$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You can see that for $\\mu < 2t  2\\gamma$ there is a net curvature, and that when $\\mu = 2t  2\\gamma$ some flux of opposite sign appears at $k_x = k_y=0$, the Dirac point, which leaves no net curvature and leads to a change in the Chern number. This is the signature of the topological transition seen from the Berry curvature."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Summary: extending the model to spinful electrons and photons"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"0gxE68kvdmw\", src_location='4.2summary')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Questions about what you just learned? Ask them below!**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Questions\", \"Haldane model\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w4_haldane/haldane_model.md b/w4_haldane/haldane_model.md
new file mode 100644
index 0000000..e8dbef2
 /dev/null
+++ b/w4_haldane/haldane_model.md
@@ 0,0 +1,477 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+import scipy
+%output size=150 fig='png'
+pi_ticks = [(np.pi, r'$\pi$'), (0, '0'), (np.pi, r'$\pi$')]
+
+
+def haldane(w=20, boundary='zigzag'):
+ def ribbon_shape_zigzag(pos):
+ return (0.5 / np.sqrt(3)  0.1 <= pos[1] < np.sqrt(3) * w / 2 + 0.01)
+
+ def ribbon_shape_armchair(pos):
+ return (1 <= pos[0] < w)
+
+ def onsite(site, p):
+ if site.family == a:
+ return p.m
+ else:
+ return p.m
+
+ def nn_hopping(site1, site2, p):
+ return p.t
+
+ def nnn_hopping(site1, site2, p):
+ return 1j * p.t_2
+
+ lat = kwant.lattice.honeycomb()
+ a, b = lat.sublattices
+ nnn_hoppings_a = (((1, 0), a, a), ((0, 1), a, a), ((1, 1), a, a))
+ nnn_hoppings_b = (((1, 0), b, b), ((0, 1), b, b), ((1, 1), b, b))
+
+ if boundary == 'zigzag':
+ syst = kwant.Builder(kwant.TranslationalSymmetry((1, 0)))
+ syst[lat.shape(ribbon_shape_zigzag, (0, 0))] = onsite
+ elif boundary == 'armchair':
+ syst = kwant.Builder(kwant.TranslationalSymmetry((0, np.sqrt(3))))
+ syst[lat.shape(ribbon_shape_armchair, (0, 0))] = onsite
+ else:
+ syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))
+ syst[lat.shape(lambda pos: True, (0, 0))] = onsite
+
+ syst[lat.neighbors()] = nn_hopping
+ syst[[kwant.builder.HoppingKind(*hopping) for hopping in nnn_hoppings_a]] = nnn_hopping
+ syst[[kwant.builder.HoppingKind(*hopping) for hopping in nnn_hoppings_b]] = nnn_hopping
+
+ return syst
+
+
+def Qi_Wu_Zhang():
+ def onsite(site, p):
+ return  p.mu * pauli.sz
+
+ def hopx(site1, site2, p):
+ return  0.5j * p.delta * pauli.sy  p.t * pauli.sz
+
+ def hopy(site1, site2, p):
+ return  1j * p.gamma * pauli.sx  p.gamma * pauli.sz
+
+ lat = kwant.lattice.square()
+
+ syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))
+ syst[lat.shape(lambda pos: True, (0, 0))] = onsite
+ syst[kwant.HoppingKind((1,0), lat)] = hopx
+ syst[kwant.HoppingKind((0,1), lat)] = hopy
+ return syst
+
+
+def berry_curvature(syst, p, ks, num_filled_bands=1):
+ """Berry curvature of a system.
+
+ Parameters:
+ 
+ sys : kwant.Builder
+ A 2D infinite system.
+ p : SimpleNamespace
+ The arguments expected by the system.
+ ks : 1D arraylike
+ Values of momentum grid to be used for Berry curvature calculation.
+ num_filled_bands : int
+ The number of filled bands.
+
+ Returns:
+ 
+ bc : 2D array
+ Berry curvature on each square in a `ks x ks` grid.
+ """
+ # Calculate an array of eigenvectors.
+ B = np.array(syst.symmetry.periods).T
+ A = B @ np.linalg.inv(B.T @ B)
+
+ syst = kwant.wraparound.wraparound(syst).finalized()
+
+ def energy(kx, ky):
+ k = np.array([kx, ky])
+ kx, ky = np.linalg.solve(A, k)
+ H = syst.hamiltonian_submatrix([p, kx, ky], sparse=False)
+ return scipy.linalg.eigh(H)[1]
+
+ vectors = np.array([[energy(kx, ky)[:, :num_filled_bands] for kx in ks] for ky in ks])
+
+ # The actual Berry curvature calculation
+ vectors_x = np.roll(vectors, 1, 0)
+ vectors_xy = np.roll(vectors_x, 1, 1)
+ vectors_y = np.roll(vectors, 1, 1)
+
+ shifted_vecs = [vectors, vectors_x, vectors_xy, vectors_y]
+
+ v_shape = vectors.shape
+
+ shifted_vecs = [i.reshape(1, v_shape[2], v_shape[1]) for i in shifted_vecs]
+
+ dets = np.ones(len(shifted_vecs[0]), dtype=complex)
+ for vec, shifted in zip(shifted_vecs, np.roll(shifted_vecs, 1, 0)):
+ dets *= [np.linalg.det(a.T.conj() @ b) for a, b in zip(vec, shifted)]
+ bc = np.angle(dets).reshape(int(np.sqrt(len(dets))), 1)
+
+ bc = (bc + np.pi / 2) % (np.pi)  np.pi / 2
+
+ return bc
+
+
+def plot_berry_curvature(syst, p, ks=None, title=None):
+ if ks is None:
+ ks = np.linspace(np.pi, np.pi, 150, endpoint=False)
+ bc = berry_curvature(syst, p, ks)[1:1,1:1]
+ vmax = max(np.abs(bc).min(), np.abs(bc).max())
+ kwargs = {'bounds': (ks.min(), ks.min(), ks.max(), ks.max()),
+ 'kdims': [r'$k_x$', r'$k_y$']}
+
+ if callable(title):
+ kwargs['label'] = title(p)
+
+ plot = {'xticks': pi_ticks, 'yticks': pi_ticks}
+ style = {'clims': [vmax, vmax]}
+ return holoviews.Image(bc, **kwargs)(plot=plot, style=style)
+
+
+def title(p):
+ title = r'$t={:.2}$, $t_2={:.2}$, $M={:.2}$'
+ return title.format(p.t, p.t_2, p.m)
+```
+
+# Intro
+
+Duncan Haldane from Princeton University will teach us about an interesting two dimensional toymodel which he [introduced](http://faculty.washington.edu/cobden/papers/haldane88.pdf) in 1988, and which has become a prototype for the anomalous quantum Hall effect.
+
+
+```python
+MoocVideo("7nVO4uMmdo", src_location='4.2intro')
+```
+
+We will now study the model in detail, starting from the beginning. Along the way, we will also learn about the Chern number, the bulk topological invariant of a quantum Hall state.
+
+# Dirac cones in graphene
+
+In the last chapter we saw how it is possible to obtain a quantum Hall state by coupling onedimensional systems. At the end, our recipe was to first obtain a Dirac cone, add a mass term to it and finally to make this mass change sign. Following this recipe we were able to obtain chiral edge states without applying an external magnetic field.
+
+There is a real (and a very important) twodimensional system which has Dirac cones: [graphene](http://en.wikipedia.org/wiki/Graphene). So in this chapter we will take graphene and make it into a topological system with chiral edge states.
+
+Graphene is a single layer of carbon atoms arranged in a honeycomb lattice. It is a triangular lattice with two atoms per unit cell, type $A$ and type $B$, represented by red and blue sites in the figure:
+
+![](figures/graphene.svg)
+
+Hence, the wave function in a unit cell can be written as a vector $(\Psi_A, \Psi_B)^T$ of amplitudes on the two sites $A$ and $B$. Taking a simple tightbinding model where electrons can hop between neighboring sites with hopping strength $t$, one obtains the Bloch Hamiltonian:
+
+$$
+H_0(\mathbf{k})= \begin{pmatrix} 0 & h(\mathbf{k}) \\ h^\dagger(\mathbf{k}) & 0 \end{pmatrix}\,,
+$$
+
+with $\mathbf{k}=(k_x, k_y)$ and
+
+$$h(\mathbf{k}) = t_1\,\sum_i\,\exp\,\left(i\,\mathbf{k}\cdot\mathbf{a}_i\right)\,.$$
+
+Here $\mathbf{a}_i$ are the three vectors in the figure, connecting nearest neighbors of the lattice [we set the lattice spacing to one, so that for instance $\mathbf{a}_1=(1,0)$]. Introducing a set of Pauli matrices $\sigma$ which act on the sublattice degree of freedom, we can write the Hamiltonian in a compact form as
+
+$$H_0(\mathbf{k}) = t_1\,\sum_i\,\left[\sigma_x\,\cos(\mathbf{k}\cdot\mathbf{a}_i)\sigma_y \,\sin(\mathbf{k}\cdot\mathbf{a}_i)\right]\,.$$
+
+The energy spectrum $E(\mathbf{k}) = \pm \,\lefth(\mathbf{k})\right$ gives rise to the famous band structure of graphene, with the two bands touching at the six corners of the Brillouin zone:
+
+
+```python
+p = SimpleNamespace(t=1.0, t_2=0.0, m=0.0, phi=np.pi/2)
+syst = haldane(boundary='infinite')
+k = (4 / 3) * np.linspace(np.pi, np.pi, 150)
+spectrum(syst, p, k_x=k, k_y=k, title=title)
+```
+
+Only two of these six Dirac cones are really distinct, the ones at $\mathbf{K}=(2\pi/3, 2\pi/3\sqrt{3})$ and $\mathbf{K}'=(2\pi/3, 2\pi/3\sqrt{3})$. All the others can be obtained by adding some reciprocal lattice vector to $\mathbf{K}$ and $\mathbf{K}'$.
+
+# Discrete symmetries of graphene
+
+The symmetries of graphene were discussed intensively in the video, so let's review them.
+
+As we already said in our first week, graphene is the prototype of a system with sublattice symmetry, which makes the Hamiltonian block offdiagonal with respect to the two sublattices. The sublattice symmetry reads
+
+$$\sigma_z\,H_0(\mathbf{k})\,\sigma_z = H_0(\mathbf{k})\,.$$
+
+Sublattice symmetry is only approximate, and it is consequence of the nearest neighbor tightbinding model. Just like the inversion symmetry mentioned in the video, it protects the Dirac points and needs to be broken in order to open a gap.
+
+In addition to sublattice and inversion symmetry, the honeycomb lattice also has a threefold rotation symmetry around the center of the unit cell. This symmetry is important to make the Dirac cones appear in the first place, but it will not play a role in all that follows.
+
+Finally, there is timereversal symmetry, which at the moment is perfectly preserved in our tightbinding model. Since we are not considering the spin degree of freedom of the electrons, the timereversal symmetry operator in real space is just complex conjugation. In momentum space representation, timereversal symmetry reads
+
+$$ H_0(\mathbf{k}) = H_0^*(\mathbf{k})\,.$$
+
+It's important to note that timereversal symmetry sends $\mathbf{K}$ into $\mathbf{K}'$ and therefore it exchanges the two Dirac cones.
+
+The product of (approximate) sublattice and timereversal symmetries yields a further discrete symmetry, a particlehole symmetry $\sigma_z H^*(\mathbf{k})\,\sigma_z = H_0(\mathbf{k})$.
+
+# Making graphene topological
+
+Let's recall that our goal is to make our graphene sheet enter a quantum Hall state, with chiral edge states. The first necessary step is to make the bulk of the system gapped.
+
+How can we open a gap in graphene? The Dirac points are protected by both sublattice (inversion) and timereversal symmetry. So there are many ways we can think of to open an energy gap at $\mathbf{K}$ and $\mathbf{K}'$.
+
+## First try
+
+The easiest way to break sublattice symmetry is to assign an opposite onsite energy $M$ or $M$ to the $A$ or $B$ sites respectively. The Hamiltonian is then given by
+
+$$ H_0(\mathbf{k}) + M\,\sigma_z\,.$$
+
+This leads to a gapped spectrum,
+
+$$E(\mathbf{k})=\pm \sqrt{\lefth(\mathbf{k})\right^2 + M^2}\,.$$
+
+However, we quickly realize that by doing this we end up in a rather boring situation. Taking the limit $\leftM\right \gg t_1$, we obtain electronic states which are localized in one of the two sublattices $A$ or $B$, independent of the sign of $M$. Most importantly, there is no trace of edge states.
+
+It's easy to see why this mass term is hopeless: it preserves timereversal symmetry. And with the timereversal symmetry present, it is definitely impossible to obtain chiral edge states.
+
+## Second try
+
+There is another, more ingenious way to gap out the Dirac cones in graphene, which is the essence of today's model. It involves adding imaginary secondnearest neighbor hoppings, with the following distinctive pattern:
+
+![](figures/haldane_hoppings.svg)
+
+With the direction of the arrow, we denote the direction in which the hopping is $+it_2$ (it is $it_2$ in the opposite direction).
+
+Note the following things about these hoppings:
+
+* they are purely imaginary and, furthermore, they all have the same chirality, in the sense that they all follow the orientation of your right hand, if the thumb points out from the screen.
+* they couple sites of same type: $A$ with $A$ and $B$ with $B$.
+
+These characteristics tell us that the new hoppings break both timereversal symmetry and sublattice symmetry. Now the full Hamiltonian becomes
+
+$$
+H(\mathbf{k}) = H_0(\mathbf{k})+ M\sigma_z + 2t_2\sum_i\,\sigma_z\,\sin(\mathbf{k}\cdot\mathbf{b}_i)\,.
+$$
+
+The last term changes sign under timereversal symmetry, breaking it. This is the Hamiltonian of the Haldane model.
+
+Let's see what happens to the system when these special second neighbor hoppings are turned on:
+
+
+```python
+p = SimpleNamespace(t=1.0, m=0.2, phi=np.pi/2, t_2=None)
+syst = haldane(boundary='infinite')
+k = (4 / 3) * np.linspace(np.pi, np.pi, 101)
+kwargs = {'k_x': k, 'k_y': k, 'title': title}
+t_2s = np.linspace(0, 0.10, 11)
+holoviews.HoloMap({p.t_2: spectrum(syst, p, **kwargs) for p.t_2 in t_2s}, kdims=[r'$t_2$'])
+```
+
+When $t_2=0$ and at a finite $M$, the system is in a boring gapped phase, generically without zero energy states. As you heard in the video, there might be zero energy states for some specific termination of the lattice, but these are not particularly interesting.
+
+Adding a small $t_2$ initially does not change the situation, but when $t_2$ passes through a value $\pm M/3\sqrt{3}$ the gap closes and changes sign. Importantly, the gap closes *only at one of the two Dirac points*: at $\mathbf{K}'$ for $t_2=M/3\sqrt{3}$ and at $\mathbf{K}$ for $t_2=M/3\sqrt{3}$.
+
+And when it does, chiral edge states appear! We can see this by looking at the onedimensional band structure of a ribbon of graphene. To convince you that they are of topological origin, let's look at the bandstructure for ribbons with two different lattice terminations: armchair and zigzag. In a zigzag ribbon, $\mathbf{K}$ and $\mathbf{K}'$ correspond to different momenta parallel to the ribbon direction, while in an armchair one they correspond to the same one.
+
+
+```python
+%%output fig='svg'
+def ribbon_bandstructure(t_2, boundary):
+ p = SimpleNamespace(t=1.0, t_2=t_2, m=0.2, phi=np.pi/2)
+
+ if boundary is 'zigzag':
+ syst = haldane(w=20, boundary='zigzag')
+ elif boundary is 'armchair':
+ syst = haldane(w=20, boundary='armchair', )
+
+ style = {'k_x': np.linspace(np.pi, np.pi, 101),
+ 'xdim': r'$k$',
+ 'ydim': r'$E/t$',
+ 'xticks': pi_ticks,
+ 'yticks': [3, 0, 3],
+ 'ylims': [3.2, 3.2],
+ 'title': title}
+
+ return spectrum(syst, p, **style)
+
+t_2s = np.linspace(0, 0.5, 20)
+boundaries = ['zigzag', 'armchair']
+plots = {(t_2, boundary): ribbon_bandstructure(t_2, boundary) for t_2 in t_2s for boundary in boundaries}
+holoviews.HoloMap(plots, kdims=[r'$t_2$', 'Boundary'])
+```
+
+The appearance of edge states means that graphene has entered a topological phase after the gap closing. This phase is akin to the quantum Hall phase  the edge states are of the same kind. However, as Duncan Haldane explained in the introduction, it is realized without a strong magnetic field.
+
+As you know, this means we have created a **Chern insulator**. The reason for this name will become obvious in the second part of the lecture.
+
+
+```python
+question = ("What happens if we take a Haldane model in the topological phase and turn "
+ "on a weak magnetic field?")
+
+answers = ["Magnetic field introduces Landau levels, which change the number of edge states.",
+ "Since the magnetic field is weak, nothing changes as long as it doesn't close the gap",
+ "The bulk gap closes and there are no edge states anymore.",
+ "The gap doesn't close but the edge states may change direction "
+ "of propagation, depending on the sign of magnetic field."]
+
+explanation = "Topological robustness is still present, so the number of edge states cannot change unless the gap closes."
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)
+```
+
+# Pumping in terms of Berry phase
+
+Last week we understood the quantum Hall effect in terms of a pumping argument that we attributed to Laughlin.
+
+Our pumping argument involved putting our system on a cylinder and adiabatically pumping a magnetic flux $\Phi$ through the cylinder so that the Hamiltonian returns to itself. The flux enters the Hamiltonian through minimal substitution as $H(\mathbf{k})\rightarrow H(\mathbf{k}+e\mathbf{A})$ where ${\bf A}=\hat{\mathbf{y}}\,\Phi/L$.
+
+Thus we can understand the effects of flux pumping on the Hamiltonian in terms of a change in momentum. When the flux is changed by the appropriate number of quanta, the momentum $\mathbf{k}$ changes by a reciprocal lattice vector and, hence the Bloch Hamiltonian returns to its original value. To simplify the discussion, in the following we will use a square Brillouin zone, with $k_x$ and $k_y$ defined in an interval $[0, 2\pi]$, but all our arguments also apply for the hexagonal Brillouin zone of graphene.
+
+Let's imagine the adiabatic timeevolution of an eigenstate $\left\psi(\mathbf{k})\right\rangle$ of this Hamiltonian, with energy $E(\mathbf{k})$, as $\mathbf{k}$ is changed slowly. Suppose the Hamiltonian is such that $\left\psi(\mathbf{k})\right\rangle$ remains nondegenerate as in the case of the Haldane model. We can then adiabatically explore an energy band by moving $\mathbf{k}$, without the risk of encountering a level crossing. After a while, let's say a time $T$, we bring $\mathbf{k}$ back to its initial value after going around the entire Brillouin Zone. For instance, we can consider the following closed path $C$, where $k_y$ changes by $2\pi$ at a fixed $k_x$, starting from $k_y=0$:
+
+![](figures/bz_path.svg)
+
+We then ask: what is the final quantum state at the time $T$? For a long time people guessed that it would just be given by the initial state $\left\psi(k_x, k_y+2\pi)\right\rangle\equiv\left\psi(k_x, k_y)\right\rangle$ times the usual phase $\exp\left(i \int_0^T E[\mathbf{k}(t)]\,d t\right)$, which an eigenstate of the Hamiltonian accumulates with time.
+
+This would be rather boring. Berry instead realized that for a closed loops there is an additional phase $\gamma$, which in our case may depend on $k_x$:
+
+$$\gamma(C) = \oint_C\,\mathbf{A}(\mathbf{k})\,\cdot d\mathbf{k}\,.$$
+
+Here, $\mathbf{A}(\mathbf{k})=i\left\langle\,\psi(\mathbf{k}) \,\,\nabla_\mathbf{k}\,\psi(\mathbf{k})\right\rangle$ is a vector with two complex entries, which are obtained by taking the derivatives of $\left\psi(\mathbf{k})\right\rangle$ with respect to $k_x$ and $k_y$ and then taking the inner product with $\left\langle\psi(\mathbf{k})\right$. This vector goes by the rather obscure name of Berry connection. In our example, the final quantum state at the end of the cycle is thus
+
+$$\exp\,\left[i\gamma(k_x)\right]\,\exp\,\left(i \int_0^T E[\mathbf{k}(t)]\,d t\right)\,\left\psi(\mathbf{k})\right\rangle\,.$$
+
+We have made explicit the fact that $\gamma$ in our case may depend on $k_x$. We will not derive the formula for the Berry phase, something which can be done directly from the Schrödinger equation, see for instance [here](http://arxiv.org/abs/0907.2021). What is important to know about $\gamma$ is that it is a **geometric phase**: its value depends on the path $C$ but not on how the path is performed in time, so not on the particular expression for $\mathbf{k}(t)$. We'll soon see that sometimes it can have an even stronger, topological character.
+
+## Flux pumping
+
+The phase $\gamma(k_x)$ must bear information about the charge pumped during an adiabatic cycle over $k_y$. Now we take advantage of pumped charge being invariant as long as the energy gap is preserved. This means that we have the freedom to change the energy dispersion $E(k_x,k_y)$ arbitrarily, as long as we do not close the gap.
+
+It is convenient to make the energy dispersion completely flat along the $k_x$ direction for $k_y=0$, analogous to the case of Landau levels. In this way, since at fixed $k_y$ all the wave functions have the same energy, we can choose our initial quantum state to be localized in a single unit cell in the $x$ direction,
+
+$$\left\psi(n,t=0)\right\rangle=\int_0^{2\pi} dk_x\, e^{i k_x n}\,\left\psi(k_x, k_y=0)\right\rangle\,.$$
+
+Starting from this state, after one adiabatic cycle we obtain
+
+$$\left\psi(n,t=T)\right\rangle=\int_0^{2\pi} dk_x\, e^{i k_x n}\,\exp\,\left[i\gamma(k_x)i\theta(k_x)\right]\,\left\psi(k_x, k_y=2\pi)\right\rangle,$$
+
+where $\theta(k_x)=\int_0^T E[k_x, k_y(t)]\,d t$ is the dynamical phase. Now we notice something strange. While $\theta(k_x)$ is a truly periodic function of $k_x$ because $E(k_x)=E(k_x+2\pi)$, the only restriction on the Berry phase $\gamma(k_x)$ is to be periodic modulo $2\pi$. That is, we can have $\gamma(k_x+2\pi)=\gamma(k_x)+2\pi W$ with $W$ an integer number.
+
+Let's try to deform the dispersion along $k_y$ in order to make the combination $\gamma(k_x)\theta(k_x)$ as large as possible (just like before, this is allowed as long as we do not close the gap). The best we can do is choose $\theta(k_x)$ so that
+
+$$\gamma(k_x)\theta(k_x)=W k_x.$$
+
+Plugging this in to the form of the wavefunction we see that
+
+$$\left\psi(n,t=T)\right\rangle=\int dk_x e^{i k_x (n+W)}\,\left\psi(k_x, k_y=0)\right\rangle,$$
+
+which means that every wave function is shifted over by $W$ unit cells. Thus the system with the wave functions $\left\psi(\mathbf{k})\right\rangle$ pumps $W$ units of charge if the Berry phase satisfies
+
+$$\gamma(k_x+2\pi)\gamma(k_x)=2\pi W.$$
+
+> The quantity $W$ is called the **Chern number** and is the topological invariant characterizing the bandstructure of two dimensional quantum Hall systems. Because it is an integer, it cannot be changed by any continuous deformation of the Hamiltonian, provided the gap does not close. The Chern number is in fact the bulk topological invariant for all insulators with broken timereversal symmetry. If $W=0$, we have a topologically trivial insulator with no chiral edge states. If $W=n$ there are $n$ chiral edge states at the boundary of the insulator.
+
+# Compact form of the Chern number as Berry curvature
+
+We did not denote the Berry connection as $\mathbf{A}(\mathbf{k})$ just by chance. We picked that letter because this vector reminds us a lot of the vector potential $\mathbf{A}(\mathbf{r})$ that is used in electromagnetism.
+
+Just like the vector potential, the definition of $\mathbf{A}(\mathbf{k})$ depends on a particular choice of the person making the calculation. If you decide to multiply the quantum state by a phase, $\left\psi(\mathbf{k})\right\rangle\,\to \exp\,[i\lambda(\mathbf{k})]\,\left\psi(\mathbf{k})\right\rangle$, then you get that the Berry connection transforms as $\mathbf{A}(\mathbf{k})\,\to\,\mathbf{A}(\mathbf{k})+\nabla_\mathbf{k} \,\lambda$. However, when you take the integral of $\mathbf{A}(\mathbf{k})$ on a closed path, the result is independent of $\lambda$. That's why the Berry phase is only meaningful for closed paths.
+
+Now that we have established an analogy with the vector potential, we cannot avoid the idea of taking the curl of the Berry connection, which is known as the **Berry curvature**:
+
+$$\mathbf{\Omega}(\mathbf{k}) = \nabla_\mathbf{k} \times \mathbf{A}(\mathbf{k})=i\left[\left\langle \frac{\partial \psi(\mathbf{k})}{\partial k_x}\,\Bigg\,\frac{\partial\,\psi(\mathbf{k})}{\partial k_y}\right\rangle\left\langle \frac{\partial \psi(\mathbf{k})}{\partial k_y}\,\Bigg\,\frac{\partial\,\psi(\mathbf{k})}{\partial k_x}\right\rangle\right]\,.$$
+
+The Berry curvature is like a *magnetic field in momentum space*. Just like the magnetic field $\mathbf{B}(\mathbf{r})=\nabla_\mathbf{r}\times\mathbf{A}(\mathbf{r})$ in electromagnetism, it is a local quantity which does not suffer from the ambiguities of the vector potential (it is gauge independent).
+
+The main advantage of introducing the analogy with the magnetic field is that it motivates us to use Stokes theorem. The Brillouin Zone has the shape of a torus. Therefore the curve $k_x=0$ and $k_x=2\pi$ on the torus bounds the entire Brillouin zone. Using Stokes theorem on this curve we can conclude that
+
+$$2\pi W=\gamma(2\pi)\gamma(0)=\iint_{\textrm{BZ}} \mathbf{\Omega}(\mathbf{k})\,\cdot\,d\mathbf{S}\,,$$
+
+where the integral extends over the entire Brillouin Zone.
+
+> As a result of this formalism, we have established two things. First, there is a Chern number which is defined entirely in terms of the momentum space wave functions. Second, the analogy with the magnetic field allows us to obtain an explicit expression for the Chern number in terms of derivatives of the wave functions.
+
+Loosely speaking, a situation with a nonzero Chern number is a bit like having a magnetic monopole, because we have a finite flux coming out of a closed surface. Now, you probably know that experimentally a magnetic monopole was never observed. For our Chern number in the Brillouin zone the situation is more exciting, as situations where it is nonzero are realized in nature.
+
+To see how this can happen, we first have to understand the following: if there is Berry curvature in the Brillouin zone, what are its sources?
+
+# Gap closings are sources of Berry curvature
+
+The Berry phase can only be computed if the Hamiltonian has a gap. For a Hamiltonian $H(\mathbf{k})$ with many bands $E_n(\mathbf{k})$, this means that we can compute the Chern number only for an isolated band $E_n(\mathbf{k})$ which does not touch any other band. If there is a band touching, the Berry phase is undefined.
+
+Now let's go back to our analogy with electromagnetism. We know that we cannot compute the electric or magnetic flux through a surface if there are electric or magnetic charges sitting exactly on it. That's because the electric or magnetic fields are *not defined* at the points where their sources are.
+
+This analogy suggests the following: that the sources for Berry flux in momentum space are points where two bands touch, just like the Dirac points at the $\mathbf{K}$ and $\mathbf{K}'$ points of the Brillouin zone in graphene.
+
+This may sound a bit abstract and confusing: where are these points located? We are used to thinking about sources of flux in real space, not in momentum space. In fact, just like you do with a twodimensional sphere surrounding a charge in threedimensional space, you can think of the Brillouin zone as lying in a threedimensional space, with two directions given by $k_x$ and $k_y$ and the third given by the **magnitude of the energy gap**.
+
+The situation is explained by the following sketch, which also gives a bird'seye view of the phase diagram of the Haldane model as a function of the ratio $t_2/M$:
+
+
+
+What you see in the sketch above is a schematic illustration of the energy spectrum close to the Dirac points in the Brillouin zone, for some representative values of $t_2/M$ (for simplicity we drew the Brillouin zone as a square and not a hexagon, but that's not essential). The two massless Dirac cones appearing for $t_2=\pm M/(3\sqrt{3})$ are the sources of the Berry curvature, which then “spreads“ along the vertical axis, passing through the Brillouin zones of the gapped phases.
+
+The $t_2=0$ Brillouin zone is “sandwiched“ between the two gap closings: it has opposite curvature for the two Dirac points, and a total Chern number of zero.
+
+The Brillouin zones for $t_2>M/(3\sqrt{3})$, on the other hand, have Berry curvature with the same sign for both Dirac points, and a total Chern number equal to $\pm 1$.
+
+To see this more clearly, we can compute the Berry curvature numerically and plot it over the whole Brillouin zone as a function of $t_2$:
+
+
+```python
+p = SimpleNamespace(t=1.0, m=0.2, phi=np.pi/2, t_2=None)
+syst = haldane(boundary='infinite')
+kwargs = {'title': title, 'ks': np.linspace(2*np.pi, 2*np.pi, 150, endpoint=False)}
+t_2s = np.linspace(0.1, 0.1, 11)
+holoviews.HoloMap({p.t_2: plot_berry_curvature(syst, p, **kwargs) for p.t_2 in t_2s}, kdims=[r'$t_2$'])
+```
+
+
+```python
+question = "How does timereversal symmetry influence the Berry curvature?"
+
+answers = ["The Berry curvature breaks timereversal, so it must be zero if timereversal is present.",
+ "Time reversal symmetry doesn't constrain Berry curvature at all.",
+ "There is no constraint, only the integral of Berry curvature (Chern number) should be zero.",
+ "The Berry curvature and momentum change sign under timereversal, so that the Berry curvature "
+ "at one momentum becomes opposite to the Berry curvature at opposite momentum."]
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=3)
+```
+
+You can see that the Berry curvature is really located around the Dirac points. Around $t_2=0$, the two Dirac points give canceling contributions. After a gap closing however, the contribution of one of the two Dirac points changes sign, so that the two add to $\pm 1$ instead of canceling each other.
+
+From both the plots above, you can also infer that each Dirac point always contributes a Berry curvature equal to $\pm 1/2$, depending on the sign of the mass in the effective Dirac Hamiltonian. We always obtain an integer number because the number of Dirac points in the Brillouin zone is even. It also implies that when the gap changes sign at a Dirac point, the Chern number changes by exactly one!
+
+At the same time it's important to know that the particular distribution of the Berry curvature depends on all the details of the eigenstates of the Hamiltonian, so it changes a lot from model to model. And in fact, it is a special feature of the Haldane model that the Berry curvature is focused around two distinct points in the Brillouin zone.
+
+For instance, here is a slider plot for the Berry curvature for the quantum Hall lattice model studied in the previous chapter.
+
+
+```python
+p = SimpleNamespace(t=1.0, delta=1.0, gamma=0.5, mu=None)
+syst = Qi_Wu_Zhang()
+
+def title_Qi(p):
+ title = r'$t={:.2}$, $\mu={:.2}$, $\Delta={:.2}$, $\gamma={:.2}$'
+ return title.format(p.t, p.mu, p.delta, p.gamma)
+
+kwargs = {'title': title_Qi}
+mus = np.linspace(2, 0, 11)
+holoviews.HoloMap({p.mu: plot_berry_curvature(syst, p, **kwargs) for p.mu in mus}, kdims=[r'$\mu$'])
+```
+
+You can see that for $\mu < 2t  2\gamma$ there is a net curvature, and that when $\mu = 2t  2\gamma$ some flux of opposite sign appears at $k_x = k_y=0$, the Dirac point, which leaves no net curvature and leads to a change in the Chern number. This is the signature of the topological transition seen from the Berry curvature.
+
+# Summary: extending the model to spinful electrons and photons
+
+
+```python
+MoocVideo("0gxE68kvdmw", src_location='4.2summary')
+```
+
+**Questions about what you just learned? Ask them below!**
+
+
+```python
+MoocDiscussion("Questions", "Haldane model")
+```
diff git a/w4_haldane/w4_assignments.ipynb b/w4_haldane/w4_assignments.ipynb
deleted file mode 100644
index ee8004e..0000000
 a/w4_haldane/w4_assignments.ipynb
+++ /dev/null
@@ 1,144 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Simulations: more Chern insulators"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As usual, start by grabbing the notebooks of this week (`w4_haldane`). They are once again over [here](http://tiny.cc/topocm_smc).\n",
 "\n",
 "### Yet another Chern insulator\n",
 "\n",
 "One more tight binding of a Chern insulator that you can encounter in the wild is a regular square lattice with half a flux quantum of magnetic field per unit cell. If you made the Hofstadter butterfly assignment from the previous week, it's just in the middle of the butterfly. Half a flux quantum per unit cell means that the hoppings in one direction are purely imaginary, and different rows have alternating signs\n",
 "\n",
 "$$t_y = t,\\quad t_x = (1)^y it.$$\n",
 "\n",
 "This model has a dispersion very similar to graphene: it has two Dirac cones without a gap. Like graphene it also has two sites per unit cell, and sublattice symmetry.\n",
 "\n",
 "Simulate this model. Think which parameters you need to add to it to make it a Chern insulator. Check that the edge states appear, and calculate the Berry curvature.\n",
 "\n",
 "### Back to the winding\n",
 "\n",
 "Integration of Berry curvature is just another way to calculate the same quantity: the topological invariant. Verify that the winding of reflection phase gives the same results. To do that, make the pumping geometry out of a Chern insulator rolled into a cylinder, thread flux through it, and check that the topological invariant obtained through Berry curvature integration is the same as that obtained from winding.\n",
 "\n",
 "We know that Berry curvature is concentrated close to the Dirac points. Do you notice anything similar for the pumped charge?"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocSelfAssessment(due=3*7 + 2, review_due=4*7 + 2)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Now share your results:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion('Labs', 'Chern insulators')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Review assignment"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "display_html(PreprintReference('1012.4723', description=\"The hunt for flat bands\"))\n",
 "display_html(PreprintReference('1409.6715', description=\"Making a Chern insulator more like quantum Hall effect\"))\n",
 "display_html(PreprintReference('1208.4579', description=\"A Chern insulator without lattice\"))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "### Bonus: Find your own paper to review!\n",
 "\n",
 "Do you know of another paper that fits into the topics of this week, and you think is good?\n",
 "Then you can get bonus points by reviewing that paper instead!"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocPeerAssessment(due=3*7 + 2, review_due=4*7 + 2)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Reviews\", \"Chern insulators\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w4_haldane/w4_assignments.md b/w4_haldane/w4_assignments.md
new file mode 100644
index 0000000..0a224d4
 /dev/null
+++ b/w4_haldane/w4_assignments.md
@@ 0,0 +1,66 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+```
+
+# Simulations: more Chern insulators
+
+As usual, start by grabbing the notebooks of this week (`w4_haldane`). They are once again over [here](http://tiny.cc/topocm_smc).
+
+### Yet another Chern insulator
+
+One more tight binding of a Chern insulator that you can encounter in the wild is a regular square lattice with half a flux quantum of magnetic field per unit cell. If you made the Hofstadter butterfly assignment from the previous week, it's just in the middle of the butterfly. Half a flux quantum per unit cell means that the hoppings in one direction are purely imaginary, and different rows have alternating signs
+
+$$t_y = t,\quad t_x = (1)^y it.$$
+
+This model has a dispersion very similar to graphene: it has two Dirac cones without a gap. Like graphene it also has two sites per unit cell, and sublattice symmetry.
+
+Simulate this model. Think which parameters you need to add to it to make it a Chern insulator. Check that the edge states appear, and calculate the Berry curvature.
+
+### Back to the winding
+
+Integration of Berry curvature is just another way to calculate the same quantity: the topological invariant. Verify that the winding of reflection phase gives the same results. To do that, make the pumping geometry out of a Chern insulator rolled into a cylinder, thread flux through it, and check that the topological invariant obtained through Berry curvature integration is the same as that obtained from winding.
+
+We know that Berry curvature is concentrated close to the Dirac points. Do you notice anything similar for the pumped charge?
+
+
+```python
+MoocSelfAssessment(due=3*7 + 2, review_due=4*7 + 2)
+```
+
+**Now share your results:**
+
+
+```python
+MoocDiscussion('Labs', 'Chern insulators')
+```
+
+# Review assignment
+
+
+```python
+display_html(PreprintReference('1012.4723', description="The hunt for flat bands"))
+display_html(PreprintReference('1409.6715', description="Making a Chern insulator more like quantum Hall effect"))
+display_html(PreprintReference('1208.4579', description="A Chern insulator without lattice"))
+```
+
+### Bonus: Find your own paper to review!
+
+Do you know of another paper that fits into the topics of this week, and you think is good?
+Then you can get bonus points by reviewing that paper instead!
+
+
+```python
+MoocPeerAssessment(due=3*7 + 2, review_due=4*7 + 2)
+```
+
+**Do you have questions about what you read? Would you like to suggest other papers? Tell us:**
+
+
+```python
+MoocDiscussion("Reviews", "Chern insulators")
+```
diff git a/w5_qshe/fermion_parity_pump.ipynb b/w5_qshe/fermion_parity_pump.ipynb
deleted file mode 100644
index 38e5d00..0000000
 a/w5_qshe/fermion_parity_pump.ipynb
+++ /dev/null
@@ 1,934 +0,0 @@
{
 "cells": [
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "import sys\n",
 "sys.path.append('../code')\n",
 "from init_mooc_nb import *\n",
 "init_notebook()\n",
 "%output size = 150\n",
 "import scipy\n",
 "from matplotlib import cm\n",
 "\n",
 "bhz_parameters = {\n",
 " 'topo': {'A': 0.5, 'B': 1.00, 'D': 0.0, 'M': 1.0, 'del_z': 0.0},\n",
 " 'triv': {'A': 0.5, 'B': 1.00, 'D': 0.0, 'M': 1.0, 'del_z': 0.0},\n",
 " 'topo2': {'A': 0.5, 'B': 1.00, 'D': 0.3, 'M': 1.0, 'del_z': 0.0},\n",
 " 'slowed': {'A': 0.05, 'B': 0.08, 'D': 0.15, 'M': 0.3, 'del_z': 0.5}}\n",
 "\n",
 "# Onsite and hoppings for bhz model\n",
 "\n",
 "def onsite(site, p):\n",
 " return (p.M  4 * p.B) * pauli.s0sz  4 * p.D * pauli.s0s0 + p.del_z * pauli.sysy\n",
 "\n",
 "\n",
 "def hopx(site1, site2, p):\n",
 " return p.B * pauli.s0sz + p.D * pauli.s0s0 + 1j * p.A * pauli.szsx\n",
 "\n",
 "\n",
 "def hopy(site1, site2, p):\n",
 " return p.B * pauli.s0sz + p.D * pauli.s0s0  1j * p.A * pauli.s0sy\n",
 "\n",
 "\n",
 "def bhz(w=20):\n",
 " \"\"\" Make ribbon system with bhz model. \n",
 "\n",
 " slowed parameters are used on the edge for finite size system.\n",
 " \"\"\"\n",
 " lat = kwant.lattice.square()\n",
 "\n",
 " def hopping_x(site1, site2, p):\n",
 " x1, y1 = site1.pos\n",
 " x2, y2 = site2.pos\n",
 " return hopx(site1, site2, p) * np.exp(0.5j * p.Bz * (x1  x2) * (y1 + y2))\n",
 "\n",
 " slowed_par = SimpleNamespace(Bz=0, **bhz_parameters['slowed'])\n",
 " if w is None:\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))\n",
 " syst[lat.shape(lambda pos: True, (0, 0))] = onsite\n",
 " syst[kwant.HoppingKind((1, 0), lat)] = hopping_x\n",
 " syst[kwant.HoppingKind((0, 1), lat)] = hopy\n",
 " else:\n",
 " syst = kwant.Builder(kwant.TranslationalSymmetry((1, 0)))\n",
 " syst[(lat(0, i) for i in range(w))] = onsite\n",
 " syst[kwant.HoppingKind((1, 0), lat)] = hopping_x\n",
 " syst[kwant.HoppingKind((0, 1), lat)] = hopy\n",
 "\n",
 " syst[lat(0, 1)] = lambda site, p: onsite(site, slowed_par)\n",
 " syst[lat(1, 1), lat(0, 1)] = lambda site1, site2, p: hopping_x(site1, site2, slowed_par)\n",
 " syst[lat(0, 0), lat(0, 1)] = hopy\n",
 "\n",
 " syst[lat(0, w)] = lambda site, p: onsite(site, slowed_par)\n",
 " syst[lat(1, w), lat(0, w)] = lambda site1, site2, p: hopping_x(site1, site2, slowed_par)\n",
 " syst[lat(0, w), lat(0, w  1)] = hopy\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def bhz_cylinder(w=3):\n",
 " \"\"\" Make cylinder system with bhz model. \"\"\"\n",
 " def ribbon_shape(pos):\n",
 " (x, y) = pos\n",
 " return (0 <= y < w)\n",
 "\n",
 " lat = kwant.lattice.square(norbs=4)\n",
 " sym = kwant.TranslationalSymmetry((1, 0))\n",
 " syst = kwant.Builder(sym)\n",
 "\n",
 " def hopping_x(site1, site2, p):\n",
 " x1, y1 = site1.pos\n",
 " x2, y2 = site2.pos\n",
 " return hopx(site1, site2, p) * np.exp(0.5j * p.Bz * (x1  x2) * (y1 + y2))\n",
 "\n",
 " def hopy_phase(site1, site2, p):\n",
 " x1, y1 = site1.pos\n",
 " x2, y2 = site2.pos\n",
 " return hopy(site1, site2, p) * np.exp(1j * p.ky)\n",
 "\n",
 " syst[lat.shape(ribbon_shape, (0, 0))] = onsite\n",
 " syst[kwant.HoppingKind((1, 0), lat)] = hopping_x\n",
 " syst[kwant.HoppingKind((0, 1), lat)] = hopy\n",
 " syst[kwant.HoppingKind((0, w + 1), lat)] = hopy_phase\n",
 "\n",
 " syst[lat(0, 0)] = onsite\n",
 " syst[lat(0, w  1)] = onsite\n",
 "\n",
 " return syst\n",
 "\n",
 "\n",
 "def make_lead(t, trs=None):\n",
 " def ribbon_shape(pos):\n",
 " (x, y) = pos\n",
 " return (0 <= y < 2)\n",
 "\n",
 " lat = kwant.lattice.square(norbs=4)\n",
 " sym = kwant.TranslationalSymmetry((1, 0))\n",
 " syst = kwant.Builder(sym, time_reversal=1j*pauli.sys0)\n",
 "\n",
 " syst[lat.shape(ribbon_shape, (0, 0))] = 1.8 * t * pauli.s0sz\n",
 " syst[kwant.HoppingKind((1, 0), lat)] = t * pauli.s0sz\n",
 " return syst\n",
 "\n",
 "\n",
 "def make_scatter_sys():\n",
 " def shape(pos):\n",
 " x, y = pos\n",
 " return (x == 0) * (0 <= y < 3)\n",
 "\n",
 " lat = kwant.lattice.square(norbs=4)\n",
 " syst = kwant.Builder()\n",
 " syst[lat.shape(shape, (0, 0))] = onsite\n",
 " syst[kwant.HoppingKind((0, 1), lat)] = hopy\n",
 "\n",
 " lead_cylinder = bhz_cylinder()\n",
 " lead = make_lead(1.0)\n",
 " syst.attach_lead(lead.reversed())\n",
 " syst.attach_lead(lead_cylinder)\n",
 " syst = syst.finalized()\n",
 " return syst\n",
 "\n",
 "\n",
 "def scattering_det_pfaff(syst, p):\n",
 "\n",
 " def pfaffian(syst, p, ky):\n",
 " p.ky = ky\n",
 " smat = kwant.smatrix(syst, energy=0.0, args=[p]).data\n",
 " # since we get relatively large numerical errors we project the matrix on\n",
 " # the space of antisymmetric matrices\n",
 " smat = 0.5 * (smat  smat.T)\n",
 " return pf.pfaffian(smat)\n",
 " \n",
 " pfaff = [pfaffian(syst, p, 0), pfaffian(syst, p, np.pi)]\n",
 " \n",
 " ks = np.linspace(0.0, np.pi, 50)\n",
 " det = [np.linalg.det(kwant.smatrix(syst, energy=0.0, args=[p]).data) for p.ky in ks]\n",
 " det = np.array(det)\n",
 "\n",
 " phase = np.angle(pfaff[0]) + 0.5 * np.cumsum(np.angle(det[1:] / det[:1]))\n",
 " kdims = ['$k_y$', 'phase']\n",
 " plot = holoviews.Path((ks[1:], phase), kdims=kdims)(style={'color': 'b'})\n",
 " plot *= holoviews.Points(([0, np.pi], np.angle(pfaff)), kdims=kdims)(style={'color': 'g'})\n",
 " xlims, ylims = slice(0.2, np.pi + 0.2), slice(np.pi  0.2, np.pi + 0.2)\n",
 " pi_ticks = [(np.pi, r'$\\pi$'), (0, '$0$'), (np.pi, r'$\\pi$')]\n",
 " ticks = {'xticks': [(0, '0'), (np.pi, '$\\pi$')], 'yticks': pi_ticks}\n",
 " return plot.relabel('Winding', depth=1)[xlims, ylims](plot=ticks)\n",
 "\n",
 "\n",
 "def title(p):\n",
 " title = r'$A={:.2}$, $B={:.2}$, $D={:.2}$, $M={:.2}$'\n",
 " return title.format(p.A, p.B, p.D, p.M)\n"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Introduction"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Charles Kane from the University of Pennsylvania will introduce today's lecture on two dimensional topological insulators with timereversal symmetry."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "MoocVideo(\"n5oUQvvsYd0\", src_location='5.1intro', res='360')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Adding symmetry to a topological insulator"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In general, there are different approaches to discover new types of topological systems.\n",
 "\n",
 "We have already used a very powerful method to make a Kitaev chain and the Chern insulator model. We started from guessing what kind of model to use for the edge, such that it is impossible to obtain without the bulk. Then we combined many such edges (dots for the Kitaev chain and wires for the Chern insulator) and tailored the coupling between them to leave exactly the type of model that we want on one edge."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "A very skilled researcher in topology (or more specifically [Ktheory](https://en.wikipedia.org/wiki/Ktheory)) may also just calculate the expected topological classification of a system starting only from its dimensionality and symmetries. This is also a powerful method, but often it's too hard and requires a very high skills in math.\n",
 "\n",
 "Another approach that we can undertake is to start with one topological Hamiltonian and see what happens if we force the Hamiltonian to have some extra symmetry. This is the approach we will use in this chapter."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's start from a simple example involving something which we already know, a quantum dot with the Hamiltonian $H_0$. We know that there is a topological invariant, the number of filled energy levels.\n",
 "\n",
 "Now we can ask what happens if we force the dot to have a particlehole symmetry. The Hamiltonian becomes\n",
 "\n",
 "$$\n",
 "H_\\textrm{BdG} =\n",
 "\\begin{pmatrix}\n",
 "H_0 & 0\\\\\n",
 "0 & H_0^*\n",
 "\\end{pmatrix}.\n",
 "$$"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "This model is clearly topologically trivial from the point of view of the old invariant, since the number of filled states is constant. However, there are still level crossings that appear. We may ask if these crossings stay protected if we also include a finite superconducting pairing $\\Delta$ in the Hamiltonian, which couples the two blocks $H_0$ and $H_0^*$.\n",
 "\n",
 "Of course we know the answer: the crossings stay protected due to the change in the Pfaffian invariant. So what we did was to construct a topologically nontrivial superconducting dot by adding particlehole symmetry to a topological Hamiltonian with a lower symmetry."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Let's now apply the same logic to a new system. Specifically, let's add timereversal symmetry to a Chern insulator. The Chern insulator has chiral edge states whose direction of propagation is flipped by timereversal symmetry $\\mathcal{T}$. So let's consider a Hamiltonian of the form\n",
 "\n",
 "$$\n",
 "H =\n",
 "\\begin{pmatrix}\n",
 "H_0 & 0\\\\\n",
 "0 & \\mathcal{T}H_0\\mathcal{T}^{1}\n",
 "\\end{pmatrix}\\,.\n",
 "$$\n",
 "\n",
 "If $H_0$ is the Hamiltonian of a Chern insulator with $N$ edge states, then $H$ will have $N$ pairs of counterpropagating edge states that transform into each other by timereversal symmetry. Moreover, the full $H$ obeys timereversal symmetry, which merely exchanges the two blocks.\n",
 "\n",
 "The following sketch describes the situation in the case $N=1$:"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/qsh_insulator.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The next task which we now face is to understand if such edges stay topologically protected once we add coupling between the two blocks."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# A perfectly transmitted channel and Kramers degeneracy"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We could try to see if all the edge states can be removed by adding some terms to the Hamiltonian, but instead we will use a closely related fact.\n",
 "\n",
 "Let's study transport through such edge states as a function of their total number and let's only use the fact that timereversal symmetry is present. Imagine, there is a total of $N$ states going in each direction along the edge, and that the edge is composed of a disordered region sandwiched between two clean regions. Again, let's represent the situation for the case $N=1$.\n",
 "\n",
 "![](figures/qsh_scattering.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Scattering states\n",
 "\n",
 "We label incoming states on the left and right with $\\leftn,\\textrm{L}\\right\\rangle$ and $\\leftn,\\textrm{R}\\right\\rangle$. The index $n$ goes from $1$ to $N$. The outgoing states are the timereversed partners of the incoming states, so they are given by $\\mathcal{T}\\leftn,\\textrm{L}\\right\\rangle$ and $\\mathcal{T}\\leftn,\\textrm{R}\\right\\rangle$. Scattering states in the left and right regions are superpositions of incoming and outgoing states,\n",
 "\n",
 "$$\n",
 "\\left\\Psi,\\textrm{L}\\right\\rangle = \\sum_{n=1}^N \\alpha_{n,\\textrm{L}}\\,\\leftn,\\textrm{L}\\right\\rangle + \\beta_{n,\\textrm{L}}\\,\\mathcal{T}\\leftn,\\textrm{L}\\right\\rangle\\,,\n",
 "$$\n",
 "$$\n",
 "\\left\\Psi,\\textrm{R}\\right\\rangle = \\sum_{n=1}^N \\alpha_{n,\\textrm{R}}\\,\\leftn,\\textrm{R}\\right\\rangle + \\beta_{n,\\textrm{R}}\\,\\mathcal{T}\\leftn,\\textrm{R}\\right\\rangle\\,.\n",
 "$$\n",
 "\n",
 "We can form vectors out of all the coefficients in the superposition, for instance $\\alpha_\\textrm{L} = (\\alpha_{1,\\textrm{L}},\\dots,\\alpha_{N,\\textrm{L}})^T$ for the incoming states on the left side. Incoming and outgoing modes are then related by the scattering matrix $S$ of the disordered region,\n",
 "\n",
 "$$\n",
 "\\begin{pmatrix} \\beta_\\textrm{L} \\\\ \\beta_\\textrm{R} \\end{pmatrix} = S \\begin{pmatrix} \\alpha_\\textrm{L} \\\\ \\alpha_\\textrm{R} \\end{pmatrix}.\n",
 "$$\n",
 "\n",
 "There are a total of $2N$ incoming and $2N$ outgoing modes, so $S$ is a $2N\\times 2N$ matrix. Since we are including all possible initial and final states, $S$ is also unitary, $S=S^\\dagger$. It can be split into reflection and transmission blocks of dimension $N\\times N$,\n",
 "\n",
 "$$\n",
 "S =\n",
 "\\begin{pmatrix}\n",
 "r & t\\\\\n",
 "t' & r'\n",
 "\\end{pmatrix}\\,.\n",
 "$$\n",
 "\n",
 "If we can gap out the edges by adding some extra terms to the Hamiltonian, or backscatter them by adding disorder, then we should be able to achieve the situation where there is no transmission at all, $t = t' = 0$. In this case, all modes must be reflected back, so the reflection blocks of the scattering matrix become unitary, $r^\\dagger r = r'^\\dagger r' = 1$.\n",
 "\n",
 "To see whether this is possible at all, we first have to understand the constraints that timereversal symmetry imposes on $S$."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Scattering matrices with timereversal symmetry\n",
 "\n",
 "Let's recall some basic facts about timereversal symmetry, which we already studied in the first week. Timereversal symmetry has an antiunitary operator $\\mathcal{T}$ which commutes with the Hamiltonian. Being antiunitary, $\\mathcal{T}$ may come in two flavors  either $\\mathcal{T}^2=1$ or $\\mathcal{T}^2=1$. The first case applies to systems with no or integer spin, such that $\\mathcal{T}=\\mathcal{K}$ in the simplest case, where $\\mathcal{K}$ is the complex conjugation operator. The second case applies to systems with halfinteger spin, and in the simplest case we have $\\mathcal{T}=i\\sigma_y\\mathcal{K}$.\n",
 "\n",
 "Let's apply the timereversal operator to our scattering states. We get\n",
 "\n",
 "$$\n",
 "\\mathcal{T}\\left\\Psi,\\textrm{L}\\right\\rangle = \\sum_{n=1}^N \\alpha^*_{n,\\textrm{L}}\\,\\mathcal{T}\\leftn,\\textrm{L}\\right\\rangle + \\beta^*_{n,\\textrm{L}}\\,\\mathcal{T}^2\\leftn,\\textrm{L}\\right\\rangle\\,,\n",
 "$$\n",
 "$$\n",
 "\\mathcal{T}\\left\\Psi,\\textrm{R}\\right\\rangle = \\sum_{n=1}^N \\alpha^*_{n,\\textrm{R}}\\,\\mathcal{T}\\leftn,\\textrm{R}\\right\\rangle + \\beta^*_{n,\\textrm{R}}\\,\\mathcal{T}^2\\leftn,\\textrm{R}\\right\\rangle\\,.\n",
 "$$\n",
 "\n",
 "Now, since timereversal symmetry does not change the energy of a state, $\\mathcal{T}\\left\\Psi,\\textrm{R}\\right\\rangle$ and $\\mathcal{T}\\left\\Psi,\\textrm{L}\\right\\rangle$ are scattering states with the same energy as $\\left\\Psi,\\textrm{R}\\right\\rangle$ and $\\left\\Psi,\\textrm{L}\\right\\rangle$. Hence, the coefficients of incoming and outgoing modes are still related by the same scattering matrix $S$ as before. Note, however, that applying $\\mathcal{T}$ exchanged the role of the $\\alpha$'s and $\\beta$'s, such that the $\\alpha$'s now correspond to outgoing states and the $\\beta$'s to incoming states. Hence, we have\n",
 "\n",
 "$$\n",
 " S\\mathcal{T}^2 \\begin{pmatrix}\\beta^*_\\textrm{L} \\\\ \\beta^*_\\textrm{R} \\end{pmatrix} = \\begin{pmatrix} \\alpha^*_\\textrm{L} \\\\ \\alpha^*_\\textrm{R} \\end{pmatrix}\\,.\n",
 "$$\n",
 "\n",
 "Multiplying both sides by $\\mathcal{T}^2S^\\dagger$ and taking the complex conjugate gives\n",
 "\n",
 "$$\n",
 "\\begin{pmatrix} \\beta_\\textrm{L} \\\\ \\beta_\\textrm{R} \\end{pmatrix} = \\mathcal{T}^2\\,S^T \\begin{pmatrix} \\alpha_\\textrm{L} \\\\ \\alpha_\\textrm{R} \\end{pmatrix}.\n",
 "$$\n",
 "\n",
 "By comparing this equation with the one a few lines above, we finally obtain\n",
 "\n",
 "$$\n",
 "S = \\mathcal{T}^2 S^T.\n",
 "$$\n",
 "\n",
 "So if $\\mathcal{T}^2=1$, the scattering matrix is symmetric ($S=S^T$), while if $\\mathcal{T}^2=1$, it is antisymmetric ($S=S^T$). "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "What does this imply if we try to set $t=t'=0$?\n",
 "\n",
 "If $S=S^T$, it turns out there is really nothing special we can tell. However, if $S=S^T$ and $t=t'=0$, the $N\\times N$ reflection matrix must be both unitary, $r^\\dagger r=1$, and antisymmetric, $r=r^T$.\n",
 "\n",
 "If $N$ is odd, this isn't possible at all, since any odddimensional antisymmetric matrix [must have](https://en.wikipedia.org/wiki/Skewsymmetric_matrix#Spectral_theory) a single zero eigenvalue, while unitary matrices only have eigenvalues with unit norm!\n",
 "\n",
 "We are forced to conclude that it is impossible to have $r$ unitary, and therefore it is impossible to have $t=0$ in this case. Furthermore, this zero eigenvalue of $r$ means that there is always a single mode that is transmitted with unit probability.\n",
 "\n",
 "This is the discovery that Charles Kane described in the introductory video. We can quickly check it by randomly selecting an antisymmetric scattering matrix with odd $N$, like the following one with $N=3$,"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "N = 3\n",
 "np.random.seed(12)\n",
 "S = kwant.rmt.circular(N*2, sym='AII')\n",
 "\n",
 "pprint_matrix(S)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "and looking at the eigenvalues of $r^\\dagger r$ and $t^\\dagger t$:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "r = S[:N, :N]\n",
 "print('Reflection eigenvalues')\n",
 "pprint_matrix(np.linalg.eigvalsh(r @ r.T.conj()))\n",
 "\n",
 "t = S[:N, N:]\n",
 "print('Transmission eigenvalues')\n",
 "pprint_matrix(np.linalg.eigvalsh(t @ t.T.conj())[::1])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "> We conclude that if $\\mathcal{T}^2=1$ and the number of edge states going in one direction is odd, they cannot be gapped out, and the system is topological. On the other hand, if there is an even number of such edge states, they can be gapped out. Since these are the only two options, the integer invariant of a Chern insulator is reduced to a $\\pm 1$ invariant in the presence of time reversal symmetry. These topologically protected, counterpropagating edge states are often referred to as **helical edge states**. "
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Helical edge states are Kramers pairs"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You might ask yourself what makes $\\mathcal{T}^2=1$ special, leading to the topological protection of the helical edge states.\n",
 "\n",
 "As was mentioned in the first week, if $\\mathcal{T}^2=1$ then Kramers' theorem applies. Kramers' theorem tells us that given an eigenstate $\\Psi\\rangle$ of the Hamiltonian with energy $E$, its timereversed partner $\\Psi_\\mathcal{T}\\rangle\\equiv\\mathcal{T}\\Psi\\rangle$ has the same energy, and the two states are orthogonal, $\\langle \\Psi  \\Psi_\\mathcal{T}\\rangle=0$. These two states form a socalled **Kramers pair**. As we already know, this leads to the fact that Hamiltonians with spinful timereversal symmetry have twofold degenerate energy levels  **Kramers degeneracy**.\n",
 "\n",
 "Now, the two counterpropagating helical modes are timereversed partners of each other, so they form precisely such a Kramers pair. The condition $\\langle \\Psi  \\Psi_\\mathcal{T}\\rangle=0$ implies that it is impossible to introduce any backscattering between the two states, unless we break timereversal symmetry. This is the origin of the unit transmission and of the topological protection of helical edge states."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "To gain a more intuitive understanding of this fact at a more microscopic level, we can assume that the projection of the electrons' spin along a given axis is conserved, say the axis $z$ perpendicular to the plane. Then at the edge you have, say, a rightmoving mode with spin up and a leftmoving mode with spin down, and no other modes if $N=1$. Let's draw again the picture of a helical edge state entering the disordered region:\n",
 "\n",
 "![](figures/spin_flip.svg)\n",
 "\n",
 "Thus, an electron moving to the right must have spin up by assumption. In order to be reflected, its spin must also be flipped. However, this spinflip scattering process is forbidden, and again we conclude that the electron is transmitted with probability one."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In the case $\\mathcal{T}^2=1$, there is no Kramers' theorem. As a consequence, even though you can construct models which have counterpropagating edge states, you will find that they have no topological protection and can be gapped out without breaking the timereversal symmetry."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# The quantum spin Hall effect"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "There is no really precise name for the 2D topological insulator with timereversal symmetry. It is often called \"$\\mathbb{Z}_2$ topological insulator.\" However, this simply indicates that there are only two values of the topological invariant, and so it isn't a very specific name.\n",
 "\n",
 "The most commonly used name for this system is \"quantum spin Hall insulator.\" To understand why, let's analyse a Hall bar made of such a nontrivial insulator. We will only need a Hall bar with four terminals, as shown below:"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "![](figures/qsh_hallbar.svg)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We have a finite voltage applied to terminal 1, so electrons are injected into the system from there. You can see that because of the helical edge states, there are as many modes connecting terminal 1 to terminal 3 as there are to terminal 4. A moment of thought, or otherwise a quick calculation, should convince you that in this case there is no net current flowing orthogonal to the applied voltage. The Hall conductance is zero, which is the expected result if timereversal symmetry is preserved, as it is in our system.\n",
 "\n",
 "However, counterpropagating edge states have to have exactly opposite spin due to Kramers degeneracy. This means that there may be a net spin current across the sample, orthogonal to the applied voltage.\n",
 "\n",
 "In particular, let's again make the simple assumption that the spin projection along some axis is conserved. Then, in the figure above, all modes colored in red have spin up, and all modes colored in blue have spin down. So terminal 1 distributes electrons coming out of it according to their spin: all electrons with spin up end up in terminal 4, and all those with spin down in terminal 3. The system has a quantized spin current between terminals 3 and 4, hence the name \"quantum spin Hall effect\"."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "However, the quantized spin Hall current is not a general property of a quantum spin Hall insulator. Here, it arises because we have combined time reversal symmetry with a spin conservation law, and as we learned in the first week, conservation laws are boring from a topological point of view."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "question = (\"Consider the simple case where spin is conserved. \"\n",
 " \"In the quantum spin Hall bar system above, what happens if, instead of applying a voltage between terminals 1 and 2, \"\n",
 " \"you manage to apply a *spinpolarized* current between terminals 1 and 2?\")\n",
 "\n",
 "answers = [\"The system will develop an opposite spinpolarized current to compensate the effect.\",\n",
 " \"A spinpolarized current will develop between terminals 3 and 4.\",\n",
 " \"A voltage difference will develop between terminals 3 and 4.\",\n",
 " \"It is impossible to apply such a current unless the bulk gap closes.\"]\n",
 "\n",
 "explanation = (\"The spinpolarized current will create an electron population imbalance between terminals 3 and 4. \"\n",
 " \"Hence, similar to the Hall effect, a voltage will develop orthogonal to the current.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=2, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# A model for the quantum spin Hall insulator"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "There is an important model which can be used to describe quantum spin Hall insulators, known as the **BernevigHughesZhang model** or, in short, BHZ model. In essence, this model is equivalent to two copies of the Chern insulator Hamiltonian on the square lattice that we studied in the fourth week.\n",
 "\n",
 "The BHZ Hamiltonian takes the form\n",
 "\n",
 "$$\n",
 "H_\\textrm{BHZ}(\\mathbf{k}) = \\begin{pmatrix} h(\\mathbf{k}) & 0 \\\\ 0 & h^*(\\mathbf{k}) \\end{pmatrix}\\,,\n",
 "$$\n",
 "\n",
 "with\n",
 "\n",
 "$$\n",
 "h(\\mathbf{k}) = \\epsilon(\\mathbf{k}) + \\mathbf{d}(\\mathbf{k})\\cdot \\pmb{\\sigma}\\,.\n",
 "$$\n",
 "\n",
 "Here $\\pmb\\sigma = (\\sigma_x, \\sigma_y, \\sigma_z)$ is a vector of Pauli matrices acting on the electron/hole degree of freedom (the original two bands of the Chern insulator), $\\epsilon(\\mathbf{k}) = C  D(k_x^2+k_y^2)$, the vector $\\mathbf{d} = [A k_x, A k_y, M(\\mathbf{k})]$, and\n",
 "$M(\\mathbf{k}) = M  B(k_x^2+k_y^2)$.\n",
 "\n",
 "You can see that it is basically two copies of the massive Dirac Hamiltonian we used to study Chern insulators. In particular, there is a linear coupling in momentum between the holes and the electrons. The gap in the Hamiltonian is given by the term $M(\\mathbf{k})$, a momentumdependent effective mass.\n",
 "\n",
 "By changing the sign of $M$ from negative to positive, you get a gap closing at $\\mathbf{k}=\\pmb{0}$:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "%%output fig='png'\n",
 "p = SimpleNamespace(Bz=0.0, **bhz_parameters['topo2'])\n",
 "syst = bhz(w=None)\n",
 "k = (4 / 3) * np.linspace(np.pi, np.pi, 101)\n",
 "kwargs = {'k_x': k, 'k_y': k, 'title': title}\n",
 "Ms = np.linspace(1, 1, 11)\n",
 "holoviews.HoloMap({p.M: spectrum(syst, p, **kwargs) for p.M in Ms}, kdims=[r'$M$'])"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "This gap closing turns your trivial insulator into a topologically nontrivial quantum spin Hall insulator.\n",
 "\n",
 "In the rest of this lecture, we will use the BHZ model as a toymodel to illustrate the behavior of a quantum spin Hall insulator using numerical examples. The BHZ model, however, is more than a toymodel, and it can be used to capture the behavior of some real semiconducting materials. For this reason, the BHZ model will be a main protagonist in the next chapter, where we will discuss real materials and the experimental evidence for the quantum spin Hall effect."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Alternative point of view: fermion parity pump"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In the previous cases of the Kitaev chain and the quantum Hall effect, the bulk topological invariant that we eventually obtained was characterized by the response to some adiabatic experiment.\n",
 "\n",
 "Since the timereversal invariant topological insulator is two dimensional like a quantum Hall system, it is reasonable to put the system in a Corbino geometry and change the flux through the system, creating an azimuthal electric field:\n",
 "\n",
 "![](figures/qsh_corbino.svg)\n",
 "\n",
 "However, because of timereversal symmetry, the system is forbidden from having a Hall conductance and therefore there cannot be any charge transfer between the two edges of the disk. For instance, if we consider two copies of the Haldane model with opposite spin, there will be two quantum Hall pumps working in opposite directions (one transferring charge from the inner edge to the outer edge, the other one from the outer edge to the inner one). So the net charge transferred is zero.\n",
 "\n",
 "Because the two pumps act on electrons with opposite spin, you might be tempted to define a spin current, which would flow in response to the electric field, orthogonal to it. However, as we just discussed, the spin along a given direction may not be conserved, so generally this is not a good way to define a robust pumping effect."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "To understand what exactly happens in the pumping process, let's look at the energy spectrum of the edge states for the BHZ model in the cylinder geometry. As we discussed in the quantum Hall lectures, the cylinder geometry is really equivalent to the Corbino disk, except that it is easier to study.\n",
 "\n",
 "You also learned that in a cylinder of finite circumference $L$, the momenta of the allowed edge states are quantized at values determined by the flux.\n",
 "\n",
 "To make things more simple, you may actually imagine that the circumference of the cylinder is just a single unit cell long. We then have only one allowed value of the momentum $k$ along the edge, which is exactly proportional to the flux threaded through the cylinder, $k = 2\\pi \\Phi/\\Phi_0$.\n",
 "\n",
 "So let's look at the energy spectrum of a cylinder as a function of $k$ (or equivalently $\\Phi$), and compare a cylinder in the quantum spin Hall phase with a cylinder in the trivial insulating phase."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "half_pi_ticks = [(0, '$0$'), (np.pi/2, r'$\\pi/2$'), (np.pi, r'$\\pi$')]\n",
 "style = {'k_x': np.linspace(0, np.pi, 101),\n",
 " 'xdim': r'$k$',\n",
 " 'ydim': r'$E$',\n",
 " 'xticks': half_pi_ticks,\n",
 " 'yticks': np.linspace(2, 2, 9),\n",
 " 'xlims': [0, np.pi],\n",
 " 'ylims': [2, 2],\n",
 " 'title': title}\n",
 "\n",
 "syst = bhz(20)\n",
 "p1 = SimpleNamespace(Bz=0, **bhz_parameters['topo'])\n",
 "p2 = SimpleNamespace(Bz=0, **bhz_parameters['triv'])\n",
 "\n",
 "(spectrum(syst, p1, **style).relabel('Topological') * holoviews.HLine(0) +\n",
 " spectrum(syst, p2, **style).relabel('Trivial') * holoviews.HLine(0))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "In both cases you see that at $k=0$ there are isolated pairs of states with degenerate energies, between the valence and conduction bands. The Fermi energy is set at $E=0$, in the middle of the gap between conduction and valence bands. These states are the Kramers pairs at the edges  one pair for the topological case, two for the trivial case.\n",
 "You also see the splitting of Kramers pairs as soon as $k$ goes away from zero. This is because $k = 0$ is a timereversal invariant point, a point in momentum space that is mapped to itself by timereversal symmetry.\n",
 "\n",
 "The plot ends at $k=\\pi$ (that is, $\\Phi=h/2e$), which is another timereversal invariant point. Indeed, timereversal symmetry sends $\\Phi\\to\\Phi$, but for $\\Phi=h/2e$ this corresponds exactly to adding or subtracting a flux quantum. Hence, all the physical properties of the system remain unchanged under the action of timereversal for this value of the flux. And indeed you can see that all levels meet again and form Kramers pairs.\n",
 "\n",
 "> We now see an interesting difference though. In the topological case, the Kramers pairs at $k=\\pi$ are not the same as those at $k=0$. In the trivial case however, the pairs are the same. As a consequence, in the topological case there is an odd number of levels crossing zeroenergy, while in the trivial cases there is an even number of them. Therefore changing the flux by $h/2e$ in the topological case changes the fermion parity at the edge, while it does nothing in the trivial case. We have thus obtained a **fermion parity pump**."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Strangely, this reminds us of the topological superconducting ring that we studied in the second week of the course. There we also had a fermion parity change in response to a flux. It turns out that this is not a coincidence, as we will see when we discuss how to realize topological superconductors using topological insulators.\n",
 "\n",
 "You may appreciate that our argument did not rely on spin being a good quantum number, or on any other detail of the system, but only on Kramers theorem. And in fact it holds very generally. Deforming the dispersion of Kramers pairs does not break the fermion parity pump, as long as the way states combine to form Kramers pairs at $k=0$ and $k=\\pi$ is unchanged."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Pumping expression for the topological invariant"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "At this point, following the same path we followed for Chern insulator, we would like to find an expression for a topological bulk invariant which characterizes the quantum spin Hall effect.\n",
 "\n",
 "However, we now encounter a problem: for complicated topological systems in higher dimensions, it is hard to evaluate the topological invariant. We know when the system is topological, and we know which values the topological invariant can take (for now just two: trivial and nontrivial), but it becomes hard to find and evaluate the correct expression for it.\n",
 "\n",
 "We were able to calculate the Chern number using Berry curvature. The analogous computation for the topological invariant of the quantum spin Hall insulator is too involved, and so we will not present it in our course."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "The scattering formulation of the topological invariant, however, is easy to implement and utilize. We can apply it by taking the cylinder threaded by a flux and connecting it to leads in the following geometry:\n",
 "\n",
 "![](figures/qsh_pumping.svg)\n",
 "\n",
 "Let us now study what happens when we try to inject electrons into the edges of the cylinder. Since we have “rolledup” our system along one direction, we have a onedimensional scattering problem. Similar to a Thouless pump, we expect to be able to find a topological signature in the reflection matrix $r$ for an electron coming in from the left.\n",
 "\n",
 "As we vary the flux, the reflection properties may change, leading to a $k$dependent reflection matrix $r(k)$. We assume that the bulk is gapped, so transmission is suppressed, and therefore $r$ is unitary. Moreover, at $k=0$ and $k=\\pi$, $r$ is also antisymmetric because of timereversal symmetry.\n",
 "\n",
 "It turns out that the topological invariant has a relatively simple form:\n",
 "\n",
 "$$\n",
 "Q = \\frac{\\textrm{Pf}[r(0)]}{\\textrm{Pf}[r(\\pi)]}\\sqrt{\\frac{\\det[r(\\pi)]}{\\det[r(0)]}}\n",
 "$$"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "This expression relies on the antisymmetry of $r$ at $k=0$ and $k=\\pi$. At these values we can compute the Pfaffian. The eigenvalues of $r$ come in pairs of opposite sign $e^{i\\alpha}$, $e^{i\\alpha}$, which correspond to the Kramers pairs formed by the helical edge states. This means we can calculate the Pfaffian at these momentum values, but its phase is arbitrary.\n",
 "\n",
 "We can however compute $\\sqrt{\\det[r(k)]}$ for all the intermediate values of $k$. To get rid of the sign ambiguity of the square root, we require that $\\sqrt{\\det[r(k)]}$ is continuous for all $k$, and that $\\sqrt{\\det[r(0)]} = \\textrm{Pf}[r(0)]$. This only gives a unique answer if $\\det r \\neq 0$ for all $k$.\n",
 "\n",
 "This gives us a curve which starts at $\\textrm{Pf}[r(0)]$ and ends at either $\\textrm{Pf}[r(\\pi)]$ or $\\textrm{Pf}[r(\\pi)]$. These two cases distinguish the trivial and nontrivial systems.\n",
 "\n",
 "In the plot below, we show how this trajectory changes for our cylinder geometry as the BHZ model is driven through the topological phase transition. In the right panel, the green dots give you the phase of $\\textrm{Pf}[r(0)]$ and $\\textrm{Pf}[r(\\pi)]$, and the blue line the phase of $\\det[r(k)]$."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {},
 "outputs": [],
 "source": [
 "%%output fig='png'\n",
 "p = SimpleNamespace(a=1.0, Bz=0.0, ky=None, **bhz_parameters['topo2'])\n",
 "syst = bhz(w=None)\n",
 "scat_syst = make_scatter_sys()\n",
 "k = (4 / 3) * np.linspace(np.pi, np.pi, 101)\n",
 "kwargs = {'k_x': k, 'k_y': k, 'title': title}\n",
 "Ms = np.linspace(1, 1, 11)\n",
 "(holoviews.HoloMap({p.M: spectrum(syst, p, **kwargs) for p.M in Ms}, kdims=[r'$M$'])+\n",
 " holoviews.HoloMap({p.M: scattering_det_pfaff(scat_syst, p) for p.M in Ms}, kdims=[r'$M$']))"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "We now have a quantity equal to $\\pm 1$, which cannot change continuously unless there's a gap closing (when there's a gap closing, $\\det r$ becomes equal to $0$). It is relatively hard to prove that this invariant counts the pumping of fermion parity, but if you're interested, check out this paper:"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "PreprintReference('1107.2215', description=\"\", show_abstract=False)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "From reading the paper, or just from the above discussion, you see that it takes a lot of effort to derive an explicit expression for a topological invariant. Even though it is a hard task, sometimes one can guess the right result (one of us was indeed able to guess the above expression for $Q$ before it was known). Other times, one can invoke some simplification and obtain some important insight. This is what we will do in the next unit."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# A simplification: inversion symmetry"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As just mentioned, topological invariants in higher dimensions are often difficult to write down and evaluate in the general case. Luckily, in the presence of [inversion symmetry](http://en.wikipedia.org/wiki/Parity_%28physics%29#Effect_of_spatial_inversion_on_some_variables_of_classical_physics)  which reverses the lattice coordinates with respect to a symmetry center  the topological condition can be stated in rather simple terms.\n",
 "This turns out to be quite useful to describe most topological materials, which happen to have crystal structure with inversion symmetry. \n",
 "\n",
 "From our earlier discussion, we know that a system is a timereversal invariant topological insulator if it has an odd number of helical edge states. We will now see how we can find an expression for the bulk topological invariant, using inversion symmetry and bulkboundary correspondence.\n",
 "\n",
 "So let's consider a twodimensional Bloch Hamiltonian $H(\\mathbf{k})$ with both inversion and timereversal symmetry. Inversion symmetry has a unitary operator $\\mathcal{P}$ which maps $\\mathbf{k}\\rightarrow \\mathbf{k}$ and satisfies $\\mathcal{P}^2=1$. If we have both inversion symmetry $\\mathcal{P}$ and timereversal $\\mathcal{T}$, we get an antiunitary symmetry $\\mathcal{T}\\otimes\\mathcal{P}$, which preserves $\\mathbf{k}$ and squares to $1$. \n",
 "\n",
 "> These are precisely the conditions needed for Kramers theorem to apply  only this time, every point $\\mathbf{k}$ is mapped to itself because inversion symmetry is included as well. We conclude that every eigenstate at any $\\mathbf{k}$ is twofold degenerate. We may label these two eigenstates with an index $\\sigma=\\pm$. If spin is a good quantum number, $\\sigma$ labels two states with opposite spin. However, this may not be the case so we will just refer to it as a pseudospin associated with Kramers degeneracy.\n",
 "\n",
 "Note that the simplification obtained by adding inversion symmetry is that the spectrum is twofold degenerate at all $\\mathbf{k}$ in the Brillouin zone. Timereversal symmetry alone cannot guarantee that, because it maps $\\mathbf{k}$ to $\\mathbf{k}$.\n",
 "\n",
 "Our next step is to calculate the effective description of helical edge states at a domain wall between a topological phase and a nontopological phase. This is something we already know how to do thanks to our experience with domain walls in the Kitaev chain and in Chern insulators. It will give us insight into the topological transition and the bulk topological invariant."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "## Study of a domain wall\n",
 "\n",
 "Let's imagine that the helical edge runs along the $y$ direction, and that the domain wall is described by a mass profile $M(x)$ along the $x$ direction, which is zero at the domain wall:\n",
 "\n",
 "![](figures/qsh_domain_wall.svg)\n",
 " \n",
 " \n",
 "In this configuration, $k_y$ is still a good quantum number, and we can study the energy dispersion of states bound to the domain wall as a function of $k_y$. If the edge is gapless there must be a momentum, say $\\bar{k}_y$, where counterpropagating modes cross at the Fermi level. Let's fix $k_y=\\bar{k}_y$, and write down an effective Hamiltonian for the motion transverse to the domain wall.\n",
 "\n",
 "We have in total four states, distinguished by two quantum numbers: their direction of propagation, which we denote with $b=\\pm$, and their pseudospin $\\sigma$. Inversion symmetry $\\mathcal{P}$ flips the direction of propagation $b$, while the pseudospin degeneracy $\\sigma$ is related to the combination of inversion and timereversal $\\mathcal{T}\\otimes\\mathcal{P}.$ To lowest order in the momentum $k_x$ perpendicular to the domain wall, the states at the transition point disperse linearly with $k_x$, and are twofold degenerate. In fact, as we noted from Kramers degeneracy, the Hamiltonian must be chosen such that none of the terms break the twofold degeneracy associated with the pseudospin $\\sigma$. This means that the domain wall cannot couple states with different values of $\\sigma$, which leads us to an effective Hamiltonian \n",
 "\n",
 "$$\n",
 "H(\\bar{k}_y)=\\sum_{\\sigma,b}\\,k_x b\\,b,\\sigma\\rangle\\langle b,\\sigma+M(x)(+,\\sigma\\rangle\\langle ,\\sigma+h.c.)]\\,.\n",
 "$$\n",
 "\n",
 "where the factor $b$ is odd under timereversal symmetry so that $k_x b$ is even under timereversal symmetry.\n",
 "\n",
 "We are back to an old friend, the one dimensional Dirac Hamiltonian with a positiondependent mass $M(x)$. Adapting our arguments from the first week, we can immediately say that the domainwall hosts a pair of zero modes only if $M(x)$ changes sign."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "As interesting as this sounds, we must remember that this pair of zero modes is present for $k_y=\\bar{k}_y$. Because of inversion symmetry, there is necessarily an identical pair at $\\bar{k}_y$. So we get a total of 4 degenerate domain wall states from this type of gap closing  an even number of pairs. As we know form before, such pairs of gap closings do not affect the value of the topological invariant on the two sides of the domain walls. To change the value of the topological invariant, we would need an odd number of pairs crossing zero energy.\n",
 "\n",
 "However, there are points in momentum space which are mapped onto each other by timereversal symmetry, up to a reciprocal lattice vector. For these values, the above counting does not hold. People refer to these momenta as \"timereversal invariant momenta\" or TRIMs. In the simple case of a square Brillouin zone, they are the points $(k_x, k_y) = (0,0), (0,\\pi), (\\pi,0),(\\pi,\\pi)$.\n",
 "\n",
 "Since TRIMs are their own timereversed partners, it is still possible for a gap closing at $\\bar{k}_y=0$ or $\\bar{k}_y=\\pi$ to change the topology of the system. In this case, our doubling problem in momentum space is solved, and we can produce just one pair of edge modes at the domain wall. If we move the momentum $k_y$ slightly away from $\\bar{k}_y$, the degenerate pair of modes splits linearly to form a single helical mode that produces a nontrivial fermion parity pump.\n",
 "\n",
 "To make the distinction clear between a gap closing at a finite $\\bar{k}_y$ and at a timereversal invariant point, let's draw a sketch of the edge dispersion in the two cases.\n",
 "\n",
 "![](figures/qsh_edge_dispersions.svg)\n",
 "\n",
 "Kramers pairs are colored in red and blue and have the same linestyle. On the left, you have two pairs of Kramers partners, which however never meet at zero energy. On the right, there is a single Kramers pair meeting at zero energy. This argument summarizes the simplification that inversion symmetry brings to timereversal invariant topological insulators.\n",
 "\n",
 "> We can determine the topological invariant for the inversion symmetric topological insulators entirely from the bulk Hamiltonian at timereversal invariant momenta, since gap closings at any other point can only add domain wall states in multiples of four."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "Does this mean that any gap closing at a TRIM is a topological transition? The states $b,\\sigma\\rangle$ are Bloch states with definite values of $k_y$. We are considering a timereversal invariant value of $k_y$, and since $b$ is flipped by inversion symmetry, we can apply inversion symmetry to conclude that the states $\\pm,\\sigma\\rangle$ \n",
 "transform into each other under inversion i.e. $\\mathcal{P}\\pm,\\sigma\\rangle= \\mp,\\sigma\\rangle$. By combining these states \n",
 "into symmetric and antisymmetric superpositions\n",
 "\n",
 "$$e,\\sigma\\rangle=\\frac{1}{\\sqrt{2}}\\left[+,\\sigma\\rangle\\, + \\,,\\sigma\\rangle\\right],\\,\\quad o,\\sigma\\rangle=\\frac{i}{\\sqrt{2}}\\left[+,\\sigma\\rangle\\,  \\,,\\sigma\\rangle\\right],$$\n",
 "\n",
 "we obtain states that are even ($e$) and odd ($o$) under inversion—they are eigenstates of $\\mathcal{P}$ with eigenvalue $+1$ or $1$. They are also eigenstates of $M$ at $k_x=k_y=0$. The factor of $i$ in $o,\\sigma\\rangle$ ensures a consistency under the timereversal transformation, such that $\\mathcal{T}(e,o),\\sigma\\rangle=\\sigma(e,o),\\sigma\\rangle$.\n",
 "\n",
 "Every gap closing at a TRIM is an even parity state crossing with an odd parity state. The effective Hamiltonian of such a gap closing must also add an extra Kramers pair of states at the domain wall, and therefore indeed every gap closing at a TRIM is a topological phase transition, while gap closings at all the other momenta are unimportant due to inversion symmetry.\n",
 "\n",
 "This leads to a simplified way of computing a topological invariant of quantum spin Hall insulators with inversion symmetry:\n",
 "\n",
 "> To compute a bulk topological invariant for a twodimensional topological state with time reversal and inversion symmetry we need to keep track of the parity $P$ of all the occupied eigenstates of $H(\\mathbf{k})$ at the different timereversal invariant momenta in the Brillouin zone. We may write such a bulk topological invariant as a product\n",
 "\n",
 "> $$Q=\\prod_{n,j}P_{n,j}\\,,$$\n",
 "\n",
 "> where $P_{n,j}$ is the parity, $n$ runs over the occupied bands of $H(\\mathbf{k})$ and $j$ over the timereversal invariant momenta."
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "You might now worry whether this definition of the invariant relied on having a smooth domain wall. From the fermion parity pump argument, bulkedge correspondence implies that the bulk must be topologically nontrivial once you have edge states for any termination. Reversing this argument, we know that once we have a topologically nontrivial bulk, we must have helical edge states for any termination.\n",
 "\n",
 "Thus, by looking at smooth domain walls we are able to establish a connection between the topological invariant in the presence of timereversal and inversion symmetry, and the existence of helical edge states and fermionparity pumping that characterizes the two dimensional topological insulator.\n",
 "\n",
 "As a bonus, thanks to the previous arguments we can begin to understand how to look for twodimensional topological insulators among real materials, or how to create them. The main idea is to generate a \"bandinversion\" between an even and an odd parity band at a TRIM.\n",
 "\n",
 "Such a band inversion is not impossible to achieve in real materials, and can be captured using the BHZ model. But let's leave this to the next lecture."
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "question = (\"What is the value of the parity invariant $Q$ if you stack together two quantum spin Hall systems \"\n",
 " \"in the topological phase (i.e., both with $Q=1$)?\")\n",
 "\n",
 "answers = [\"The system has edge states and is therefore topologically nontrivial.\",\n",
 " \"The total number of odd parity occupied orbitals must be even, so you get $Q=1$.\",\n",
 " \"It depends on whether the helical states in the two layers have same \"\n",
 " \"or opposite spin for a given direction.\",\n",
 " \"The invariant depends on the number of edge Dirac points at $k$ away from 0.\"]\n",
 "\n",
 "explanation = (\"Both layers have $Q=1$ and hence an odd number of odd parity orbitals. Therefore, by combining the layers \"\n",
 " \"we get an even number of odd parity orbitals. Hence $Q$, which is the parity of odd parity orbitals must be \"\n",
 " \"$Q=1$.\")\n",
 "\n",
 "MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=1, explanation=explanation)"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "# Summary"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocVideo(\"ft9ppqqLhH4\", src_location='5.1summary', res='360')"
 ]
 },
 {
 "cell_type": "markdown",
 "metadata": {},
 "source": [
 "**Questions about what you just learned? Ask them below!**"
 ]
 },
 {
 "cell_type": "code",
 "execution_count": null,
 "metadata": {
 "collapsed": true
 },
 "outputs": [],
 "source": [
 "MoocDiscussion(\"Questions\", \"QSHE  theory\")"
 ]
 }
 ],
 "metadata": {
 "kernelspec": {
 "display_name": "Python 3",
 "language": "python",
 "name": "python3"
 },
 "language_info": {
 "codemirror_mode": {
 "name": "ipython",
 "version": 3
 },
 "file_extension": ".py",
 "mimetype": "text/xpython",
 "name": "python",
 "nbconvert_exporter": "python",
 "pygments_lexer": "ipython3"
 }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
diff git a/w5_qshe/fermion_parity_pump.md b/w5_qshe/fermion_parity_pump.md
new file mode 100644
index 0000000..4ce32dc
 /dev/null
+++ b/w5_qshe/fermion_parity_pump.md
@@ 0,0 +1,615 @@
+
+
+```python
+import sys
+sys.path.append('../code')
+from init_mooc_nb import *
+init_notebook()
+%output size = 150
+import scipy
+from matplotlib import cm
+
+bhz_parameters = {
+ 'topo': {'A': 0.5, 'B': 1.00, 'D': 0.0, 'M': 1.0, 'del_z': 0.0},
+ 'triv': {'A': 0.5, 'B': 1.00, 'D': 0.0, 'M': 1.0, 'del_z': 0.0},
+ 'topo2': {'A': 0.5, 'B': 1.00, 'D': 0.3, 'M': 1.0, 'del_z': 0.0},
+ 'slowed': {'A': 0.05, 'B': 0.08, 'D': 0.15, 'M': 0.3, 'del_z': 0.5}}
+
+# Onsite and hoppings for bhz model
+
+def onsite(site, p):
+ return (p.M  4 * p.B) * pauli.s0sz  4 * p.D * pauli.s0s0 + p.del_z * pauli.sysy
+
+
+def hopx(site1, site2, p):
+ return p.B * pauli.s0sz + p.D * pauli.s0s0 + 1j * p.A * pauli.szsx
+
+
+def hopy(site1, site2, p):
+ return p.B * pauli.s0sz + p.D * pauli.s0s0  1j * p.A * pauli.s0sy
+
+
+def bhz(w=20):
+ """ Make ribbon system with bhz model.
+
+ slowed parameters are used on the edge for finite size system.
+ """
+ lat = kwant.lattice.square()
+
+ def hopping_x(site1, site2, p):
+ x1, y1 = site1.pos
+ x2, y2 = site2.pos
+ return hopx(site1, site2, p) * np.exp(0.5j * p.Bz * (x1  x2) * (y1 + y2))
+
+ slowed_par = SimpleNamespace(Bz=0, **bhz_parameters['slowed'])
+ if w is None:
+ syst = kwant.Builder(kwant.TranslationalSymmetry(*lat.prim_vecs))
+ syst[lat.shape(lambda pos: True, (0, 0))] = onsite
+ syst[kwant.HoppingKind((1, 0), lat)] = hopping_x
+ syst[kwant.HoppingKind((0, 1), lat)] = hopy
+ else:
+ syst = kwant.Builder(kwant.TranslationalSymmetry((1, 0)))
+ syst[(lat(0, i) for i in range(w))] = onsite
+ syst[kwant.HoppingKind((1, 0), lat)] = hopping_x
+ syst[kwant.HoppingKind((0, 1), lat)] = hopy
+
+ syst[lat(0, 1)] = lambda site, p: onsite(site, slowed_par)
+ syst[lat(1, 1), lat(0, 1)] = lambda site1, site2, p: hopping_x(site1, site2, slowed_par)
+ syst[lat(0, 0), lat(0, 1)] = hopy
+
+ syst[lat(0, w)] = lambda site, p: onsite(site, slowed_par)
+ syst[lat(1, w), lat(0, w)] = lambda site1, site2, p: hopping_x(site1, site2, slowed_par)
+ syst[lat(0, w), lat(0, w  1)] = hopy
+
+ return syst
+
+
+def bhz_cylinder(w=3):
+ """ Make cylinder system with bhz model. """
+ def ribbon_shape(pos):
+ (x, y) = pos
+ return (0 <= y < w)
+
+ lat = kwant.lattice.square(norbs=4)
+ sym = kwant.TranslationalSymmetry((1, 0))
+ syst = kwant.Builder(sym)
+
+ def hopping_x(site1, site2, p):
+ x1, y1 = site1.pos
+ x2, y2 = site2.pos
+ return hopx(site1, site2, p) * np.exp(0.5j * p.Bz * (x1  x2) * (y1 + y2))
+
+ def hopy_phase(site1, site2, p):
+ x1, y1 = site1.pos
+ x2, y2 = site2.pos
+ return hopy(site1, site2, p) * np.exp(1j * p.ky)
+
+ syst[lat.shape(ribbon_shape, (0, 0))] = onsite
+ syst[kwant.HoppingKind((1, 0), lat)] = hopping_x
+ syst[kwant.HoppingKind((0, 1), lat)] = hopy
+ syst[kwant.HoppingKind((0, w + 1), lat)] = hopy_phase
+
+ syst[lat(0, 0)] = onsite
+ syst[lat(0, w  1)] = onsite
+
+ return syst
+
+
+def make_lead(t, trs=None):
+ def ribbon_shape(pos):
+ (x, y) = pos
+ return (0 <= y < 2)
+
+ lat = kwant.lattice.square(norbs=4)
+ sym = kwant.TranslationalSymmetry((1, 0))
+ syst = kwant.Builder(sym, time_reversal=1j*pauli.sys0)
+
+ syst[lat.shape(ribbon_shape, (0, 0))] = 1.8 * t * pauli.s0sz
+ syst[kwant.HoppingKind((1, 0), lat)] = t * pauli.s0sz
+ return syst
+
+
+def make_scatter_sys():
+ def shape(pos):
+ x, y = pos
+ return (x == 0) * (0 <= y < 3)
+
+ lat = kwant.lattice.square(norbs=4)
+ syst = kwant.Builder()
+ syst[lat.shape(shape, (0, 0))] = onsite
+ syst[kwant.HoppingKind((0, 1), lat)] = hopy
+
+ lead_cylinder = bhz_cylinder()
+ lead = make_lead(1.0)
+ syst.attach_lead(lead.reversed())
+ syst.attach_lead(lead_cylinder)
+ syst = syst.finalized()
+ return syst
+
+
+def scattering_det_pfaff(syst, p):
+
+ def pfaffian(syst, p, ky):
+ p.ky = ky
+ smat = kwant.smatrix(syst, energy=0.0, args=[p]).data
+ # since we get relatively large numerical errors we project the matrix on
+ # the space of antisymmetric matrices
+ smat = 0.5 * (smat  smat.T)
+ return pf.pfaffian(smat)
+
+ pfaff = [pfaffian(syst, p, 0), pfaffian(syst, p, np.pi)]
+
+ ks = np.linspace(0.0, np.pi, 50)
+ det = [np.linalg.det(kwant.smatrix(syst, energy=0.0, args=[p]).data) for p.ky in ks]
+ det = np.array(det)
+
+ phase = np.angle(pfaff[0]) + 0.5 * np.cumsum(np.angle(det[1:] / det[:1]))
+ kdims = ['$k_y$', 'phase']
+ plot = holoviews.Path((ks[1:], phase), kdims=kdims)(style={'color': 'b'})
+ plot *= holoviews.Points(([0, np.pi], np.angle(pfaff)), kdims=kdims)(style={'color': 'g'})
+ xlims, ylims = slice(0.2, np.pi + 0.2), slice(np.pi  0.2, np.pi + 0.2)
+ pi_ticks = [(np.pi, r'$\pi$'), (0, '$0$'), (np.pi, r'$\pi$')]
+ ticks = {'xticks': [(0, '0'), (np.pi, '$\pi$')], 'yticks': pi_ticks}
+ return plot.relabel('Winding', depth=1)[xlims, ylims](plot=ticks)
+
+
+def title(p):
+ title = r'$A={:.2}$, $B={:.2}$, $D={:.2}$, $M={:.2}$'
+ return title.format(p.A, p.B, p.D, p.M)
+
+```
+
+# Introduction
+
+Charles Kane from the University of Pennsylvania will introduce today's lecture on two dimensional topological insulators with timereversal symmetry.
+
+
+```python
+MoocVideo("n5oUQvvsYd0", src_location='5.1intro', res='360')
+```
+
+# Adding symmetry to a topological insulator
+
+In general, there are different approaches to discover new types of topological systems.
+
+We have already used a very powerful method to make a Kitaev chain and the Chern insulator model. We started from guessing what kind of model to use for the edge, such that it is impossible to obtain without the bulk. Then we combined many such edges (dots for the Kitaev chain and wires for the Chern insulator) and tailored the coupling between them to leave exactly the type of model that we want on one edge.
+
+A very skilled researcher in topology (or more specifically [Ktheory](https://en.wikipedia.org/wiki/Ktheory)) may also just calculate the expected topological classification of a system starting only from its dimensionality and symmetries. This is also a powerful method, but often it's too hard and requires a very high skills in math.
+
+Another approach that we can undertake is to start with one topological Hamiltonian and see what happens if we force the Hamiltonian to have some extra symmetry. This is the approach we will use in this chapter.
+
+Let's start from a simple example involving something which we already know, a quantum dot with the Hamiltonian $H_0$. We know that there is a topological invariant, the number of filled energy levels.
+
+Now we can ask what happens if we force the dot to have a particlehole symmetry. The Hamiltonian becomes
+
+$$
+H_\textrm{BdG} =
+\begin{pmatrix}
+H_0 & 0\\
+0 & H_0^*
+\end{pmatrix}.
+$$
+
+This model is clearly topologically trivial from the point of view of the old invariant, since the number of filled states is constant. However, there are still level crossings that appear. We may ask if these crossings stay protected if we also include a finite superconducting pairing $\Delta$ in the Hamiltonian, which couples the two blocks $H_0$ and $H_0^*$.
+
+Of course we know the answer: the crossings stay protected due to the change in the Pfaffian invariant. So what we did was to construct a topologically nontrivial superconducting dot by adding particlehole symmetry to a topological Hamiltonian with a lower symmetry.
+
+Let's now apply the same logic to a new system. Specifically, let's add timereversal symmetry to a Chern insulator. The Chern insulator has chiral edge states whose direction of propagation is flipped by timereversal symmetry $\mathcal{T}$. So let's consider a Hamiltonian of the form
+
+$$
+H =
+\begin{pmatrix}
+H_0 & 0\\
+0 & \mathcal{T}H_0\mathcal{T}^{1}
+\end{pmatrix}\,.
+$$
+
+If $H_0$ is the Hamiltonian of a Chern insulator with $N$ edge states, then $H$ will have $N$ pairs of counterpropagating edge states that transform into each other by timereversal symmetry. Moreover, the full $H$ obeys timereversal symmetry, which merely exchanges the two blocks.
+
+The following sketch describes the situation in the case $N=1$:
+
+![](figures/qsh_insulator.svg)
+
+The next task which we now face is to understand if such edges stay topologically protected once we add coupling between the two blocks.
+
+# A perfectly transmitted channel and Kramers degeneracy
+
+We could try to see if all the edge states can be removed by adding some terms to the Hamiltonian, but instead we will use a closely related fact.
+
+Let's study transport through such edge states as a function of their total number and let's only use the fact that timereversal symmetry is present. Imagine, there is a total of $N$ states going in each direction along the edge, and that the edge is composed of a disordered region sandwiched between two clean regions. Again, let's represent the situation for the case $N=1$.
+
+![](figures/qsh_scattering.svg)
+
+## Scattering states
+
+We label incoming states on the left and right with $\leftn,\textrm{L}\right\rangle$ and $\leftn,\textrm{R}\right\rangle$. The index $n$ goes from $1$ to $N$. The outgoing states are the timereversed partners of the incoming states, so they are given by $\mathcal{T}\leftn,\textrm{L}\right\rangle$ and $\mathcal{T}\leftn,\textrm{R}\right\rangle$. Scattering states in the left and right regions are superpositions of incoming and outgoing states,
+
+$$
+\left\Psi,\textrm{L}\right\rangle = \sum_{n=1}^N \alpha_{n,\textrm{L}}\,\leftn,\textrm{L}\right\rangle + \beta_{n,\textrm{L}}\,\mathcal{T}\leftn,\textrm{L}\right\rangle\,,
+$$
+$$
+\left\Psi,\textrm{R}\right\rangle = \sum_{n=1}^N \alpha_{n,\textrm{R}}\,\leftn,\textrm{R}\right\rangle + \beta_{n,\textrm{R}}\,\mathcal{T}\leftn,\textrm{R}\right\rangle\,.
+$$
+
+We can form vectors out of all the coefficients in the superposition, for instance $\alpha_\textrm{L} = (\alpha_{1,\textrm{L}},\dots,\alpha_{N,\textrm{L}})^T$ for the incoming states on the left side. Incoming and outgoing modes are then related by the scattering matrix $S$ of the disordered region,
+
+$$
+\begin{pmatrix} \beta_\textrm{L} \\ \beta_\textrm{R} \end{pmatrix} = S \begin{pmatrix} \alpha_\textrm{L} \\ \alpha_\textrm{R} \end{pmatrix}.
+$$
+
+There are a total of $2N$ incoming and $2N$ outgoing modes, so $S$ is a $2N\times 2N$ matrix. Since we are including all possible initial and final states, $S$ is also unitary, $S=S^\dagger$. It can be split into reflection and transmission blocks of dimension $N\times N$,
+
+$$
+S =
+\begin{pmatrix}
+r & t\\
+t' & r'
+\end{pmatrix}\,.
+$$
+
+If we can gap out the edges by adding some extra terms to the Hamiltonian, or backscatter them by adding disorder, then we should be able to achieve the situation where there is no transmission at all, $t = t' = 0$. In this case, all modes must be reflected back, so the reflection blocks of the scattering matrix become unitary, $r^\dagger r = r'^\dagger r' = 1$.
+
+To see whether this is possible at all, we first have to understand the constraints that timereversal symmetry imposes on $S$.
+
+## Scattering matrices with timereversal symmetry
+
+Let's recall some basic facts about timereversal symmetry, which we already studied in the first week. Timereversal symmetry has an antiunitary operator $\mathcal{T}$ which commutes with the Hamiltonian. Being antiunitary, $\mathcal{T}$ may come in two flavors  either $\mathcal{T}^2=1$ or $\mathcal{T}^2=1$. The first case applies to systems with no or integer spin, such that $\mathcal{T}=\mathcal{K}$ in the simplest case, where $\mathcal{K}$ is the complex conjugation operator. The second case applies to systems with halfinteger spin, and in the simplest case we have $\mathcal{T}=i\sigma_y\mathcal{K}$.
+
+Let's apply the timereversal operator to our scattering states. We get
+
+$$
+\mathcal{T}\left\Psi,\textrm{L}\right\rangle = \sum_{n=1}^N \alpha^*_{n,\textrm{L}}\,\mathcal{T}\leftn,\textrm{L}\right\rangle + \beta^*_{n,\textrm{L}}\,\mathcal{T}^2\leftn,\textrm{L}\right\rangle\,,
+$$
+$$
+\mathcal{T}\left\Psi,\textrm{R}\right\rangle = \sum_{n=1}^N \alpha^*_{n,\textrm{R}}\,\mathcal{T}\leftn,\textrm{R}\right\rangle + \beta^*_{n,\textrm{R}}\,\mathcal{T}^2\leftn,\textrm{R}\right\rangle\,.
+$$
+
+Now, since timereversal symmetry does not change the energy of a state, $\mathcal{T}\left\Psi,\textrm{R}\right\rangle$ and $\mathcal{T}\left\Psi,\textrm{L}\right\rangle$ are scattering states with the same energy as $\left\Psi,\textrm{R}\right\rangle$ and $\left\Psi,\textrm{L}\right\rangle$. Hence, the coefficients of incoming and outgoing modes are still related by the same scattering matrix $S$ as before. Note, however, that applying $\mathcal{T}$ exchanged the role of the $\alpha$'s and $\beta$'s, such that the $\alpha$'s now correspond to outgoing states and the $\beta$'s to incoming states. Hence, we have
+
+$$
+ S\mathcal{T}^2 \begin{pmatrix}\beta^*_\textrm{L} \\ \beta^*_\textrm{R} \end{pmatrix} = \begin{pmatrix} \alpha^*_\textrm{L} \\ \alpha^*_\textrm{R} \end{pmatrix}\,.
+$$
+
+Multiplying both sides by $\mathcal{T}^2S^\dagger$ and taking the complex conjugate gives
+
+$$
+\begin{pmatrix} \beta_\textrm{L} \\ \beta_\textrm{R} \end{pmatrix} = \mathcal{T}^2\,S^T \begin{pmatrix} \alpha_\textrm{L} \\ \alpha_\textrm{R} \end{pmatrix}.
+$$
+
+By comparing this equation with the one a few lines above, we finally obtain
+
+$$
+S = \mathcal{T}^2 S^T.
+$$
+
+So if $\mathcal{T}^2=1$, the scattering matrix is symmetric ($S=S^T$), while if $\mathcal{T}^2=1$, it is antisymmetric ($S=S^T$).
+
+What does this imply if we try to set $t=t'=0$?
+
+If $S=S^T$, it turns out there is really nothing special we can tell. However, if $S=S^T$ and $t=t'=0$, the $N\times N$ reflection matrix must be both unitary, $r^\dagger r=1$, and antisymmetric, $r=r^T$.
+
+If $N$ is odd, this isn't possible at all, since any odddimensional antisymmetric matrix [must have](https://en.wikipedia.org/wiki/Skewsymmetric_matrix#Spectral_theory) a single zero eigenvalue, while unitary matrices only have eigenvalues with unit norm!
+
+We are forced to conclude that it is impossible to have $r$ unitary, and therefore it is impossible to have $t=0$ in this case. Furthermore, this zero eigenvalue of $r$ means that there is always a single mode that is transmitted with unit probability.
+
+This is the discovery that Charles Kane described in the introductory video. We can quickly check it by randomly selecting an antisymmetric scattering matrix with odd $N$, like the following one with $N=3$,
+
+
+```python
+N = 3
+np.random.seed(12)
+S = kwant.rmt.circular(N*2, sym='AII')
+
+pprint_matrix(S)
+```
+
+and looking at the eigenvalues of $r^\dagger r$ and $t^\dagger t$:
+
+
+```python
+r = S[:N, :N]
+print('Reflection eigenvalues')
+pprint_matrix(np.linalg.eigvalsh(r @ r.T.conj()))
+
+t = S[:N, N:]
+print('Transmission eigenvalues')
+pprint_matrix(np.linalg.eigvalsh(t @ t.T.conj())[::1])
+```
+
+> We conclude that if $\mathcal{T}^2=1$ and the number of edge states going in one direction is odd, they cannot be gapped out, and the system is topological. On the other hand, if there is an even number of such edge states, they can be gapped out. Since these are the only two options, the integer invariant of a Chern insulator is reduced to a $\pm 1$ invariant in the presence of time reversal symmetry. These topologically protected, counterpropagating edge states are often referred to as **helical edge states**.
+
+# Helical edge states are Kramers pairs
+
+You might ask yourself what makes $\mathcal{T}^2=1$ special, leading to the topological protection of the helical edge states.
+
+As was mentioned in the first week, if $\mathcal{T}^2=1$ then Kramers' theorem applies. Kramers' theorem tells us that given an eigenstate $\Psi\rangle$ of the Hamiltonian with energy $E$, its timereversed partner $\Psi_\mathcal{T}\rangle\equiv\mathcal{T}\Psi\rangle$ has the same energy, and the two states are orthogonal, $\langle \Psi  \Psi_\mathcal{T}\rangle=0$. These two states form a socalled **Kramers pair**. As we already know, this leads to the fact that Hamiltonians with spinful timereversal symmetry have twofold degenerate energy levels  **Kramers degeneracy**.
+
+Now, the two counterpropagating helical modes are timereversed partners of each other, so they form precisely such a Kramers pair. The condition $\langle \Psi  \Psi_\mathcal{T}\rangle=0$ implies that it is impossible to introduce any backscattering between the two states, unless we break timereversal symmetry. This is the origin of the unit transmission and of the topological protection of helical edge states.
+
+To gain a more intuitive understanding of this fact at a more microscopic level, we can assume that the projection of the electrons' spin along a given axis is conserved, say the axis $z$ perpendicular to the plane. Then at the edge you have, say, a rightmoving mode with spin up and a leftmoving mode with spin down, and no other modes if $N=1$. Let's draw again the picture of a helical edge state entering the disordered region:
+
+![](figures/spin_flip.svg)
+
+Thus, an electron moving to the right must have spin up by assumption. In order to be reflected, its spin must also be flipped. However, this spinflip scattering process is forbidden, and again we conclude that the electron is transmitted with probability one.
+
+In the case $\mathcal{T}^2=1$, there is no Kramers' theorem. As a consequence, even though you can construct models which have counterpropagating edge states, you will find that they have no topological protection and can be gapped out without breaking the timereversal symmetry.
+
+# The quantum spin Hall effect
+
+There is no really precise name for the 2D topological insulator with timereversal symmetry. It is often called "$\mathbb{Z}_2$ topological insulator." However, this simply indicates that there are only two values of the topological invariant, and so it isn't a very specific name.
+
+The most commonly used name for this system is "quantum spin Hall insulator." To understand why, let's analyse a Hall bar made of such a nontrivial insulator. We will only need a Hall bar with four terminals, as shown below:
+
+![](figures/qsh_hallbar.svg)
+
+We have a finite voltage applied to terminal 1, so electrons are injected into the system from there. You can see that because of the helical edge states, there are as many modes connecting terminal 1 to terminal 3 as there are to terminal 4. A moment of thought, or otherwise a quick calculation, should convince you that in this case there is no net current flowing orthogonal to the applied voltage. The Hall conductance is zero, which is the expected result if timereversal symmetry is preserved, as it is in our system.
+
+However, counterpropagating edge states have to have exactly opposite spin due to Kramers degeneracy. This means that there may be a net spin current across the sample, orthogonal to the applied voltage.
+
+In particular, let's again make the simple assumption that the spin projection along some axis is conserved. Then, in the figure above, all modes colored in red have spin up, and all modes colored in blue have spin down. So terminal 1 distributes electrons coming out of it according to their spin: all electrons with spin up end up in terminal 4, and all those with spin down in terminal 3. The system has a quantized spin current between terminals 3 and 4, hence the name "quantum spin Hall effect".
+
+However, the quantized spin Hall current is not a general property of a quantum spin Hall insulator. Here, it arises because we have combined time reversal symmetry with a spin conservation law, and as we learned in the first week, conservation laws are boring from a topological point of view.
+
+
+```python
+question = ("Consider the simple case where spin is conserved. "
+ "In the quantum spin Hall bar system above, what happens if, instead of applying a voltage between terminals 1 and 2, "
+ "you manage to apply a *spinpolarized* current between terminals 1 and 2?")
+
+answers = ["The system will develop an opposite spinpolarized current to compensate the effect.",
+ "A spinpolarized current will develop between terminals 3 and 4.",
+ "A voltage difference will develop between terminals 3 and 4.",
+ "It is impossible to apply such a current unless the bulk gap closes."]
+
+explanation = ("The spinpolarized current will create an electron population imbalance between terminals 3 and 4. "
+ "Hence, similar to the Hall effect, a voltage will develop orthogonal to the current.")
+
+MoocMultipleChoiceAssessment(question=question, answers=answers, correct_answer=2, explanation=explanation)
+```
+
+# A model for the quantum spin Hall insulator
+
+There is an important model which can be used to describe quantum spin Hall insulators, known as the **BernevigHughesZhang model** or, in short, BHZ model. In essence, this model is equivalent to two copies of the Chern insulator Hamiltonian on the square lattice that we studied in the fourth week.
+
+The BHZ Hamiltonian takes the form
+
+$$
+H_\textrm{BHZ}(\mathbf{k}) = \begin{pmatrix} h(\mathbf{k}) & 0 \\ 0 & h^*(\mathbf{k}) \end{pmatrix}\,,
+$$
+
+with
+
+$$
+h(\mathbf{k}) = \epsilon(\mathbf{k}) + \mathbf{d}(\mathbf{k})\cdot \pmb{\sigma}\,.
+$$
+
+Here $\pmb\sigma = (\sigma_x, \sigma_y, \sigma_z)$ is a vector of Pauli matrices acting on the electron/hole degree of freedom (the original two bands of the Chern insulator), $\epsilon(\mathbf{k}) = C  D(k_x^2+k_y^2)$, the vector $\mathbf{d} = [A k_x, A k_y, M(\mathbf{k})]$, and
+$M(\mathbf{k}) = M  B(k_x^2+k_y^2)$.
+
+You can see that it is basically two copies of the massive Dirac Hamiltonian we used to study Chern insulators. In particular, there is a linear coupling in momentum between the holes and the electrons. The gap in the Hamiltonian is given by the term $M(\mathbf{k})$, a momentumdependent effective mass.
+
+By changing the sign of $M$ from negative to positive, you get a gap closing at $\mathbf{k}=\pmb{0}$:
+
+
+```python
+%%output fig='png'
+p = SimpleNamespace(Bz=0.0, **bhz_parameters['topo2'])
+syst = bhz(w=None)
+k = (4 / 3) * np.linspace(np.pi, np.pi, 101)
+kwargs = {'k_x': k, 'k_y': k, 'title': title}
+Ms = np.linspace(1, 1, 11)
+holoviews.HoloMap({p.M: spectrum(syst, p, **kwargs) for p.M in Ms}, kdims=[r'$M$'])
+```
+
+This gap closing turns your trivial insulator into a topologically nontrivial quantum spin Hall insulator.
+
+In the rest of this lecture, we will use the BHZ model as a toymodel to illustrate the behavior of a quantum spin Hall insulator using numerical examples. The BHZ model, however, is more than a toymodel, and it can be used to capture the behavior of some real semiconducting materials. For this reason, the BHZ model will be a main protagonist in the next chapter, where we will discuss real materials and the experimental evidence for the quantum spin Hall effect.
+
+# Alternative point of view: fermion parity pump
+
+In the previous cases of the Kitaev chain and the quantum Hall effect, the bulk topological invariant that we eventually obtained was characterized by the response to some adiabatic experiment.
+
+Since the timereversal invariant topological insulator is two dimensional like a quantum Hall system, it is reasonable to put the system in a Corbino geometry and change the flux through the system, creating an azimuthal electric field:
+
+![](figures/qsh_corbino.svg)
+
+However, because of timereversal symmetry, the system is forbidden from having a Hall conductance and therefore there cannot be any charge transfer between the two edges of the disk. For instance, if we consider two copies of the Haldane model with opposite spin, there will be two quantum Hall pumps working in opposite directions (one transferring charge from the inner edge to the outer edge, the other one from the outer edge to the inner one). So the net charge transferred is zero.
+
+Because the two pumps act on electrons with opposite spin, you might be tempted to define a spin current, which would flow in response to the electric field, orthogonal to it. However, as we just discussed, the spin along a given direction may not be conserved, so generally this is not a good way to define a robust pumping effect.
+
+To understand what exactly happens in the pumping process, let's look at the energy spectrum of the edge states for the BHZ model in the cylinder geometry. As we discussed in the quantum Hall lectures, the cylinder geometry is really equivalent to the Corbino disk, except that it is easier to study.
+
+You also learned that in a cylinder of finite circumference $L$, the momenta of the allowed edge states are quantized at values determined by the flux.
+
+To make things more simple, you may actually imagine that the circumference of the cylinder is just a single unit cell long. We then have only one allowed value of the momentum $k$ along the edge, which is exactly proportional to the flux threaded through the cylinder, $k = 2\pi \Phi/\Phi_0$.
+
+So let's look at the energy spectrum of a cylinder as a function of $k$ (or equivalently $\Phi$), and compare a cylinder in the quantum spin Hall phase with a cylinder in the trivial insulating phase.
+
+
+```python
+half_pi_ticks = [(0, '$0$'), (np.pi/2, r'$\pi/2$'), (np.pi, r'$\pi$')]
+style = {'k_x': np.linspace(0, np.pi, 101),
+ 'xdim': r'$k$',
+ 'ydim': r'$E$',
+ 'xticks': half_pi_ticks,
+ 'yticks': np.linspace(2, 2, 9),
+ 'xlims': [0, np.pi],
+ 'ylims': [2, 2],
+ 'title': title}
+
+syst = bhz(20)
+p1 = SimpleNamespace(Bz=0, **bhz_parameters['topo'])
+p2 = SimpleNamespace(Bz=0, **bhz_parameters['triv'])
+
+(spectrum(syst, p1, **style).relabel('Topological') * holoviews.HLine(0) +
+ spectrum(syst, p2, **style).relabel('Trivial') * holoviews.HLine(0))
+```
+
+In both cases you see that at $k=0$ there are isolated pairs of states with degenerate energies, between the valence and conduction bands. The Fermi energy is set at $E=0$, in the middle of the gap between conduction and valence bands. These states are the Kramers pairs at the edges  one pair for the topological case, two for the trivial case.
+You also see the splitting of Kramers pairs as soon as $k$ goes away from zero. This is because $k = 0$ is a timereversal invariant point, a point in momentum space that is mapped to itself by timereversal symmetry.
+
+The plot ends at $k=\pi$ (that is, $\Phi=h/2e$), which is another timereversal invariant point. Indeed, timereversal symmetry sends $\Phi\to\Phi$, but for $\Phi=h/2e$ this corresponds exactly to adding or subtracting a flux quantum. Hence, all the physical properties of the system remain unchanged under the action of timereversal for this value of the flux. And indeed you can see that all levels meet again and form Kramers pairs.
+
+> We now see an interesting difference though. In the topological case, the Kramers pairs at $k=\pi$ are not the same as those at $k=0$. In the trivial case however, the pairs are the same. As a consequence, in the topological case there is an odd number of levels crossing zeroenergy, while in the trivial cases there is an even number of them. Therefore changing the flux by $h/2e$ in the topological case changes the fermion parity at the edge, while it does nothing in the trivial case. We have thus obtained a **fermion parity pump**.
+
+Strangely, this reminds us of the topological superconducting ring that we studied in the second week of the course. There we also had a fermion parity change in response to a flux. It turns out that this is not a coincidence, as we will see when we discuss how to realize topological superconductors using topological insulators.
+
+You may appreciate that our argument did not rely on spin being a good quantum number, or on any other detail of the system, but only on Kramers theorem. And in fact it holds very generally. Deforming the dispersion of Kramers pairs does not break the fermion parity pump, as long as the way states combine to form Kramers pairs at $k=0$ and $k=\pi$ is unchanged.
+
+# Pumping expression for the topological invariant
+
+At this point, following the same path we followed for Chern insulator, we would like to find an expression for a topological bulk invariant which characterizes the quantum