{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tensor Network Renormalization Group for the 2D Ising model" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "using LinearAlgebra" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "using Plots" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define the basic functions for the Ising model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define Kronecker Delta" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define the weight functions of Ising model" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$Z_2$ has two representations, $k=0$ and $k=1$. The weight on an edge is $\\cosh(\\beta)$ for $k=0$, $\\sinh(\\beta)$ for $k=1$." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Define the initial tensor" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The tensor is 4-valent, each edge carrying a representation of $Z_2$, and a square root of an edge weight (for $\\beta$ and $k$). On the vertex, we have a Kronecker Delta of the sum of the 4 representations meeting at the vertex modulo 2; if this sum is 1, it vanishes." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that Julia starts counting array indices with 1, not 0. You need to account for that." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "length(tensor[:,1,1,1])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Splitting tensors for the singular value decomposition" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This will be similar to the introductory Julia File. We pair the indices of the tensor in the way we want to split it, and define a matrix. On this matrix we will apply a singular value decomposition, truncate here at 2 singular values, and define new 3-valent tensors from it." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Translating back just means splitting the combined index again into two separate ones." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The function should return two 3-valent tensors and a list of singular values." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Normalize the singular values with respect to the largest one (so the largest singular value is always one)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We need to the same again, but this time for the other splitting." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To get the new effective tensor, we now have to contract the fine degrees of freedom." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To compute the flow of renormalized tensors, we have to iterate these procedures a few times. We write this into a main function." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We have to specify the number of iterations of the algorithm, then define the initial tensor. We can pass $\\beta$ as a parameter of the main function." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we do a for loop, in which we do the first splitting, second splitting and then contract the new three valent tensor. Then we repeat.\n", "\n", "For each iteration we should store the singular values computed in the singular value decomposition. We will afterwards plot them to distinguish the phases of the Ising model and finding the phase transition." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If it is running, try the algorithm for different initial values of $\\beta$ and look for a phase transition. The actual critical inverse temperature of the 2D square lattice Ising model is $\\beta_c \\approx 0.4406...$. The plot the singular values for different betas." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot the singular values, actually the second largest one. The x-axis is simply the iteration number." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.0.1", "language": "julia", "name": "julia-1.0" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.0.1" } }, "nbformat": 4, "nbformat_minor": 2 }