Advanced Computing Platform for Theoretical Physics

commit大文件会使得服务器变得不稳定,请大家尽量只commit代码,不要commit大的文件。

Commit 7a91c2ad authored by Pan Zhang's avatar Pan Zhang
Browse files

CTM, iPEPS for 2D Ising

parent 71b5a85c
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# iPEPS contraction for computing $\\ln Z$ of the $2-$D ferromagnetic Ising model"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## $Z$ as contraction of PEPS\n",
"The partition function of $2-$D Ising model can be written as\n",
"$$Z=\\sum_\\mathbf{s}\\prod_{ij}e^{\\beta J_{ij}s_is_j}=\\sum_\\mathbf{s}\\prod_i^\\circ\\sqrt{A_i}.$$ Where $\\prod_i^\\circ$ denotes tensor contraction of all the $A_i$ tensors, each of which is a tensor given by $$A_i = I_i\\prod_{j\\in\\partial i}\\sqrt{B_{ij}},$$ where $I$ is a identity tensor with order equals to the degree of node $i$, and $B_{ij}$ defines a Boltzmann matrix with $$B_{ij}=\\left[\\begin{array}{l}e^{\\beta J_{ij}}& e^{-\\beta J_{ij}} \\\\ e^{-\\beta J_{ij}}& e^{\\beta J_{ij}}\\end{array}\\right].$$ $\\sqrt{B}$ indicates square root of matrix $B$, yileding $\\sqrt{B}\\times \\sqrt{B} = B$. For the ferromagnetic model, every $B$ matrix and $A$ tensor are identical, the system has a rotational invariance."
]
},
{
"cell_type": "code",
"execution_count": 130,
"metadata": {},
"outputs": [],
"source": [
"import torch\n",
"from scipy.linalg import sqrtm\n",
"import numpy as np\n",
"import sys,math\n",
"\n",
"mydevice = torch.device('cpu')\n",
"mydtype=torch.float64\n",
"beta=0.5\n",
"def get_A(beta=0.5):\n",
" b=np.exp(beta)\n",
" B=torch.tensor(sqrtm(np.array([[b,1/b],[1/b,b]])),dtype=mydtype,device=mydevice) # the Boltzmann matrix\n",
" I=torch.zeros([2,2,2,2],dtype=mydtype) # the identity matrix defined on each site\n",
" I[0,0,0,0]=1\n",
" I[1,1,1,1]=1\n",
" Im=I.clone()\n",
" Im[1,1,1,1]=-1\n",
" A=torch.einsum(\"ij,ab,cd,xy,jbdy->iacx\",B,B,B,B,I) #\n",
" Am= torch.einsum(\"ij,ab,cd,xy,jbdy->iacx\",B,B,B,B,Im) # this will be used for computing magnetization\n",
" return A,Am"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Onsager solution\n",
"What we are going to compare with is the Onsager solution, with $\\ln Z$, critical temperature $\\beta_c$, and the spontaneous magnetization are given as\n",
"\\begin{align} \\ln Z&=\\ln 2 +\\frac{1}{8\\pi^2}\\int_0^{2\\pi}d\\theta_1\\int_0^{2\\pi}d\\theta_2\\ln\\left[ \\cosh^2(2\\beta)-\\sinh(2\\beta)\\cos(\\theta_1)-\\sinh(2\\beta)\\cos(\\theta_2) \\right]\\\\\n",
"\\beta_c&=\\frac{\\ln (1+\\sqrt{2})}{2},\\\\\n",
"m_{\\beta \\gt \\beta_c}&=\\left[ 1-\\sinh^{-4}(2\\beta) \\right]^{\\frac{1}{8}}.\n",
"\\end{align}\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 161,
"metadata": {},
"outputs": [],
"source": [
"def m_exact(beta):\n",
" if(beta>0.5*math.log(1+math.sqrt(2))):\n",
" return math.pow((1- math.pow(math.sinh(2*beta),-4)),1/8 )\n",
" else:\n",
" return 0"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## CTMRG for rotational and translational symmetric iPEPS\n",
"The Corner Transfer Matrix RG method for contracting iPEPS takes care of a corner matrix $C$ and an edge matrix $E$, with $Z$ finally expressed as\n",
"$$ Z=\\begin{array}{c}C&-&E&-&C\\\\|&&|&&|\\\\E&-&A&-&E\\\\|&&|&&|\\\\C&-&E&-&C\\end{array}$$\n",
"The $C$ is updated by \n",
"$$ \\begin{array}{c}C&-&E&-\\\\|&&|\\\\E&-&A&-\\\\|&&|&\\\\\\end{array}\\,\\,\\,\\,\\,\\longrightarrow\\begin{array}{c}\\widehat C&=\\\\\\|&\\\\ \\end{array}\\,\\,\\,\\,\\,\\longrightarrow \\begin{array}{c}C&-&U&=\\\\|&&&\\\\U^{\\dagger}&&&\\\\\\|&&& \\end{array}$$\n",
"And we can see that after one step of update, $C$ is actually the diagonal matrix containing truncated eigenvalues of $\\widehat C$, and $U$ contains conrreponding eigenvectors.\n",
"The edge tensor $E$ is updated as\n",
"$$ \\begin{array}{c}|&&|\\\\E&-&A&-\\\\|&&| \\end{array}\\,\\,\\,\\,\\,\\longrightarrow \\begin{array}{c} \\|\\\\ \\widehat E&-\\\\ \\| \\end{array} \\,\\,\\,\\,\\,\\longrightarrow \\,\\,\\,\\,\\, \\begin{array}{c} \\|\\\\ U \\\\ |\\\\U^{\\dagger}\\\\ \\| \\\\ \\widehat E&-\\\\\\|\\\\U\\\\|\\\\U^{\\dagger}\\\\ \\|\\end{array} \\longrightarrow \\,\\,\\,\\,\\, \\begin{array}{c} \\|\\\\ U \\\\ |\\\\ E&-\\\\|\\\\U^{\\dagger}\\\\\\|\\end{array}$$ \n",
"\n",
"For the detailed einsum rules for updates corner matrix $C$, I have used in the code that\n",
"$$ \\begin{array}{c}C&-_j&E&-_k\\\\|_i&&|_l\\\\E&-_n&A&-_a\\\\|_m&&|_b&\\\\\\end{array}$$\n",
"\n",
"For update of $E$, \n",
"$$ \\begin{array}{c}|_j&&|_l\\\\E&-_k&A&-_m\\\\|_i&&|_n \\end{array}$$\n",
"\n",
"And for finall contractions \n",
"$$ Z=\\begin{array}{c}C&-_b&E&-_d&C\\\\|_a&&|_c&&|_e\\\\E&-_g&A&-_i&E\\\\|_f&&|_h&&|_j\\\\C&-_k&E&-_l&C\\end{array}$$\n",
"Also be very careful about the order of the original indices of bonds when two bonds are merged into a singer boarder bond.\n"
]
},
{
"cell_type": "code",
"execution_count": 173,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"beta=0.48,beta_C=0.440687\n",
"m_ctm = -0.877523 m_exact=0.877523\n"
]
}
],
"source": [
"beta=0.48\n",
"A,Am = get_A(beta)\n",
"iter_max = 100\n",
"tol = 1.0e-10\n",
"Dmax = 10\n",
"C = B@torch.eye(2,dtype=mydtype)@B # initial C\n",
"I3=torch.zeros([2,2,2],dtype=mydtype) \n",
"I3[0,0,0]=1\n",
"I3[1,1,1]=1\n",
"E = torch.einsum(\"ij,ab,cd,jbd->iac\",B,B,B,I3) # initial E\n",
"C = torch.randn(2,2,dtype=mydtype)\n",
"E = torch.randn(2,2,2,dtype=mydtype)\n",
"err=1.0\n",
"for iter in range(iter_max):\n",
" #update C\n",
" Chat = torch.einsum(\"ij,jkl,min,nlab->bmak\",C,E,E,A).contiguous().view([E.shape[0]*A.shape[3],E.shape[1]*A.shape[2]])\n",
" [U,s,V]=torch.svd(Chat)\n",
" if(s.numel()>Dmax):\n",
" s=s[:Dmax]\n",
" U=U[:,:Dmax]\n",
" Cnew = torch.diag(s)\n",
" Cnew = Cnew/Cnew.norm()\n",
" if(C.shape == Cnew.shape):\n",
" err=(Cnew-C).norm()\n",
" #sys.stdout.write(\"#%d err=%.3g \\n\"%(iter,err))\n",
" if(err<tol):\n",
" #print(\"\\nC matrix converged\\n\")\n",
" break\n",
" C=Cnew.clone()\n",
" \n",
" E = torch.einsum(\"ijk,klmn->niljm\",E,A).contiguous().view(E.shape[0]*A.shape[3],E.shape[1]*A.shape[1],A.shape[2])\n",
" E = torch.einsum(\"ijk,jl,im->mlk\",E,U,U)\n",
" E = E/E.norm()\n",
"Z=torch.einsum(\"ab,bdc,de,fag,hgci,eji,kf,lkh,jl\",C,E,C,E,A,E,C,E,C)\n",
"Zm=torch.einsum(\"ab,bdc,de,fag,hgci,eji,kf,lkh,jl\",C,E,C,E,Am,E,C,E,C)\n",
"\n",
"print(\"beta=%g,beta_C=%g\"%(beta,0.5*math.log(1+math.sqrt(2))))\n",
"print(\"m_ctm = %g\"%(Zm/Z).item(),\"m_exact=%g\"% m_exact(beta))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"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/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment