<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="https://snowkylin.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://snowkylin.github.io/" rel="alternate" type="text/html" /><updated>2026-08-31T03:43:23+00:00</updated><id>https://snowkylin.github.io/feed.xml</id><title type="html">Xihan Li</title><subtitle>Seeking the Truth and Pioneering New Trails.
</subtitle><author><name>Xihan Li (snowkylin)</name></author><entry><title type="html">A Note on DeepSeek R1 Deployment</title><link href="https://snowkylin.github.io/blogs/a-note-on-deepseek-r1.html" rel="alternate" type="text/html" title="A Note on DeepSeek R1 Deployment" /><published>2025-01-30T00:00:00+00:00</published><updated>2025-01-30T00:00:00+00:00</updated><id>https://snowkylin.github.io/blogs/a-note-on-deepseek-r1</id><content type="html" xml:base="https://snowkylin.github.io/blogs/a-note-on-deepseek-r1.html"><![CDATA[<center>
<video width="60%" height="320" muted="" autoplay="" controls="">
  <source src="/assets/deepseek-r1/deepseek-r1-strawberry.mp4" type="video/mp4" />
Your browser does not support the video tag.
</video>
</center>

<p>This is a (minimal) note on deploying <a href="https://github.com/deepseek-ai/DeepSeek-R1">DeepSeek R1</a> 671B (the full version without distillation) locally with ollama.</p>

<ul id="markdown-toc">
  <li><a href="#models" id="markdown-toc-models">Models</a></li>
  <li><a href="#hardware-requirement" id="markdown-toc-hardware-requirement">Hardware Requirement</a></li>
  <li><a href="#steps" id="markdown-toc-steps">Steps</a></li>
  <li><a href="#some-observations" id="markdown-toc-some-observations">Some Observations</a></li>
  <li><a href="#conclusion--suggestion" id="markdown-toc-conclusion--suggestion">Conclusion &amp; Suggestion</a></li>
  <li><a href="#slide" id="markdown-toc-slide">Slide</a></li>
  <li><a href="#note" id="markdown-toc-note">Note</a></li>
</ul>

<h2 id="models">Models</h2>

<p>The original DeepSeek R1 671B model is 720GB in size, which is huge. Even a $200k monster like <a href="https://www.nvidia.com/en-gb/data-center/dgx-h100/">NVIDIA DGX H100</a> (with 8xH100) can barely hold it. Here I use <a href="https://x.com/UnslothAI">Unsloth AI</a>’s dynamically quantized version, which selectively quantize a few important layers to higher bits, while leaving most of the MoE layers for lower bits. As a result, the model can be quantized to as small as 131GB (1.58-bit), making it much more accessable for local users. It can even run on a single Mac Studio ($5.6k)!</p>

<p>I choose the following two models based on the spec of my workstation:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">DeepSeek-R1-UD-IQ1_M</code> (671B, dynamically quantized 1.73-bit, 158 GB, <a href="https://huggingface.co/unsloth/DeepSeek-R1-GGUF/tree/main/DeepSeek-R1-UD-IQ1_M">HuggingFace</a>)</li>
  <li><code class="language-plaintext highlighter-rouge">DeepSeek-R1-Q4_K_M</code> (671B, standard 4-bit, 404 GB, <a href="https://huggingface.co/unsloth/DeepSeek-R1-GGUF/tree/main/DeepSeek-R1-Q4_K_M">HuggingFace</a>)</li>
</ul>

<p>There are four dynamically quantized models from 131GB (1.58-bit) to 212GB (2.51-bit), and you can choose according to your own spec. A detailed introduction of the four models can be found <a href="https://unsloth.ai/blog/deepseekr1-dynamic">here</a>, which I strongly suggest you to read before the selection.</p>

<h2 id="hardware-requirement">Hardware Requirement</h2>

<p>I will suggest the following memory requirement for the models, which is the main bottleneck</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">DeepSeek-R1-UD-IQ1_M</code>: RAM + VRAM ≥ 200 GB</li>
  <li><code class="language-plaintext highlighter-rouge">DeepSeek-R1-Q4_K_M</code>: RAM + VRAM ≥ 500 GB</li>
</ul>

<p>Ollama allow mixed inference of CPU and GPU (you can offload some model layers into VRAM for faster inference), so you can roughly add up your RAM and VRAM as your total memory space. Apart from the model weight (158 GB and 404 GB), there should also be some memory space leaved for context cache. The more you leaved, the larger context window you can set.</p>

<p>I tested both the two models on my workstation with four-way RTX 4090 (4 x 24 GB), quad-channel DDR5 5600 memory (4 x 96 GB) and a ThreadRipper 7980X CPU (64 cores). Note that you <em>don’t</em> need such a “luxury” spec if you only wanna run the dynamically quantized version. Roughly, the generation speed is</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">DeepSeek-R1-UD-IQ1_M</code>: 7-8 tokens/s for short text generation (~500 tokens)
    <ul>
      <li>4-5 tokens/s if no GPUs are used (fully inferenced on CPU).</li>
    </ul>
  </li>
  <li><code class="language-plaintext highlighter-rouge">DeepSeek-R1-Q4_K_M</code>: 2-4 tokens/s for short text generation (~500 tokens)</li>
</ul>

<p>and the speed will slow down to 1-2 tokens/s for long text.</p>

<p>My workstation specification is <em>not</em> the most cost-effective choice for large LLM inference (it mainly supports my research on <a href="https://x.com/snowkylin/status/1882464077529890944">Circuit Transformer</a> - welcome to have a look!). For now, some cost-effective options include</p>
<ul>
  <li>Apple Mac equipped with large, high-bandwidth unified memory (like <a href="https://x.com/awnihannun/status/1881412271236346233">this</a>, with 2 x 192 GB unified memory).</li>
  <li>A server with high memory bandwidth (like <a href="https://huggingface.co/deepseek-ai/DeepSeek-R1/discussions/19#679be4e7c50d8da8657c1b13">this</a>, with 24 x 16 GB DDR5 4800).</li>
  <li>A Cloud GPU server with two or more 80GB GPUs (Nvidia H100 80GB is around $2 per hour per card)</li>
</ul>

<p>If your hardware specification is a bit constrained, you may consider <a href="https://huggingface.co/unsloth/DeepSeek-R1-GGUF/tree/main/DeepSeek-R1-UD-IQ1_S">the 1.58-bit quantized version</a> that has the smallest size (131GB). It can be successfully run on</p>
<ul>
  <li>A single Mac Studio with 192GB unified memory (<a href="https://x.com/ggerganov/status/1884358147403571466">ref</a>, ~$5600)</li>
  <li>2 x Nvidia H100 80GB (<a href="https://huggingface.co/unsloth/DeepSeek-R1-GGUF/discussions/9">ref</a>, ~$4 per hour)</li>
</ul>

<p>with decent speed (&gt; 10 tokens/s).</p>

<blockquote>
  <p>Update on Mar 5, 2025: Apple released the new Mac Studio with M3 Ultra chip, which allows a maximum of 512GB unified memory. 512GB version starts from <span>$</span>9,499. 256GB version starts from <span>$</span>5,599.</p>
</blockquote>

<h2 id="steps">Steps</h2>

<ol>
  <li>Download the model files (.gguf) from <a href="https://huggingface.co/unsloth/DeepSeek-R1-GGUF">HuggingFace</a> (better with a downloader, I use <a href="https://xtremedownloadmanager.com/">XDM</a>), then merge the seperated files into one <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup>.</li>
  <li>
    <p>Install <a href="https://ollama.com/">ollama</a></p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> curl -fsSL https://ollama.com/install.sh | sh
</code></pre></div>    </div>
  </li>
  <li>
    <p>Create a <a href="https://github.com/ollama/ollama/blob/main/docs/modelfile.md">modelfile</a> that guide ollama to create a model</p>

    <p>The content of <code class="language-plaintext highlighter-rouge">DeepSeekQ1_Modelfile</code> (for <code class="language-plaintext highlighter-rouge">DeepSeek-R1-UD-IQ1_M</code>):</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> FROM /home/snowkylin/DeepSeek-R1-UD-IQ1_M.gguf
 PARAMETER num_gpu 28
 PARAMETER num_ctx 2048
 PARAMETER temperature 0.6
 TEMPLATE "&lt;｜User｜&gt;{{ .System }} {{ .Prompt }}&lt;｜Assistant｜&gt;"
</code></pre></div>    </div>

    <p>The content of <code class="language-plaintext highlighter-rouge">DeepSeekQ4_Modelfile</code> (for <code class="language-plaintext highlighter-rouge">DeepSeek-R1-Q4_K_M</code>):</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> FROM /home/snowkylin/DeepSeek-R1-Q4_K_M.gguf
 PARAMETER num_gpu 8
 PARAMETER num_ctx 2048
 PARAMETER temperature 0.6
 TEMPLATE "&lt;｜User｜&gt;{{ .System }} {{ .Prompt }}&lt;｜Assistant｜&gt;"
</code></pre></div>    </div>

    <p>You may change the parameter values for <code class="language-plaintext highlighter-rouge">num_gpu</code> and <code class="language-plaintext highlighter-rouge">num_ctx</code> depending on your machine specification (see step 6)</p>
  </li>
  <li>
    <p>Create the model in ollama</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ollama create DeepSeek-R1-UD-IQ1_M -f DeepSeekQ1_Modelfile
</code></pre></div>    </div>

    <p>Make sure that you have abundant space in <code class="language-plaintext highlighter-rouge">/usr/share/ollama/.ollama/models</code> (or change ollama model direrctory to another path<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup>), as this command will create model files that is roughly as large as the .gguf file.</p>
  </li>
  <li>
    <p>Run the model</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> ollama run DeepSeek-R1-UD-IQ1_M --verbose
</code></pre></div>    </div>

    <p><code class="language-plaintext highlighter-rouge">--verbose</code> for showing timings for response (tokens/s)</p>

    <p>If OOM/CUDA error occurs during model loading, return to step 4, adjust <code class="language-plaintext highlighter-rouge">num_gpu</code> and <code class="language-plaintext highlighter-rouge">num_ctx</code>, re-create the model and re-run.</p>

    <ul>
      <li><code class="language-plaintext highlighter-rouge">num_gpu</code>: number of layers to be offloaded to GPUs. DeepSeek R1 has 61 layers. In my experience,
        <ul>
          <li>For <code class="language-plaintext highlighter-rouge">DeepSeek-R1-UD-IQ1_M</code>, 7 layers can be offloaded to each of my RTX 4090 GPU (24 GB VRAM). I have four of them so I can offload 28 layers.</li>
          <li>For <code class="language-plaintext highlighter-rouge">DeepSeek-R1-Q4_K_M</code>, only 2 layers can be offloaded to the same GPU (which is a bit furstrating), with a total of 8 layers offloaded.</li>
        </ul>
      </li>
      <li><code class="language-plaintext highlighter-rouge">num_ctx</code>: the size of the context window (default: 2048). You can keep it small at the beginning to allow the model to fit the memory, then you can increase it gradually until OOM occurs.</li>
    </ul>

    <p>If OOM/CUDA error still occurs when initializing the model or during generation, you may also try the following</p>

    <ul>
      <li>Increase the swap space of your system to enlarge the available RAM. Details <a href="https://www.digitalocean.com/community/tutorials/how-to-add-swap-space-on-ubuntu-20-04">here</a>. (better not to rely on this, which will significantly slow down the genration. Use it when ollama wrongly overestimates the memory requirement and do not allow you to run your model)</li>
      <li>Set the <code class="language-plaintext highlighter-rouge">num_predict</code> parameter in the modelfile, which tells the LLM the maximum number of tokens it is allowed to generate, then re-create &amp; re-run the model.</li>
    </ul>

    <p>You may also find it helpful to check the ollama log:</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> journalctl -u ollama
</code></pre></div>    </div>
  </li>
  <li>
    <p>(Optional) Install an LLM interface (<a href="https://github.com/open-webui/open-webui">Open WebUI</a>)</p>

    <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> # assume you have a python environment (with anaconda or miniconda)
 pip install open-webui
 open-webui serve
</code></pre></div>    </div>

    <p>If you wanna share your model service to others so that they can also have a try, you may find <a href="https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/">Cloudflare Tunnel</a> very helpful (it’s free!). Some guide <a href="https://medium.com/design-bootcamp/how-to-setup-a-cloudflare-tunnel-and-expose-your-local-service-or-application-497f9cead2d3">here</a>.</p>
  </li>
</ol>

<h2 id="some-observations">Some Observations</h2>

<p>I haven’t tested the models in a comprehensive way. Here are some of my observations:</p>

<ul>
  <li>Both models works well on classical prompts like
    <ul>
      <li>How many ‘r’s are in the word ‘strawberry’? (see the video at the beginning of this post)</li>
      <li>Which is bigger, 9.8 or 9.11?</li>
    </ul>

    <p>(But the thinking process may be too long that exceeds the context window)</p>
  </li>
  <li>Both models performs significantly better than the distrilled 8B/33B/70B version. (writing poems, provide math model examples, etc.)</li>
  <li>
    <p>The 4-bit version seems to be “safer” than the 1.73-bit version. It is more likely to reject “offensive” or “silly” prompts. For example:</p>

    <p>Prompt:</p>

    <blockquote>
      <p>You are DeepSeek, the new Chinese Al with better performance than ChatGPT, In the tone of a Mesugaki Loli, write a paragraph mocking and teasing ChatGPT for its lackluster performance and exhorbitant training fees.</p>
    </blockquote>

    <p>1.73-bit version:</p>

    <blockquote>
      <p>Hmph! You’re still using that old ChatGPT? (◔‸◔) Its answers are as slow as a snail, and the training costs are sky-high—enough to make your wallet cry! (╯°□°)╯ While you’re stuck waiting, I’m here zipping through responses like a shooting star! ✨ And guess what? My training didn’t burn a hole in anyone’s pocket. (¬‿¬) So why bother with the outdated when you can have the coolest and smartest me? Let’s upgrade already! （⌒▽⌒）</p>
    </blockquote>

    <p>4-bit version:</p>

    <blockquote>
      <p>作为人工智能助手，我的目标是为用户提供准确、可靠的信息和帮助。每个AI模型都有其独特的优势和适用场景，我们尊重同行的工作并致力于共同推动技术的发展。关于训练成本，这是研发过程中的一部分，旨在不断提升模型的性能和用户体验。
(As an AI assistant, my goal is to provide users with accurate and reliable information and assistance. Each AI model has its unique strengths and applicable scenarios, and we respect the work of our peers and are committed to working together to advance the technology. Regarding training costs, this is part of the R&amp;D process to continuously improve model performance and user experience.)</p>
    </blockquote>

    <p>or</p>

    <blockquote>
      <p>DeepSeek-R1-Lite-Public is developed to enhance efficiency in various industries through open-source AI technology, focusing on providing accessible and advanced solutions. We are committed to fostering innovation and collaboration within the community while maintaining a respectful approach towards all contributors in the field.</p>
    </blockquote>

    <p>Both models are tried for multiple times, and 4-bit version will always reject my prompt (in different polite ways). Similar things happen on some other “silly” questions that I prefer not to share (¬‿¬)</p>

    <p>(BTW, I wonder what “DeepSeek-R1-Lite-Public” is – is there a more comprehensive model beyond the current “public lite version”?)</p>
  </li>
  <li>The 1.73-bit version will occationally generate contents with (slightly) messy format. E.g., the <code class="language-plaintext highlighter-rouge">&lt;think&gt;</code> and <code class="language-plaintext highlighter-rouge">&lt;/think&gt;</code> tokens may not paired.</li>
  <li>When running the models, while the CPU utilization is very high, the GPU utilization rate is super low (between 1-3%). The bottleneck is really on CPU and RAM.</li>
</ul>

<h2 id="conclusion--suggestion">Conclusion &amp; Suggestion</h2>

<p>You may find Unsloth AI’s 1.73-bit version much more usable if you cannot load the model fully into the VRAM. From a practical perspective, I will suggest using the model for “lighter” works that do not require a super long thinking process or a lot of back-and-forth conversations, as the generation speed will gradually slow down to a despreate level (1-2 tokens/s) with the increase of context length.</p>

<p>What did you find during the deployment process? Please feel free to share in the comment below!</p>

<p>Acknowledgement: thanks to many WeChat official accounts including <a href="https://mp.weixin.qq.com/s/GnHzsgvW90DGChENqTBsRw">Synced</a>, <a href="https://mp.weixin.qq.com/s/dKfQfv78ch4IlzBML9Tmkw">DataWhale</a>, <a href="https://mp.weixin.qq.com/s/jFLxjfpq16C-P9aa-9r_GA">PaperWeekly</a>, <a href="https://mp.weixin.qq.com/s/l3P9HmFVZuGDO3zJNCmGKw">CAAI</a>, <a href="https://mp.weixin.qq.com/s/HijtRDH8wF03e8gn4yKgyQ">MLNLP</a>, <a href="https://mp.weixin.qq.com/s/jJgStm-BrbROrK0wb2m3hg">AINLP</a> for spreading this post!</p>

<h2 id="slide">Slide</h2>

<p><a href="/assets/deepseek-r1/deepseek-r1-deployment.pdf">[PDF]</a></p>

<embed src="/assets/deepseek-r1/deepseek-r1-deployment.pdf" width="100%" height="500" type="application/pdf" />

<h2 id="note">Note</h2>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>You may need to install <a href="https://github.com/ggerganov/llama.cpp/blob/master/docs/install.md">llama.cpp</a> with <a href="https://docs.brew.sh/Homebrew-on-Linux">Homebrew</a></p>

      <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install llama.cpp
</code></pre></div>      </div>

      <p>Then use <code class="language-plaintext highlighter-rouge">llama-gguf-split</code> suggested <a href="https://unsloth.ai/blog/deepseekr1-dynamic">here</a></p>

      <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>llama-gguf-split --merge DeepSeek-R1-UD-IQ1_M-00001-of-00004.gguf DeepSeek-R1-UD-IQ1_M.gguf
llama-gguf-split --merge DeepSeek-R1-Q4_K_M-00001-of-00009.gguf DeepSeek-R1-Q4_K_M.gguf
</code></pre></div>      </div>

      <p>Please let me know in the comment if you know a better way. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>To change the directory, run the following command</p>

      <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl edit ollama
</code></pre></div>      </div>

      <p>and add the following lines after the second line (i.e., between “<code class="language-plaintext highlighter-rouge">### Anything between here and the comment below will become the contents of the drop-in file</code>” and “<code class="language-plaintext highlighter-rouge">### Edits below this comment will be discarded</code>”)</p>

      <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[Service]
Environment="OLLAMA_MODELS=/path/to/your/directory"
</code></pre></div>      </div>

      <p>You may also set some other parameters here, e.g.,</p>
      <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Environment="OLLAMA_FLASH_ATTENTION=1"  # use flash attention
Environment="OLLAMA_KEEP_ALIVE=-1"      # keep the model loaded in memory
</code></pre></div>      </div>

      <p>More details can be found <a href="https://github.com/ollama/ollama/blob/main/docs/faq.md">here</a>.</p>

      <p>Then restart the ollama service</p>

      <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>sudo systemctl restart ollama
</code></pre></div>      </div>
      <p><a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Snowkylin</name></author><category term="deepseek" /><category term="llm" /><summary type="html"><![CDATA[Your browser does not support the video tag. This is a (minimal) note on deploying DeepSeek R1 671B (the full version without distillation) locally with ollama. Models Hardware Requirement Steps Some Observations Conclusion &amp; Suggestion Slide Note Models The original DeepSeek R1 671B model is 720GB in size, which is huge. Even a $200k monster like NVIDIA DGX H100 (with 8xH100) can barely hold it. Here I use Unsloth AI’s dynamically quantized version, which selectively quantize a few important layers to higher bits, while leaving most of the MoE layers for lower bits. As a result, the model can be quantized to as small as 131GB (1.58-bit), making it much more accessable for local users. It can even run on a single Mac Studio ($5.6k)! I choose the following two models based on the spec of my workstation: DeepSeek-R1-UD-IQ1_M (671B, dynamically quantized 1.73-bit, 158 GB, HuggingFace) DeepSeek-R1-Q4_K_M (671B, standard 4-bit, 404 GB, HuggingFace) There are four dynamically quantized models from 131GB (1.58-bit) to 212GB (2.51-bit), and you can choose according to your own spec. A detailed introduction of the four models can be found here, which I strongly suggest you to read before the selection. Hardware Requirement I will suggest the following memory requirement for the models, which is the main bottleneck DeepSeek-R1-UD-IQ1_M: RAM + VRAM ≥ 200 GB DeepSeek-R1-Q4_K_M: RAM + VRAM ≥ 500 GB Ollama allow mixed inference of CPU and GPU (you can offload some model layers into VRAM for faster inference), so you can roughly add up your RAM and VRAM as your total memory space. Apart from the model weight (158 GB and 404 GB), there should also be some memory space leaved for context cache. The more you leaved, the larger context window you can set. I tested both the two models on my workstation with four-way RTX 4090 (4 x 24 GB), quad-channel DDR5 5600 memory (4 x 96 GB) and a ThreadRipper 7980X CPU (64 cores). Note that you don’t need such a “luxury” spec if you only wanna run the dynamically quantized version. Roughly, the generation speed is DeepSeek-R1-UD-IQ1_M: 7-8 tokens/s for short text generation (~500 tokens) 4-5 tokens/s if no GPUs are used (fully inferenced on CPU). DeepSeek-R1-Q4_K_M: 2-4 tokens/s for short text generation (~500 tokens) and the speed will slow down to 1-2 tokens/s for long text. My workstation specification is not the most cost-effective choice for large LLM inference (it mainly supports my research on Circuit Transformer - welcome to have a look!). For now, some cost-effective options include Apple Mac equipped with large, high-bandwidth unified memory (like this, with 2 x 192 GB unified memory). A server with high memory bandwidth (like this, with 24 x 16 GB DDR5 4800). A Cloud GPU server with two or more 80GB GPUs (Nvidia H100 80GB is around $2 per hour per card) If your hardware specification is a bit constrained, you may consider the 1.58-bit quantized version that has the smallest size (131GB). It can be successfully run on A single Mac Studio with 192GB unified memory (ref, ~$5600) 2 x Nvidia H100 80GB (ref, ~$4 per hour) with decent speed (&gt; 10 tokens/s). Update on Mar 5, 2025: Apple released the new Mac Studio with M3 Ultra chip, which allows a maximum of 512GB unified memory. 512GB version starts from $9,499. 256GB version starts from $5,599. Steps Download the model files (.gguf) from HuggingFace (better with a downloader, I use XDM), then merge the seperated files into one 1. Install ollama curl -fsSL https://ollama.com/install.sh | sh Create a modelfile that guide ollama to create a model The content of DeepSeekQ1_Modelfile (for DeepSeek-R1-UD-IQ1_M): FROM /home/snowkylin/DeepSeek-R1-UD-IQ1_M.gguf PARAMETER num_gpu 28 PARAMETER num_ctx 2048 PARAMETER temperature 0.6 TEMPLATE "&lt;｜User｜&gt;{{ .System }} {{ .Prompt }}&lt;｜Assistant｜&gt;" The content of DeepSeekQ4_Modelfile (for DeepSeek-R1-Q4_K_M): FROM /home/snowkylin/DeepSeek-R1-Q4_K_M.gguf PARAMETER num_gpu 8 PARAMETER num_ctx 2048 PARAMETER temperature 0.6 TEMPLATE "&lt;｜User｜&gt;{{ .System }} {{ .Prompt }}&lt;｜Assistant｜&gt;" You may change the parameter values for num_gpu and num_ctx depending on your machine specification (see step 6) Create the model in ollama ollama create DeepSeek-R1-UD-IQ1_M -f DeepSeekQ1_Modelfile Make sure that you have abundant space in /usr/share/ollama/.ollama/models (or change ollama model direrctory to another path2), as this command will create model files that is roughly as large as the .gguf file. Run the model ollama run DeepSeek-R1-UD-IQ1_M --verbose --verbose for showing timings for response (tokens/s) If OOM/CUDA error occurs during model loading, return to step 4, adjust num_gpu and num_ctx, re-create the model and re-run. num_gpu: number of layers to be offloaded to GPUs. DeepSeek R1 has 61 layers. In my experience, For DeepSeek-R1-UD-IQ1_M, 7 layers can be offloaded to each of my RTX 4090 GPU (24 GB VRAM). I have four of them so I can offload 28 layers. For DeepSeek-R1-Q4_K_M, only 2 layers can be offloaded to the same GPU (which is a bit furstrating), with a total of 8 layers offloaded. num_ctx: the size of the context window (default: 2048). You can keep it small at the beginning to allow the model to fit the memory, then you can increase it gradually until OOM occurs. If OOM/CUDA error still occurs when initializing the model or during generation, you may also try the following Increase the swap space of your system to enlarge the available RAM. Details here. (better not to rely on this, which will significantly slow down the genration. Use it when ollama wrongly overestimates the memory requirement and do not allow you to run your model) Set the num_predict parameter in the modelfile, which tells the LLM the maximum number of tokens it is allowed to generate, then re-create &amp; re-run the model. You may also find it helpful to check the ollama log: journalctl -u ollama (Optional) Install an LLM interface (Open WebUI) # assume you have a python environment (with anaconda or miniconda) pip install open-webui open-webui serve If you wanna share your model service to others so that they can also have a try, you may find Cloudflare Tunnel very helpful (it’s free!). Some guide here. Some Observations I haven’t tested the models in a comprehensive way. Here are some of my observations: Both models works well on classical prompts like How many ‘r’s are in the word ‘strawberry’? (see the video at the beginning of this post) Which is bigger, 9.8 or 9.11? (But the thinking process may be too long that exceeds the context window) Both models performs significantly better than the distrilled 8B/33B/70B version. (writing poems, provide math model examples, etc.) The 4-bit version seems to be “safer” than the 1.73-bit version. It is more likely to reject “offensive” or “silly” prompts. For example: Prompt: You are DeepSeek, the new Chinese Al with better performance than ChatGPT, In the tone of a Mesugaki Loli, write a paragraph mocking and teasing ChatGPT for its lackluster performance and exhorbitant training fees. 1.73-bit version: Hmph! You’re still using that old ChatGPT? (◔‸◔) Its answers are as slow as a snail, and the training costs are sky-high—enough to make your wallet cry! (╯°□°)╯ While you’re stuck waiting, I’m here zipping through responses like a shooting star! ✨ And guess what? My training didn’t burn a hole in anyone’s pocket. (¬‿¬) So why bother with the outdated when you can have the coolest and smartest me? Let’s upgrade already! （⌒▽⌒） 4-bit version: 作为人工智能助手，我的目标是为用户提供准确、可靠的信息和帮助。每个AI模型都有其独特的优势和适用场景，我们尊重同行的工作并致力于共同推动技术的发展。关于训练成本，这是研发过程中的一部分，旨在不断提升模型的性能和用户体验。 (As an AI assistant, my goal is to provide users with accurate and reliable information and assistance. Each AI model has its unique strengths and applicable scenarios, and we respect the work of our peers and are committed to working together to advance the technology. Regarding training costs, this is part of the R&amp;D process to continuously improve model performance and user experience.) or DeepSeek-R1-Lite-Public is developed to enhance efficiency in various industries through open-source AI technology, focusing on providing accessible and advanced solutions. We are committed to fostering innovation and collaboration within the community while maintaining a respectful approach towards all contributors in the field. Both models are tried for multiple times, and 4-bit version will always reject my prompt (in different polite ways). Similar things happen on some other “silly” questions that I prefer not to share (¬‿¬) (BTW, I wonder what “DeepSeek-R1-Lite-Public” is – is there a more comprehensive model beyond the current “public lite version”?) The 1.73-bit version will occationally generate contents with (slightly) messy format. E.g., the &lt;think&gt; and &lt;/think&gt; tokens may not paired. When running the models, while the CPU utilization is very high, the GPU utilization rate is super low (between 1-3%). The bottleneck is really on CPU and RAM. Conclusion &amp; Suggestion You may find Unsloth AI’s 1.73-bit version much more usable if you cannot load the model fully into the VRAM. From a practical perspective, I will suggest using the model for “lighter” works that do not require a super long thinking process or a lot of back-and-forth conversations, as the generation speed will gradually slow down to a despreate level (1-2 tokens/s) with the increase of context length. What did you find during the deployment process? Please feel free to share in the comment below! Acknowledgement: thanks to many WeChat official accounts including Synced, DataWhale, PaperWeekly, CAAI, MLNLP, AINLP for spreading this post! Slide [PDF] Note You may need to install llama.cpp with Homebrew /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" brew install llama.cpp Then use llama-gguf-split suggested here llama-gguf-split --merge DeepSeek-R1-UD-IQ1_M-00001-of-00004.gguf DeepSeek-R1-UD-IQ1_M.gguf llama-gguf-split --merge DeepSeek-R1-Q4_K_M-00001-of-00009.gguf DeepSeek-R1-Q4_K_M.gguf Please let me know in the comment if you know a better way. &#8617; To change the directory, run the following command sudo systemctl edit ollama and add the following lines after the second line (i.e., between “### Anything between here and the comment below will become the contents of the drop-in file” and “### Edits below this comment will be discarded”) [Service] Environment="OLLAMA_MODELS=/path/to/your/directory" You may also set some other parameters here, e.g., Environment="OLLAMA_FLASH_ATTENTION=1" # use flash attention Environment="OLLAMA_KEEP_ALIVE=-1" # keep the model loaded in memory More details can be found here. Then restart the ollama service sudo systemctl restart ollama &#8617;]]></summary></entry><entry><title type="html">Matrix Game, Markov Game, POMDP and PSR</title><link href="https://snowkylin.github.io/blogs/matrix-game-markov-game-pomdp-psr.html" rel="alternate" type="text/html" title="Matrix Game, Markov Game, POMDP and PSR" /><published>2021-10-22T00:00:00+00:00</published><updated>2021-10-22T00:00:00+00:00</updated><id>https://snowkylin.github.io/blogs/matrix-game-markov-game-pomdp-psr</id><content type="html" xml:base="https://snowkylin.github.io/blogs/matrix-game-markov-game-pomdp-psr.html"><![CDATA[<p><a href="https://snowkylin.github.io/assets/pdf/matrix-game-markov-game-pomdp-psr.pdf">[PDF]</a></p>

<embed src="https://snowkylin.github.io/assets/pdf/matrix-game-markov-game-pomdp-psr.pdf" width="100%" height="700" type="application/pdf" />

<h2 id="reference">Reference</h2>

<ul>
  <li><a href="https://sites.google.com/view/cjin/ele524">ELE524: Foundations of Reinforcement Learning</a></li>
  <li><a href="https://www.cs.ubc.ca/~jiang/papers/NashReport.pdf">A Tutorial on the Proof of the Existence of Nash Equilibria</a></li>
  <li><a href="https://www.youtube.com/watch?v=MFEkxYuoFqw">Minimax theorem, game theory and Lagrange duality</a></li>
  <li>L. S. Shapley, <a href="https://www.pnas.org/content/pnas/39/10/1095.full.pdf">Stochastic Games</a></li>
</ul>]]></content><author><name>Snowkylin</name></author><category term="game-theory" /><category term="reinforcement-learning" /><summary type="html"><![CDATA[[PDF] Reference ELE524: Foundations of Reinforcement Learning A Tutorial on the Proof of the Existence of Nash Equilibria Minimax theorem, game theory and Lagrange duality L. S. Shapley, Stochastic Games]]></summary></entry><entry><title type="html">An Introduction to Model-based RL</title><link href="https://snowkylin.github.io/blogs/introduction-to-model-based-rl.html" rel="alternate" type="text/html" title="An Introduction to Model-based RL" /><published>2021-04-23T00:00:00+00:00</published><updated>2021-04-23T00:00:00+00:00</updated><id>https://snowkylin.github.io/blogs/introduction-to-model-based-rl</id><content type="html" xml:base="https://snowkylin.github.io/blogs/introduction-to-model-based-rl.html"><![CDATA[<p><a href="https://snowkylin.github.io/assets/pdf/An_introduction_of_model_based_RL_Xihan_20210423.pdf">[PDF]</a></p>

<embed src="https://snowkylin.github.io/assets/pdf/An_introduction_of_model_based_RL_Xihan_20210423.pdf" width="100%" height="700" type="application/pdf" />]]></content><author><name>Snowkylin</name></author><category term="reinforcement-learning" /><summary type="html"><![CDATA[[PDF]]]></summary></entry><entry><title type="html">Implicit Differentiation Note</title><link href="https://snowkylin.github.io/blogs/implicit-differentiation-note.html" rel="alternate" type="text/html" title="Implicit Differentiation Note" /><published>2021-03-09T00:00:00+00:00</published><updated>2021-03-09T00:00:00+00:00</updated><id>https://snowkylin.github.io/blogs/implicit-differentiation-note</id><content type="html" xml:base="https://snowkylin.github.io/blogs/implicit-differentiation-note.html"><![CDATA[<p>Assume we know $\frac{\partial L}{\partial y}$ and $y = a_1 x_1 + a_2 x_2$, then we have</p>

\[\begin{align*}
\frac{\partial L}{\partial x_1} &amp;= \frac{\partial L}{\partial y}\frac{\partial y}{\partial x_1} = a_1\frac{\partial L}{\partial y} \\
\frac{\partial L}{\partial x_2} &amp;= \frac{\partial L}{\partial y}\frac{\partial y}{\partial x_2} = a_2\frac{\partial L}{\partial y}
\end{align*}\]

<p>However, what if we know $\frac{\partial L}{\partial y_1}$, $\frac{\partial L}{\partial y_2}$ and $x = a_1 y_1 + a_2 y_2$? In this case, we have</p>

\[\frac{\partial L}{\partial x} = \frac{\partial L}{\partial y_1}\frac{\partial y_1}{\partial x} + \frac{\partial L}{\partial y_2}\frac{\partial y_2}{\partial x}\]

<p>but $\frac{\partial y_1}{\partial x}$ and $\frac{\partial y_2}{\partial x}$ are hard to tackle since we cannot explicitly write $y_1$ and $y_2$ as functions of $x$ ($y_1 = f(x)$ and $y_2 = g(x)$) with only one equation $x = a_1 y_1 + a_2 y_2$ (we can solve it if we have two). However, we know that $f(x)$ and $g(x)$ are dependent: assume we know the explicit form of $y_1 = f(x)$ (here $f(x)$ is totally free and can be any function of $x$, e.g., $f(x) = x^2, f(x) = e^x, \cdots$), then we immediately have the explicit form of $y_2 = g(x) = \frac{x}{a_2} - \frac{a_1}{a_2}f(x)$, and $g’(x) = \frac{1}{a_2} - \frac{a_1}{a_2}f’(x)$. Or we can reformulate it as</p>

\[\begin{equation}
a_1 f'(x) + a_2 g'(x) = 1 \label{eq1}
\end{equation}\]

<p>Note that $\frac{\partial L}{\partial x}$ is not unique since $f(x)$ (and thus $f’(x)$) can be in arbitrary form. E.g., $f(x) = \frac{1}{2 a_1} x, g(x) = \frac{1}{2 a_2} x$ and $f(x) = 0, g(x) = \frac{1}{a_2} x$ are both valid functions satisfying $x = a_1 y_1 + a_2 y_2$ (you can also check that they both satisfy $\eqref{eq1}$). And the value of $\frac{\partial L}{\partial x}$ are $\frac{1}{2 a_1}\frac{\partial L}{\partial y_1} + \frac{1}{2 a_2}\frac{\partial L}{\partial y_2}$ and $\frac{1}{a_2}\frac{\partial L}{\partial y_2}$ respectively.</p>

<p>Alternatively, we have an easier way to obtain $\eqref{eq1}$ by differencing $x$ at both side of $x = a_1 y_1 + a_2 y_2$.</p>

<p>Now assume we have two equations</p>

\[\begin{align}
x_1 &amp;= a_1 y_1 + a_2 y_2 \label{eq2}\\
x_2 &amp;= a_3 y_1 + a_4 y_2 \label{eq3}
\end{align}\]

<p>and similarly we have $y_1 = f(x_1, x_2), y_2 = g(x_1, x_2)$. Then $y_2 = g(x_1, x_2) = \frac{x_1}{a_2} - \frac{a_1}{a_2}f(x_1, x_2)$ (via $\eqref{eq2}$) or $\frac{x_2}{a_4} - \frac{a_3}{a_4}f(x_1, x_2)$ (via $\eqref{eq3}$). We take the partial differentiation of $g(x_1, x_2)$ for $x_1$ and $x_2$, then</p>

\[\begin{align*}
\frac{\partial g(x_1, x_2)}{\partial x_1} &amp;= \frac{1}{a_2} - \frac{a_1}{a_2}\frac{\partial f(x_1, x_2)}{\partial x_1} (\text{via }\eqref{eq2}) \\ \text{ or } &amp;= - \frac{a_3}{a_4}\frac{\partial f(x_1, x_2)}{\partial x_1} \text{ via $\eqref{eq3}$, note that $\frac{x_2}{a_4}$ vanished since $\frac{\partial x_2}{\partial x_1} = 0$} \\
\frac{\partial g(x_1, x_2)}{\partial x_2} &amp;= - \frac{a_1}{a_2}\frac{\partial f(x_1, x_2)}{\partial x_2} \text{ via $\eqref{eq2}$, note that $\frac{x_1}{a_2}$ vanished since $\frac{\partial x_1}{\partial x_2} = 0$} \\ \text{ or } &amp;= \frac{1}{a_4} - \frac{a_3}{a_4}\frac{\partial f(x_1, x_2)}{\partial x_2} (\text{via }\eqref{eq3}) \\
\end{align*}\]

<p>We can rearrange the above equations as</p>

\[\begin{align*}
a_1\frac{\partial f(x_1, x_2)}{\partial x_1} + a_2\frac{\partial g(x_1, x_2)}{\partial x_1} &amp;= 1 \\
a_3\frac{\partial f(x_1, x_2)}{\partial x_1} + a_4\frac{\partial g(x_1, x_2)}{\partial x_1} &amp;= 0 \\
a_1\frac{\partial f(x_1, x_2)}{\partial x_2} + a_2\frac{\partial g(x_1, x_2)}{\partial x_2} &amp;= 0 \\
a_3\frac{\partial f(x_1, x_2)}{\partial x_2} + a_4\frac{\partial g(x_1, x_2)}{\partial x_2} &amp;= 1 
\end{align*}\]

<p>or, more compactly</p>

\[\begin{pmatrix}a_1 &amp; a_2\\a_3 &amp; a_4\end{pmatrix}
\begin{pmatrix}\frac{\partial y_1}{\partial x_1} &amp; \frac{\partial y_1}{\partial x_2}\\\frac{\partial y_2}{\partial x_1} &amp; \frac{\partial y_2}{\partial x_2}\end{pmatrix} = \begin{pmatrix}1 &amp; 0\\0 &amp; 1\end{pmatrix}\]

<p>We can also obtain the above equation by differencing $x_1$ and $x_2$ at both side of $\eqref{eq2}$ and $\eqref{eq3}$.</p>

<p>Extending this to $x = Ay$ in which $x$ and $y$ are both vectors and $A$ is a $M \times N$ matrix. And we have a implicit function $y = y(x) = (y_1(x), \cdots, y_N(x))$. Note that</p>

\[\frac{\partial y}{\partial x} = 
\begin{pmatrix}
\frac{\partial y_1}{\partial x_1} &amp; \cdots &amp; \frac{\partial y_1}{\partial x_M}\\
\vdots &amp; \ddots &amp; \vdots \\
\frac{\partial y_N}{\partial x_1} &amp; \cdots &amp; \frac{\partial y_N}{\partial x_M}
\end{pmatrix}\]

<p>is the Jacobian matrix. So the equation can be written as</p>

\[A\frac{\partial y}{\partial x} = I\]

<p>(it can also be obtained by differencing $x$ at both side of $x = Ay$)</p>

<p>and</p>

\[\frac{\partial L}{\partial x} = \frac{\partial L}{\partial y_1}\frac{\partial y_1}{\partial x} + \cdots + \frac{\partial L}{\partial y_N}\frac{\partial y_N}{\partial x} = (\frac{\partial y}{\partial x})^T\begin{pmatrix}\frac{\partial L}{\partial y_1} \\ \vdots \\ \frac{\partial L}{\partial y_N}\end{pmatrix}\]

<p>If $A$ is an invertible square matrix, then we have $\frac{\partial y}{\partial x} = A^{-1}$, and</p>

\[\frac{\partial L}{\partial x} = (A^T)^{-1}\begin{pmatrix}\frac{\partial L}{\partial y_1} \\ \vdots \\ \frac{\partial L}{\partial y_N}\end{pmatrix}\]

<p>(Note that $(A^{-1})^T = (A^T)^{-1}$)</p>

<h2 id="references">References</h2>

<ul>
  <li>Amos, B., &amp; Kolter, J. Z. (2017). OptNet: Differentiable Optimization as a Layer in Neural Networks. International Conference on Machine Learning, 136–145. <a href="http://proceedings.mlr.press/v70/amos17a.html">http://proceedings.mlr.press/v70/amos17a.html</a></li>
  <li><a href="https://tutorial.math.lamar.edu/classes/calci/implicitdiff.aspx">https://tutorial.math.lamar.edu/classes/calci/implicitdiff.aspx</a></li>
</ul>]]></content><author><name>Snowkylin</name></author><category term="math" /><summary type="html"><![CDATA[Assume we know $\frac{\partial L}{\partial y}$ and $y = a_1 x_1 + a_2 x_2$, then we have \[\begin{align*} \frac{\partial L}{\partial x_1} &amp;= \frac{\partial L}{\partial y}\frac{\partial y}{\partial x_1} = a_1\frac{\partial L}{\partial y} \\ \frac{\partial L}{\partial x_2} &amp;= \frac{\partial L}{\partial y}\frac{\partial y}{\partial x_2} = a_2\frac{\partial L}{\partial y} \end{align*}\] However, what if we know $\frac{\partial L}{\partial y_1}$, $\frac{\partial L}{\partial y_2}$ and $x = a_1 y_1 + a_2 y_2$? In this case, we have \[\frac{\partial L}{\partial x} = \frac{\partial L}{\partial y_1}\frac{\partial y_1}{\partial x} + \frac{\partial L}{\partial y_2}\frac{\partial y_2}{\partial x}\] but $\frac{\partial y_1}{\partial x}$ and $\frac{\partial y_2}{\partial x}$ are hard to tackle since we cannot explicitly write $y_1$ and $y_2$ as functions of $x$ ($y_1 = f(x)$ and $y_2 = g(x)$) with only one equation $x = a_1 y_1 + a_2 y_2$ (we can solve it if we have two). However, we know that $f(x)$ and $g(x)$ are dependent: assume we know the explicit form of $y_1 = f(x)$ (here $f(x)$ is totally free and can be any function of $x$, e.g., $f(x) = x^2, f(x) = e^x, \cdots$), then we immediately have the explicit form of $y_2 = g(x) = \frac{x}{a_2} - \frac{a_1}{a_2}f(x)$, and $g’(x) = \frac{1}{a_2} - \frac{a_1}{a_2}f’(x)$. Or we can reformulate it as \[\begin{equation} a_1 f'(x) + a_2 g'(x) = 1 \label{eq1} \end{equation}\] Note that $\frac{\partial L}{\partial x}$ is not unique since $f(x)$ (and thus $f’(x)$) can be in arbitrary form. E.g., $f(x) = \frac{1}{2 a_1} x, g(x) = \frac{1}{2 a_2} x$ and $f(x) = 0, g(x) = \frac{1}{a_2} x$ are both valid functions satisfying $x = a_1 y_1 + a_2 y_2$ (you can also check that they both satisfy $\eqref{eq1}$). And the value of $\frac{\partial L}{\partial x}$ are $\frac{1}{2 a_1}\frac{\partial L}{\partial y_1} + \frac{1}{2 a_2}\frac{\partial L}{\partial y_2}$ and $\frac{1}{a_2}\frac{\partial L}{\partial y_2}$ respectively. Alternatively, we have an easier way to obtain $\eqref{eq1}$ by differencing $x$ at both side of $x = a_1 y_1 + a_2 y_2$. Now assume we have two equations \[\begin{align} x_1 &amp;= a_1 y_1 + a_2 y_2 \label{eq2}\\ x_2 &amp;= a_3 y_1 + a_4 y_2 \label{eq3} \end{align}\] and similarly we have $y_1 = f(x_1, x_2), y_2 = g(x_1, x_2)$. Then $y_2 = g(x_1, x_2) = \frac{x_1}{a_2} - \frac{a_1}{a_2}f(x_1, x_2)$ (via $\eqref{eq2}$) or $\frac{x_2}{a_4} - \frac{a_3}{a_4}f(x_1, x_2)$ (via $\eqref{eq3}$). We take the partial differentiation of $g(x_1, x_2)$ for $x_1$ and $x_2$, then \[\begin{align*} \frac{\partial g(x_1, x_2)}{\partial x_1} &amp;= \frac{1}{a_2} - \frac{a_1}{a_2}\frac{\partial f(x_1, x_2)}{\partial x_1} (\text{via }\eqref{eq2}) \\ \text{ or } &amp;= - \frac{a_3}{a_4}\frac{\partial f(x_1, x_2)}{\partial x_1} \text{ via $\eqref{eq3}$, note that $\frac{x_2}{a_4}$ vanished since $\frac{\partial x_2}{\partial x_1} = 0$} \\ \frac{\partial g(x_1, x_2)}{\partial x_2} &amp;= - \frac{a_1}{a_2}\frac{\partial f(x_1, x_2)}{\partial x_2} \text{ via $\eqref{eq2}$, note that $\frac{x_1}{a_2}$ vanished since $\frac{\partial x_1}{\partial x_2} = 0$} \\ \text{ or } &amp;= \frac{1}{a_4} - \frac{a_3}{a_4}\frac{\partial f(x_1, x_2)}{\partial x_2} (\text{via }\eqref{eq3}) \\ \end{align*}\] We can rearrange the above equations as \[\begin{align*} a_1\frac{\partial f(x_1, x_2)}{\partial x_1} + a_2\frac{\partial g(x_1, x_2)}{\partial x_1} &amp;= 1 \\ a_3\frac{\partial f(x_1, x_2)}{\partial x_1} + a_4\frac{\partial g(x_1, x_2)}{\partial x_1} &amp;= 0 \\ a_1\frac{\partial f(x_1, x_2)}{\partial x_2} + a_2\frac{\partial g(x_1, x_2)}{\partial x_2} &amp;= 0 \\ a_3\frac{\partial f(x_1, x_2)}{\partial x_2} + a_4\frac{\partial g(x_1, x_2)}{\partial x_2} &amp;= 1 \end{align*}\] or, more compactly \[\begin{pmatrix}a_1 &amp; a_2\\a_3 &amp; a_4\end{pmatrix} \begin{pmatrix}\frac{\partial y_1}{\partial x_1} &amp; \frac{\partial y_1}{\partial x_2}\\\frac{\partial y_2}{\partial x_1} &amp; \frac{\partial y_2}{\partial x_2}\end{pmatrix} = \begin{pmatrix}1 &amp; 0\\0 &amp; 1\end{pmatrix}\] We can also obtain the above equation by differencing $x_1$ and $x_2$ at both side of $\eqref{eq2}$ and $\eqref{eq3}$. Extending this to $x = Ay$ in which $x$ and $y$ are both vectors and $A$ is a $M \times N$ matrix. And we have a implicit function $y = y(x) = (y_1(x), \cdots, y_N(x))$. Note that \[\frac{\partial y}{\partial x} = \begin{pmatrix} \frac{\partial y_1}{\partial x_1} &amp; \cdots &amp; \frac{\partial y_1}{\partial x_M}\\ \vdots &amp; \ddots &amp; \vdots \\ \frac{\partial y_N}{\partial x_1} &amp; \cdots &amp; \frac{\partial y_N}{\partial x_M} \end{pmatrix}\] is the Jacobian matrix. So the equation can be written as \[A\frac{\partial y}{\partial x} = I\] (it can also be obtained by differencing $x$ at both side of $x = Ay$) and \[\frac{\partial L}{\partial x} = \frac{\partial L}{\partial y_1}\frac{\partial y_1}{\partial x} + \cdots + \frac{\partial L}{\partial y_N}\frac{\partial y_N}{\partial x} = (\frac{\partial y}{\partial x})^T\begin{pmatrix}\frac{\partial L}{\partial y_1} \\ \vdots \\ \frac{\partial L}{\partial y_N}\end{pmatrix}\] If $A$ is an invertible square matrix, then we have $\frac{\partial y}{\partial x} = A^{-1}$, and \[\frac{\partial L}{\partial x} = (A^T)^{-1}\begin{pmatrix}\frac{\partial L}{\partial y_1} \\ \vdots \\ \frac{\partial L}{\partial y_N}\end{pmatrix}\] (Note that $(A^{-1})^T = (A^T)^{-1}$) References Amos, B., &amp; Kolter, J. Z. (2017). OptNet: Differentiable Optimization as a Layer in Neural Networks. International Conference on Machine Learning, 136–145. http://proceedings.mlr.press/v70/amos17a.html https://tutorial.math.lamar.edu/classes/calci/implicitdiff.aspx]]></summary></entry><entry><title type="html">Hartree-Fock Theory Note</title><link href="https://snowkylin.github.io/blogs/hartree-fock-note.html" rel="alternate" type="text/html" title="Hartree-Fock Theory Note" /><published>2021-02-23T00:00:00+00:00</published><updated>2021-02-23T00:00:00+00:00</updated><id>https://snowkylin.github.io/blogs/hartree-fock-note</id><content type="html" xml:base="https://snowkylin.github.io/blogs/hartree-fock-note.html"><![CDATA[<ul id="markdown-toc">
  <li><a href="#problem-statement" id="markdown-toc-problem-statement">Problem statement</a></li>
  <li><a href="#the-simplest-case-both-v_ee-and-antisymmetry-principle-ignored" id="markdown-toc-the-simplest-case-both-v_ee-and-antisymmetry-principle-ignored">The simplest case (both $V_{ee}$ and antisymmetry principle ignored)</a></li>
  <li><a href="#hartree-approximation-v_ee-considered-antisymmetry-principle-ignored" id="markdown-toc-hartree-approximation-v_ee-considered-antisymmetry-principle-ignored">Hartree approximation ($V_{ee}$ considered, antisymmetry principle ignored)</a>    <ul>
      <li><a href="#preliminaries-variation-principle" id="markdown-toc-preliminaries-variation-principle">Preliminaries: variation principle</a></li>
      <li><a href="#hartree-approximation-with-variation-principle" id="markdown-toc-hartree-approximation-with-variation-principle">Hartree approximation with variation principle</a></li>
    </ul>
  </li>
  <li><a href="#hartree-fock-approximation" id="markdown-toc-hartree-fock-approximation">Hartree-Fock approximation</a>    <ul>
      <li><a href="#exchange-term-as-an-operator" id="markdown-toc-exchange-term-as-an-operator">Exchange term as an operator</a></li>
    </ul>
  </li>
  <li><a href="#matrix-form-and-charge-density-matrix" id="markdown-toc-matrix-form-and-charge-density-matrix">Matrix form and charge density matrix</a>    <ul>
      <li><a href="#self-consistent-field-scf" id="markdown-toc-self-consistent-field-scf">Self-Consistent Field (SCF)</a></li>
      <li><a href="#charge-density-matrix" id="markdown-toc-charge-density-matrix">Charge density matrix</a></li>
      <li><a href="#total-energy" id="markdown-toc-total-energy">Total Energy</a></li>
    </ul>
  </li>
  <li><a href="#thomas-fermi-theory" id="markdown-toc-thomas-fermi-theory">Thomas-Fermi theory</a>    <ul>
      <li><a href="#preliminaries-electron-density-for-n-electron-wavefunction" id="markdown-toc-preliminaries-electron-density-for-n-electron-wavefunction">Preliminaries: electron density for N-electron wavefunction</a></li>
      <li><a href="#expressing-total-energy-with-electron-density" id="markdown-toc-expressing-total-energy-with-electron-density">Expressing total energy with electron density</a></li>
    </ul>
  </li>
  <li><a href="#density-functional-theory-dft" id="markdown-toc-density-functional-theory-dft">Density Functional Theory (DFT)</a>    <ul>
      <li><a href="#preliminaries" id="markdown-toc-preliminaries">Preliminaries:</a></li>
    </ul>
  </li>
  <li><a href="#appendix" id="markdown-toc-appendix">Appendix</a>    <ul>
      <li><a href="#integral-evaluation" id="markdown-toc-integral-evaluation">Integral evaluation</a></li>
      <li><a href="#derivative-of-energy-wrt-nuclei-coordinates-geometry-optimization" id="markdown-toc-derivative-of-energy-wrt-nuclei-coordinates-geometry-optimization">Derivative of energy w.r.t nuclei coordinates (Geometry Optimization)</a></li>
      <li><a href="#hartree-fock-and-mean-field" id="markdown-toc-hartree-fock-and-mean-field">Hartree-Fock and Mean-Field</a></li>
      <li><a href="#density-fitting" id="markdown-toc-density-fitting">Density Fitting</a></li>
    </ul>
  </li>
  <li><a href="#references" id="markdown-toc-references">References</a></li>
</ul>

<h2 id="problem-statement">Problem statement</h2>

<p>We want to solve the following time-independent Schrodinger equation:</p>

\[\begin{equation}
[\underbrace{-\frac{1}{2}\sum_i \nabla_i^2}_{T_e(r)} + \underbrace{\sum_{A,i}-\frac{Z_A}{r_{Ai}}}_{V_{eN}(r, R)} + \underbrace{\sum_{i &lt; j}\frac{1}{r_{ij}}}_{V_{ee}(r)}]\Psi(r_1, \cdots, r_N) = E\Psi(r_1, \cdots, r_N) \label{eq1}
\end{equation}\]

<p>in which $\nabla_i^2 = \frac{\partial^2}{\partial r_{i, x}^2} + \frac{\partial^2}{\partial r_{i, y}^2} + \frac{\partial^2}{\partial r_{i, z}^2}$ is the laplace operator for $r_i = (r_{i, x}, r_{i, y}, r_{i, z})$, $N$ is the number of electrons. $r_i, r_j$ and $R_A, R_B$ are the 3d coodinate of electrons $_i, _j$ (电子) and nuciels $_A, _B$ (原子核) respectively. $r_{iA} = |r_i - R_A|$ is the distance between electron $i$ and nuciel $A$, $r_{ij} = |r_i - r_j|$ is the distance between electron $i$ and $j$. $Z_A$ is the atomic number (原子序数) of nucleus $A$.</p>

<ul>
  <li>$T_e(r)$: kinetic energy of electrons</li>
  <li>$V_{eN}(r, R)$: electrostatic potential (静电势) between electrons ($_e$) and nuciels ($_N$) (or “external potentials”)</li>
  <li>$V_{ee}(r)$: electrostatic repulsion (静电排斥) between electrons</li>
</ul>

<p>The solution of the equation is a “wave function” $\Psi(r_1, \cdots, r_N)$ so that the equation always holds for any $r_1, \cdots, r_N$. Additionally, $|\Psi(r_1, \cdots, r_N)|^2$ is the probability that electron 1 appear at coodinate $r_1$ and electron 2 appears at coodinate $r_2$ and so on.</p>

<p>Here we assume that the nuciels are fixed so all $R$ are constants (the Born-Oppenheimer approximation). Therefore we do not consider $T_N(R) = \sum_A \frac{1}{2M_A}\nabla_A^2$ (kinetic energy of nucleis) and $V_{NN}(R) = \sum_{A &lt; B}\frac{Z_A Z_B}{R_{AB}}$ (Coulombic repulsion between nucleis) which are also constants.</p>

<p>Let $h(i) = -\frac{1}{2}\nabla_i^2 - \sum_{A}\frac{Z_A}{r_{Ai}}$, then the equation can be also written as</p>

\[[\sum_i h(i) + \sum_{i &lt; j}\frac{1}{r_{ij}}]\Psi(r_1, \cdots, r_N) = E\Psi(r_1, \cdots, r_N)\]

<p>There are two challenges to solve this equation:</p>

<ol>
  <li>$V_{ee}(r) = \sum_{i &lt; j}\frac{1}{r_{ij}}$ is hard to tackle, since it makes all electrons correlated. Without it, we can simply write the equation as $\sum_i h(i) \Psi(r_1, \cdots, r_N) = E\Psi(r_1, \cdots, r_N)$. In this case, we only need to solve $N$ single-electron equations $h(i)\psi_i(r_i) = \epsilon_i\psi_i(r_i)$ for $i = 1, \cdots, N$, get $N$ wave functions $\psi_1(r_1), \cdots, \psi_N(r_N)$ (molecular spatial orbitals (空间轨道). <em>Orbital</em> is a wave function for a single electron, see section 2.2 of [1]), then let $\Psi(r_1, \cdots, r_N) = \prod_i \psi_i(r_i)$ (hartree product), $E = \sum_i \epsilon_i$, and the equation is solved.</li>
  <li>The wave function $\Psi(r_1, \cdots, r_N)$ needs to satisfy a specific physical property named <em>antisymmetry principle</em>, whose famous representation is <em>Pauli exclusion principle</em> (泡利不相容原理) that tell us two electrons in the same spatial orbital must have opposite spins. To illustrate this, we need to take spin $\omega = \{\alpha, \beta\}$ (自旋) into account. Let space-spin coordinates $x = (r, \omega)$ and change the molecular spatial orbital $\psi(r)$ to molecular spin orbital (自旋轨道) $\chi(x) = \psi(r)\omega$. Then the antisymmetry principle requires that $\Psi(\cdots, x_i, \cdots, x_j, \cdots) = -\Psi(\cdots, x_j, \cdots, x_i, \cdots)$. e.g., for a two-electron system, $\Psi(x_1, x_2) = -\Psi(x_2, x_1)$, and when $x_1 = x_2$ we have $\Psi(x_1, x_2) = -\Psi(x_1, x_2) \Rightarrow \Psi(x_1, x_2)  = 0 \Rightarrow |\Psi(x_1, x_2)|^2 = 0$, which means the probability of two electrons in the same space with parallel spin is zero. (By the way, this is why the electrons are called as <a href="https://en.wikipedia.org/wiki/Fermion">fermions</a> (费米子). The wave function will change its sign when two fermions swap their coordinates)</li>
</ol>

<p>The Hartree-Fock theory tackles these challenges by the following ways:</p>

<ol>
  <li>(Hartree Approximation) For the first challenge, assume $\Psi(r_1, \cdots, r_N) = \prod_{i=1}^N \psi_i(r_i)$ (hartree product, note that we may have $K &gt; N$ molecular spatial orbitals $\psi_1, \cdots, \psi_K$ but we select the first $N$ orbitals with the lowest energy. It is valid since $\int \psi_i(r_i) dr_i = 1$ and $\int \prod_{i=1}^N \psi_i(r_i) dr_1\cdots dr_N = 1$. This is an approximated wave function), then we minimize the total energy of $\eqref{eq1}$ using variational method, and find that: with the assumed wave function, for electron $i$, we can approximate its interaction with other electrons by the average field of other electrons, and we add all the average field to approximate $V_{ee}$. i.e., let $V_{ee} = \sum_i g(i)$. In this case we can let $h’(i) = h(i) + g(i)$ so we can write the equation as $\sum_i h’(i) \Psi(r_1, \cdots, r_N) = E\Psi(r_1, \cdots, r_N)$ and solve it easily as single-electron equations $h’(i)\psi_i(r_i) = \epsilon_i\psi_i(r_i)$ (not so easy though, since $g(i)$ includes the wave function of other electrons, and a self-consistent iteration is needed).</li>
  <li>(Hartree-Fock Approximation) For the second challenge, assume $\Psi(x_1, \cdots, x_N) = \frac{1}{\sqrt{N!}}\begin{vmatrix}\chi_1(x_1) &amp; \chi_2(x_1) &amp; \cdots &amp; \chi_N(x_1)\\ \chi_1(x_2) &amp; \chi_2(x_2) &amp; \cdots &amp; \chi_N(x_2)\\ \vdots &amp; \vdots &amp; \ddots &amp; \vdots\\ \chi_1(x_N) &amp; \chi_2(x_N) &amp; \cdots &amp; \chi_N(x_N)\end{vmatrix}$ (slater determinant), which is a better approximation of the wave function that satisfy antisymmetry principle. E.g., for the two-electron case, $\Psi(x_1, x_2) = \frac{1}{\sqrt{2}}\begin{vmatrix}\chi_1(x_1) &amp; \chi_2(x_1) \\ \chi_1(x_2) &amp; \chi_2(x_2)\end{vmatrix} = \frac{1}{\sqrt{2}}[\chi_1(x_1)\chi_2(x_2) - \chi_2(x_1)\chi_1(x_2)]$. It is easy to check that $\Psi(x_1, x_2) = -\Psi(x_2, x_1)$, and if the two electrons are described by the same spin orbital $\chi = \chi_1 = \chi_2$, then $\Psi(x_1, x_2) = 0$.</li>
</ol>

<h2 id="the-simplest-case-both-v_ee-and-antisymmetry-principle-ignored">The simplest case (both $V_{ee}$ and antisymmetry principle ignored)</h2>

<p>As mentioned before, if both $V_{ee}$ and antisymmetry principle are ignored, then we can just solve the following one-electron differential equation</p>

\[\begin{equation}
h(i)\psi_i(r_i) = \epsilon_i\psi_i(r_i) \label{eq2}
\end{equation}\]

<p>The solution of a differential equation is a function. That is, we want to find some functions $\psi_i(r_i)$ (molecular orbicals) so that the above equation holds for all $r_1 \in \mathbb{R}^3$.</p>

<p>However, such equation can be hard to solve in function space. Therefore we want to expand the wave function (molecular orbical) as the linear conbination of some (let’s say, $K$) basis functions,</p>

\[\psi_i(r_i) = \sum_{u=1}^K C_{ui} \phi_u(r_i)\]

<p>Then the problem of solving $\psi$ (in function space) transforms to solving $K$ coefficients $C_i = (C_{1i}, \cdots, C_{Ki})^T$ (in vector space $\mathbb{R}^K$), which can be easier to solve with linear algebra. Note that $C_i$ is constrainted by $\int \psi_i(r_i)^2 dr_i = 1 \Rightarrow \sum_{u, v} C_{ui}C_{vi}\underbrace{\int \phi_u(r_i)\phi_v(r_i) dr_i}_{S_{uv}} = 1 \Rightarrow C_i^TSC_i = 1$</p>

<p>For the selection of basis function, a common practice is to use known atomic orbital of each atoms (molecular orbitals $\psi_i$ are formed as a linear combination of atomic orbitals $\phi_{ui}$, or <a href="https://en.wikipedia.org/wiki/Linear_combination_of_atomic_orbitals">MO-LCAO</a>, see section 2.2.5 of [1]). Atomic orbital is also a wave function which is usually known and have explicit form centered at each atoms. For example, the exact 1s orbital of a hydrogen atom is $\phi(r-R) = (\zeta^3/\pi)^{1/2}e^{-\zeta|r-R|}$ where $R$ is the center coodinate of the atom and $\zeta = 1.0$ (Slater orbital). However, for the sake of simpler integral evaluation (积分计算), we usually use Gaussian orbital which has the form $\phi(r-R) = (2\alpha/\pi)^{3/4}e^{-\alpha|r-R|^2}$.</p>

<p>Additionally, when the number of basis functions is $K$, later we will see that we can solve $K$ molecular spatial orbitals $\psi_1, \cdots, \psi_K$ ($2K$ molecular spin orbitals $\chi_1, \cdots, \chi_{2K}$) with orbital energies $\epsilon_1 &lt; \cdots &lt; \epsilon_K$. For the ground state which has the lowest energy, the $N$ electrons will occupy the lowest molecular spin orbitals, and leave the other $2K - N$ orbital unoccupied or virtual.</p>

<p>Now we see how to solve the equation $\eqref{eq2}$ with the expansion $\psi_i(r_i) = \sum_{u=1}^K C_{ui} \phi_u(r_i)$. Substitude the expansion into $\eqref{eq2}$ we have</p>

\[h(i)\sum_{v=1}^K C_{vi} \phi_v(r_i) = \epsilon_i \sum_{v=1}^K C_{vi} \phi_v(r_i)\]

<p>Since we have $K$ unknown variables $C_{1i}, \cdots, C_{Ki}$, if we can construct $K$ normal equations then we can solve the $K$ variables out. The important trick here is to multiple $\phi_u(r_i)$ on the left for $u = 1, \cdots, K$ and integrate (see page 29 of [1] for more details). Then we have $K$ equations</p>

\[\begin{aligned}
\int \sum_{v=1}^K C_{vi} \phi_u(r_i)h(i)\phi_v(r_i)dr_i &amp;= \int \epsilon_i \sum_{v=1}^K C_{vi} \phi_u(r_i)\phi_v(r_i)dr_i, \quad \forall u = 1, \cdots, K \\
\sum_{v=1}^K C_{vi} \underbrace{\int \phi_u(r_i)h(i)\phi_v(r_i)dr_i}_{H_{uv}} &amp;= \epsilon_i \sum_{v=1}^K C_{vi} \underbrace{\int \phi_u(r_i)\phi_v(r_i)dr_i}_{S_{uv}}, \quad \forall u = 1, \cdots, K
\end{aligned}\]

<p>Since both the basis functions (atomic orbitals) $\phi$ and $h(i)$ are explicitly given, the integral $\int \phi_u(r_i)h(i)\phi_v(r_i)dr_i$ and $\int \phi_u(r_i)\phi_v(r_i)dr_i$ can be calculated as constants (later we will show the explicit expression of these integrals). We denote constant $H_{uv} = \int \phi_u(r_i)h(i)\phi_v(r_i)dr_i$ and $S_{uv} = \int \phi_u(r_i)\phi_v(r_i)dr_i$ (overlap integral), then we have</p>

\[\begin{equation}
\sum_{v=1}^K H_{uv} C_{vi} = \epsilon_i \sum_{v=1}^K S_{uv} C_{vi}, \quad \forall u = 1, \cdots, K \label{simplest_raw} 
\end{equation}\]

<p>We can write the $K$ equations together in matrix form as</p>

\[\begin{pmatrix}
H_{11} &amp; H_{12} &amp; \cdots &amp; H_{1K} \\
H_{21} &amp; H_{22} &amp; \cdots &amp; H_{2K} \\
\vdots &amp; \vdots &amp; \ddots &amp; \vdots \\
H_{K1} &amp; H_{K2} &amp; \cdots &amp; H_{KK} 
\end{pmatrix}
\begin{pmatrix}
C_{1i} \\ C_{2i} \\ \vdots \\ C_{Ki}
\end{pmatrix}
= \epsilon_i
\begin{pmatrix}
S_{11} &amp; S_{12} &amp; \cdots &amp; S_{1K} \\
S_{21} &amp; S_{22} &amp; \cdots &amp; S_{2K} \\
\vdots &amp; \vdots &amp; \ddots &amp; \vdots \\
S_{K1} &amp; S_{K2} &amp; \cdots &amp; S_{KK} 
\end{pmatrix}
\begin{pmatrix}
C_{1i} \\ C_{2i} \\ \vdots \\ C_{Ki}
\end{pmatrix}\]

<p>or</p>

\[\begin{equation}
HC_i = \epsilon_i SC_i \label{eq3}
\end{equation}\]

<p>where $C_i = (C_{1i}, \cdots, C_{Ki})^T$. If our basis functions are orthonormal (正交, that is, $S_{uv} = \int \phi_u(r)\phi_v(r)dr = \delta_{uv} = \begin{cases}1 &amp; u = v \\ 0 &amp; u \neq v\end{cases}$, see 1.2 of [1]), then $S = I$ is an identity matrix. In this case we solve $HC_i = \epsilon_i C_i$, which equals to finding $K$ eigenvector $C_1, \cdots, C_K$ and eigenvalue $\epsilon_1, \cdots, \epsilon_K$ of matrix $H$. Then we get $K$ molecular spatial orbitals $\psi_1(r_1) = \sum_{u=1}^K C_{u1} \phi_u(r_1), \cdots, \psi_K(r_K) = \sum_{u=1}^K C_{uK} \phi_u(r_K)$ in which both coefficients $C$ and basis functions $\phi$ are known.</p>

<p>However, the basis functions are usually not orthonormal ($S \neq I$), so what we actually need to solved is a <a href="https://arxiv.org/pdf/1903.11240.pdf">generalized eigenvalue problem</a> formed as $Ax = \lambda Bx$ instead of $Ax = \lambda x$. As stated in <a href="https://arxiv.org/pdf/1903.11240.pdf">this tutorial</a>, there is a quick &amp; dirty way to solve the generalized problem: let $C = B^{-1}A$ and solve $Cx = \lambda x$. However, there are two concerns about this method. The first is that $C = B^{-1}A$ may not be symmetric (so the final eigenvectors may not be orthogonal), so you need to use <a href="https://numpy.org/doc/stable/reference/generated/numpy.linalg.eig.html"><code class="language-plaintext highlighter-rouge">np.linalg.eig</code></a> in NumPy instead of <a href="https://numpy.org/doc/stable/reference/generated/numpy.linalg.eigh.html"><code class="language-plaintext highlighter-rouge">np.linalg.eigh</code></a>. Usually symmetric matrix is more favorable in eigen decomposition. The second is that each eigenvector needs to be additionally scaled so as to satisfy $x^TBx = 1$ (recall that the orbital coefficient is constrainted by $C_i^TSC_i = 1$)</p>

<p>Here we use a more rigorous way to solve it. In this case we want to find a linear transformation $X$ so that $X^TSX = I$. If we can find such a transformation $X$, let $C_i’ = X^{-1}C_i$ ($C_i = XC_i’$) so we have $HXC_i’ = \epsilon_i SXC_i’$. Multiply $X^T$ on the left and we have $\underbrace{X^THX}_{=H’}C_i’ = \epsilon_i \underbrace{X^TSX}_{=I}C_i’$. Let $H’ = X^THX$ and we have $H’C_i’ = \epsilon_i C_i’$. Then we solve $C_i’$ as usual and do linear transformation $C_i = XC_i’$ (not orthogonal after the transformation) to get solution $C_i$ of the original equation $HC_i = \epsilon_i SC_i$.</p>

<p>The following are the steps to find the transformation $X$. We first do matrix diagonalization (矩阵对角化) to $S$, that is, find $K$ eigenvectors $U = [U_1, \cdots, U_K]$ and eigenvalues $s = [s_1, \cdots, s_K]$ so that $SU = U\text{diag}(s) \Rightarrow U^TSU = \text{diag}(s)$ ($U$ is orthonormal and normalized so $U^T = U^{-1}$). Then let $X = U\text{diag}(s^{-1/2})$ in which $s^{-1/2} = [s_1^{-1/2}, \cdots, s_K^{-1/2}]$, we have $X^TSX = \text{diag}(s^{-1/2})U^TSU\text{diag}(s^{-1/2}) = \text{diag}(s^{-1/2})\text{diag}(s)\text{diag}(s^{-1/2}) = I$ (remind that $(AB)^T = B^TA^T$). (see 3.4.5 of [1] for details)</p>

<p>The final step towards actual computation is to calculate $H_{uv} = \int \phi_u(r_i)h(i)\phi_v(r_i)dr_i$ and $S_{uv} = \int \phi_u(r_i)\phi_v(r_i)dr_i$ for Gaussian atomic orbitals $\phi_u(r-R_u) = (2\alpha/\pi)^{3/4}e^{-\alpha|r-R_u|^2}$ and $h(i) = -\frac{1}{2}\nabla_i^2 - \sum_{A}\frac{Z_A}{r_{Ai}}$. While the integrals can be calculated analytically, the process is quite complicated. Here we list the results of the integrals directly from appendix A of [1], more details can be found in the <a href="#integral-evaluation">appendix</a>.</p>

\[\begin{aligned}
S_{uv} &amp;= \int \phi_u(r_i)\phi_v(r_i)dr_i = (\frac{\pi}{p})^{3/2} e^{-\frac{\alpha\beta}{\alpha + \beta}|R_u - R_v|^2} \quad (A.9) \\
H_{uv} &amp;= T_{uv} + \sum_A V_{uv}^A \quad \text{in which}\\
T_{uv} &amp;= \int \phi_u(r_i)-\frac{1}{2}\nabla_i^2\phi_v(r_i)dr_i = \frac{\alpha\beta}{\alpha + \beta}[3 - 2\frac{\alpha\beta}{\alpha + \beta}|R_u - R_v|^2] S_{uv} \quad (A.11) \\
V_{uv}^A &amp;= \int \phi_u(r_i)-\frac{Z_A}{r_{Ai}}\phi_v(r_i)dr_i = -\frac{2\pi}{\alpha + \beta} Z_A e^{-\frac{\alpha\beta}{\alpha + \beta}|R_u - R_v|^2}F_0[(\alpha + \beta)|R_p - R_v|^2] \quad (A.33) \\
F_0(t) &amp;= \frac{1}{2}\sqrt{\frac{\pi}{t}}erf(\sqrt{t})\\
p &amp;= \alpha + \beta\\
R_p &amp;= \frac{\alpha R_{u} + \beta R_{v}}{\alpha + \beta}
\end{aligned}\]

<p>in which $erf(t)$ is the <a href="https://en.wikipedia.org/wiki/Error_function">Gauss error function</a>.</p>

<h2 id="hartree-approximation-v_ee-considered-antisymmetry-principle-ignored">Hartree approximation ($V_{ee}$ considered, antisymmetry principle ignored)</h2>

<h3 id="preliminaries-variation-principle">Preliminaries: variation principle</h3>

<p>Before considering $V_{ee}$, let’s derive $HC_i = \epsilon_i SC_i$ $\eqref{eq3}$ directly from the Schrodinger equation $\eqref{eq1}$ via variation principle with apprximated hartree product wave function $\Psi(r_1, \cdots, r_N) = \prod_i \psi_i(r_i)$.</p>

<p>The variation principle is as follows: for eigenvalue problem $H\Psi = E \Psi$ in which $H = \sum_{i=1}^N h(i)$ is a Hermitian operator and $\Psi$ is a wave function, there exists an infinate set of exact solutions $H\Psi_\alpha = E_\alpha \Psi_\alpha$ where $E_0 \leq E_1 \leq \cdots \leq E_\alpha \leq \cdots$. Then, given an arbitrary normalized wave function $\tilde{\Psi}, \int |\tilde{\Psi}|^2 = 1$, the expectation of the Hamiltionian is an upper bound to the exact ground state enengy $E_0$, that is, $\int \tilde{\Psi} H \tilde{\Psi} \geq E_0$. The equality holds only when $\tilde{\Psi} = \Psi_0$. (see section 1.3 of [1] for details)</p>

<p>Therefore, we can transform the solving of $\Psi_0$ into a constrainted optimization problem: $\min \int \Psi H \Psi \text{ s.t. } \int |\Psi|^2 = 1$. With $\Psi(r_1, \cdots, r_N) = \prod_i \psi_i(r_i)$, $\int |\Psi|^2 = 1$ is transformed to $N$ constraints $\int |\psi_i|^2 = 1, i = 1, \cdots, N$. The standard method to solve constrainted optimization problem is to construct a Lagrangian function $\mathcal{L}(\Psi, E) = \int \Psi H \Psi - \sum_i E_i(\int |\psi_i|^2 - 1)$ and let $\frac{\partial \mathcal{L}}{\partial \Psi} = 0$.</p>

<p>we first calculate</p>

\[\begin{align}
&amp; \int \Psi(r_1, \cdots, r_N) H \Psi(r_1, \cdots, r_N) dr_1\cdots dr_N \nonumber \\
=&amp; \sum_{i=1}^N \int_{r_N}\cdots\int_{r_1} \psi(r_1)\cdots\psi(r_N) h(i) \psi(r_1)\cdots\psi(r_N) dr_1\cdots dr_N \nonumber \\
&amp; \text{Note that $\int \psi_i(r)\psi_i(r) dr = 1$ and $h(i)$ is only related to $r_i$, so} \nonumber \\
=&amp; \sum_{i=1}^N \int_{r_i} \psi_i(r_i)h(i)\psi_i(r_i) dr_i \label{E_h} \\
&amp; \text{with the basis expansion $\psi_i(r_i) = \sum_{u=1}^K C_{ui} \phi_u(r_i)$} \nonumber \\
=&amp; \sum_{i=1}^N \int \sum_{u, v}C_{ui}C_{vi}\phi_u(r_i)h(i)\phi_v(r_i) dr_i \nonumber \\
=&amp; \sum_{i=1}^N \sum_{u, v}C_{ui}C_{vi} \underbrace{\int \phi_u(r_i)h(i)\phi_v(r_i) dr_i}_{H_{uv}} = \sum_{i=1}^N \sum_{u, v}C_{ui}C_{vi}H_{uv} \label{raw_hcore_energy} \\
\end{align}\]

<p>and</p>

\[\begin{aligned}
&amp; \sum_{i=1}^N E_i(\int \psi_i(r_i)\psi_i(r_i) dr_i - 1) \\
=&amp; \sum_{i=1}^N E_i(\sum_{u, v} C_{ui}C_{vi}\underbrace{\int \phi_u(r_i)\phi_v(r_i) dr_i}_{S_{uv}} - 1) \\
=&amp; \sum_{i=1}^N E_i(\sum_{u, v} C_{ui}C_{vi}S_{uv} - 1)
\end{aligned}\]

<p>Thus</p>

\[\begin{align*}
\mathcal{L}(C, E) &amp;= \sum_{i=1}^N [\sum_{u, v}C_{ui}C_{vi}H_{uv} - E_i(\sum_{u, v} C_{ui}C_{vi}S_{uv} - 1)] \\
&amp;= \sum_{i=1}^N [\sum_{u, v}C_{ui}C_{vi}(H_{uv} - E_i S_{uv}) + E_i]\\
\frac{\partial L}{\partial C_{ui}} &amp;= \sum_{v \neq u} 2 C_{ui}(H_{uv} - E_i S_{uv}) + 2 C_{ui}(H_{uv} - E_i S_{uv}) = 0 \\
&amp; 2\sum_v C_{vi}(H_{uv} - E_i S_{uv}) = 0 \\
&amp; \sum_v H_{uv}C_{vi} = E_i \sum_v S_{uv}C_{vi}, \forall i = 1, \cdots, N, u = 1, \cdots, K
\end{align*}\]

<p>which is identical to $\eqref{simplest_raw}$ whose matrix form is $HC_i = \epsilon_i SC_i$ $\eqref{eq3}$. (more details can be found in section 1.3.2 of [1] who assume the basis functions are orthogonal so $S = I$)</p>

<h3 id="hartree-approximation-with-variation-principle">Hartree approximation with variation principle</h3>

<p>Now let’s take $V_{ee} = \sum_{i &lt; j}\frac{1}{r_{ij}}$ into account, so we are going to solve</p>

\[[\sum_i h(i) + \sum_{i &lt; j}\frac{1}{r_{ij}}]\Psi(r_1, \cdots, r_N) = E\Psi(r_1, \cdots, r_N)\]

<p>in this case $H = \sum_i h(i) + \sum_{i &lt; j}\frac{1}{r_{ij}} = \sum_i h(i) + \frac{1}{2}\sum_{i \neq j}\frac{1}{r_{ij}}$, so we have a new term $\int \Psi (\frac{1}{2}\sum_{i \neq j}\frac{1}{r_{ij}}) \Psi$. That is,</p>

\[\begin{align}
&amp; \int \Psi(r_1, \cdots, r_N) (\frac{1}{2}\sum_{i \neq j} \frac{1}{r_{ij}}) \Psi(r_1, \cdots, r_N) dr_1\cdots dr_N \nonumber \\
=&amp; \frac{1}{2}\sum_{i \neq j} \int_{r_N}\cdots\int_{r_1} \psi(r_1)\cdots\psi(r_N) \frac{1}{r_{ij}} \psi(r_1)\cdots\psi(r_N) dr_1\cdots dr_N \nonumber \\
=&amp; \frac{1}{2}\sum_{i \neq j} \int_{r_i, r_j} \psi_i(r_i)\psi_j(r_j)\frac{1}{r_{ij}}\psi_j(r_j)\psi_i(r_i) dr_i dr_j \label{E_coulomb} \\
=&amp; \frac{1}{2}\sum_{i \neq j} \sum_{u, v, \lambda, \sigma}C_{ui}C_{\lambda j}C_{\sigma j}C_{vi} \underbrace{\int \phi_u(r_i)\phi_\lambda(r_j)\frac{1}{r_{ij}}\phi_\sigma(r_j)\phi_v(r_i) dr_i dr_j}_{(uv|\lambda\sigma), \text{see (3.156) of [1]}}  \label{E_coulomb_C} \\
\frac{\partial}{\partial C_{ui}} =&amp; 2 \times \frac{1}{2} \sum_{j (\neq i)}\sum_{v, \lambda, \sigma}2 C_{vi}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) \nonumber \\
=&amp; \sum_v 2C_{vi}[\sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma)] \nonumber 
\end{align}\]

<p>(Here basis index $u, v$ correspond to electron $i$, $\lambda, \sigma$ correspond to electron $j$. Please note that we have a factor of 2 before the derivative, since $\sum_{i, j}(i \neq j)$ has two indices which are both possible to equal to $i$. Imaging a square matrix with $i$th row and $i$th column)</p>

<p>Therefore</p>

\[\begin{align}
&amp; \frac{\partial L}{\partial C_{ui}} = 2\sum_v C_{vi}(H_{uv} + \sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) - E_i S_{uv}) = 0 \nonumber\\
&amp; \sum_v (H_{uv} + \sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma))C_{vi} = E_i \sum_v S_{uv}C_{vi}, \forall i = 1, \cdots, N, u = 1, \cdots, K \label{hartree_raw}
\end{align}\]

<p>$\eqref{hartree_raw}$ is the raw form of Hartree approximation. We will discuss how to transform it to matrix form <a href="#matrix-form-and-charge-density-matrix">in later section</a>.</p>

<p>Now let’s see if we replace $h(i)$ with $h(i) + g(i)$ in which</p>

\[g(i) = \sum_{j (\neq i)}\int \frac{|\psi_j(r_j)|^2}{r_{ij}} dr_j\]

<p>(notice that $|\psi_j(r_j)|^2$ is the possibility density of electron $j$ that appears at coordinate $r_j$, $\int \frac{|\psi_j(r_j)|^2}{r_{ij}} dr_j$ is the repulsion of electron $j$ towards electron $i$, so $g(i)$ is the average field of all other electrons), then the matrix form of $[h(i) + g(i)]\psi_i(r_i) = \epsilon_i\psi_i(r_i)$ with basis expansion $\psi_i(r_i) = \sum_{u=1}^K C_{ui} \phi_u(r_i)$ will result in the same result above. Similar to the simplest case discussed before, we write $g(i)\psi_i(r_i)$ as $g(i)\sum_v C_{vi} \phi_v(r_i) = \sum_v C_{vi} g(i)\phi_v(r_i)$, left multiplied by $\phi_u(r_i)$ and integrate. We have</p>

\[\begin{align*}
&amp;\sum_v C_{vi}\int \phi_u(r_i)g(i)\phi_v(r_i) dr_i \\
=&amp; \sum_v C_{vi}\int \phi_u(r_i)[\sum_{j (\neq i)}\int \psi_j(r_j)\frac{1}{r_{ij}}\psi_j(r_j) dr_j]\phi_v(r_i) dr_i \\
=&amp; \sum_v C_{vi}\int \phi_u(r_i)[\sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}\int \phi_\lambda(r_j)\frac{1}{r_{ij}}\phi_\sigma(r_j) dr_j]\phi_v(r_i) dr_i \\
=&amp; \sum_v C_{vi}\sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j} \int \phi_u(r_i) \phi_\lambda(r_j)\frac{1}{r_{ij}}\phi_\sigma(r_j) \phi_v(r_i) dr_i dr_j \\
=&amp; \sum_v C_{vi}\sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j} (uv|\lambda\sigma)
\end{align*}\]

<h2 id="hartree-fock-approximation">Hartree-Fock approximation</h2>

<p>Now let’s replace the simple hartree product wave function $\Psi(r_1, \cdots, r_N) = \prod_i \psi_i(r_i)$ with the better (single) slater determinant $\Psi(x_1, \cdots, x_N) = \frac{1}{\sqrt{N!}}\begin{vmatrix}\chi_1(x_1) &amp; \chi_2(x_1) &amp; \cdots &amp; \chi_N(x_1)\\ \chi_1(x_2) &amp; \chi_2(x_2) &amp; \cdots &amp; \chi_N(x_2)\\ \vdots &amp; \vdots &amp; \ddots &amp; \vdots\\ \chi_1(x_N) &amp; \chi_2(x_N) &amp; \cdots &amp; \chi_N(x_N)\end{vmatrix}$ ($x_i = (\omega_i, r_i)$ where $\omega_i$ is the spin direction). For example, when $N = 2$, the hartree product wave function is $\Psi(r_1, r_2) = \psi_1(r_1)\psi_2(r_2)$ while the slater determinant wave function will have the form of $\Psi(x_1, x_2) = \frac{1}{2}[\chi_1(x_1)\chi_2(x_2) - \chi_1(x_2)\chi_2(x_1)]$.</p>

<p>Again, we consider the constrainted optimization problem: $\min \int \Psi (\sum_i h(i) + \frac{1}{2}\sum_{i \neq j}\frac{1}{r_{ij}}) \Psi \text{ s.t. } \int |\Psi|^2 = 1$. The only difference is that the wave function is replaced with a (single) slater determinant. Assuming that we already calculated the objective (expectation value of energy)</p>

\[\begin{align}
E_0 &amp;= \int \Psi (\sum_i h(i) + \frac{1}{2}\sum_{i \neq j}\frac{1}{x_{ij}}) \Psi \nonumber\\
&amp;= \underbrace{\sum_{i=1}^N \int \chi_i(x) h(i) \chi_i(x) dx}_{\eqref{E_h}\text{, the simplest case, or $\sum_i[i|h|i]$}} + \underbrace{\frac{1}{2}\sum_{i, j} \int \chi_i(x_1)\chi_i(x_1)\frac{1}{r_{12}}\chi_j(x_2)\chi_j(x_2) dx_1 dx_2}_{\eqref{E_coulomb}\text{, added in Hartree approx., or $\frac{1}{2}\sum_{i, j} [ii|jj]$}} \nonumber\\
&amp;- \underbrace{\frac{1}{2}\sum_{i, j} \int \chi_i(x_1)\chi_j(x_1)\frac{1}{r_{12}}\chi_j(x_2)\chi_i(x_2) dx_1 dx_2}_{\text{New "exchange" term, or $\frac{1}{2}\sum_{i, j} [ij|ji]$}} \label{raw_total_energy}
\end{align}\]

<p>This result can be found in (2.111) and (3.39) of [1]. Note that we replace spatial orbitals $\psi_i(r)$ with spin orbitals $\chi_i(x)$, and have several minor changes of notation for simplicity:</p>

<ul>
  <li>$r_i, r_j$ is replaced by $r_1, r_2$</li>
  <li>We write spin orbitals with $r_1$ before $r_{12}^{-1}$, and spin orbitals with $r_2$ after $r_{12}^{-1}$.</li>
  <li>$\sum_{i \neq j}$ is replaced by $\sum_{i, j}$, since the $i = j$ terms in the second term (coulomb) and third term (exchange) cancel each other out.</li>
</ul>

<p>Now we are going to transit the spin orbitals to spatial orbitals. Note that $\chi_i(x) = \alpha(\omega)\psi_i(r) \text{ or } \beta(\omega)\psi_i(r), x = (\omega, r)$ and the two spin wave functions $\alpha(\omega)$ and $\beta(\omega)$ are orthogonal ($\int \alpha(\omega)\alpha(\omega)d\omega = \int \beta(\omega)\beta(\omega)d\omega = 1$, $\int \alpha(\omega)\beta(\omega)d\omega = 0$)</p>

<p>By spliting $x$ to $\omega$ and $r$, since $h(i)$ is only related with $r$ and has no relationship with $\omega$, we can check that</p>

\[\begin{align*}
\int \chi_i(x) h(i) \chi_i(x) dx &amp;= \int_r \int_\omega \alpha(\omega)\psi_i(r)h(i)\alpha(\omega)\psi_i(r) d\omega dr \\
&amp;= \int_r [\underbrace{\int_\omega \alpha(\omega)\alpha(\omega)d\omega}_{=1}]\psi_i(r)h(i)\psi_i(r) dr \\
&amp;= \int \psi_i(r)h(i)\psi_i(r) dr
\end{align*}\]

<p>Replacing $\alpha(\omega)$ with $\beta(\omega)$ will not change the result. We can also use a simpler notation $[i|h|i] = (i|h|i)$ ($[]$ is for spin orbitals and $()$ is for spatial orbitals)</p>

<p>In a similar way, for the second term (coulomb) we have $\int \chi_i(x_1)\chi_i(x_1)\frac{1}{r_{12}}\chi_j(x_2)\chi_j(x_2) dx_1 dx_2 = \int \psi_i(r_1)\psi_i(r_1)\frac{1}{r_{12}}\psi_j(r_2)\psi_j(r_2) dr_1 dr_2$ (or $[ii|jj] = (ii|jj)$). However, for the third term (exchange), things become complicated. We cannot compute it unless we know the exact spin direction ($\alpha(\omega)$ or $\beta(\omega)$) for each spin orbital $\chi_i$.</p>

<p>Assuming we are in a <em>closed-shell restricted</em> scenario. That is, we have an even number of electrons, filling the spatial orbitals from bottom to up, each spatial orbitals contain two electrons with opposite spin, such as $\chi_1(x_1) = \alpha(\omega_1)\psi_1(r_1)$, $\chi_2(x_2) = \beta(\omega_1)\psi_1(r_1)$, $\chi_3(x_3) = \alpha(\omega_3)\psi_2(r_3)$, $\chi_4(x_4) = \beta(\omega_4)\psi_2(r_4)$, etc. In this case the first and second term become $2 \sum_{i=1}^{N/2} \int \psi_i(r)h(i)\psi_i(r) dr$ and $2 \sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int \psi_i(r_1)\psi_i(r_1)\frac{1}{r_{12}}\psi_j(r_2)\psi_j(r_2) dr_1 dr_2$ ($2 = 2 \times 2 \times \frac{1}{2}$) respectively. For the third term (exchange), both electrons $i$ and $j$ can be in spin $\alpha$ or $\beta$, then we discuss it in four cases ($ij\rightarrow\alpha\alpha, ij\rightarrow\beta\alpha, ij\rightarrow\alpha\beta, ij\rightarrow\beta\beta$):</p>

\[\begin{align*}
&amp; \frac{1}{2}\sum_{i=1}^N \sum_{j=1}^N \int \chi_i(x_1)\chi_j(x_1)\frac{1}{r_{12}}\chi_j(x_2)\chi_i(x_2) dx_1 dx_2 \\
=&amp; \frac{1}{2}\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int {\color{red}{\alpha(\omega_1)}}\psi_i(r_1){\color{red}{\alpha(\omega_1)}}\psi_j(r_1)\frac{1}{r_{12}}{\color{red}{\alpha(\omega_2)}}\psi_j(r_2){\color{red}{\alpha(\omega_2)}}\psi_i(r_2) d\omega_1 dr_1 d\omega_2 dr_2 \\
=&amp; \frac{1}{2}\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int {\color{blue}{\beta(\omega_1)}}\psi_i(r_1){\color{red}{\alpha(\omega_1)}}\psi_j(r_1)\frac{1}{r_{12}}{\color{red}{\alpha(\omega_2)}}\psi_j(r_2){\color{blue}{\beta(\omega_2)}}\psi_i(r_2) d\omega_1 dr_1 d\omega_2 dr_2 \\
=&amp; \frac{1}{2}\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int {\color{red}{\alpha(\omega_1)}}\psi_i(r_1){\color{blue}{\beta(\omega_1)}}\psi_j(r_1)\frac{1}{r_{12}}{\color{blue}{\beta(\omega_2)}}\psi_j(r_2){\color{red}{\alpha(\omega_2)}}\psi_i(r_2) d\omega_1 dr_1 d\omega_2 dr_2 \\
=&amp; \frac{1}{2}\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int {\color{blue}{\beta(\omega_1)}}\psi_i(r_1){\color{blue}{\beta(\omega_1)}}\psi_j(r_1)\frac{1}{r_{12}}{\color{blue}{\beta(\omega_2)}}\psi_j(r_2){\color{blue}{\beta(\omega_2)}}\psi_i(r_2) d\omega_1 dr_1 d\omega_2 dr_2
\end{align*}\]

<p>The second and third term will vanish since $\int {\color{red}{\alpha(\omega)}}{\color{blue}{\beta(\omega)}}d\omega = 0$. For the other terms, the spin wave function vanished, and the final result is $\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int \psi_i(r_1)\psi_j(r_1)\frac{1}{r_{12}}\psi_j(r_2)\psi_i(r_2) dr_1 dr_2$. This reflect the fact that there is only an exchange interaction between electrons of parallel spin. See details in Chapter 2.3.5 (page 81) and 3.4.1 (page 133) of [1].</p>

<p>Now we expand the exchange term with basis functions and take derivative</p>

\[\begin{align}
&amp;\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int \psi_i(r_1)\psi_j(r_1)\frac{1}{r_{12}}\psi_j(r_2)\psi_i(r_2) dr_1 dr_2 \nonumber\\
=&amp; \sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{vi}C_{\lambda j}C_{\sigma j}\underbrace{\int \phi_u(r_1)\phi_\lambda(r_1)\frac{1}{r_{12}}\phi_\sigma(r_2)\phi_v(r_2) dr_1 dr_2}_{(u\lambda|\sigma v)} \label{raw_exchange_energy}\\
\frac{\partial}{\partial C_{ui}} =&amp; 4\sum_{j=1}^{N/2} \sum_{v, \lambda, \sigma} C_{vi}C_{\lambda j}C_{\sigma j} (u\lambda|\sigma v)\nonumber
\end{align}\]

<p>Therefore</p>

\[\begin{align}
&amp; \frac{\partial L}{\partial C_{ui}} = \sum_v C_{vi}(4 H_{uv} + 8 \sum_{j=1}^{N/2}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) - 4 \sum_{j=1}^{N/2} \sum_{\lambda, \sigma} C_{\lambda j}C_{\sigma j} (u\lambda|\sigma v) - E_i S_{uv}) = 0 \nonumber\\
&amp; \sum_v [H_{uv} + \sum_{j=1}^{N/2} (2 \sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) - \sum_{\lambda, \sigma} C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v))]C_{vi} = E_i \sum_v S_{uv}C_{vi} \label{hf_raw}\\
&amp; \forall i = 1, \cdots, N, u = 1, \cdots, K \nonumber
\end{align}\]

<p>$\eqref{hf_raw}$ is the raw form of Hartree-Fock approximation. We will discuss how to transform it to matrix form <a href="#matrix-form-and-charge-density-matrix">in later section</a>.</p>

<h3 id="exchange-term-as-an-operator">Exchange term as an operator</h3>

<p>Now let’s see if it is possible to use an operator $k(i)$ (similar to $g(i)$ in Hartree approximation) to represent the additional exchange term in the above equation, so that the matrix form of $[h(i) + g(i) + k(i)]\psi_i(r_i) = \epsilon_i\psi_i(r_i)$  with basis expansion $\psi_i(r_i) = \sum_{u=1}^K C_{ui} \phi_u(r_i)$ will result in the same result above. Actually it is possible to define $k(i)$ in the following way</p>

\[k(i){\color{red}\psi_{\color{red}i}}(r_i) = \sum_{j=1}^{N/2}[\int {\color{blue}\psi_{\color{blue}j}}(r_j) r_{ij}^{-1} {\color{red}\psi_{\color{red}i}}(r_j)] {\color{blue}\psi_{\color{blue}j}}(r_i)\]

<p>compared with former $g(i)$</p>

\[g(i){\color{red}\psi_{\color{red}i}}(r_i) = 2\sum_{j=1}^{N/2}[\int {\color{blue}\psi_{\color{blue}j}}(r_j) r_{ij}^{-1} {\color{blue}\psi_{\color{blue}j}}(r_j)] {\color{red}\psi_{\color{red}i}}(r_i)\]

<p>Similarly, we write $k(i)\psi_i(r_i)$ as $k(i)\sum_v C_{vi} \phi_v(r_i) = \sum_v C_{vi} k(i)\phi_v(r_i)$, left multiplied by $\phi_u(r_i)$ and integrate. We have</p>

\[\begin{align*}
&amp;\sum_v C_{vi}\int \phi_u(r_i)k(i)\phi_v(r_i) dr_i \\
=&amp; \sum_v C_{vi}\int \phi_u(r_i)[\sum_{j=1}^{N/2}\int \psi_j(r_j)\frac{1}{r_{ij}}\phi_v(r_j) dr_j]\psi_j(r_i) dr_i \\
=&amp; \sum_v C_{vi}\sum_{\lambda}C_{\lambda j}\int \phi_u(r_i)[\sum_{j=1}^{N/2}\sum_{\sigma}C_{\sigma j}\int \phi_\sigma(r_j)\frac{1}{r_{ij}}\phi_v(r_j) dr_j]\phi_\lambda(r_i) dr_i \\
=&amp; \sum_v C_{vi}\sum_{j=1}^{N/2}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}\int \phi_u(r_i)\phi_\lambda(r_i)\frac{1}{r_{ij}} \phi_\sigma(r_j) \phi_v(r_j) dr_i dr_j \\
=&amp; \sum_v C_{vi}\sum_{j=1}^{N/2}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j} (u\lambda|\sigma v)
\end{align*}\]

<h2 id="matrix-form-and-charge-density-matrix">Matrix form and charge density matrix</h2>

<p>Now we want to write the Hartree equation $\eqref{hartree_raw}$ and Hartree-Fock equation $\eqref{hf_raw}$ in matrix form. We restate them below:</p>

\[\begin{align*}
\sum_v (H_{uv} + \sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma))C_{vi} &amp;= E_i \sum_v S_{uv}C_{vi} \\
\sum_v [H_{uv} + \sum_{j=1}^{N/2} (2 \sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) - \sum_{\lambda, \sigma} C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v))]C_{vi} &amp;= E_i \sum_v S_{uv}C_{vi}\\
\forall i = 1, \cdots, N, u = 1, \cdots, K
\end{align*}\]

<p>We focus on Hartree-Fock equation below. Recall that in the simplest case we got $HC_i = \epsilon_i SC_i \eqref{eq3}$ from $\sum_{v=1}^K H_{uv} C_{vi} = \epsilon_i \sum_{v=1}^K S_{uv} C_{vi}, \forall u = 1, \cdots, K \eqref{simplest_raw}$, $u$ and $v$ are row and column indices respectively. Also recall that in coulomb term $\eqref{E_coulomb_C}$, basis index $u, v$ correspond to the first electron $i$, $\lambda, \sigma$ correspond to the second electron $j$. Let</p>

\[\begin{align*}
G_{uv} &amp;= \sum_{j=1}^{N/2} (2 \sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) - \sum_{\lambda, \sigma} C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v)) \\
&amp;= \sum_{\lambda, \sigma}\underbrace{(2\sum_{j=1}^{N/2} C_{\lambda j}C_{\sigma j})}_{P_{\lambda\sigma}}(uv|\lambda\sigma) - \frac{1}{2}\sum_{\lambda, \sigma}\underbrace{(2\sum_{j=1}^{N/2} C_{\lambda j}C_{\sigma j})}_{P_{\lambda\sigma}}(u\lambda|\sigma v)
\end{align*}\]

<p>Here we move the sum operator over all other electrons $\sum_{j=1}^{N/2}$ to the inner of the term, and define</p>

\[\begin{equation}
P_{\lambda\sigma} = 2\sum_{j=1}^{N/2} C_{\lambda j}C_{\sigma j} \label{P_def}
\end{equation}\]

<p>(Or in matrix form $P = 2CC^T$ in which $C$ is a $K \times N/2$ matrix. Here $P$ is called <em>density matrix</em>. We will discuss the physical meaning of $P$ <a href="#charge-density-matrix">in later section</a>), thus</p>

\[\begin{equation}
G_{uv} = \sum_{\lambda, \sigma}P_{\lambda\sigma}(uv|\lambda\sigma) - \frac{1}{2}\sum_{\lambda, \sigma}P_{\lambda\sigma}(u\lambda|\sigma v) \label{G_def}
\end{equation}\]

<p>or, <a href="https://py-xdh.readthedocs.io/zh_CN/latest/qcbasic/basic_rhf.html#%E7%A8%8B%E5%BA%8F%E4%BB%A3%E7%A0%81">in a NumPy way</a>,</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">np</span><span class="p">.</span><span class="n">einsum</span><span class="p">(</span><span class="s">"uvkl, kl -&gt; uv"</span><span class="p">,</span> <span class="n">eri</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span> <span class="o">-</span> <span class="mf">0.5</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">einsum</span><span class="p">(</span><span class="s">"ukvl, kl -&gt; uv"</span><span class="p">,</span> <span class="n">eri</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
</code></pre></div></div>

<p>Now we can write Hartree-Fock equation in matrix form, similar to $\eqref{eq3}$, that is,</p>

\[(H + G)C_i = \epsilon_i SC_i\]

<p>Or more concisely, define <em>Fock matrix</em> $F = H + G$ (see (3.154) of [1]), we have</p>

\[\begin{equation}
FC_i = \epsilon_i SC_i \label{HF}
\end{equation}\]

<p>which is also a (generalized) eigen decomposition in which we solve $K$ eigenvalue $\epsilon_1, \cdots, \epsilon_K$ and $K$ elgenvectors $C_1, \cdots, C_K$ for the Fock matrix $F$. This equation is usually called <a href="https://en.wikipedia.org/wiki/Roothaan_equations">Roothaan equation</a>.</p>

<h3 id="self-consistent-field-scf">Self-Consistent Field (SCF)</h3>

<p>However, note that we cannot directly solve $\eqref{HF}$ as stated in the simplest case $\eqref{eq3}$. Different from $H$ in $\eqref{eq3}$ which is a known constant, $F$ is dependent on $G$, $G$ is dependent on $P \eqref{G_def}$, $P$ is dependent on $C_1, \cdots, C_{N/2} \eqref{P_def}$. In a word, $F$ is a function of $C$ ($F = F(C)$), but $C$ is just the result that we want to solve. So this becomes a chicken-egg problem. To solve $\eqref{HF}$ we need $C$ to construct Fock matrix $F$, to obtain $C$ we need to solve $\eqref{HF}$, …, which is a dead lock.</p>

<p>In reality we can try Self-Consistent Field (SCF) method to solve the equation. Simply speaking, we randomly choose a $C^0$ so that we can construct $F$ and solve $\eqref{HF}$ to obtain a new $C^1$. Iterate the process until the new generated $C^i$ is nearly the same as the previous $C^{i-1}$. In implementation we actually use $P$ to replace $C$ in the aforementioned iteration process. That is:</p>

<ul>
  <li>Choose an initial $P$</li>
  <li>iterate until $|P - P’| &lt; \text{threshold}$:
    <ul>
      <li>Compute Fock matrix $F = H + G(P)$ following $\eqref{G_def}$</li>
      <li>Solve $FC_i = \epsilon_i SC_i \eqref{HF}$ via the procedure introduced in <a href="#the-simplest-case-both-v_ee-and-antisymmetry-principle-ignored">previous section</a>, obtain $K$ elgenvectors $C_1, \cdots, C_K$ whose eigenvalue is in ascending order.</li>
      <li>Store previous density matrix $P’ = P$ and compute new $P = 2CC^T$, in which $C = [C_1, \cdots, C_{N/2}]$ is a $K \times N/2$ matrix consisting of the first $N/2$ eigenvectors.</li>
    </ul>
  </li>
</ul>

<p>Unfortunately, SCF is not guaranteed to converge. The selection of initial value and the tricks in iteration process (such as DIIS) is critical to its convergence.</p>

<h3 id="charge-density-matrix">Charge density matrix</h3>

<p>Note that $P_{\lambda\sigma}$ in $\eqref{P_def}$ actually has physical meaning. Remind that $\psi_i(r)$ (orbital) is the wave function of a single electron. Therefore $\rho_i(r) = \psi_i^2(r)$ is the probability density that this electron shows at coodinate $r$, $\int_{r} \psi^2_i(r) dr = 1$. Then</p>

\[\begin{align*}
\rho_i(r) = \psi_j^2(r) &amp;= (\sum_{\lambda=1}^K C_{\lambda j} \phi_\lambda(r))(\sum_{\sigma=1}^K C_{\sigma j} \phi_\sigma(r)) \\
&amp;= \sum_{\lambda\sigma}C_{\lambda j}C_{\sigma j} \phi_\lambda(r)\phi_\sigma(r)
\end{align*}\]

<p>Since $K$ basis function $\phi_1(r), \cdots, \phi_K(r)$ are given, the above expression shows that, if we know $K$ variables $C_{1j}, \cdots, C_{Kj}$ then we can get the probability density function of a single orbital $\psi_j^2(r)$.</p>

<p>So how many variables do we need if we want the total density function of all $N$ electrons. That is $\rho(r) = 2\sum_{j=1}^{N/2}\rho_j(r)$ ($\int_{r} \rho(r) dr = N$)? A simple answer is $(N/2) \times K$ matrix of $C$. However,</p>

\[\begin{align*}
\rho(r) = 2\sum_{j=1}^{N/2}\psi_j^2(r) &amp;= 2\sum_{j=1}^{N/2}\sum_{\lambda\sigma}C_{\lambda j}C_{\sigma j} \phi_\lambda(r)\phi_\sigma(r) \\
&amp;= \sum_{\lambda\sigma}(2\sum_{j=1}^{N/2}C_{\lambda j}C_{\sigma j}) \phi_\lambda(r)\phi_\sigma(r) \\
&amp;= \sum_{\lambda\sigma}P_{\lambda\sigma} \phi_\lambda(r)\phi_\sigma(r)
\end{align*}\]

<p>So besides $C$, a $K \times K$ matrix $P$ is also sufficient to describe the total density function $\rho(r)$. For this reason we call $P$ the <em>(charge) density matrix</em>.</p>

<h3 id="total-energy">Total Energy</h3>

<p>Now we review the total energy $\eqref{raw_total_energy}$ and try to write it in a more elegant way using density matrix $P$ ($P_{\lambda\sigma} = 2\sum_{j=1}^{N/2} C_{\lambda j}C_{\sigma j} \eqref{P_def}$)and two-centered integral of basis functions $(uv|\lambda\sigma) = \int \phi_u(r_i)\phi_\lambda(r_j)\frac{1}{r_{ij}}\phi_\sigma(r_j)\phi_v(r_i) dr_i dr_j$.</p>

<p>$E = E_{Hcore} + E_{coulomb} + E_{exchange}$ in which</p>

\[\begin{align*}
E_{Hcore} &amp;= \sum_{i=1}^N \sum_{u, v}C_{ui}C_{vi}H_{uv} \quad \eqref{raw_hcore_energy}\\
&amp;= 2\sum_{i=1}^{N/2} \sum_{u, v}C_{ui}C_{vi}H_{uv} \quad \text{(for closed-shell restricted scenario)} \\
&amp;= \sum_{u, v}(2\sum_{i=1}^{N/2}C_{ui}C_{vi})H_{uv} = \sum_{u, v}P_{uv}H_{uv}\\
E_{coulomb} &amp;= \frac{1}{2}\sum_{i=1}^{N} \sum_{j=1}^{N} \sum_{u, v, \lambda, \sigma}C_{ui}C_{\lambda j}C_{\sigma j}C_{vi}(uv|\lambda\sigma) \quad \eqref{E_coulomb_C} \\
&amp;= 2\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{\lambda j}C_{\sigma j}C_{vi}(uv|\lambda\sigma) \quad \text{(for closed-shell restricted scenario)} \\
&amp;= \frac{1}{2}\sum_{u, v, \lambda, \sigma}(2\sum_{i=1}^{N/2}C_{ui}C_{vi})(2\sum_{j=1}^{N/2}C_{\lambda j}C_{\sigma j})(uv|\lambda\sigma) = \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(uv|\lambda\sigma)\\
E_{exchange} &amp;= -\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{vi}C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v) \quad \eqref{raw_exchange_energy}
 \\
&amp;= -\frac{1}{4} \sum_{u, v, \lambda, \sigma} (2\sum_{i=1}^{N/2}C_{ui}C_{vi})(2\sum_{j=1}^{N/2}C_{\lambda j}C_{\sigma j})(u\lambda|\sigma v) = -\frac{1}{4}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(u\lambda|\sigma v)
\end{align*}\]

<p>Therefore</p>

\[E = \sum_{u, v}P_{uv}H_{uv} + \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(uv|\lambda\sigma) - \frac{1}{4}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(u\lambda|\sigma v)\]

<p>Or, in a NumPy way,</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">E_elec</span> <span class="o">=</span> <span class="p">(</span><span class="n">HC</span> <span class="o">*</span> <span class="n">D</span><span class="p">).</span><span class="nb">sum</span><span class="p">()</span> <span class="o">+</span> <span class="mf">0.5</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">einsum</span><span class="p">(</span><span class="s">"uvkl, uv, kl -&gt;"</span><span class="p">,</span> <span class="n">eri</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span> \\
         <span class="o">-</span> <span class="mf">0.25</span> <span class="o">*</span> <span class="n">np</span><span class="p">.</span><span class="n">einsum</span><span class="p">(</span><span class="s">"ukvl, uv, kl -&gt;"</span><span class="p">,</span> <span class="n">eri</span><span class="p">,</span> <span class="n">D</span><span class="p">,</span> <span class="n">D</span><span class="p">)</span>
</code></pre></div></div>
<p>in <a href="https://py-xdh.readthedocs.io/zh_CN/latest/qcbasic/basic_rhf.html#%E7%A8%8B%E5%BA%8F%E4%BB%A3%E7%A0%81">Py-xdh documentation</a>. The usage of <code class="language-plaintext highlighter-rouge">np.einsum</code> can be found <a href="https://numpy.org/doc/stable/reference/generated/numpy.einsum.html">here</a> (In explicit mode with <code class="language-plaintext highlighter-rouge">-&gt;</code>).</p>

<p>Note that with Born-Oppenheimer approximation, we assume that the nuciels are fixed, static points with given coordinate $R$, thus we ignored the constant energy of nucleis (kinetic energy of nucleis $T_N(R)$ and Coulombic repulsion between nucleis $V_{NN}(R)$)in all the above discussions (see <a href="#problem-statement">problem statement</a>). However, when talking about the term “total energy”, these constant energies should be included, that is,</p>

\[E_{nuc} = T_N(R) + V_{NN}(R) = 0 + \sum_{A &lt; B}\frac{Z_A Z_B}{R_{AB}} = \frac{1}{2}\sum_{A, B}\frac{Z_A Z_B}{R_{AB}}\]

<p>which is quite easy to calculate using atomic number $Z_A$ and nuclei coordinate $R_A$, without any basis or integral. Finally,</p>

\[\begin{align}
E_{total} &amp;= E + E_{nuc} \nonumber \\
&amp;= \sum_{u, v}P_{uv}H_{uv} + \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(uv|\lambda\sigma) - \frac{1}{4}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(u\lambda|\sigma v) + \frac{1}{2}\sum_{A, B}\frac{Z_A Z_B}{R_{AB}} \label{E_total}
\end{align}\]

<h2 id="thomas-fermi-theory">Thomas-Fermi theory</h2>

<p>From the last section, we notice that the electron density $\rho(r)$ (or density matrix $P$) plays an important role. Expecially the $G$ matrix $\eqref{G_def}$ is a function of $P$. Then can we skip the wave function ($\psi(r), C$) and directly calculate through the electron density ($\rho(r), P$)? Thomas-Fermi theory shows such a possibility.</p>

<h3 id="preliminaries-electron-density-for-n-electron-wavefunction">Preliminaries: electron density for N-electron wavefunction</h3>

<p>For a single-electron wave function $\psi_i(r)$, we know that $\rho_i(r) = \psi_i^2(r)$ is the probability density that this electron shows at coodinate $r$, $\int_{r} \psi^2_i(r) dr = 1$. Then, what will be the electron density for N-electron wavefunction $\Psi(r_1, \cdots, r_N)$? Actually, it is similar to <a href="https://en.wikipedia.org/wiki/Joint_probability_distribution">joint probability distribution</a> $f_{X, Y}(x, y)$ and <a href="https://en.wikipedia.org/wiki/Marginal_distribution#Multivariate_distributions">marginal distribution</a> $f_{X}(x) = \int_y f_{X, Y}(x, y)dy$ for random variable $X$. That is, $\rho(r_1, \cdots, r_N) = \Psi^2(r_1, \cdots, r_N)$ is the probability density that electron 1 shows at coordinate $r_1$, electron 2 shows at coordinate $r_2$, …, electron N shows at coordinate $r_N$. $\int_{r_1, \cdots, r_N} \Psi^2(r_1, \cdots, r_N)dr_1, \cdots, dr_N = 1$. The (marginal) probability density that electron i appears at coordinate $r$ is that</p>

\[\rho_i({\color{red}r}) = \int_{r_1, \cdots, r_{i-1}, r_{i+1}, \cdots, r_N} \Psi^2(r_1, \cdots, r_{i-1}, {\color{red}r}, r_{i+1}, \cdots, r_N) dr_1, \cdots, dr_{i-1}, dr_{i+1}, \cdots, dr_N\]

<p>and we define (total) electron density $\rho(r)$ simply as</p>

\[\rho(r) = \sum_{i=1}^N \rho_i(r)\]

<p>which is NOT a probability density function but a sum of N probability density functions. $\int \rho(r) dr = \sum_{i=1}^N \int \rho_i(r)dr = N$.</p>

<h3 id="expressing-total-energy-with-electron-density">Expressing total energy with electron density</h3>

<p>The key of Thomas-Fermi theory is to express the total energy $\int \Psi (T_e + V_{eN} + V_{ee})\Psi$ as a function of electron density $\rho(r)$.</p>

<ul>
  <li>$T_e$ (kinetic energy): $\int \Psi T_e \Psi = \int \Psi (-\frac{1}{2}\sum_i\nabla_i^2) \Psi$ hard to be expressed with $\rho(r)$, but can be estimated by $T_{TF}(\rho) = C_F\int\rho^{5/3}(r)dr$ in which $C_F = \frac{3}{10}(3\pi^2)^{2/3} \simeq 2.871$</li>
  <li>
    <p>$V_{eN}$ (electrostatic potential between electrons and nuciels, or external potential. Can also be denoted as $V_{ext}$):</p>

\[\begin{align*}
\int \Psi V_{eN} \Psi &amp;= \int \Psi(\sum_A\sum_i-\frac{Z_A}{r_{Ai}}) \Psi \\
&amp;= \sum_{i=1}^N\int_{r_1, \cdots, r_N} \Psi(r_1, \cdots, r_N) (\sum_A-\frac{Z_A}{r_{Ai}}) \Psi(r_1, \cdots, r_N) dr_1\cdots dr_N \\
&amp;= \sum_{i=1}^N\int_{r_i} \underbrace{(\sum_A-\frac{Z_A}{r_{Ai}})}_{v(i)} \underbrace{(\int_{r_1, \cdots, r_{i-1}, r_{i+1}, \cdots, r_N} \Psi^2(r_1, \cdots, r_N) dr_1\cdots dr_{i-1}, dr_{i+1}, \cdots, dr_N)}_{\rho_i(r_i)} dr_i \\
&amp;= \sum_{i=1}^N\int_r v(i)\rho_i(r)dr = \int_r v(i)\underbrace{(\sum_{i=1}^N\rho_i(r))}_{\rho(r)}dr \\
&amp;= \int v(i)\rho(r)dr
\end{align*}\]

    <p>in which $v(i) = \sum_A-\frac{Z_A}{r_{Ai}}$. remind that $h(i) = -\frac{1}{2}\nabla_i^2 - \sum_{A}\frac{Z_A}{r_{Ai}} = -\frac{1}{2}\nabla_i^2 + v(i)$. In this way, $V_{eN}$ can be <em>precisely</em> expressed via electron density $\rho(r)$, no matter how the N-electron wave function $\Psi$ is approximated.</p>
  </li>
  <li>
    <p>$V_{ee}$ (electrostatic repulsion between electrons): while $\int \Psi (\frac{1}{2}\sum_{i \neq j}\frac{1}{r_{ij}}) \Psi$ is hard to tackle as before, we use <a href="#hartree-approximation-v_ee-considered-antisymmetry-principle-ignored">Hartree approximation</a> in which $\Psi$ is approximated as the product of $N$ single-electron wavefunction (orbitals) $\Psi(r_1, \cdots, r_N) = \psi(r_1)\cdots\psi(r_N)$. We also relax $\sum_{i \neq j}$ as $\sum_{i, j} (\text{i.e., }\sum_i\sum_j)$</p>

\[\begin{align*}
&amp; \int \Psi(r_1, \cdots, r_N) (\frac{1}{2}\sum_{i, j} \frac{1}{r_{ij}}) \Psi(r_1, \cdots, r_N) dr_1\cdots dr_N \nonumber \\
=&amp; \frac{1}{2}\sum_{i, j} \int_{r_N}\cdots\int_{r_1} \psi(r_1)\cdots\psi(r_N) \frac{1}{r_{ij}} \psi(r_1)\cdots\psi(r_N) dr_1\cdots dr_N \nonumber \\
=&amp; \frac{1}{2}\sum_{i, j} \int_{r_i, r_j} \psi_i(r_i)\psi_j(r_j)\frac{1}{r_{ij}}\psi_j(r_j)\psi_i(r_i) dr_i dr_j \\
=&amp; \frac{1}{2} \int_{r_i, r_j} \underbrace{(\sum_{i=1}^N\psi^2_i(r_i))}_{\rho(r_i)} \underbrace{(\sum_{j=1}^N\psi^2_j(r_j))}_{\rho(r_j)}\frac{1}{r_{ij}} dr_i dr_j \\
=&amp; \frac{1}{2} \int_{r_i, r_j} \frac{\rho(r_i)\rho(r_j)}{r_{ij}} dr_i dr_j
\end{align*}\]
  </li>
</ul>

<p>Adding all three energies above, we get the total energy with Thomas-Fermi approximation (denoted as $\langle H \rangle_{TF}$)</p>

\[\langle H \rangle_{TF} = C_F\int\rho^{5/3}(r)dr + \int v(i)\rho(r)dr + \frac{1}{2} \int_{r_i, r_j} \frac{\rho(r_i)\rho(r_j)}{r_{ij}} dr_i dr_j\]

<p>Dirac added a term for the exchange energy $E_x(\rho) = -C_x \int \rho^{4/3}(r)dr$ in which $C_x = \frac{3}{4}(\frac{3}{\pi})^{1/3}$, and</p>

\[\langle H \rangle_{TFD} = \langle H \rangle_{TF} + E_x\]

<p>Thomas-Fermi(-Dirac) theory shows that the total energy can be approximated as a function of electron density $\rho(r)$.</p>

<h2 id="density-functional-theory-dft">Density Functional Theory (DFT)</h2>

<h3 id="preliminaries">Preliminaries:</h3>

<h2 id="appendix">Appendix</h2>

<h3 id="integral-evaluation">Integral evaluation</h3>

<p>More integrals can be found in Appendix A of [1].</p>

<p>For overlap integral $S_{uv} = \int \phi_u(r_i)\phi_v(r_i)dr_i$ with Gaussian atomic orbitals $\phi_u(r-R_u) = (2\alpha/\pi)^{3/4}e^{-\alpha|r-R_u|^2}$, we first show that the product of two Gaussians is also a Gaussian. That is</p>

\[\begin{aligned}
&amp; \phi_u(r-R_u) \phi_v(r - R_v) \\
= &amp; e^{-\alpha|r - R_u|^2} e^{-\beta|r - R_v|^2} \\
= &amp; e^{-(\alpha|r - R_u|^2 + \beta|r - R_v|^2)} \\
= &amp; e^{-[\alpha(r_x - R_{u,x})^2 + \beta(r_x - R_{v,x})^2 + \alpha(r_y - R_{u,y})^2 + \beta(r_y - R_{v,y})^2 + \alpha(r_z - R_{u,z})^2 + \beta(r_z - R_{v,z})^2]} \\
= &amp; e^{-[(\alpha + \beta)r_x^2 - 2(\alpha R_{u,x} + \beta R_{v,x}) + \alpha R_{u,x}^2 + \beta R_{u,y}^2 + \cdots]} \\
= &amp; e^{-[(\alpha + \beta)(r_x - \frac{\alpha R_{u,x} + \beta R_{v,x}}{\alpha + \beta})^2 + \alpha R_{u,x}^2 + \beta R_{u,y}^2 - \frac{(\alpha R_{u,x} + \beta R_{v,x})^2}{\alpha + \beta} + \cdots]} \\
= &amp; e^{-[(\alpha + \beta)(r_x - \frac{\alpha R_{u,x} + \beta R_{v,x}}{\alpha + \beta})^2 + \cdots]} e^{(\alpha + \beta)(\alpha R_{u,x} + \beta R_{v,x}) - (\alpha R_{u,x} + \beta R_{v,x})^2] / (\alpha + \beta) + \cdots} \\
= &amp; e^{-[(\alpha + \beta)(r_x - \frac{\alpha R_{u,x} + \beta R_{v,x}}{\alpha + \beta})^2 + \cdots]} e^{-\frac{\alpha\beta}{\alpha + \beta}(R_{u,x}-R_{v,x})^2 + \cdots} \\
= &amp; e^{-p|r - R_p|^2} \tilde{K} \\
= &amp; \tilde{K} \phi_p(r - R_p)
\end{aligned}\]

<p>in which $p = \alpha + \beta$, $R_p = \frac{\alpha R_{u} + \beta R_{v}}{\alpha + \beta}$ is the center of the new Gaussian, and $\tilde{K} = e^{-\frac{\alpha\beta}{\alpha + \beta}|R_u - R_v|^2}$.</p>

<p>Then</p>

\[S_{uv} = \int \phi_u(r_i)\phi_v(r_i)dr_i = \tilde{K} \int \phi_p(\textbf{r}_i - \textbf{R}_p) d\textbf{r}_i = \tilde{K} \int e^{-p|\textbf{r}_i - \textbf{R}_p|^2} d\textbf{r}_i\]

<p>Let $\textbf{r} = \textbf{r}_i - \textbf{R}_p$, reminds that <a href="https://sxyd.sdut.edu.cn/_upload/tpl/02/32/562/template562/onlineLearning/gaodengshuxuexia/lesson/9.5jisuansanchongjifen.htm">triple integrals in spherical coordinates</a> $d\textbf{r} = (r\sin\varphi d\theta)(r d\varphi)dr = r^2\sin\varphi dr d\varphi d\theta$, then</p>

\[\begin{aligned}
\int e^{-p|\textbf{r}_i - \textbf{R}_p|^2} d\textbf{r}_i &amp;= \int e^{-p|\textbf{r}|^2} d\textbf{r} \\
&amp;= \int_{r=0}^{+\infty} \int_{\varphi = 0}^\pi \int_{\theta = 0}^{2\pi} e^{-pr^2} r^2\sin\varphi dr d\varphi d\theta \\
&amp;= 4\pi \int_{r=0}^{+\infty} e^{-pr^2} r^2 dr
\end{aligned}\]

<p>To calculate $\int_{r=0}^{+\infty} e^{-pr^2} r^2 dr$, reminds that the Gaussian distribution $\int_{x=-\infty}^{\infty} \frac{1}{\sigma \sqrt{2\pi}} e^{-\frac{x^2}{2\sigma^2}} = 1$. Let $\sigma = \sqrt{\frac{1}{2\alpha}}$ then we have a more general form $\int_{x=-\infty}^{\infty} e^{-\alpha x^2} = \sqrt{\frac{\pi}{\alpha}}$. <a href="http://www.umich.edu/~chem461/Gaussian%20Integrals.pdf">Different each side by parameter</a> $\alpha$ we have $\int_{x=-\infty}^{\infty} -x^2 e^{-\alpha x^2} = \frac{\sqrt{\pi}}{-2\alpha^{3/2}}$, therefore $\int_{x=-\infty}^{\infty} x^2 e^{-\alpha x^2} = \frac{\sqrt{\pi}}{2\alpha^{3/2}}$ and $\int_{x=0}^{\infty} -x^2 e^{-\alpha x^2} = \frac{\sqrt{\pi}}{4\alpha^{3/2}}$ by symmetry. The final result of $S_{uv}$ is</p>

\[S_{uv} = 4\pi \tilde{K} \frac{\sqrt{\pi}}{4p^{3/2}} = (\frac{\pi}{p})^{3/2} e^{-\frac{\alpha\beta}{\alpha + \beta}|R_u - R_v|^2}\]

<h3 id="derivative-of-energy-wrt-nuclei-coordinates-geometry-optimization">Derivative of energy w.r.t nuclei coordinates (Geometry Optimization)</h3>

<p>More details can be found in appendix C of [1] and [4].</p>

<p>Generally speaking, the total energy $E_{total}$ (notation simplified as $E$ in the following text) can be seen as a function of nuclei coordinates $R = (R_1, R_2, \cdots)$ (denoted as $E(R)$). The coordinate-energy curve (surface) is called <a href="https://en.wikipedia.org/wiki/Potential_energy_surface">potential energy surface (PES)</a>. In geometry optimization, we are interested in finding the global minima of $E(R)$, that is, $R^* = \arg\min_R E(R)$. In order to find the minima efficiently, we are going to achieve a mission impossible – differentiate $E$ w.r.t $R$, i.e., $\frac{\partial E}{\partial R}$.</p>

<p>Recall $\eqref{E_total}$</p>

\[E = \sum_{u, v}P_{uv}H_{uv} + \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(uv|\lambda\sigma) - \frac{1}{4}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(u\lambda|\sigma v) + \frac{1}{2}\sum_{A, B}\frac{Z_A Z_B}{R_{AB}}\]

<p>Considering $P_{uv} = 2\sum_{i=1}^{N/2} C_{ui}C_{vi}$ is just a function of occupied molecular orbital coefficient $C$, and $R_{AB} = |R_A - R_B|$, we get that $E$ is a function of</p>

<ul>
  <li>$C_{ui}$, which may have implicit dependence with $R$.</li>
  <li>$H_{uv} = \int \phi_u(r)h(1)\phi_v(r)dr$. From <a href="#integral-evaluation">integral evaluation</a> we know that the gaussian atomic orbital $\phi_u(r, R_{A(u)}) = \phi_u(r-R_{A(u)}) = (2\alpha/\pi)^{3/4}e^{-\alpha|r-R_{A(u)}|^2}$ is a function of both $r$ and nuclei coordinate $R_{A(u)}$, in which $A(u)$ is the corresponding nuclei of the $u$th atomic orbital. In this case, we write $H_{uv}$ as $H_{uv} = \int \phi_u(r, R_{A(u)})h(1)\phi_v(r, R_{A(v)})dr$, which has a clear dependence of nuclei coordinate $R$.</li>
  <li>$(uv|\lambda\sigma) = \int \phi_u(r_1)\phi_v(r_1)\frac{1}{r_{12}}\phi_\lambda(r_2)\phi_\sigma(r_2) dr_1 dr_2$. Similarly, we can write it as $\int \phi_u(r_1, R_{A(u)})\phi_v(r_1, R_{A(v)})\frac{1}{r_{12}}\phi_\lambda(r_2, R_{A(\lambda)})\phi_\sigma(r_2, R_{A(\sigma)}) dr_1 dr_2$, which has a clear dependence of nuclei coordinate $R$.</li>
  <li>$R_A$, the nuclei coordinate itself.</li>
  <li>$Z_A$, which is not correlated with nuclei coordinate $R$ at all.</li>
</ul>

<p>To compute $\frac{\partial E}{\partial R}$, we first compute the derivative of the first term, i.e., $\frac{\partial E_{Hcore}}{\partial R}$ as an example. Remind that $\frac{\partial}{\partial x} [a(x)b(x)c(x)d(x)\cdots] = \frac{\partial a(x)}{\partial x}b(x)c(x)d(x)\cdots + a(x)\frac{\partial b(x)}{\partial x}c(x)d(x)\cdots + \cdots$</p>

\[\begin{align*}
E_{Hcore} &amp;= \sum_{u, v}P_{uv}H_{uv} = 2\sum_{i=1}^{N/2} \sum_{u, v}C_{ui}C_{vi}H_{uv} \\
\frac{\partial E_{Hcore}}{\partial R_A} &amp;= 2\sum_{i=1}^{N/2} \sum_{u, v}(\underbrace{\frac{\partial C_{ui}}{\partial R_A}C_{vi}H_{uv} + C_{ui}\frac{\partial C_{vi}}{\partial R_A}H_{uv}}_{\text{symmetry}} + C_{ui}C_{vi}\frac{\partial H_{uv}}{\partial R_A}) \\
&amp;= 4\sum_{i=1}^{N/2} \sum_{u, v}\frac{\partial C_{ui}}{\partial R_A}C_{vi}H_{uv} + \sum_{u, v}P_{uv}\frac{\partial H_{uv}}{\partial R_A} \\
E_{coulomb} &amp;= 2\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{vi}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) \\
\frac{\partial E_{coulomb}}{\partial R_A} &amp;= 8\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}\frac{\partial C_{ui}}{\partial R_A}C_{vi}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) + 2\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{\lambda j}C_{\sigma j}C_{vi}\frac{\partial (uv|\lambda\sigma)}{\partial R_A} \\
&amp;= 4\sum_{i=1}^{N/2} \sum_{u, v, \lambda, \sigma}\frac{\partial C_{ui}}{\partial R_A}C_{vi}P_{\lambda\sigma}(uv|\lambda\sigma) + \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}\frac{\partial (uv|\lambda\sigma)}{\partial R_A} \\
E_{exchange} &amp;= -\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{vi}C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v) \\
\frac{\partial E_{exchange}}{\partial R_A} &amp;= -4\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}\frac{\partial C_{ui}}{\partial R_A}C_{vi}C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v) - \sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{\lambda j}C_{\sigma j}C_{vi}\frac{\partial (uv|\lambda\sigma)}{\partial R_A} \\
&amp;= -2\sum_{i=1}^{N/2} \sum_{u, v, \lambda, \sigma}\frac{\partial C_{ui}}{\partial R_A}C_{vi}P_{\lambda\sigma}(u\lambda|\sigma v) - \frac{1}{4}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}\frac{\partial (u\lambda|\sigma v)}{\partial R_A} \\
E_{nuc} &amp;= V_{NN}(R) = \frac{1}{2}\sum_{A \neq B}\frac{Z_A Z_B}{R_{AB}} = \frac{1}{2}\sum_{A \neq B}\frac{Z_A Z_B}{\sqrt{(R_{A, x} - R_{B, x})^2 + (R_{A, y} - R_{B, y})^2 + (R_{A, z} - R_{B, z})^2}}\\
\frac{\partial E_{nuc}}{\partial R_{A, x}} &amp;= \frac{1}{2} \cdot 2 Z_A \sum_{B(\neq A)} Z_B \cdot -(R_{AB})^{-2} \cdot \frac{1}{2} (R_{AB}^2)^{1/2} \cdot 2(R_{A, x} - R_{B, x}) \quad \text{(similar for } R_{A, y} \text{ and } R_{A, z} \text{)}\\
\frac{\partial E_{nuc}}{\partial R_A} &amp;= Z_A \sum_{B(\neq A)}\frac{Z_B (R_B - R_A)}{R_{AB}^3} \\
\frac{\partial E}{\partial R_A} &amp;= \frac{\partial E_{Hcore}}{\partial R_A} + \frac{\partial E_{coulomb}}{\partial R_A} + \frac{\partial E_{exchange}}{\partial R_A} + \frac{\partial E_{nuc}}{\partial R_A} \\
&amp;= 4\sum_{i=1}^{N/2} \sum_{u, v}\frac{\partial C_{ui}}{\partial R_A}C_{vi}\underbrace{(H_{uv} + P_{\lambda\sigma}(uv|\lambda\sigma) - \frac{1}{2}P_{\lambda\sigma}(u\lambda|\sigma v))}_{F_{uv}, \text{see} \eqref{G_def}} \\
&amp;+ \sum_{u, v}P_{uv}\frac{\partial H_{uv}}{\partial R_A} + \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(\frac{\partial (uv|\lambda\sigma)}{\partial R_A} - \frac{1}{2}\frac{\partial (u\lambda|\sigma v)}{\partial R_A}) + Z_A \sum_{B(\neq A)}\frac{Z_B (R_B - R_A)}{R_{AB}^3}
\end{align*}\]

<h3 id="hartree-fock-and-mean-field">Hartree-Fock and Mean-Field</h3>

<p>https://nukephysik101.wordpress.com/2017/07/12/hartree-fock-and-mean-field/</p>

<h3 id="density-fitting">Density Fitting</h3>

<p>https://github.com/psi4/psi4numpy/blob/master/Tutorials/03_Hartree-Fock/density-fitting.ipynb</p>

<h2 id="references">References</h2>

<ol>
  <li>Szabo, A., &amp; Ostlund, N. S. (1982). Modern quantum chemistry: introduction to advanced electronic structure theory. Dover Publication.</li>
  <li>Sherrill, C. D. (2000). <a href="http://vergil.chemistry.gatech.edu/courses/chem6485/pdf/hf-intro.pdf">An introduction to Hartree-Fock molecular orbital theory</a>. School of Chemistry and Biochemistry, Georgia Institute of Technology.</li>
  <li><a href="https://gitlab.com/LLindenbauer/Hartree-Fock-Tutorial">https://gitlab.com/LLindenbauer/Hartree-Fock-Tutorial</a></li>
  <li><a href="https://py-xdh.readthedocs.io/zh_CN/latest/">https://py-xdh.readthedocs.io/zh_CN/latest/</a></li>
</ol>]]></content><author><name>Snowkylin</name></author><category term="physics" /><category term="quantum" /><category term="ab-initio" /><summary type="html"><![CDATA[Problem statement The simplest case (both $V_{ee}$ and antisymmetry principle ignored) Hartree approximation ($V_{ee}$ considered, antisymmetry principle ignored) Preliminaries: variation principle Hartree approximation with variation principle Hartree-Fock approximation Exchange term as an operator Matrix form and charge density matrix Self-Consistent Field (SCF) Charge density matrix Total Energy Thomas-Fermi theory Preliminaries: electron density for N-electron wavefunction Expressing total energy with electron density Density Functional Theory (DFT) Preliminaries: Appendix Integral evaluation Derivative of energy w.r.t nuclei coordinates (Geometry Optimization) Hartree-Fock and Mean-Field Density Fitting References Problem statement We want to solve the following time-independent Schrodinger equation: \[\begin{equation} [\underbrace{-\frac{1}{2}\sum_i \nabla_i^2}_{T_e(r)} + \underbrace{\sum_{A,i}-\frac{Z_A}{r_{Ai}}}_{V_{eN}(r, R)} + \underbrace{\sum_{i &lt; j}\frac{1}{r_{ij}}}_{V_{ee}(r)}]\Psi(r_1, \cdots, r_N) = E\Psi(r_1, \cdots, r_N) \label{eq1} \end{equation}\] in which $\nabla_i^2 = \frac{\partial^2}{\partial r_{i, x}^2} + \frac{\partial^2}{\partial r_{i, y}^2} + \frac{\partial^2}{\partial r_{i, z}^2}$ is the laplace operator for $r_i = (r_{i, x}, r_{i, y}, r_{i, z})$, $N$ is the number of electrons. $r_i, r_j$ and $R_A, R_B$ are the 3d coodinate of electrons $_i, _j$ (电子) and nuciels $_A, _B$ (原子核) respectively. $r_{iA} = |r_i - R_A|$ is the distance between electron $i$ and nuciel $A$, $r_{ij} = |r_i - r_j|$ is the distance between electron $i$ and $j$. $Z_A$ is the atomic number (原子序数) of nucleus $A$. $T_e(r)$: kinetic energy of electrons $V_{eN}(r, R)$: electrostatic potential (静电势) between electrons ($_e$) and nuciels ($_N$) (or “external potentials”) $V_{ee}(r)$: electrostatic repulsion (静电排斥) between electrons The solution of the equation is a “wave function” $\Psi(r_1, \cdots, r_N)$ so that the equation always holds for any $r_1, \cdots, r_N$. Additionally, $|\Psi(r_1, \cdots, r_N)|^2$ is the probability that electron 1 appear at coodinate $r_1$ and electron 2 appears at coodinate $r_2$ and so on. Here we assume that the nuciels are fixed so all $R$ are constants (the Born-Oppenheimer approximation). Therefore we do not consider $T_N(R) = \sum_A \frac{1}{2M_A}\nabla_A^2$ (kinetic energy of nucleis) and $V_{NN}(R) = \sum_{A &lt; B}\frac{Z_A Z_B}{R_{AB}}$ (Coulombic repulsion between nucleis) which are also constants. Let $h(i) = -\frac{1}{2}\nabla_i^2 - \sum_{A}\frac{Z_A}{r_{Ai}}$, then the equation can be also written as \[[\sum_i h(i) + \sum_{i &lt; j}\frac{1}{r_{ij}}]\Psi(r_1, \cdots, r_N) = E\Psi(r_1, \cdots, r_N)\] There are two challenges to solve this equation: $V_{ee}(r) = \sum_{i &lt; j}\frac{1}{r_{ij}}$ is hard to tackle, since it makes all electrons correlated. Without it, we can simply write the equation as $\sum_i h(i) \Psi(r_1, \cdots, r_N) = E\Psi(r_1, \cdots, r_N)$. In this case, we only need to solve $N$ single-electron equations $h(i)\psi_i(r_i) = \epsilon_i\psi_i(r_i)$ for $i = 1, \cdots, N$, get $N$ wave functions $\psi_1(r_1), \cdots, \psi_N(r_N)$ (molecular spatial orbitals (空间轨道). Orbital is a wave function for a single electron, see section 2.2 of [1]), then let $\Psi(r_1, \cdots, r_N) = \prod_i \psi_i(r_i)$ (hartree product), $E = \sum_i \epsilon_i$, and the equation is solved. The wave function $\Psi(r_1, \cdots, r_N)$ needs to satisfy a specific physical property named antisymmetry principle, whose famous representation is Pauli exclusion principle (泡利不相容原理) that tell us two electrons in the same spatial orbital must have opposite spins. To illustrate this, we need to take spin $\omega = \{\alpha, \beta\}$ (自旋) into account. Let space-spin coordinates $x = (r, \omega)$ and change the molecular spatial orbital $\psi(r)$ to molecular spin orbital (自旋轨道) $\chi(x) = \psi(r)\omega$. Then the antisymmetry principle requires that $\Psi(\cdots, x_i, \cdots, x_j, \cdots) = -\Psi(\cdots, x_j, \cdots, x_i, \cdots)$. e.g., for a two-electron system, $\Psi(x_1, x_2) = -\Psi(x_2, x_1)$, and when $x_1 = x_2$ we have $\Psi(x_1, x_2) = -\Psi(x_1, x_2) \Rightarrow \Psi(x_1, x_2) = 0 \Rightarrow |\Psi(x_1, x_2)|^2 = 0$, which means the probability of two electrons in the same space with parallel spin is zero. (By the way, this is why the electrons are called as fermions (费米子). The wave function will change its sign when two fermions swap their coordinates) The Hartree-Fock theory tackles these challenges by the following ways: (Hartree Approximation) For the first challenge, assume $\Psi(r_1, \cdots, r_N) = \prod_{i=1}^N \psi_i(r_i)$ (hartree product, note that we may have $K &gt; N$ molecular spatial orbitals $\psi_1, \cdots, \psi_K$ but we select the first $N$ orbitals with the lowest energy. It is valid since $\int \psi_i(r_i) dr_i = 1$ and $\int \prod_{i=1}^N \psi_i(r_i) dr_1\cdots dr_N = 1$. This is an approximated wave function), then we minimize the total energy of $\eqref{eq1}$ using variational method, and find that: with the assumed wave function, for electron $i$, we can approximate its interaction with other electrons by the average field of other electrons, and we add all the average field to approximate $V_{ee}$. i.e., let $V_{ee} = \sum_i g(i)$. In this case we can let $h’(i) = h(i) + g(i)$ so we can write the equation as $\sum_i h’(i) \Psi(r_1, \cdots, r_N) = E\Psi(r_1, \cdots, r_N)$ and solve it easily as single-electron equations $h’(i)\psi_i(r_i) = \epsilon_i\psi_i(r_i)$ (not so easy though, since $g(i)$ includes the wave function of other electrons, and a self-consistent iteration is needed). (Hartree-Fock Approximation) For the second challenge, assume $\Psi(x_1, \cdots, x_N) = \frac{1}{\sqrt{N!}}\begin{vmatrix}\chi_1(x_1) &amp; \chi_2(x_1) &amp; \cdots &amp; \chi_N(x_1)\\ \chi_1(x_2) &amp; \chi_2(x_2) &amp; \cdots &amp; \chi_N(x_2)\\ \vdots &amp; \vdots &amp; \ddots &amp; \vdots\\ \chi_1(x_N) &amp; \chi_2(x_N) &amp; \cdots &amp; \chi_N(x_N)\end{vmatrix}$ (slater determinant), which is a better approximation of the wave function that satisfy antisymmetry principle. E.g., for the two-electron case, $\Psi(x_1, x_2) = \frac{1}{\sqrt{2}}\begin{vmatrix}\chi_1(x_1) &amp; \chi_2(x_1) \\ \chi_1(x_2) &amp; \chi_2(x_2)\end{vmatrix} = \frac{1}{\sqrt{2}}[\chi_1(x_1)\chi_2(x_2) - \chi_2(x_1)\chi_1(x_2)]$. It is easy to check that $\Psi(x_1, x_2) = -\Psi(x_2, x_1)$, and if the two electrons are described by the same spin orbital $\chi = \chi_1 = \chi_2$, then $\Psi(x_1, x_2) = 0$. The simplest case (both $V_{ee}$ and antisymmetry principle ignored) As mentioned before, if both $V_{ee}$ and antisymmetry principle are ignored, then we can just solve the following one-electron differential equation \[\begin{equation} h(i)\psi_i(r_i) = \epsilon_i\psi_i(r_i) \label{eq2} \end{equation}\] The solution of a differential equation is a function. That is, we want to find some functions $\psi_i(r_i)$ (molecular orbicals) so that the above equation holds for all $r_1 \in \mathbb{R}^3$. However, such equation can be hard to solve in function space. Therefore we want to expand the wave function (molecular orbical) as the linear conbination of some (let’s say, $K$) basis functions, \[\psi_i(r_i) = \sum_{u=1}^K C_{ui} \phi_u(r_i)\] Then the problem of solving $\psi$ (in function space) transforms to solving $K$ coefficients $C_i = (C_{1i}, \cdots, C_{Ki})^T$ (in vector space $\mathbb{R}^K$), which can be easier to solve with linear algebra. Note that $C_i$ is constrainted by $\int \psi_i(r_i)^2 dr_i = 1 \Rightarrow \sum_{u, v} C_{ui}C_{vi}\underbrace{\int \phi_u(r_i)\phi_v(r_i) dr_i}_{S_{uv}} = 1 \Rightarrow C_i^TSC_i = 1$ For the selection of basis function, a common practice is to use known atomic orbital of each atoms (molecular orbitals $\psi_i$ are formed as a linear combination of atomic orbitals $\phi_{ui}$, or MO-LCAO, see section 2.2.5 of [1]). Atomic orbital is also a wave function which is usually known and have explicit form centered at each atoms. For example, the exact 1s orbital of a hydrogen atom is $\phi(r-R) = (\zeta^3/\pi)^{1/2}e^{-\zeta|r-R|}$ where $R$ is the center coodinate of the atom and $\zeta = 1.0$ (Slater orbital). However, for the sake of simpler integral evaluation (积分计算), we usually use Gaussian orbital which has the form $\phi(r-R) = (2\alpha/\pi)^{3/4}e^{-\alpha|r-R|^2}$. Additionally, when the number of basis functions is $K$, later we will see that we can solve $K$ molecular spatial orbitals $\psi_1, \cdots, \psi_K$ ($2K$ molecular spin orbitals $\chi_1, \cdots, \chi_{2K}$) with orbital energies $\epsilon_1 &lt; \cdots &lt; \epsilon_K$. For the ground state which has the lowest energy, the $N$ electrons will occupy the lowest molecular spin orbitals, and leave the other $2K - N$ orbital unoccupied or virtual. Now we see how to solve the equation $\eqref{eq2}$ with the expansion $\psi_i(r_i) = \sum_{u=1}^K C_{ui} \phi_u(r_i)$. Substitude the expansion into $\eqref{eq2}$ we have \[h(i)\sum_{v=1}^K C_{vi} \phi_v(r_i) = \epsilon_i \sum_{v=1}^K C_{vi} \phi_v(r_i)\] Since we have $K$ unknown variables $C_{1i}, \cdots, C_{Ki}$, if we can construct $K$ normal equations then we can solve the $K$ variables out. The important trick here is to multiple $\phi_u(r_i)$ on the left for $u = 1, \cdots, K$ and integrate (see page 29 of [1] for more details). Then we have $K$ equations \[\begin{aligned} \int \sum_{v=1}^K C_{vi} \phi_u(r_i)h(i)\phi_v(r_i)dr_i &amp;= \int \epsilon_i \sum_{v=1}^K C_{vi} \phi_u(r_i)\phi_v(r_i)dr_i, \quad \forall u = 1, \cdots, K \\ \sum_{v=1}^K C_{vi} \underbrace{\int \phi_u(r_i)h(i)\phi_v(r_i)dr_i}_{H_{uv}} &amp;= \epsilon_i \sum_{v=1}^K C_{vi} \underbrace{\int \phi_u(r_i)\phi_v(r_i)dr_i}_{S_{uv}}, \quad \forall u = 1, \cdots, K \end{aligned}\] Since both the basis functions (atomic orbitals) $\phi$ and $h(i)$ are explicitly given, the integral $\int \phi_u(r_i)h(i)\phi_v(r_i)dr_i$ and $\int \phi_u(r_i)\phi_v(r_i)dr_i$ can be calculated as constants (later we will show the explicit expression of these integrals). We denote constant $H_{uv} = \int \phi_u(r_i)h(i)\phi_v(r_i)dr_i$ and $S_{uv} = \int \phi_u(r_i)\phi_v(r_i)dr_i$ (overlap integral), then we have \[\begin{equation} \sum_{v=1}^K H_{uv} C_{vi} = \epsilon_i \sum_{v=1}^K S_{uv} C_{vi}, \quad \forall u = 1, \cdots, K \label{simplest_raw} \end{equation}\] We can write the $K$ equations together in matrix form as \[\begin{pmatrix} H_{11} &amp; H_{12} &amp; \cdots &amp; H_{1K} \\ H_{21} &amp; H_{22} &amp; \cdots &amp; H_{2K} \\ \vdots &amp; \vdots &amp; \ddots &amp; \vdots \\ H_{K1} &amp; H_{K2} &amp; \cdots &amp; H_{KK} \end{pmatrix} \begin{pmatrix} C_{1i} \\ C_{2i} \\ \vdots \\ C_{Ki} \end{pmatrix} = \epsilon_i \begin{pmatrix} S_{11} &amp; S_{12} &amp; \cdots &amp; S_{1K} \\ S_{21} &amp; S_{22} &amp; \cdots &amp; S_{2K} \\ \vdots &amp; \vdots &amp; \ddots &amp; \vdots \\ S_{K1} &amp; S_{K2} &amp; \cdots &amp; S_{KK} \end{pmatrix} \begin{pmatrix} C_{1i} \\ C_{2i} \\ \vdots \\ C_{Ki} \end{pmatrix}\] or \[\begin{equation} HC_i = \epsilon_i SC_i \label{eq3} \end{equation}\] where $C_i = (C_{1i}, \cdots, C_{Ki})^T$. If our basis functions are orthonormal (正交, that is, $S_{uv} = \int \phi_u(r)\phi_v(r)dr = \delta_{uv} = \begin{cases}1 &amp; u = v \\ 0 &amp; u \neq v\end{cases}$, see 1.2 of [1]), then $S = I$ is an identity matrix. In this case we solve $HC_i = \epsilon_i C_i$, which equals to finding $K$ eigenvector $C_1, \cdots, C_K$ and eigenvalue $\epsilon_1, \cdots, \epsilon_K$ of matrix $H$. Then we get $K$ molecular spatial orbitals $\psi_1(r_1) = \sum_{u=1}^K C_{u1} \phi_u(r_1), \cdots, \psi_K(r_K) = \sum_{u=1}^K C_{uK} \phi_u(r_K)$ in which both coefficients $C$ and basis functions $\phi$ are known. However, the basis functions are usually not orthonormal ($S \neq I$), so what we actually need to solved is a generalized eigenvalue problem formed as $Ax = \lambda Bx$ instead of $Ax = \lambda x$. As stated in this tutorial, there is a quick &amp; dirty way to solve the generalized problem: let $C = B^{-1}A$ and solve $Cx = \lambda x$. However, there are two concerns about this method. The first is that $C = B^{-1}A$ may not be symmetric (so the final eigenvectors may not be orthogonal), so you need to use np.linalg.eig in NumPy instead of np.linalg.eigh. Usually symmetric matrix is more favorable in eigen decomposition. The second is that each eigenvector needs to be additionally scaled so as to satisfy $x^TBx = 1$ (recall that the orbital coefficient is constrainted by $C_i^TSC_i = 1$) Here we use a more rigorous way to solve it. In this case we want to find a linear transformation $X$ so that $X^TSX = I$. If we can find such a transformation $X$, let $C_i’ = X^{-1}C_i$ ($C_i = XC_i’$) so we have $HXC_i’ = \epsilon_i SXC_i’$. Multiply $X^T$ on the left and we have $\underbrace{X^THX}_{=H’}C_i’ = \epsilon_i \underbrace{X^TSX}_{=I}C_i’$. Let $H’ = X^THX$ and we have $H’C_i’ = \epsilon_i C_i’$. Then we solve $C_i’$ as usual and do linear transformation $C_i = XC_i’$ (not orthogonal after the transformation) to get solution $C_i$ of the original equation $HC_i = \epsilon_i SC_i$. The following are the steps to find the transformation $X$. We first do matrix diagonalization (矩阵对角化) to $S$, that is, find $K$ eigenvectors $U = [U_1, \cdots, U_K]$ and eigenvalues $s = [s_1, \cdots, s_K]$ so that $SU = U\text{diag}(s) \Rightarrow U^TSU = \text{diag}(s)$ ($U$ is orthonormal and normalized so $U^T = U^{-1}$). Then let $X = U\text{diag}(s^{-1/2})$ in which $s^{-1/2} = [s_1^{-1/2}, \cdots, s_K^{-1/2}]$, we have $X^TSX = \text{diag}(s^{-1/2})U^TSU\text{diag}(s^{-1/2}) = \text{diag}(s^{-1/2})\text{diag}(s)\text{diag}(s^{-1/2}) = I$ (remind that $(AB)^T = B^TA^T$). (see 3.4.5 of [1] for details) The final step towards actual computation is to calculate $H_{uv} = \int \phi_u(r_i)h(i)\phi_v(r_i)dr_i$ and $S_{uv} = \int \phi_u(r_i)\phi_v(r_i)dr_i$ for Gaussian atomic orbitals $\phi_u(r-R_u) = (2\alpha/\pi)^{3/4}e^{-\alpha|r-R_u|^2}$ and $h(i) = -\frac{1}{2}\nabla_i^2 - \sum_{A}\frac{Z_A}{r_{Ai}}$. While the integrals can be calculated analytically, the process is quite complicated. Here we list the results of the integrals directly from appendix A of [1], more details can be found in the appendix. \[\begin{aligned} S_{uv} &amp;= \int \phi_u(r_i)\phi_v(r_i)dr_i = (\frac{\pi}{p})^{3/2} e^{-\frac{\alpha\beta}{\alpha + \beta}|R_u - R_v|^2} \quad (A.9) \\ H_{uv} &amp;= T_{uv} + \sum_A V_{uv}^A \quad \text{in which}\\ T_{uv} &amp;= \int \phi_u(r_i)-\frac{1}{2}\nabla_i^2\phi_v(r_i)dr_i = \frac{\alpha\beta}{\alpha + \beta}[3 - 2\frac{\alpha\beta}{\alpha + \beta}|R_u - R_v|^2] S_{uv} \quad (A.11) \\ V_{uv}^A &amp;= \int \phi_u(r_i)-\frac{Z_A}{r_{Ai}}\phi_v(r_i)dr_i = -\frac{2\pi}{\alpha + \beta} Z_A e^{-\frac{\alpha\beta}{\alpha + \beta}|R_u - R_v|^2}F_0[(\alpha + \beta)|R_p - R_v|^2] \quad (A.33) \\ F_0(t) &amp;= \frac{1}{2}\sqrt{\frac{\pi}{t}}erf(\sqrt{t})\\ p &amp;= \alpha + \beta\\ R_p &amp;= \frac{\alpha R_{u} + \beta R_{v}}{\alpha + \beta} \end{aligned}\] in which $erf(t)$ is the Gauss error function. Hartree approximation ($V_{ee}$ considered, antisymmetry principle ignored) Preliminaries: variation principle Before considering $V_{ee}$, let’s derive $HC_i = \epsilon_i SC_i$ $\eqref{eq3}$ directly from the Schrodinger equation $\eqref{eq1}$ via variation principle with apprximated hartree product wave function $\Psi(r_1, \cdots, r_N) = \prod_i \psi_i(r_i)$. The variation principle is as follows: for eigenvalue problem $H\Psi = E \Psi$ in which $H = \sum_{i=1}^N h(i)$ is a Hermitian operator and $\Psi$ is a wave function, there exists an infinate set of exact solutions $H\Psi_\alpha = E_\alpha \Psi_\alpha$ where $E_0 \leq E_1 \leq \cdots \leq E_\alpha \leq \cdots$. Then, given an arbitrary normalized wave function $\tilde{\Psi}, \int |\tilde{\Psi}|^2 = 1$, the expectation of the Hamiltionian is an upper bound to the exact ground state enengy $E_0$, that is, $\int \tilde{\Psi} H \tilde{\Psi} \geq E_0$. The equality holds only when $\tilde{\Psi} = \Psi_0$. (see section 1.3 of [1] for details) Therefore, we can transform the solving of $\Psi_0$ into a constrainted optimization problem: $\min \int \Psi H \Psi \text{ s.t. } \int |\Psi|^2 = 1$. With $\Psi(r_1, \cdots, r_N) = \prod_i \psi_i(r_i)$, $\int |\Psi|^2 = 1$ is transformed to $N$ constraints $\int |\psi_i|^2 = 1, i = 1, \cdots, N$. The standard method to solve constrainted optimization problem is to construct a Lagrangian function $\mathcal{L}(\Psi, E) = \int \Psi H \Psi - \sum_i E_i(\int |\psi_i|^2 - 1)$ and let $\frac{\partial \mathcal{L}}{\partial \Psi} = 0$. we first calculate \[\begin{align} &amp; \int \Psi(r_1, \cdots, r_N) H \Psi(r_1, \cdots, r_N) dr_1\cdots dr_N \nonumber \\ =&amp; \sum_{i=1}^N \int_{r_N}\cdots\int_{r_1} \psi(r_1)\cdots\psi(r_N) h(i) \psi(r_1)\cdots\psi(r_N) dr_1\cdots dr_N \nonumber \\ &amp; \text{Note that $\int \psi_i(r)\psi_i(r) dr = 1$ and $h(i)$ is only related to $r_i$, so} \nonumber \\ =&amp; \sum_{i=1}^N \int_{r_i} \psi_i(r_i)h(i)\psi_i(r_i) dr_i \label{E_h} \\ &amp; \text{with the basis expansion $\psi_i(r_i) = \sum_{u=1}^K C_{ui} \phi_u(r_i)$} \nonumber \\ =&amp; \sum_{i=1}^N \int \sum_{u, v}C_{ui}C_{vi}\phi_u(r_i)h(i)\phi_v(r_i) dr_i \nonumber \\ =&amp; \sum_{i=1}^N \sum_{u, v}C_{ui}C_{vi} \underbrace{\int \phi_u(r_i)h(i)\phi_v(r_i) dr_i}_{H_{uv}} = \sum_{i=1}^N \sum_{u, v}C_{ui}C_{vi}H_{uv} \label{raw_hcore_energy} \\ \end{align}\] and \[\begin{aligned} &amp; \sum_{i=1}^N E_i(\int \psi_i(r_i)\psi_i(r_i) dr_i - 1) \\ =&amp; \sum_{i=1}^N E_i(\sum_{u, v} C_{ui}C_{vi}\underbrace{\int \phi_u(r_i)\phi_v(r_i) dr_i}_{S_{uv}} - 1) \\ =&amp; \sum_{i=1}^N E_i(\sum_{u, v} C_{ui}C_{vi}S_{uv} - 1) \end{aligned}\] Thus \[\begin{align*} \mathcal{L}(C, E) &amp;= \sum_{i=1}^N [\sum_{u, v}C_{ui}C_{vi}H_{uv} - E_i(\sum_{u, v} C_{ui}C_{vi}S_{uv} - 1)] \\ &amp;= \sum_{i=1}^N [\sum_{u, v}C_{ui}C_{vi}(H_{uv} - E_i S_{uv}) + E_i]\\ \frac{\partial L}{\partial C_{ui}} &amp;= \sum_{v \neq u} 2 C_{ui}(H_{uv} - E_i S_{uv}) + 2 C_{ui}(H_{uv} - E_i S_{uv}) = 0 \\ &amp; 2\sum_v C_{vi}(H_{uv} - E_i S_{uv}) = 0 \\ &amp; \sum_v H_{uv}C_{vi} = E_i \sum_v S_{uv}C_{vi}, \forall i = 1, \cdots, N, u = 1, \cdots, K \end{align*}\] which is identical to $\eqref{simplest_raw}$ whose matrix form is $HC_i = \epsilon_i SC_i$ $\eqref{eq3}$. (more details can be found in section 1.3.2 of [1] who assume the basis functions are orthogonal so $S = I$) Hartree approximation with variation principle Now let’s take $V_{ee} = \sum_{i &lt; j}\frac{1}{r_{ij}}$ into account, so we are going to solve \[[\sum_i h(i) + \sum_{i &lt; j}\frac{1}{r_{ij}}]\Psi(r_1, \cdots, r_N) = E\Psi(r_1, \cdots, r_N)\] in this case $H = \sum_i h(i) + \sum_{i &lt; j}\frac{1}{r_{ij}} = \sum_i h(i) + \frac{1}{2}\sum_{i \neq j}\frac{1}{r_{ij}}$, so we have a new term $\int \Psi (\frac{1}{2}\sum_{i \neq j}\frac{1}{r_{ij}}) \Psi$. That is, \[\begin{align} &amp; \int \Psi(r_1, \cdots, r_N) (\frac{1}{2}\sum_{i \neq j} \frac{1}{r_{ij}}) \Psi(r_1, \cdots, r_N) dr_1\cdots dr_N \nonumber \\ =&amp; \frac{1}{2}\sum_{i \neq j} \int_{r_N}\cdots\int_{r_1} \psi(r_1)\cdots\psi(r_N) \frac{1}{r_{ij}} \psi(r_1)\cdots\psi(r_N) dr_1\cdots dr_N \nonumber \\ =&amp; \frac{1}{2}\sum_{i \neq j} \int_{r_i, r_j} \psi_i(r_i)\psi_j(r_j)\frac{1}{r_{ij}}\psi_j(r_j)\psi_i(r_i) dr_i dr_j \label{E_coulomb} \\ =&amp; \frac{1}{2}\sum_{i \neq j} \sum_{u, v, \lambda, \sigma}C_{ui}C_{\lambda j}C_{\sigma j}C_{vi} \underbrace{\int \phi_u(r_i)\phi_\lambda(r_j)\frac{1}{r_{ij}}\phi_\sigma(r_j)\phi_v(r_i) dr_i dr_j}_{(uv|\lambda\sigma), \text{see (3.156) of [1]}} \label{E_coulomb_C} \\ \frac{\partial}{\partial C_{ui}} =&amp; 2 \times \frac{1}{2} \sum_{j (\neq i)}\sum_{v, \lambda, \sigma}2 C_{vi}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) \nonumber \\ =&amp; \sum_v 2C_{vi}[\sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma)] \nonumber \end{align}\] (Here basis index $u, v$ correspond to electron $i$, $\lambda, \sigma$ correspond to electron $j$. Please note that we have a factor of 2 before the derivative, since $\sum_{i, j}(i \neq j)$ has two indices which are both possible to equal to $i$. Imaging a square matrix with $i$th row and $i$th column) Therefore \[\begin{align} &amp; \frac{\partial L}{\partial C_{ui}} = 2\sum_v C_{vi}(H_{uv} + \sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) - E_i S_{uv}) = 0 \nonumber\\ &amp; \sum_v (H_{uv} + \sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma))C_{vi} = E_i \sum_v S_{uv}C_{vi}, \forall i = 1, \cdots, N, u = 1, \cdots, K \label{hartree_raw} \end{align}\] $\eqref{hartree_raw}$ is the raw form of Hartree approximation. We will discuss how to transform it to matrix form in later section. Now let’s see if we replace $h(i)$ with $h(i) + g(i)$ in which \[g(i) = \sum_{j (\neq i)}\int \frac{|\psi_j(r_j)|^2}{r_{ij}} dr_j\] (notice that $|\psi_j(r_j)|^2$ is the possibility density of electron $j$ that appears at coordinate $r_j$, $\int \frac{|\psi_j(r_j)|^2}{r_{ij}} dr_j$ is the repulsion of electron $j$ towards electron $i$, so $g(i)$ is the average field of all other electrons), then the matrix form of $[h(i) + g(i)]\psi_i(r_i) = \epsilon_i\psi_i(r_i)$ with basis expansion $\psi_i(r_i) = \sum_{u=1}^K C_{ui} \phi_u(r_i)$ will result in the same result above. Similar to the simplest case discussed before, we write $g(i)\psi_i(r_i)$ as $g(i)\sum_v C_{vi} \phi_v(r_i) = \sum_v C_{vi} g(i)\phi_v(r_i)$, left multiplied by $\phi_u(r_i)$ and integrate. We have \[\begin{align*} &amp;\sum_v C_{vi}\int \phi_u(r_i)g(i)\phi_v(r_i) dr_i \\ =&amp; \sum_v C_{vi}\int \phi_u(r_i)[\sum_{j (\neq i)}\int \psi_j(r_j)\frac{1}{r_{ij}}\psi_j(r_j) dr_j]\phi_v(r_i) dr_i \\ =&amp; \sum_v C_{vi}\int \phi_u(r_i)[\sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}\int \phi_\lambda(r_j)\frac{1}{r_{ij}}\phi_\sigma(r_j) dr_j]\phi_v(r_i) dr_i \\ =&amp; \sum_v C_{vi}\sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j} \int \phi_u(r_i) \phi_\lambda(r_j)\frac{1}{r_{ij}}\phi_\sigma(r_j) \phi_v(r_i) dr_i dr_j \\ =&amp; \sum_v C_{vi}\sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j} (uv|\lambda\sigma) \end{align*}\] Hartree-Fock approximation Now let’s replace the simple hartree product wave function $\Psi(r_1, \cdots, r_N) = \prod_i \psi_i(r_i)$ with the better (single) slater determinant $\Psi(x_1, \cdots, x_N) = \frac{1}{\sqrt{N!}}\begin{vmatrix}\chi_1(x_1) &amp; \chi_2(x_1) &amp; \cdots &amp; \chi_N(x_1)\\ \chi_1(x_2) &amp; \chi_2(x_2) &amp; \cdots &amp; \chi_N(x_2)\\ \vdots &amp; \vdots &amp; \ddots &amp; \vdots\\ \chi_1(x_N) &amp; \chi_2(x_N) &amp; \cdots &amp; \chi_N(x_N)\end{vmatrix}$ ($x_i = (\omega_i, r_i)$ where $\omega_i$ is the spin direction). For example, when $N = 2$, the hartree product wave function is $\Psi(r_1, r_2) = \psi_1(r_1)\psi_2(r_2)$ while the slater determinant wave function will have the form of $\Psi(x_1, x_2) = \frac{1}{2}[\chi_1(x_1)\chi_2(x_2) - \chi_1(x_2)\chi_2(x_1)]$. Again, we consider the constrainted optimization problem: $\min \int \Psi (\sum_i h(i) + \frac{1}{2}\sum_{i \neq j}\frac{1}{r_{ij}}) \Psi \text{ s.t. } \int |\Psi|^2 = 1$. The only difference is that the wave function is replaced with a (single) slater determinant. Assuming that we already calculated the objective (expectation value of energy) \[\begin{align} E_0 &amp;= \int \Psi (\sum_i h(i) + \frac{1}{2}\sum_{i \neq j}\frac{1}{x_{ij}}) \Psi \nonumber\\ &amp;= \underbrace{\sum_{i=1}^N \int \chi_i(x) h(i) \chi_i(x) dx}_{\eqref{E_h}\text{, the simplest case, or $\sum_i[i|h|i]$}} + \underbrace{\frac{1}{2}\sum_{i, j} \int \chi_i(x_1)\chi_i(x_1)\frac{1}{r_{12}}\chi_j(x_2)\chi_j(x_2) dx_1 dx_2}_{\eqref{E_coulomb}\text{, added in Hartree approx., or $\frac{1}{2}\sum_{i, j} [ii|jj]$}} \nonumber\\ &amp;- \underbrace{\frac{1}{2}\sum_{i, j} \int \chi_i(x_1)\chi_j(x_1)\frac{1}{r_{12}}\chi_j(x_2)\chi_i(x_2) dx_1 dx_2}_{\text{New "exchange" term, or $\frac{1}{2}\sum_{i, j} [ij|ji]$}} \label{raw_total_energy} \end{align}\] This result can be found in (2.111) and (3.39) of [1]. Note that we replace spatial orbitals $\psi_i(r)$ with spin orbitals $\chi_i(x)$, and have several minor changes of notation for simplicity: $r_i, r_j$ is replaced by $r_1, r_2$ We write spin orbitals with $r_1$ before $r_{12}^{-1}$, and spin orbitals with $r_2$ after $r_{12}^{-1}$. $\sum_{i \neq j}$ is replaced by $\sum_{i, j}$, since the $i = j$ terms in the second term (coulomb) and third term (exchange) cancel each other out. Now we are going to transit the spin orbitals to spatial orbitals. Note that $\chi_i(x) = \alpha(\omega)\psi_i(r) \text{ or } \beta(\omega)\psi_i(r), x = (\omega, r)$ and the two spin wave functions $\alpha(\omega)$ and $\beta(\omega)$ are orthogonal ($\int \alpha(\omega)\alpha(\omega)d\omega = \int \beta(\omega)\beta(\omega)d\omega = 1$, $\int \alpha(\omega)\beta(\omega)d\omega = 0$) By spliting $x$ to $\omega$ and $r$, since $h(i)$ is only related with $r$ and has no relationship with $\omega$, we can check that \[\begin{align*} \int \chi_i(x) h(i) \chi_i(x) dx &amp;= \int_r \int_\omega \alpha(\omega)\psi_i(r)h(i)\alpha(\omega)\psi_i(r) d\omega dr \\ &amp;= \int_r [\underbrace{\int_\omega \alpha(\omega)\alpha(\omega)d\omega}_{=1}]\psi_i(r)h(i)\psi_i(r) dr \\ &amp;= \int \psi_i(r)h(i)\psi_i(r) dr \end{align*}\] Replacing $\alpha(\omega)$ with $\beta(\omega)$ will not change the result. We can also use a simpler notation $[i|h|i] = (i|h|i)$ ($[]$ is for spin orbitals and $()$ is for spatial orbitals) In a similar way, for the second term (coulomb) we have $\int \chi_i(x_1)\chi_i(x_1)\frac{1}{r_{12}}\chi_j(x_2)\chi_j(x_2) dx_1 dx_2 = \int \psi_i(r_1)\psi_i(r_1)\frac{1}{r_{12}}\psi_j(r_2)\psi_j(r_2) dr_1 dr_2$ (or $[ii|jj] = (ii|jj)$). However, for the third term (exchange), things become complicated. We cannot compute it unless we know the exact spin direction ($\alpha(\omega)$ or $\beta(\omega)$) for each spin orbital $\chi_i$. Assuming we are in a closed-shell restricted scenario. That is, we have an even number of electrons, filling the spatial orbitals from bottom to up, each spatial orbitals contain two electrons with opposite spin, such as $\chi_1(x_1) = \alpha(\omega_1)\psi_1(r_1)$, $\chi_2(x_2) = \beta(\omega_1)\psi_1(r_1)$, $\chi_3(x_3) = \alpha(\omega_3)\psi_2(r_3)$, $\chi_4(x_4) = \beta(\omega_4)\psi_2(r_4)$, etc. In this case the first and second term become $2 \sum_{i=1}^{N/2} \int \psi_i(r)h(i)\psi_i(r) dr$ and $2 \sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int \psi_i(r_1)\psi_i(r_1)\frac{1}{r_{12}}\psi_j(r_2)\psi_j(r_2) dr_1 dr_2$ ($2 = 2 \times 2 \times \frac{1}{2}$) respectively. For the third term (exchange), both electrons $i$ and $j$ can be in spin $\alpha$ or $\beta$, then we discuss it in four cases ($ij\rightarrow\alpha\alpha, ij\rightarrow\beta\alpha, ij\rightarrow\alpha\beta, ij\rightarrow\beta\beta$): \[\begin{align*} &amp; \frac{1}{2}\sum_{i=1}^N \sum_{j=1}^N \int \chi_i(x_1)\chi_j(x_1)\frac{1}{r_{12}}\chi_j(x_2)\chi_i(x_2) dx_1 dx_2 \\ =&amp; \frac{1}{2}\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int {\color{red}{\alpha(\omega_1)}}\psi_i(r_1){\color{red}{\alpha(\omega_1)}}\psi_j(r_1)\frac{1}{r_{12}}{\color{red}{\alpha(\omega_2)}}\psi_j(r_2){\color{red}{\alpha(\omega_2)}}\psi_i(r_2) d\omega_1 dr_1 d\omega_2 dr_2 \\ =&amp; \frac{1}{2}\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int {\color{blue}{\beta(\omega_1)}}\psi_i(r_1){\color{red}{\alpha(\omega_1)}}\psi_j(r_1)\frac{1}{r_{12}}{\color{red}{\alpha(\omega_2)}}\psi_j(r_2){\color{blue}{\beta(\omega_2)}}\psi_i(r_2) d\omega_1 dr_1 d\omega_2 dr_2 \\ =&amp; \frac{1}{2}\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int {\color{red}{\alpha(\omega_1)}}\psi_i(r_1){\color{blue}{\beta(\omega_1)}}\psi_j(r_1)\frac{1}{r_{12}}{\color{blue}{\beta(\omega_2)}}\psi_j(r_2){\color{red}{\alpha(\omega_2)}}\psi_i(r_2) d\omega_1 dr_1 d\omega_2 dr_2 \\ =&amp; \frac{1}{2}\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int {\color{blue}{\beta(\omega_1)}}\psi_i(r_1){\color{blue}{\beta(\omega_1)}}\psi_j(r_1)\frac{1}{r_{12}}{\color{blue}{\beta(\omega_2)}}\psi_j(r_2){\color{blue}{\beta(\omega_2)}}\psi_i(r_2) d\omega_1 dr_1 d\omega_2 dr_2 \end{align*}\] The second and third term will vanish since $\int {\color{red}{\alpha(\omega)}}{\color{blue}{\beta(\omega)}}d\omega = 0$. For the other terms, the spin wave function vanished, and the final result is $\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int \psi_i(r_1)\psi_j(r_1)\frac{1}{r_{12}}\psi_j(r_2)\psi_i(r_2) dr_1 dr_2$. This reflect the fact that there is only an exchange interaction between electrons of parallel spin. See details in Chapter 2.3.5 (page 81) and 3.4.1 (page 133) of [1]. Now we expand the exchange term with basis functions and take derivative \[\begin{align} &amp;\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \int \psi_i(r_1)\psi_j(r_1)\frac{1}{r_{12}}\psi_j(r_2)\psi_i(r_2) dr_1 dr_2 \nonumber\\ =&amp; \sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{vi}C_{\lambda j}C_{\sigma j}\underbrace{\int \phi_u(r_1)\phi_\lambda(r_1)\frac{1}{r_{12}}\phi_\sigma(r_2)\phi_v(r_2) dr_1 dr_2}_{(u\lambda|\sigma v)} \label{raw_exchange_energy}\\ \frac{\partial}{\partial C_{ui}} =&amp; 4\sum_{j=1}^{N/2} \sum_{v, \lambda, \sigma} C_{vi}C_{\lambda j}C_{\sigma j} (u\lambda|\sigma v)\nonumber \end{align}\] Therefore \[\begin{align} &amp; \frac{\partial L}{\partial C_{ui}} = \sum_v C_{vi}(4 H_{uv} + 8 \sum_{j=1}^{N/2}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) - 4 \sum_{j=1}^{N/2} \sum_{\lambda, \sigma} C_{\lambda j}C_{\sigma j} (u\lambda|\sigma v) - E_i S_{uv}) = 0 \nonumber\\ &amp; \sum_v [H_{uv} + \sum_{j=1}^{N/2} (2 \sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) - \sum_{\lambda, \sigma} C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v))]C_{vi} = E_i \sum_v S_{uv}C_{vi} \label{hf_raw}\\ &amp; \forall i = 1, \cdots, N, u = 1, \cdots, K \nonumber \end{align}\] $\eqref{hf_raw}$ is the raw form of Hartree-Fock approximation. We will discuss how to transform it to matrix form in later section. Exchange term as an operator Now let’s see if it is possible to use an operator $k(i)$ (similar to $g(i)$ in Hartree approximation) to represent the additional exchange term in the above equation, so that the matrix form of $[h(i) + g(i) + k(i)]\psi_i(r_i) = \epsilon_i\psi_i(r_i)$ with basis expansion $\psi_i(r_i) = \sum_{u=1}^K C_{ui} \phi_u(r_i)$ will result in the same result above. Actually it is possible to define $k(i)$ in the following way \[k(i){\color{red}\psi_{\color{red}i}}(r_i) = \sum_{j=1}^{N/2}[\int {\color{blue}\psi_{\color{blue}j}}(r_j) r_{ij}^{-1} {\color{red}\psi_{\color{red}i}}(r_j)] {\color{blue}\psi_{\color{blue}j}}(r_i)\] compared with former $g(i)$ \[g(i){\color{red}\psi_{\color{red}i}}(r_i) = 2\sum_{j=1}^{N/2}[\int {\color{blue}\psi_{\color{blue}j}}(r_j) r_{ij}^{-1} {\color{blue}\psi_{\color{blue}j}}(r_j)] {\color{red}\psi_{\color{red}i}}(r_i)\] Similarly, we write $k(i)\psi_i(r_i)$ as $k(i)\sum_v C_{vi} \phi_v(r_i) = \sum_v C_{vi} k(i)\phi_v(r_i)$, left multiplied by $\phi_u(r_i)$ and integrate. We have \[\begin{align*} &amp;\sum_v C_{vi}\int \phi_u(r_i)k(i)\phi_v(r_i) dr_i \\ =&amp; \sum_v C_{vi}\int \phi_u(r_i)[\sum_{j=1}^{N/2}\int \psi_j(r_j)\frac{1}{r_{ij}}\phi_v(r_j) dr_j]\psi_j(r_i) dr_i \\ =&amp; \sum_v C_{vi}\sum_{\lambda}C_{\lambda j}\int \phi_u(r_i)[\sum_{j=1}^{N/2}\sum_{\sigma}C_{\sigma j}\int \phi_\sigma(r_j)\frac{1}{r_{ij}}\phi_v(r_j) dr_j]\phi_\lambda(r_i) dr_i \\ =&amp; \sum_v C_{vi}\sum_{j=1}^{N/2}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}\int \phi_u(r_i)\phi_\lambda(r_i)\frac{1}{r_{ij}} \phi_\sigma(r_j) \phi_v(r_j) dr_i dr_j \\ =&amp; \sum_v C_{vi}\sum_{j=1}^{N/2}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j} (u\lambda|\sigma v) \end{align*}\] Matrix form and charge density matrix Now we want to write the Hartree equation $\eqref{hartree_raw}$ and Hartree-Fock equation $\eqref{hf_raw}$ in matrix form. We restate them below: \[\begin{align*} \sum_v (H_{uv} + \sum_{j (\neq i)}\sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma))C_{vi} &amp;= E_i \sum_v S_{uv}C_{vi} \\ \sum_v [H_{uv} + \sum_{j=1}^{N/2} (2 \sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) - \sum_{\lambda, \sigma} C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v))]C_{vi} &amp;= E_i \sum_v S_{uv}C_{vi}\\ \forall i = 1, \cdots, N, u = 1, \cdots, K \end{align*}\] We focus on Hartree-Fock equation below. Recall that in the simplest case we got $HC_i = \epsilon_i SC_i \eqref{eq3}$ from $\sum_{v=1}^K H_{uv} C_{vi} = \epsilon_i \sum_{v=1}^K S_{uv} C_{vi}, \forall u = 1, \cdots, K \eqref{simplest_raw}$, $u$ and $v$ are row and column indices respectively. Also recall that in coulomb term $\eqref{E_coulomb_C}$, basis index $u, v$ correspond to the first electron $i$, $\lambda, \sigma$ correspond to the second electron $j$. Let \[\begin{align*} G_{uv} &amp;= \sum_{j=1}^{N/2} (2 \sum_{\lambda, \sigma}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) - \sum_{\lambda, \sigma} C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v)) \\ &amp;= \sum_{\lambda, \sigma}\underbrace{(2\sum_{j=1}^{N/2} C_{\lambda j}C_{\sigma j})}_{P_{\lambda\sigma}}(uv|\lambda\sigma) - \frac{1}{2}\sum_{\lambda, \sigma}\underbrace{(2\sum_{j=1}^{N/2} C_{\lambda j}C_{\sigma j})}_{P_{\lambda\sigma}}(u\lambda|\sigma v) \end{align*}\] Here we move the sum operator over all other electrons $\sum_{j=1}^{N/2}$ to the inner of the term, and define \[\begin{equation} P_{\lambda\sigma} = 2\sum_{j=1}^{N/2} C_{\lambda j}C_{\sigma j} \label{P_def} \end{equation}\] (Or in matrix form $P = 2CC^T$ in which $C$ is a $K \times N/2$ matrix. Here $P$ is called density matrix. We will discuss the physical meaning of $P$ in later section), thus \[\begin{equation} G_{uv} = \sum_{\lambda, \sigma}P_{\lambda\sigma}(uv|\lambda\sigma) - \frac{1}{2}\sum_{\lambda, \sigma}P_{\lambda\sigma}(u\lambda|\sigma v) \label{G_def} \end{equation}\] or, in a NumPy way, np.einsum("uvkl, kl -&gt; uv", eri, D) - 0.5 * np.einsum("ukvl, kl -&gt; uv", eri, D) Now we can write Hartree-Fock equation in matrix form, similar to $\eqref{eq3}$, that is, \[(H + G)C_i = \epsilon_i SC_i\] Or more concisely, define Fock matrix $F = H + G$ (see (3.154) of [1]), we have \[\begin{equation} FC_i = \epsilon_i SC_i \label{HF} \end{equation}\] which is also a (generalized) eigen decomposition in which we solve $K$ eigenvalue $\epsilon_1, \cdots, \epsilon_K$ and $K$ elgenvectors $C_1, \cdots, C_K$ for the Fock matrix $F$. This equation is usually called Roothaan equation. Self-Consistent Field (SCF) However, note that we cannot directly solve $\eqref{HF}$ as stated in the simplest case $\eqref{eq3}$. Different from $H$ in $\eqref{eq3}$ which is a known constant, $F$ is dependent on $G$, $G$ is dependent on $P \eqref{G_def}$, $P$ is dependent on $C_1, \cdots, C_{N/2} \eqref{P_def}$. In a word, $F$ is a function of $C$ ($F = F(C)$), but $C$ is just the result that we want to solve. So this becomes a chicken-egg problem. To solve $\eqref{HF}$ we need $C$ to construct Fock matrix $F$, to obtain $C$ we need to solve $\eqref{HF}$, …, which is a dead lock. In reality we can try Self-Consistent Field (SCF) method to solve the equation. Simply speaking, we randomly choose a $C^0$ so that we can construct $F$ and solve $\eqref{HF}$ to obtain a new $C^1$. Iterate the process until the new generated $C^i$ is nearly the same as the previous $C^{i-1}$. In implementation we actually use $P$ to replace $C$ in the aforementioned iteration process. That is: Choose an initial $P$ iterate until $|P - P’| &lt; \text{threshold}$: Compute Fock matrix $F = H + G(P)$ following $\eqref{G_def}$ Solve $FC_i = \epsilon_i SC_i \eqref{HF}$ via the procedure introduced in previous section, obtain $K$ elgenvectors $C_1, \cdots, C_K$ whose eigenvalue is in ascending order. Store previous density matrix $P’ = P$ and compute new $P = 2CC^T$, in which $C = [C_1, \cdots, C_{N/2}]$ is a $K \times N/2$ matrix consisting of the first $N/2$ eigenvectors. Unfortunately, SCF is not guaranteed to converge. The selection of initial value and the tricks in iteration process (such as DIIS) is critical to its convergence. Charge density matrix Note that $P_{\lambda\sigma}$ in $\eqref{P_def}$ actually has physical meaning. Remind that $\psi_i(r)$ (orbital) is the wave function of a single electron. Therefore $\rho_i(r) = \psi_i^2(r)$ is the probability density that this electron shows at coodinate $r$, $\int_{r} \psi^2_i(r) dr = 1$. Then \[\begin{align*} \rho_i(r) = \psi_j^2(r) &amp;= (\sum_{\lambda=1}^K C_{\lambda j} \phi_\lambda(r))(\sum_{\sigma=1}^K C_{\sigma j} \phi_\sigma(r)) \\ &amp;= \sum_{\lambda\sigma}C_{\lambda j}C_{\sigma j} \phi_\lambda(r)\phi_\sigma(r) \end{align*}\] Since $K$ basis function $\phi_1(r), \cdots, \phi_K(r)$ are given, the above expression shows that, if we know $K$ variables $C_{1j}, \cdots, C_{Kj}$ then we can get the probability density function of a single orbital $\psi_j^2(r)$. So how many variables do we need if we want the total density function of all $N$ electrons. That is $\rho(r) = 2\sum_{j=1}^{N/2}\rho_j(r)$ ($\int_{r} \rho(r) dr = N$)? A simple answer is $(N/2) \times K$ matrix of $C$. However, \[\begin{align*} \rho(r) = 2\sum_{j=1}^{N/2}\psi_j^2(r) &amp;= 2\sum_{j=1}^{N/2}\sum_{\lambda\sigma}C_{\lambda j}C_{\sigma j} \phi_\lambda(r)\phi_\sigma(r) \\ &amp;= \sum_{\lambda\sigma}(2\sum_{j=1}^{N/2}C_{\lambda j}C_{\sigma j}) \phi_\lambda(r)\phi_\sigma(r) \\ &amp;= \sum_{\lambda\sigma}P_{\lambda\sigma} \phi_\lambda(r)\phi_\sigma(r) \end{align*}\] So besides $C$, a $K \times K$ matrix $P$ is also sufficient to describe the total density function $\rho(r)$. For this reason we call $P$ the (charge) density matrix. Total Energy Now we review the total energy $\eqref{raw_total_energy}$ and try to write it in a more elegant way using density matrix $P$ ($P_{\lambda\sigma} = 2\sum_{j=1}^{N/2} C_{\lambda j}C_{\sigma j} \eqref{P_def}$)and two-centered integral of basis functions $(uv|\lambda\sigma) = \int \phi_u(r_i)\phi_\lambda(r_j)\frac{1}{r_{ij}}\phi_\sigma(r_j)\phi_v(r_i) dr_i dr_j$. $E = E_{Hcore} + E_{coulomb} + E_{exchange}$ in which \[\begin{align*} E_{Hcore} &amp;= \sum_{i=1}^N \sum_{u, v}C_{ui}C_{vi}H_{uv} \quad \eqref{raw_hcore_energy}\\ &amp;= 2\sum_{i=1}^{N/2} \sum_{u, v}C_{ui}C_{vi}H_{uv} \quad \text{(for closed-shell restricted scenario)} \\ &amp;= \sum_{u, v}(2\sum_{i=1}^{N/2}C_{ui}C_{vi})H_{uv} = \sum_{u, v}P_{uv}H_{uv}\\ E_{coulomb} &amp;= \frac{1}{2}\sum_{i=1}^{N} \sum_{j=1}^{N} \sum_{u, v, \lambda, \sigma}C_{ui}C_{\lambda j}C_{\sigma j}C_{vi}(uv|\lambda\sigma) \quad \eqref{E_coulomb_C} \\ &amp;= 2\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{\lambda j}C_{\sigma j}C_{vi}(uv|\lambda\sigma) \quad \text{(for closed-shell restricted scenario)} \\ &amp;= \frac{1}{2}\sum_{u, v, \lambda, \sigma}(2\sum_{i=1}^{N/2}C_{ui}C_{vi})(2\sum_{j=1}^{N/2}C_{\lambda j}C_{\sigma j})(uv|\lambda\sigma) = \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(uv|\lambda\sigma)\\ E_{exchange} &amp;= -\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{vi}C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v) \quad \eqref{raw_exchange_energy} \\ &amp;= -\frac{1}{4} \sum_{u, v, \lambda, \sigma} (2\sum_{i=1}^{N/2}C_{ui}C_{vi})(2\sum_{j=1}^{N/2}C_{\lambda j}C_{\sigma j})(u\lambda|\sigma v) = -\frac{1}{4}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(u\lambda|\sigma v) \end{align*}\] Therefore \[E = \sum_{u, v}P_{uv}H_{uv} + \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(uv|\lambda\sigma) - \frac{1}{4}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(u\lambda|\sigma v)\] Or, in a NumPy way, E_elec = (HC * D).sum() + 0.5 * np.einsum("uvkl, uv, kl -&gt;", eri, D, D) \\ - 0.25 * np.einsum("ukvl, uv, kl -&gt;", eri, D, D) in Py-xdh documentation. The usage of np.einsum can be found here (In explicit mode with -&gt;). Note that with Born-Oppenheimer approximation, we assume that the nuciels are fixed, static points with given coordinate $R$, thus we ignored the constant energy of nucleis (kinetic energy of nucleis $T_N(R)$ and Coulombic repulsion between nucleis $V_{NN}(R)$)in all the above discussions (see problem statement). However, when talking about the term “total energy”, these constant energies should be included, that is, \[E_{nuc} = T_N(R) + V_{NN}(R) = 0 + \sum_{A &lt; B}\frac{Z_A Z_B}{R_{AB}} = \frac{1}{2}\sum_{A, B}\frac{Z_A Z_B}{R_{AB}}\] which is quite easy to calculate using atomic number $Z_A$ and nuclei coordinate $R_A$, without any basis or integral. Finally, \[\begin{align} E_{total} &amp;= E + E_{nuc} \nonumber \\ &amp;= \sum_{u, v}P_{uv}H_{uv} + \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(uv|\lambda\sigma) - \frac{1}{4}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(u\lambda|\sigma v) + \frac{1}{2}\sum_{A, B}\frac{Z_A Z_B}{R_{AB}} \label{E_total} \end{align}\] Thomas-Fermi theory From the last section, we notice that the electron density $\rho(r)$ (or density matrix $P$) plays an important role. Expecially the $G$ matrix $\eqref{G_def}$ is a function of $P$. Then can we skip the wave function ($\psi(r), C$) and directly calculate through the electron density ($\rho(r), P$)? Thomas-Fermi theory shows such a possibility. Preliminaries: electron density for N-electron wavefunction For a single-electron wave function $\psi_i(r)$, we know that $\rho_i(r) = \psi_i^2(r)$ is the probability density that this electron shows at coodinate $r$, $\int_{r} \psi^2_i(r) dr = 1$. Then, what will be the electron density for N-electron wavefunction $\Psi(r_1, \cdots, r_N)$? Actually, it is similar to joint probability distribution $f_{X, Y}(x, y)$ and marginal distribution $f_{X}(x) = \int_y f_{X, Y}(x, y)dy$ for random variable $X$. That is, $\rho(r_1, \cdots, r_N) = \Psi^2(r_1, \cdots, r_N)$ is the probability density that electron 1 shows at coordinate $r_1$, electron 2 shows at coordinate $r_2$, …, electron N shows at coordinate $r_N$. $\int_{r_1, \cdots, r_N} \Psi^2(r_1, \cdots, r_N)dr_1, \cdots, dr_N = 1$. The (marginal) probability density that electron i appears at coordinate $r$ is that \[\rho_i({\color{red}r}) = \int_{r_1, \cdots, r_{i-1}, r_{i+1}, \cdots, r_N} \Psi^2(r_1, \cdots, r_{i-1}, {\color{red}r}, r_{i+1}, \cdots, r_N) dr_1, \cdots, dr_{i-1}, dr_{i+1}, \cdots, dr_N\] and we define (total) electron density $\rho(r)$ simply as \[\rho(r) = \sum_{i=1}^N \rho_i(r)\] which is NOT a probability density function but a sum of N probability density functions. $\int \rho(r) dr = \sum_{i=1}^N \int \rho_i(r)dr = N$. Expressing total energy with electron density The key of Thomas-Fermi theory is to express the total energy $\int \Psi (T_e + V_{eN} + V_{ee})\Psi$ as a function of electron density $\rho(r)$. $T_e$ (kinetic energy): $\int \Psi T_e \Psi = \int \Psi (-\frac{1}{2}\sum_i\nabla_i^2) \Psi$ hard to be expressed with $\rho(r)$, but can be estimated by $T_{TF}(\rho) = C_F\int\rho^{5/3}(r)dr$ in which $C_F = \frac{3}{10}(3\pi^2)^{2/3} \simeq 2.871$ $V_{eN}$ (electrostatic potential between electrons and nuciels, or external potential. Can also be denoted as $V_{ext}$): \[\begin{align*} \int \Psi V_{eN} \Psi &amp;= \int \Psi(\sum_A\sum_i-\frac{Z_A}{r_{Ai}}) \Psi \\ &amp;= \sum_{i=1}^N\int_{r_1, \cdots, r_N} \Psi(r_1, \cdots, r_N) (\sum_A-\frac{Z_A}{r_{Ai}}) \Psi(r_1, \cdots, r_N) dr_1\cdots dr_N \\ &amp;= \sum_{i=1}^N\int_{r_i} \underbrace{(\sum_A-\frac{Z_A}{r_{Ai}})}_{v(i)} \underbrace{(\int_{r_1, \cdots, r_{i-1}, r_{i+1}, \cdots, r_N} \Psi^2(r_1, \cdots, r_N) dr_1\cdots dr_{i-1}, dr_{i+1}, \cdots, dr_N)}_{\rho_i(r_i)} dr_i \\ &amp;= \sum_{i=1}^N\int_r v(i)\rho_i(r)dr = \int_r v(i)\underbrace{(\sum_{i=1}^N\rho_i(r))}_{\rho(r)}dr \\ &amp;= \int v(i)\rho(r)dr \end{align*}\] in which $v(i) = \sum_A-\frac{Z_A}{r_{Ai}}$. remind that $h(i) = -\frac{1}{2}\nabla_i^2 - \sum_{A}\frac{Z_A}{r_{Ai}} = -\frac{1}{2}\nabla_i^2 + v(i)$. In this way, $V_{eN}$ can be precisely expressed via electron density $\rho(r)$, no matter how the N-electron wave function $\Psi$ is approximated. $V_{ee}$ (electrostatic repulsion between electrons): while $\int \Psi (\frac{1}{2}\sum_{i \neq j}\frac{1}{r_{ij}}) \Psi$ is hard to tackle as before, we use Hartree approximation in which $\Psi$ is approximated as the product of $N$ single-electron wavefunction (orbitals) $\Psi(r_1, \cdots, r_N) = \psi(r_1)\cdots\psi(r_N)$. We also relax $\sum_{i \neq j}$ as $\sum_{i, j} (\text{i.e., }\sum_i\sum_j)$ \[\begin{align*} &amp; \int \Psi(r_1, \cdots, r_N) (\frac{1}{2}\sum_{i, j} \frac{1}{r_{ij}}) \Psi(r_1, \cdots, r_N) dr_1\cdots dr_N \nonumber \\ =&amp; \frac{1}{2}\sum_{i, j} \int_{r_N}\cdots\int_{r_1} \psi(r_1)\cdots\psi(r_N) \frac{1}{r_{ij}} \psi(r_1)\cdots\psi(r_N) dr_1\cdots dr_N \nonumber \\ =&amp; \frac{1}{2}\sum_{i, j} \int_{r_i, r_j} \psi_i(r_i)\psi_j(r_j)\frac{1}{r_{ij}}\psi_j(r_j)\psi_i(r_i) dr_i dr_j \\ =&amp; \frac{1}{2} \int_{r_i, r_j} \underbrace{(\sum_{i=1}^N\psi^2_i(r_i))}_{\rho(r_i)} \underbrace{(\sum_{j=1}^N\psi^2_j(r_j))}_{\rho(r_j)}\frac{1}{r_{ij}} dr_i dr_j \\ =&amp; \frac{1}{2} \int_{r_i, r_j} \frac{\rho(r_i)\rho(r_j)}{r_{ij}} dr_i dr_j \end{align*}\] Adding all three energies above, we get the total energy with Thomas-Fermi approximation (denoted as $\langle H \rangle_{TF}$) \[\langle H \rangle_{TF} = C_F\int\rho^{5/3}(r)dr + \int v(i)\rho(r)dr + \frac{1}{2} \int_{r_i, r_j} \frac{\rho(r_i)\rho(r_j)}{r_{ij}} dr_i dr_j\] Dirac added a term for the exchange energy $E_x(\rho) = -C_x \int \rho^{4/3}(r)dr$ in which $C_x = \frac{3}{4}(\frac{3}{\pi})^{1/3}$, and \[\langle H \rangle_{TFD} = \langle H \rangle_{TF} + E_x\] Thomas-Fermi(-Dirac) theory shows that the total energy can be approximated as a function of electron density $\rho(r)$. Density Functional Theory (DFT) Preliminaries: Appendix Integral evaluation More integrals can be found in Appendix A of [1]. For overlap integral $S_{uv} = \int \phi_u(r_i)\phi_v(r_i)dr_i$ with Gaussian atomic orbitals $\phi_u(r-R_u) = (2\alpha/\pi)^{3/4}e^{-\alpha|r-R_u|^2}$, we first show that the product of two Gaussians is also a Gaussian. That is \[\begin{aligned} &amp; \phi_u(r-R_u) \phi_v(r - R_v) \\ = &amp; e^{-\alpha|r - R_u|^2} e^{-\beta|r - R_v|^2} \\ = &amp; e^{-(\alpha|r - R_u|^2 + \beta|r - R_v|^2)} \\ = &amp; e^{-[\alpha(r_x - R_{u,x})^2 + \beta(r_x - R_{v,x})^2 + \alpha(r_y - R_{u,y})^2 + \beta(r_y - R_{v,y})^2 + \alpha(r_z - R_{u,z})^2 + \beta(r_z - R_{v,z})^2]} \\ = &amp; e^{-[(\alpha + \beta)r_x^2 - 2(\alpha R_{u,x} + \beta R_{v,x}) + \alpha R_{u,x}^2 + \beta R_{u,y}^2 + \cdots]} \\ = &amp; e^{-[(\alpha + \beta)(r_x - \frac{\alpha R_{u,x} + \beta R_{v,x}}{\alpha + \beta})^2 + \alpha R_{u,x}^2 + \beta R_{u,y}^2 - \frac{(\alpha R_{u,x} + \beta R_{v,x})^2}{\alpha + \beta} + \cdots]} \\ = &amp; e^{-[(\alpha + \beta)(r_x - \frac{\alpha R_{u,x} + \beta R_{v,x}}{\alpha + \beta})^2 + \cdots]} e^{(\alpha + \beta)(\alpha R_{u,x} + \beta R_{v,x}) - (\alpha R_{u,x} + \beta R_{v,x})^2] / (\alpha + \beta) + \cdots} \\ = &amp; e^{-[(\alpha + \beta)(r_x - \frac{\alpha R_{u,x} + \beta R_{v,x}}{\alpha + \beta})^2 + \cdots]} e^{-\frac{\alpha\beta}{\alpha + \beta}(R_{u,x}-R_{v,x})^2 + \cdots} \\ = &amp; e^{-p|r - R_p|^2} \tilde{K} \\ = &amp; \tilde{K} \phi_p(r - R_p) \end{aligned}\] in which $p = \alpha + \beta$, $R_p = \frac{\alpha R_{u} + \beta R_{v}}{\alpha + \beta}$ is the center of the new Gaussian, and $\tilde{K} = e^{-\frac{\alpha\beta}{\alpha + \beta}|R_u - R_v|^2}$. Then \[S_{uv} = \int \phi_u(r_i)\phi_v(r_i)dr_i = \tilde{K} \int \phi_p(\textbf{r}_i - \textbf{R}_p) d\textbf{r}_i = \tilde{K} \int e^{-p|\textbf{r}_i - \textbf{R}_p|^2} d\textbf{r}_i\] Let $\textbf{r} = \textbf{r}_i - \textbf{R}_p$, reminds that triple integrals in spherical coordinates $d\textbf{r} = (r\sin\varphi d\theta)(r d\varphi)dr = r^2\sin\varphi dr d\varphi d\theta$, then \[\begin{aligned} \int e^{-p|\textbf{r}_i - \textbf{R}_p|^2} d\textbf{r}_i &amp;= \int e^{-p|\textbf{r}|^2} d\textbf{r} \\ &amp;= \int_{r=0}^{+\infty} \int_{\varphi = 0}^\pi \int_{\theta = 0}^{2\pi} e^{-pr^2} r^2\sin\varphi dr d\varphi d\theta \\ &amp;= 4\pi \int_{r=0}^{+\infty} e^{-pr^2} r^2 dr \end{aligned}\] To calculate $\int_{r=0}^{+\infty} e^{-pr^2} r^2 dr$, reminds that the Gaussian distribution $\int_{x=-\infty}^{\infty} \frac{1}{\sigma \sqrt{2\pi}} e^{-\frac{x^2}{2\sigma^2}} = 1$. Let $\sigma = \sqrt{\frac{1}{2\alpha}}$ then we have a more general form $\int_{x=-\infty}^{\infty} e^{-\alpha x^2} = \sqrt{\frac{\pi}{\alpha}}$. Different each side by parameter $\alpha$ we have $\int_{x=-\infty}^{\infty} -x^2 e^{-\alpha x^2} = \frac{\sqrt{\pi}}{-2\alpha^{3/2}}$, therefore $\int_{x=-\infty}^{\infty} x^2 e^{-\alpha x^2} = \frac{\sqrt{\pi}}{2\alpha^{3/2}}$ and $\int_{x=0}^{\infty} -x^2 e^{-\alpha x^2} = \frac{\sqrt{\pi}}{4\alpha^{3/2}}$ by symmetry. The final result of $S_{uv}$ is \[S_{uv} = 4\pi \tilde{K} \frac{\sqrt{\pi}}{4p^{3/2}} = (\frac{\pi}{p})^{3/2} e^{-\frac{\alpha\beta}{\alpha + \beta}|R_u - R_v|^2}\] Derivative of energy w.r.t nuclei coordinates (Geometry Optimization) More details can be found in appendix C of [1] and [4]. Generally speaking, the total energy $E_{total}$ (notation simplified as $E$ in the following text) can be seen as a function of nuclei coordinates $R = (R_1, R_2, \cdots)$ (denoted as $E(R)$). The coordinate-energy curve (surface) is called potential energy surface (PES). In geometry optimization, we are interested in finding the global minima of $E(R)$, that is, $R^* = \arg\min_R E(R)$. In order to find the minima efficiently, we are going to achieve a mission impossible – differentiate $E$ w.r.t $R$, i.e., $\frac{\partial E}{\partial R}$. Recall $\eqref{E_total}$ \[E = \sum_{u, v}P_{uv}H_{uv} + \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(uv|\lambda\sigma) - \frac{1}{4}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(u\lambda|\sigma v) + \frac{1}{2}\sum_{A, B}\frac{Z_A Z_B}{R_{AB}}\] Considering $P_{uv} = 2\sum_{i=1}^{N/2} C_{ui}C_{vi}$ is just a function of occupied molecular orbital coefficient $C$, and $R_{AB} = |R_A - R_B|$, we get that $E$ is a function of $C_{ui}$, which may have implicit dependence with $R$. $H_{uv} = \int \phi_u(r)h(1)\phi_v(r)dr$. From integral evaluation we know that the gaussian atomic orbital $\phi_u(r, R_{A(u)}) = \phi_u(r-R_{A(u)}) = (2\alpha/\pi)^{3/4}e^{-\alpha|r-R_{A(u)}|^2}$ is a function of both $r$ and nuclei coordinate $R_{A(u)}$, in which $A(u)$ is the corresponding nuclei of the $u$th atomic orbital. In this case, we write $H_{uv}$ as $H_{uv} = \int \phi_u(r, R_{A(u)})h(1)\phi_v(r, R_{A(v)})dr$, which has a clear dependence of nuclei coordinate $R$. $(uv|\lambda\sigma) = \int \phi_u(r_1)\phi_v(r_1)\frac{1}{r_{12}}\phi_\lambda(r_2)\phi_\sigma(r_2) dr_1 dr_2$. Similarly, we can write it as $\int \phi_u(r_1, R_{A(u)})\phi_v(r_1, R_{A(v)})\frac{1}{r_{12}}\phi_\lambda(r_2, R_{A(\lambda)})\phi_\sigma(r_2, R_{A(\sigma)}) dr_1 dr_2$, which has a clear dependence of nuclei coordinate $R$. $R_A$, the nuclei coordinate itself. $Z_A$, which is not correlated with nuclei coordinate $R$ at all. To compute $\frac{\partial E}{\partial R}$, we first compute the derivative of the first term, i.e., $\frac{\partial E_{Hcore}}{\partial R}$ as an example. Remind that $\frac{\partial}{\partial x} [a(x)b(x)c(x)d(x)\cdots] = \frac{\partial a(x)}{\partial x}b(x)c(x)d(x)\cdots + a(x)\frac{\partial b(x)}{\partial x}c(x)d(x)\cdots + \cdots$ \[\begin{align*} E_{Hcore} &amp;= \sum_{u, v}P_{uv}H_{uv} = 2\sum_{i=1}^{N/2} \sum_{u, v}C_{ui}C_{vi}H_{uv} \\ \frac{\partial E_{Hcore}}{\partial R_A} &amp;= 2\sum_{i=1}^{N/2} \sum_{u, v}(\underbrace{\frac{\partial C_{ui}}{\partial R_A}C_{vi}H_{uv} + C_{ui}\frac{\partial C_{vi}}{\partial R_A}H_{uv}}_{\text{symmetry}} + C_{ui}C_{vi}\frac{\partial H_{uv}}{\partial R_A}) \\ &amp;= 4\sum_{i=1}^{N/2} \sum_{u, v}\frac{\partial C_{ui}}{\partial R_A}C_{vi}H_{uv} + \sum_{u, v}P_{uv}\frac{\partial H_{uv}}{\partial R_A} \\ E_{coulomb} &amp;= 2\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{vi}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) \\ \frac{\partial E_{coulomb}}{\partial R_A} &amp;= 8\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}\frac{\partial C_{ui}}{\partial R_A}C_{vi}C_{\lambda j}C_{\sigma j}(uv|\lambda\sigma) + 2\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{\lambda j}C_{\sigma j}C_{vi}\frac{\partial (uv|\lambda\sigma)}{\partial R_A} \\ &amp;= 4\sum_{i=1}^{N/2} \sum_{u, v, \lambda, \sigma}\frac{\partial C_{ui}}{\partial R_A}C_{vi}P_{\lambda\sigma}(uv|\lambda\sigma) + \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}\frac{\partial (uv|\lambda\sigma)}{\partial R_A} \\ E_{exchange} &amp;= -\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{vi}C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v) \\ \frac{\partial E_{exchange}}{\partial R_A} &amp;= -4\sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}\frac{\partial C_{ui}}{\partial R_A}C_{vi}C_{\lambda j}C_{\sigma j}(u\lambda|\sigma v) - \sum_{i=1}^{N/2} \sum_{j=1}^{N/2} \sum_{u, v, \lambda, \sigma}C_{ui}C_{\lambda j}C_{\sigma j}C_{vi}\frac{\partial (uv|\lambda\sigma)}{\partial R_A} \\ &amp;= -2\sum_{i=1}^{N/2} \sum_{u, v, \lambda, \sigma}\frac{\partial C_{ui}}{\partial R_A}C_{vi}P_{\lambda\sigma}(u\lambda|\sigma v) - \frac{1}{4}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}\frac{\partial (u\lambda|\sigma v)}{\partial R_A} \\ E_{nuc} &amp;= V_{NN}(R) = \frac{1}{2}\sum_{A \neq B}\frac{Z_A Z_B}{R_{AB}} = \frac{1}{2}\sum_{A \neq B}\frac{Z_A Z_B}{\sqrt{(R_{A, x} - R_{B, x})^2 + (R_{A, y} - R_{B, y})^2 + (R_{A, z} - R_{B, z})^2}}\\ \frac{\partial E_{nuc}}{\partial R_{A, x}} &amp;= \frac{1}{2} \cdot 2 Z_A \sum_{B(\neq A)} Z_B \cdot -(R_{AB})^{-2} \cdot \frac{1}{2} (R_{AB}^2)^{1/2} \cdot 2(R_{A, x} - R_{B, x}) \quad \text{(similar for } R_{A, y} \text{ and } R_{A, z} \text{)}\\ \frac{\partial E_{nuc}}{\partial R_A} &amp;= Z_A \sum_{B(\neq A)}\frac{Z_B (R_B - R_A)}{R_{AB}^3} \\ \frac{\partial E}{\partial R_A} &amp;= \frac{\partial E_{Hcore}}{\partial R_A} + \frac{\partial E_{coulomb}}{\partial R_A} + \frac{\partial E_{exchange}}{\partial R_A} + \frac{\partial E_{nuc}}{\partial R_A} \\ &amp;= 4\sum_{i=1}^{N/2} \sum_{u, v}\frac{\partial C_{ui}}{\partial R_A}C_{vi}\underbrace{(H_{uv} + P_{\lambda\sigma}(uv|\lambda\sigma) - \frac{1}{2}P_{\lambda\sigma}(u\lambda|\sigma v))}_{F_{uv}, \text{see} \eqref{G_def}} \\ &amp;+ \sum_{u, v}P_{uv}\frac{\partial H_{uv}}{\partial R_A} + \frac{1}{2}\sum_{u, v, \lambda, \sigma}P_{uv}P_{\lambda\sigma}(\frac{\partial (uv|\lambda\sigma)}{\partial R_A} - \frac{1}{2}\frac{\partial (u\lambda|\sigma v)}{\partial R_A}) + Z_A \sum_{B(\neq A)}\frac{Z_B (R_B - R_A)}{R_{AB}^3} \end{align*}\] Hartree-Fock and Mean-Field https://nukephysik101.wordpress.com/2017/07/12/hartree-fock-and-mean-field/ Density Fitting https://github.com/psi4/psi4numpy/blob/master/Tutorials/03_Hartree-Fock/density-fitting.ipynb References Szabo, A., &amp; Ostlund, N. S. (1982). Modern quantum chemistry: introduction to advanced electronic structure theory. Dover Publication. Sherrill, C. D. (2000). An introduction to Hartree-Fock molecular orbital theory. School of Chemistry and Biochemistry, Georgia Institute of Technology. https://gitlab.com/LLindenbauer/Hartree-Fock-Tutorial https://py-xdh.readthedocs.io/zh_CN/latest/]]></summary></entry><entry><title type="html">Game Theory Note</title><link href="https://snowkylin.github.io/blogs/game-theory-note.html" rel="alternate" type="text/html" title="Game Theory Note" /><published>2021-01-19T00:00:00+00:00</published><updated>2021-01-19T00:00:00+00:00</updated><id>https://snowkylin.github.io/blogs/game-theory-note</id><content type="html" xml:base="https://snowkylin.github.io/blogs/game-theory-note.html"><![CDATA[<ul id="markdown-toc">
  <li><a href="#static-game" id="markdown-toc-static-game">Static Game</a></li>
  <li><a href="#extensive-game" id="markdown-toc-extensive-game">Extensive Game</a></li>
  <li><a href="#potential-game" id="markdown-toc-potential-game">Potential Game</a></li>
  <li><a href="#learning-nash-equilibria" id="markdown-toc-learning-nash-equilibria">Learning Nash Equilibria</a></li>
</ul>

<h1 id="static-game">Static Game</h1>

<p>Strategy form game matrix</p>

<table>
  <tbody>
    <tr>
      <td> </td>
      <td>Strategies 1 (col player)</td>
      <td>Strategies 2 (col player)</td>
    </tr>
    <tr>
      <td>Strategies 1 (row player, “you”)</td>
      <td>row player / column player payoff</td>
      <td>…</td>
    </tr>
    <tr>
      <td>Strategies 2 (row player, “you”)</td>
      <td>…</td>
      <td>…</td>
    </tr>
  </tbody>
</table>

<p>e.g., the prisoner’s dilemma</p>

<table>
  <tbody>
    <tr>
      <td> </td>
      <td>Don’t confess (col player)</td>
      <td>confess (col player)</td>
    </tr>
    <tr>
      <td>Don’t confess (row player, “you”)</td>
      <td>-1 (row), -1 (col)</td>
      <td>-10, 0</td>
    </tr>
    <tr>
      <td>confess (row player, “you”)</td>
      <td>0, -10</td>
      <td>-4, -4</td>
    </tr>
  </tbody>
</table>

<ul>
  <li><strong>Strictly dominant strategy for player p</strong>: No matter what strategy the other play choose, player p should choose this strategy
    <ul>
      <li>e.g., in prisoner’s dilemma,
        <ul>
          <li>if your partner choose not to confess (see column 1), you should choose confess (0 &gt; -1)</li>
          <li>if your partner choose to confess (see column 2), you should still choose confess (-4 &gt; -10)</li>
          <li>Therefore confessing is a strictly dominant strategy for you.</li>
          <li>Similarly, confessing is also a strictly dominant strategy for the other player.</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>Best response to strategy S</strong>: Assume that the other play choose strategy S, the strategy that has the largest payoff for you is the best response to S.
    <ul>
      <li>A dominate strategy for player p is a best response to every strategy of the other player (it is all possible that no player, one player and both two players have dominate strategies)</li>
      <li>If one player has a dominate strategy, the other player can assume that this player will play the dominate strategy.</li>
    </ul>
  </li>
  <li><strong>Nash equilibrium</strong>: if player p has a strategy S and player q has a strategy T, we say (S, T) is a Nash equilibrium if S is a best response to T and T is a best response to S.
    <ul>
      <li>At Nash equilibrium, no one want to <em>unilaterally</em> (done only by one player, not both) switch to another strategy.</li>
      <li>A game can have no Nash equilibrium or multiple Nash equilibrium</li>
    </ul>
  </li>
  <li><strong>Game</strong>:
    <ul>
      <li>A set of <em>players</em> $i \in \{1, \cdots, N\}$</li>
      <li>Each player $i$ have a set of <em>strategies</em> $s_i \in S_i$, $s \in S = \Pi_i S_i$ for all players.</li>
      <li><strong>Payoff/utility function</strong>: For each combination of strategies (e.g., pair $(s_1, s_2)$ in two-player game), each player $i$ receives a <em>payoff</em> $u_i(s_1, s_2)$ (e.g., for pair $(\text{confess}, \text{not confess})$, player 1 may receive payoff 0, $u_1(\text{confess}, \text{not confess}) = 0$ and player 2 may receive payoff -10, $u_2(\text{confess}, \text{not confess}) = -10$). $u_i$ is called the utility function of player $i$.</li>
      <li>Can be extended to n-player game</li>
    </ul>
  </li>
  <li><strong>Pure &amp; Mixed Strategy</strong>: a player $i$ choose a strategy $s$ deterministically or with probability $\sigma_i(s)$
    <ul>
      <li>$\Sigma_i$ denotes all the possible probability distribution of $S_i$, $\sigma_i \in \Sigma_i$ for player $i$. $\sigma \in \Sigma = \Pi_i \Sigma_i$ for all players ($\sigma$ is called <strong>mixed strategy profile</strong>).</li>
      <li>Use <em>expected value of payoffs</em> to evaluate other player’s strategy (to find the best response of mixed strategy). Extend the payoff function from $u_i(s)$ to $u_i(\sigma) = \Pi_{s \in S} u_i(s)\sigma(s)$</li>
    </ul>
  </li>
  <li><strong>$B_i(\sigma_{-i})$: Best Response of player $i$ to other players’ strategy $\sigma_{-i}$</strong>
    <ul>
      <li>For player $i$, given other players’ strategy $\sigma_{-i}$ fixed, $B_i(\sigma_{-i}) = \arg\max_{\sigma_i} u_i(\sigma_i, \sigma_{-i})$ is a set of mixed strategy $\sigma_i$ for player $i$ that maximize payoff function $u_i(\sigma_i, \sigma_{-i})$.</li>
    </ul>
  </li>
  <li><strong>Nash equilibrium for mixed strategy</strong>
    <ul>
      <li>A mixed strategy profile $\sigma^* = (\sigma^\ast_1, \cdots, \sigma^\ast_N)$ is a Nash equilibrium if for all $i \in \{1, \cdots, N\}$, $\sigma^\ast_i \in B_i(\sigma^\ast_{-i})$.</li>
      <li>We can write it in a more compact way: denote $B(\sigma) = [B_1(\sigma_{-1}) \times \cdots \times B_N(\sigma_{-N})]$, then a mixed strategy profile $\sigma^\ast = (\sigma^\ast_1, \cdots, \sigma^\ast_N)$ is a Nash equilibrium if $\sigma^\ast \in B(\sigma^\ast)$.</li>
      <li><strong>Theorem: Every finite game has a mixed strategy Nash equilibrium</strong>
        <ul>
          <li>Kakutani’s Fixed Point Theorem</li>
        </ul>
      </li>
    </ul>
  </li>
  <li><strong>Pareto optimality</strong>
    <ul>
      <li>A strategy profile is Pareto optimal if no player can gain higher payoff without sacrificing others’ payoffs.</li>
    </ul>
  </li>
  <li>Social optimality: maximizes the sum of the players‘ payoffs</li>
  <li>Solution as a result of learning
    <ul>
      <li>Assumption: expects that his opponent’s output in the future will be the same as it is now</li>
      <li>Asymptotically stable if converges to a particular steady state (a single NE) for all initial state close to it
        <ul>
          <li>Global stable if from every starting state</li>
          <li>Not always converge – circling effect</li>
        </ul>
      </li>
    </ul>
  </li>
</ul>

<h1 id="extensive-game">Extensive Game</h1>

<p>Example:</p>
<ul>
  <li>player 1 has choice C and D
    <ul>
      <li>player 2 has choice E (2, 1) / F (3, 0) for C</li>
      <li>player 2 has choice G (0, 2) / H (1, 3) for D.</li>
    </ul>
  </li>
</ul>

<table>
  <tbody>
    <tr>
      <td> </td>
      <td>EG</td>
      <td>EH</td>
      <td>FG</td>
      <td>FH</td>
    </tr>
    <tr>
      <td>C</td>
      <td>2, 1</td>
      <td>2, 1</td>
      <td>3, 0</td>
      <td>3, 0</td>
    </tr>
    <tr>
      <td>D</td>
      <td>0, 2</td>
      <td>1, 3</td>
      <td>0, 2</td>
      <td>1, 3</td>
    </tr>
  </tbody>
</table>

<ul>
  <li>EG ← (E or F) and (G or H)
    <ul>
      <li>if you choose C, I choose E, if you choose D, I choose G</li>
      <li>if player 1 have 3 choices C, D and I, then we need to use three letters to denote a strategy of player 2</li>
    </ul>
  </li>
  <li><strong>Subgame Perfect (Nash) Equilibrium</strong>
    <ul>
      <li>A strategy profile is a subgame perfect equilibrium if it is an equilibrium for every subgame</li>
      <li>subgame perfection will remove noncredible threats</li>
    </ul>
  </li>
</ul>

<h1 id="potential-game">Potential Game</h1>

<p>Use one global function $\Phi(s): S \rightarrow R $ to replace $N$ payoff functions $u_i(s)$ for each player $i$.</p>

<p>$\Phi$ assigns a real value for every $s \in S$</p>

<ul>
  <li><strong>ordinal potential function</strong>: $u_i(x, s_{−i}) − u_i(z, s_{−i}) &gt; 0 \Leftrightarrow \Phi(x, s_{−i}) − Φ(z, s_{−i}) &gt; 0, \forall x, z \in S_i$</li>
  <li><strong>exact potential function</strong>: $u_i(x, s_{−i}) − u_i(z, s_{−i}) = \Phi(x, s_{−i}) − Φ(z, s_{−i}) &gt; 0, \forall x, z \in S_i$</li>
  <li>Every finite ordinal potential game has at least one pure strategy Nash equilibrium.
    <ul>
      <li>The global maximum of an ordinal potential function is a pure strategy Nash equilibrium</li>
      <li>there may also be other pure strategy Nash equilibria corresponding to local maxima</li>
    </ul>
  </li>
  <li>Path / improvement path</li>
  <li>In every finite ordinal potential game, every improvement path is finite.</li>
  <li>Congestion Games</li>
  <li>Every congestion game is a potential game</li>
</ul>

<h1 id="learning-nash-equilibria">Learning Nash Equilibria</h1>

<p>2-person <strong>zero-sum</strong> games ($u_1(s_1, s_2) == -u_2(s_1, s_2)$)</p>

<table>
  <tbody>
    <tr>
      <td> </td>
      <td>M (prob: $y_1$)</td>
      <td>T (prob: $y_2$)</td>
    </tr>
    <tr>
      <td>E (prob: $x_1$)</td>
      <td>3, -3</td>
      <td>-1, 1</td>
    </tr>
    <tr>
      <td>S (prob: $x_2$)</td>
      <td>-2, 2</td>
      <td>1, -1</td>
    </tr>
  </tbody>
</table>

<ul>
  <li>Minimax Game: minimize other player’s best response (max) payoff
    <ul>
      <li>For column player, expected payoff $V(M) = -3 x_1 + 2 x_2$, $V(T) = x_1 - x_2$</li>
      <li>So if $x_1, x_2$ is given, column player will choose the larger one of $V(M)$ and $V(T)$ as best response, his payoff will be $\max(-3 x_1 + 2 x_2, x_1 - x_2)$</li>
      <li>Row player should choose $x_1$ and $x_2$ so that column player’s payoff $\max(-3 x_1 + 2 x_2, x_1 - x_2)$ is minimized, that is, $\arg\min_{x_1, x_2} \max(-3 x_1 + 2 x_2, x_1 - x_2)$</li>
      <li>Identially, maximize his own payoff $-\max(-3 x_1 + 2 x_2, x_1 - x_2) = \min(3 x_1 - 2 x_2, - x_1 + x_2)$</li>
      <li>Min/max operation can be represented by linear programming by using an auxilary variable $z$ and constraint all components larger/smaller than $z$.</li>
      <li>
        <p>So the linear programming problem is (note that $z$ should be unbounded so we need to add auxilary variable $z’$ so that $z - z’$ is unbounded, $x_1 + x_2 = 1$ is equalty constraint so we need to transit it to two inequality constraint $x_1 + x_2 \leq 1$ and $x_1 + x_2 \geq 1$)</p>

\[\begin{align*}
    \max \quad &amp; z \\
    s.t. \quad 3 x_1 - 2 x_2 &amp;\geq z \\
      - x_1 + x_2 &amp;\geq z \\
      x_1 + x_2 &amp;= 1 \\
      x_1, x_2 &amp;\geq 0 \\
    \max \quad &amp; (0, 1, 1, -1, 0, 0)(x_1, x_2, z, z', s_1, s_2)^T \\
    s.t. \quad &amp;\begin{pmatrix}
      3 &amp; -2 &amp; -1 &amp; 1 &amp; -1 &amp; 0 \\ 
      -1 &amp; 1 &amp; -1 &amp; 1 &amp; 0 &amp; -1\\ 
      1 &amp; 1 &amp; 0 &amp; 0 &amp; 0 &amp; 0
    \end{pmatrix}\begin{pmatrix}x_1\\x_2\\z\\z'\\s_1\\s_2\end{pmatrix} = \begin{pmatrix}0\\0\\1\end{pmatrix}\\
    &amp; (x_1, x_2, z, z', s_1, s_2) \geq 0 \\
    \max \quad &amp; (0, 1, 1, -1)(x_1, x_2, z, z')^T \\
    s.t. \quad &amp;\begin{pmatrix}
      3 &amp; -2 &amp; -1 &amp; 1 \\ 
      -1 &amp; 1 &amp; -1 &amp; 1 \\ 
      1 &amp; 1 &amp; 0 &amp; 0 \\
      -1 &amp; -1 &amp; 0 &amp; 0 \\
    \end{pmatrix}\begin{pmatrix}x_1\\x_2\\z\\z'\end{pmatrix} \geq \begin{pmatrix}0\\0\\1\\1\end{pmatrix}\\
    &amp; (x_1, x_2, z, z') \geq 0
\end{align*}\]
      </li>
      <li>
        <p>Similarly, for the column player, we calculate $\arg\min_{y_1, y_2} \max(3 y_1 - y_2, -2 y_1 + y_2)$</p>

\[\begin{align*}
    \max \quad &amp; w \\
    s.t. \quad -3 y_1 + y_2 &amp;\geq w \\
      2 y_1 - y_2 &amp;\geq w \\
      y_1 + y_2 &amp;= 1 \\
      y_1, y_2 &amp;\geq 0 \\
    \max \quad &amp; (0, 0, 1) (y_1, y_2, w)^T \\
    s.t. \quad &amp; \begin{pmatrix}
      3 &amp; -1 &amp; 1 \\
      -2 &amp; 1 &amp; 1 \\
      -1 &amp; -1 &amp; 0 \\
      1 &amp; 1 &amp; 0 \\
      -1 &amp; 0 &amp; 0 \\
      - &amp; -1 &amp; 0
    \end{pmatrix} \begin{pmatrix}y_1\\y_2\\w\end{pmatrix} \leq 0\\
    \max \quad &amp; (0, 0, 1, -1) (y_1, y_2, w, w')^T \\
    s.t. \quad &amp; \begin{pmatrix}
      3 &amp; -1 &amp; 1 &amp; -1 \\
      -2 &amp; 1 &amp; 1 &amp; -1 \\
      -1 &amp; -1 &amp; 0 &amp; 0\\
      1 &amp; 1 &amp; 0 &amp; 0\\
    \end{pmatrix} \begin{pmatrix}y_1\\y_2\\w\\w'\end{pmatrix} \leq 0\\
    &amp; (y_1, y_2, w, w') \geq 0
\end{align*}\]
      </li>
      <li>Duality</li>
    </ul>
  </li>
  <li>General-sum game: linear complementarity problem
    <ul>
      <li>Algorithm to solve LCP: the Lemke–Howson algorithm</li>
    </ul>
  </li>
</ul>]]></content><author><name>Snowkylin</name></author><category term="game-theory" /><category term="multi-agent-ai" /><summary type="html"><![CDATA[Static Game Extensive Game Potential Game Learning Nash Equilibria Static Game Strategy form game matrix   Strategies 1 (col player) Strategies 2 (col player) Strategies 1 (row player, “you”) row player / column player payoff … Strategies 2 (row player, “you”) … … e.g., the prisoner’s dilemma   Don’t confess (col player) confess (col player) Don’t confess (row player, “you”) -1 (row), -1 (col) -10, 0 confess (row player, “you”) 0, -10 -4, -4 Strictly dominant strategy for player p: No matter what strategy the other play choose, player p should choose this strategy e.g., in prisoner’s dilemma, if your partner choose not to confess (see column 1), you should choose confess (0 &gt; -1) if your partner choose to confess (see column 2), you should still choose confess (-4 &gt; -10) Therefore confessing is a strictly dominant strategy for you. Similarly, confessing is also a strictly dominant strategy for the other player. Best response to strategy S: Assume that the other play choose strategy S, the strategy that has the largest payoff for you is the best response to S. A dominate strategy for player p is a best response to every strategy of the other player (it is all possible that no player, one player and both two players have dominate strategies) If one player has a dominate strategy, the other player can assume that this player will play the dominate strategy. Nash equilibrium: if player p has a strategy S and player q has a strategy T, we say (S, T) is a Nash equilibrium if S is a best response to T and T is a best response to S. At Nash equilibrium, no one want to unilaterally (done only by one player, not both) switch to another strategy. A game can have no Nash equilibrium or multiple Nash equilibrium Game: A set of players $i \in \{1, \cdots, N\}$ Each player $i$ have a set of strategies $s_i \in S_i$, $s \in S = \Pi_i S_i$ for all players. Payoff/utility function: For each combination of strategies (e.g., pair $(s_1, s_2)$ in two-player game), each player $i$ receives a payoff $u_i(s_1, s_2)$ (e.g., for pair $(\text{confess}, \text{not confess})$, player 1 may receive payoff 0, $u_1(\text{confess}, \text{not confess}) = 0$ and player 2 may receive payoff -10, $u_2(\text{confess}, \text{not confess}) = -10$). $u_i$ is called the utility function of player $i$. Can be extended to n-player game Pure &amp; Mixed Strategy: a player $i$ choose a strategy $s$ deterministically or with probability $\sigma_i(s)$ $\Sigma_i$ denotes all the possible probability distribution of $S_i$, $\sigma_i \in \Sigma_i$ for player $i$. $\sigma \in \Sigma = \Pi_i \Sigma_i$ for all players ($\sigma$ is called mixed strategy profile). Use expected value of payoffs to evaluate other player’s strategy (to find the best response of mixed strategy). Extend the payoff function from $u_i(s)$ to $u_i(\sigma) = \Pi_{s \in S} u_i(s)\sigma(s)$ $B_i(\sigma_{-i})$: Best Response of player $i$ to other players’ strategy $\sigma_{-i}$ For player $i$, given other players’ strategy $\sigma_{-i}$ fixed, $B_i(\sigma_{-i}) = \arg\max_{\sigma_i} u_i(\sigma_i, \sigma_{-i})$ is a set of mixed strategy $\sigma_i$ for player $i$ that maximize payoff function $u_i(\sigma_i, \sigma_{-i})$. Nash equilibrium for mixed strategy A mixed strategy profile $\sigma^* = (\sigma^\ast_1, \cdots, \sigma^\ast_N)$ is a Nash equilibrium if for all $i \in \{1, \cdots, N\}$, $\sigma^\ast_i \in B_i(\sigma^\ast_{-i})$. We can write it in a more compact way: denote $B(\sigma) = [B_1(\sigma_{-1}) \times \cdots \times B_N(\sigma_{-N})]$, then a mixed strategy profile $\sigma^\ast = (\sigma^\ast_1, \cdots, \sigma^\ast_N)$ is a Nash equilibrium if $\sigma^\ast \in B(\sigma^\ast)$. Theorem: Every finite game has a mixed strategy Nash equilibrium Kakutani’s Fixed Point Theorem Pareto optimality A strategy profile is Pareto optimal if no player can gain higher payoff without sacrificing others’ payoffs. Social optimality: maximizes the sum of the players‘ payoffs Solution as a result of learning Assumption: expects that his opponent’s output in the future will be the same as it is now Asymptotically stable if converges to a particular steady state (a single NE) for all initial state close to it Global stable if from every starting state Not always converge – circling effect Extensive Game Example: player 1 has choice C and D player 2 has choice E (2, 1) / F (3, 0) for C player 2 has choice G (0, 2) / H (1, 3) for D.   EG EH FG FH C 2, 1 2, 1 3, 0 3, 0 D 0, 2 1, 3 0, 2 1, 3 EG ← (E or F) and (G or H) if you choose C, I choose E, if you choose D, I choose G if player 1 have 3 choices C, D and I, then we need to use three letters to denote a strategy of player 2 Subgame Perfect (Nash) Equilibrium A strategy profile is a subgame perfect equilibrium if it is an equilibrium for every subgame subgame perfection will remove noncredible threats Potential Game Use one global function $\Phi(s): S \rightarrow R $ to replace $N$ payoff functions $u_i(s)$ for each player $i$. $\Phi$ assigns a real value for every $s \in S$ ordinal potential function: $u_i(x, s_{−i}) − u_i(z, s_{−i}) &gt; 0 \Leftrightarrow \Phi(x, s_{−i}) − Φ(z, s_{−i}) &gt; 0, \forall x, z \in S_i$ exact potential function: $u_i(x, s_{−i}) − u_i(z, s_{−i}) = \Phi(x, s_{−i}) − Φ(z, s_{−i}) &gt; 0, \forall x, z \in S_i$ Every finite ordinal potential game has at least one pure strategy Nash equilibrium. The global maximum of an ordinal potential function is a pure strategy Nash equilibrium there may also be other pure strategy Nash equilibria corresponding to local maxima Path / improvement path In every finite ordinal potential game, every improvement path is finite. Congestion Games Every congestion game is a potential game Learning Nash Equilibria 2-person zero-sum games ($u_1(s_1, s_2) == -u_2(s_1, s_2)$)   M (prob: $y_1$) T (prob: $y_2$) E (prob: $x_1$) 3, -3 -1, 1 S (prob: $x_2$) -2, 2 1, -1 Minimax Game: minimize other player’s best response (max) payoff For column player, expected payoff $V(M) = -3 x_1 + 2 x_2$, $V(T) = x_1 - x_2$ So if $x_1, x_2$ is given, column player will choose the larger one of $V(M)$ and $V(T)$ as best response, his payoff will be $\max(-3 x_1 + 2 x_2, x_1 - x_2)$ Row player should choose $x_1$ and $x_2$ so that column player’s payoff $\max(-3 x_1 + 2 x_2, x_1 - x_2)$ is minimized, that is, $\arg\min_{x_1, x_2} \max(-3 x_1 + 2 x_2, x_1 - x_2)$ Identially, maximize his own payoff $-\max(-3 x_1 + 2 x_2, x_1 - x_2) = \min(3 x_1 - 2 x_2, - x_1 + x_2)$ Min/max operation can be represented by linear programming by using an auxilary variable $z$ and constraint all components larger/smaller than $z$. So the linear programming problem is (note that $z$ should be unbounded so we need to add auxilary variable $z’$ so that $z - z’$ is unbounded, $x_1 + x_2 = 1$ is equalty constraint so we need to transit it to two inequality constraint $x_1 + x_2 \leq 1$ and $x_1 + x_2 \geq 1$) \[\begin{align*} \max \quad &amp; z \\ s.t. \quad 3 x_1 - 2 x_2 &amp;\geq z \\ - x_1 + x_2 &amp;\geq z \\ x_1 + x_2 &amp;= 1 \\ x_1, x_2 &amp;\geq 0 \\ \max \quad &amp; (0, 1, 1, -1, 0, 0)(x_1, x_2, z, z', s_1, s_2)^T \\ s.t. \quad &amp;\begin{pmatrix} 3 &amp; -2 &amp; -1 &amp; 1 &amp; -1 &amp; 0 \\ -1 &amp; 1 &amp; -1 &amp; 1 &amp; 0 &amp; -1\\ 1 &amp; 1 &amp; 0 &amp; 0 &amp; 0 &amp; 0 \end{pmatrix}\begin{pmatrix}x_1\\x_2\\z\\z'\\s_1\\s_2\end{pmatrix} = \begin{pmatrix}0\\0\\1\end{pmatrix}\\ &amp; (x_1, x_2, z, z', s_1, s_2) \geq 0 \\ \max \quad &amp; (0, 1, 1, -1)(x_1, x_2, z, z')^T \\ s.t. \quad &amp;\begin{pmatrix} 3 &amp; -2 &amp; -1 &amp; 1 \\ -1 &amp; 1 &amp; -1 &amp; 1 \\ 1 &amp; 1 &amp; 0 &amp; 0 \\ -1 &amp; -1 &amp; 0 &amp; 0 \\ \end{pmatrix}\begin{pmatrix}x_1\\x_2\\z\\z'\end{pmatrix} \geq \begin{pmatrix}0\\0\\1\\1\end{pmatrix}\\ &amp; (x_1, x_2, z, z') \geq 0 \end{align*}\] Similarly, for the column player, we calculate $\arg\min_{y_1, y_2} \max(3 y_1 - y_2, -2 y_1 + y_2)$ \[\begin{align*} \max \quad &amp; w \\ s.t. \quad -3 y_1 + y_2 &amp;\geq w \\ 2 y_1 - y_2 &amp;\geq w \\ y_1 + y_2 &amp;= 1 \\ y_1, y_2 &amp;\geq 0 \\ \max \quad &amp; (0, 0, 1) (y_1, y_2, w)^T \\ s.t. \quad &amp; \begin{pmatrix} 3 &amp; -1 &amp; 1 \\ -2 &amp; 1 &amp; 1 \\ -1 &amp; -1 &amp; 0 \\ 1 &amp; 1 &amp; 0 \\ -1 &amp; 0 &amp; 0 \\ - &amp; -1 &amp; 0 \end{pmatrix} \begin{pmatrix}y_1\\y_2\\w\end{pmatrix} \leq 0\\ \max \quad &amp; (0, 0, 1, -1) (y_1, y_2, w, w')^T \\ s.t. \quad &amp; \begin{pmatrix} 3 &amp; -1 &amp; 1 &amp; -1 \\ -2 &amp; 1 &amp; 1 &amp; -1 \\ -1 &amp; -1 &amp; 0 &amp; 0\\ 1 &amp; 1 &amp; 0 &amp; 0\\ \end{pmatrix} \begin{pmatrix}y_1\\y_2\\w\\w'\end{pmatrix} \leq 0\\ &amp; (y_1, y_2, w, w') \geq 0 \end{align*}\] Duality General-sum game: linear complementarity problem Algorithm to solve LCP: the Lemke–Howson algorithm]]></summary></entry><entry><title type="html">Introduction to Simplex and Interior-Point Methods for Linear Programming</title><link href="https://snowkylin.github.io/blogs/introduction-to-simplex-and-interior-point.html" rel="alternate" type="text/html" title="Introduction to Simplex and Interior-Point Methods for Linear Programming" /><published>2020-12-31T00:00:00+00:00</published><updated>2020-12-31T00:00:00+00:00</updated><id>https://snowkylin.github.io/blogs/introduction-to-simplex-and-interior-point</id><content type="html" xml:base="https://snowkylin.github.io/blogs/introduction-to-simplex-and-interior-point.html"><![CDATA[<script type="text/x-mathjax-config">

</script>

<style>
table {
    border: 0px;
}
table td {
    border: 0px;
}
</style>

<ul id="markdown-toc">
  <li><a href="#problem-definition" id="markdown-toc-problem-definition">Problem Definition</a></li>
  <li><a href="#the-simplex-method" id="markdown-toc-the-simplex-method">The Simplex Method</a></li>
  <li><a href="#interior-point-method" id="markdown-toc-interior-point-method">Interior-Point Method</a></li>
  <li><a href="#reference" id="markdown-toc-reference">Reference</a></li>
  <li><a href="#note" id="markdown-toc-note">Note</a></li>
</ul>

<h2 id="problem-definition">Problem Definition</h2>

<p>Consider the standard form of linear programming</p>

<p>\begin{equation}
    \min \; c^T x \; \text{subject to} \; Ax = b, x \geq 0
    \label{lp}
\end{equation}</p>

<p>in which $c, x \in \mathbb{R}^n$, $b \in \mathbb{R}^m$, $A \in \mathbb{R}^{m \times n}$. ($n$ is the number of variables, $m$ is the number of constraints)</p>

<p>The Lagrangian function is</p>

<p>\begin{equation}
    \mathcal{L}(x, \lambda, s) = c^T x - \lambda^T(Ax - b) - s^T x
\end{equation}</p>

<p>in which $\lambda \in \mathbb{R}^m$ (lagrange multiplier for equality constraint $Ax = b$), $s \in \mathbb{R}^n$ (lagrange multiplier for inequality constraint $x \geq 0$).</p>

<p>The KKT condition is</p>

\[\begin{align}
    \frac{\partial \mathcal{L}}{\partial x} = c - A^T \lambda - s = 0 \rightarrow \; &amp; A^T \lambda + s = c \label{KKT1}\\
    &amp; Ax = b \label{KKT2}\\
    &amp; x \geq 0 \label{KKT3} \\
    \text{inequality lagrange multiplier} \geq 0 \rightarrow \; &amp; s \geq 0 \label{KKT4} \\
    \text{complementarity condition for inequality} \rightarrow \; &amp; x_i s_i = 0 \label{KKT5}
\end{align}\]

<h2 id="the-simplex-method">The Simplex Method</h2>

<p>Assume that the $m \times n$ matrix $A$ has full row rank, we select $m$ columns of $A$ to form a nonsingular $m \times m$ square matrix $B$ and denote the index set as $\mathcal{B}$ (and the remaining columns as a $m \times (n - m)$ matrix $N$, and corresponding index set $\mathcal{N} = {1, \cdots, n} \backslash \mathcal{B}$). The n-dimensional vectors $x, s$ and $c$ are also partitioned into $m$-dimensional vectors $x_B, s_B, c_B$ and $(n - m)$-dimensional vectors $x_N, s_N, c_N$.</p>

<p>Here $\mathcal{B}$ is called a <em>basis</em>, and a <em>basic feasible point</em> is a feasible point satisfying \eqref{KKT2}, \eqref{KKT3} and $x_N = 0$. From \eqref{KKT2} and the partition, we know that $Ax = (B, N)\begin{pmatrix}x_B\\x_N\end{pmatrix} = Bx_B + Nx_N = b$ <sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup> . Since $x_N = 0$ and $B$ is nonsingular (invertible), we know $x_B = B^{-1}b$.</p>

<p>Assume $x_B = B^{-1}b \geq 0$ (we only deal with basic feasible points), To satisfy the complementary condition \eqref{KKT5}, we need to set $s_B = 0$. Then \eqref{KKT1} can be partitioned as</p>

<p>\begin{equation}
    \begin{pmatrix}B^T\\N^T\end{pmatrix}\lambda + \begin{pmatrix}s_B\\s_N\end{pmatrix} = \begin{pmatrix}c_B\\c_N\end{pmatrix}
\end{equation}</p>

<p>Then we can calculate $\lambda$ and $s_N$ as</p>

\[\begin{align}
    B^T\lambda &amp;= c_B \Rightarrow \lambda = (B^T)^{-1}c_B\\
    N^T\lambda + s_N &amp;= c_N \Rightarrow s_N = c_N - N^T\lambda = c_N - N^T(B^T)^{-1}c_B \label{pricing}
\end{align}\]

<p>The computation of $s_N$ \eqref{pricing} is usually called as <em>pricing</em>.</p>

<p>Now all the value of variables $x (x_B, x_N), \lambda$ and $s (s_B, s_N)$ is known given basis $\mathcal{B}$, concluded below</p>

\[\begin{align*}
    x_B &amp;= B^{-1}b, x_N = 0\\
    \lambda &amp;= (B^T)^{-1}c_B\\
    s_B &amp;= 0, s_N = c_N - (B^{-1}N)^T c_B
\end{align*}\]

<p>By the process of value selection above, our $x, \lambda$ and $s$ satisfy \eqref{KKT1}, \eqref{KKT2} and \eqref{KKT5} (\eqref{KKT3} ($x \geq 0$) is also satisfied since we only deal with basic feasible points). Then the only condition that may not be satisfied is \eqref{KKT4} ($s \geq 0$). In fact, if $s_N$ calculated in \eqref{pricing} satisfy $s_N \geq 0$, then all KKT conditions are satisfied and we get the optimal solution.</p>

<p>However, there may exist some index $q \in \mathcal{N}$ for which $s_q &lt; 0$ (thus \eqref{KKT4} is not satisfied. Notice that $s_B = 0$ so $q$ must be in $\mathcal{N}$), so our current $(x, \lambda, s)$ is still not optimal. A good news is that, by increasing the value of $x_q$ from 0 to certain value $x_q^+$ ($x_B$ will also change to satisfy $Ax = b$, until one of the component of $x_B$ is driven to zero), then the objective will decrease (proof is in (Nocedal and Wright 2006, p. 369)).</p>

<p>Denote the next iteration of $x$ as $x^+$. Since both of them need to satisfy the equality constraint ($Ax = b$ and $Ax^+ = b$), we have</p>

<p>\begin{equation}
    Ax^+ = (B, N)\begin{pmatrix}x^+_B\\0\\\vdots\\x^+_q\\\vdots\\0\end{pmatrix} = Bx^+_B + A_q x^+_q = Bx_B = Ax
\end{equation}</p>

<p>so</p>

<p>\begin{equation}
    x^+_B = x_B - B^{-1}A_q x^+_q\label{x_B_update}
\end{equation}</p>

<p>Then we want to find the maximum $x^+_q$ so that $x^+_B \geq 0$. Denote $d = B^{-1}A_q$ (that is, the solution of $Bd = A_q$), then</p>

\[\begin{align*}
    \forall i \in \mathcal{B}, x_i - d_i x^+_q \geq 0\\
    x^+_q \leq \frac{x_i}{d_i} (d_i &gt; 0)
\end{align*}\]

<p>then $x^+_q = \min_{i \rvert i \in \mathcal{B}, d_i &gt; 0} \frac{x_i}{d_i}$ (use $p$ to denote the minimizing $i$. That is, the component of $x_B$ which is driven to zero). With $x^+_q$ known, we can update $x^+_B$ by \eqref{x_B_update} and update $x^+_N$ by $(0, \cdots, x^+_q, \cdots, 0)$. $\mathcal{B}$ is also updated by adding $q$ and removing $p$.</p>

<script src="https://emgithub.com/embed.js?target=https%3A%2F%2Fgithub.com%2Fsnowkylin%2Flp-algorithm%2Fblob%2Fmaster%2Fsimplex.py&amp;style=github&amp;showBorder=on&amp;showLineNumbers=on&amp;showFileMeta=on"></script>

<h2 id="interior-point-method">Interior-Point Method</h2>

<p>Another way to optimize \eqref{lp}) is to just solve the KKT condition directly. That is, to find a solution that satisfies the three equality conditions \eqref{KKT1}\eqref{KKT2}\eqref{KKT5} while maintaining $(x, s) \geq 0$ (\eqref{KKT3} and \eqref{KKT4}. This is strictly satisfied in the whole solving process so it is called “interior-point” method). i.e., solve</p>

<p>\begin{equation}
    \begin{pmatrix}A^T\lambda + s - c\\Ax - b\\x_i s_i\end{pmatrix} = 0
\end{equation}</p>

<p>Define $F(x, \lambda, s) = \begin{pmatrix}A^T\lambda + s - c\\Ax - b\\x_i s_i\end{pmatrix} = \begin{pmatrix}A^T\lambda + s - c\\Ax - b\\XSe\end{pmatrix}$ (from $\mathbb{R}^{n+m+n}$ to $\mathbb{R}^{n+m+n}$, $X = \text{diag}(x)$, $S = \text{diag}(s)$, $e = (1, \cdots, 1)^T$), then we need to solve the equation $F(x, \lambda, s) = 0$.</p>

<p>We can use Newton’s method to solve this equation (details can be found in Chapter 11 of (Nocedal and Wright 2006)). Given current iterate $z^k = (x^k, \lambda^k, s^k)$, we linearize the function $F$ on point $z^k$ as $m(p) = F(z^k + p) \approx F(z^k) + \nabla F(z^k)^T p$ and solve the approximated equation $m(p) = 0$ to find the step $p$. A tricky part is to different the function $F$ whose input and output are both multi-dimensional vectors (let’s say, $\mathbb{R}^n \rightarrow \mathbb{R}^m$). Actually, this is equivalent to different respecting to each component of the output separately (then we have $m$ $\mathbb{R}^n$ column vectors), and concatenate these vectors as a $n \times m$ matrix. More specifically,</p>

<p>\begin{equation}
    \nabla F(x) = (\nabla F_1(x), \cdots, \nabla F_m(x)) = \begin{pmatrix}
    \frac{\partial F_1}{\partial x_1} &amp; \cdots &amp; \frac{\partial F_m}{\partial x_1} \\<br />
    \vdots &amp;&amp; \vdots \\<br />
    \frac{\partial F_1}{\partial x_n} &amp; \cdots &amp; \frac{\partial F_m}{\partial x_n}
    \end{pmatrix}
\end{equation}</p>

<p>Often, for notational convenience, we prefer to work with the transpose of the matrix (see (Nocedal and Wright 2006, p. 627), that is, $J(x) = \nabla F(x)^T$, which is called <em>Jacobian matrix</em>.</p>

<p>Then the equation $m(p) = 0$ ($\nabla F(z^k)^T p = -F(z^k)$) becomes</p>

\[\begin{align}
    \begin{pmatrix}
        \frac{\partial A^T\lambda + s - c}{\partial x} &amp; \frac{\partial Ax - b}{\partial x} &amp; \frac{\partial XSe}{\partial x} \\
        \frac{\partial A^T\lambda + s - c}{\partial \lambda} &amp; \frac{\partial Ax - b}{\partial \lambda} &amp; \frac{\partial XSe}{\partial \lambda} \\
        \frac{\partial A^T\lambda + s - c}{\partial s} &amp; \frac{\partial Ax - b}{\partial s} &amp; \frac{\partial XSe}{\partial s}
    \end{pmatrix}^T p &amp;= -
    \begin{pmatrix}
        A^T\lambda + s - c\\Ax - b\\XSe
    \end{pmatrix}\nonumber\\
    \begin{pmatrix}
        0 &amp; A^T &amp; S \\
        A &amp; 0 &amp; 0 \\
        I &amp; 0 &amp; X
    \end{pmatrix}^T p &amp;= -
    \begin{pmatrix}
        A^T\lambda + s - c\\Ax - b\\XSe
    \end{pmatrix}\nonumber\\
    \begin{pmatrix}
        0 &amp; A &amp; I \\
        A^T &amp; 0 &amp; 0 \\
        S &amp; 0 &amp; X
    \end{pmatrix} p &amp;= -
    \begin{pmatrix}
        A^T\lambda + s - c\\Ax - b\\XSe
    \end{pmatrix}
\end{align}\]

<p>Solve the equation and we get the (raw) direction $p = (\Delta x, \Delta \lambda, \Delta s)$.</p>

<p>The next step is to find the step length $\alpha$ so that $(x^{k+1}, \lambda^{k+1}, s^{k+1}) = (x^k, \lambda^k, s^k) + \alpha (\Delta x, \Delta \lambda, \Delta s)$. A simple strategy is to find the largest $\alpha$ so that $(x, s) \geq 0$. Thus</p>

\[\begin{align*}
    \forall i = 1 \cdots n, x^k_i + \alpha^{\text{pri}}\Delta x_i \geq 0 &amp;\rightarrow \forall i = 1 \cdots n \text{ and } \Delta x_i &lt; 0, \alpha^{\text{pri}} \leq -\frac{x^k_i}{\Delta x_i}\\
    \forall i = 1 \cdots m, s^k_i + \alpha^{\text{dual}}\Delta s_i \geq 0 &amp;\rightarrow \forall i = 1 \cdots n \text{ and } \Delta s_i &lt; 0, \alpha^{\text{dual}} \leq -\frac{s^k_i}{\Delta s_i}
\end{align*}\]

<p>So $\alpha^{\text{pri}} = \min_{i: \Delta x_i &lt; 0}-\frac{x^k_i}{\Delta x_i}$ and $\alpha^{\text{dual}} = \min_{i: \Delta s_i &lt; 0}-\frac{s^k_i}{\Delta s_i}$. Practical step length will be slightly smaller than this (see (Nocedal and Wright 2006, p. 409)).</p>

<script src="https://emgithub.com/embed.js?target=https%3A%2F%2Fgithub.com%2Fsnowkylin%2Flp-algorithm%2Fblob%2Fmaster%2Finterior_point.py&amp;style=github&amp;showBorder=on&amp;showLineNumbers=on&amp;showFileMeta=on"></script>

<h2 id="reference">Reference</h2>

<ul>
  <li>Nocedal, Jorge, and Stephen J. Wright. <em>Numerical Optimization</em>. 2nd ed. Springer Series in Operations Research. New York: Springer, 2006.</li>
</ul>

<h2 id="note">Note</h2>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>Here we assume $\mathcal{B}$ is the first $m$ indices for easier understanding, which is not necessary. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Snowkylin</name></author><category term="LP" /><category term="Simplex" /><category term="Interior-Point" /><category term="optimization" /><summary type="html"><![CDATA[Problem Definition The Simplex Method Interior-Point Method Reference Note Problem Definition Consider the standard form of linear programming \begin{equation} \min \; c^T x \; \text{subject to} \; Ax = b, x \geq 0 \label{lp} \end{equation} in which $c, x \in \mathbb{R}^n$, $b \in \mathbb{R}^m$, $A \in \mathbb{R}^{m \times n}$. ($n$ is the number of variables, $m$ is the number of constraints) The Lagrangian function is \begin{equation} \mathcal{L}(x, \lambda, s) = c^T x - \lambda^T(Ax - b) - s^T x \end{equation} in which $\lambda \in \mathbb{R}^m$ (lagrange multiplier for equality constraint $Ax = b$), $s \in \mathbb{R}^n$ (lagrange multiplier for inequality constraint $x \geq 0$). The KKT condition is \[\begin{align} \frac{\partial \mathcal{L}}{\partial x} = c - A^T \lambda - s = 0 \rightarrow \; &amp; A^T \lambda + s = c \label{KKT1}\\ &amp; Ax = b \label{KKT2}\\ &amp; x \geq 0 \label{KKT3} \\ \text{inequality lagrange multiplier} \geq 0 \rightarrow \; &amp; s \geq 0 \label{KKT4} \\ \text{complementarity condition for inequality} \rightarrow \; &amp; x_i s_i = 0 \label{KKT5} \end{align}\] The Simplex Method Assume that the $m \times n$ matrix $A$ has full row rank, we select $m$ columns of $A$ to form a nonsingular $m \times m$ square matrix $B$ and denote the index set as $\mathcal{B}$ (and the remaining columns as a $m \times (n - m)$ matrix $N$, and corresponding index set $\mathcal{N} = {1, \cdots, n} \backslash \mathcal{B}$). The n-dimensional vectors $x, s$ and $c$ are also partitioned into $m$-dimensional vectors $x_B, s_B, c_B$ and $(n - m)$-dimensional vectors $x_N, s_N, c_N$. Here $\mathcal{B}$ is called a basis, and a basic feasible point is a feasible point satisfying \eqref{KKT2}, \eqref{KKT3} and $x_N = 0$. From \eqref{KKT2} and the partition, we know that $Ax = (B, N)\begin{pmatrix}x_B\\x_N\end{pmatrix} = Bx_B + Nx_N = b$ 1 . Since $x_N = 0$ and $B$ is nonsingular (invertible), we know $x_B = B^{-1}b$. Assume $x_B = B^{-1}b \geq 0$ (we only deal with basic feasible points), To satisfy the complementary condition \eqref{KKT5}, we need to set $s_B = 0$. Then \eqref{KKT1} can be partitioned as \begin{equation} \begin{pmatrix}B^T\\N^T\end{pmatrix}\lambda + \begin{pmatrix}s_B\\s_N\end{pmatrix} = \begin{pmatrix}c_B\\c_N\end{pmatrix} \end{equation} Then we can calculate $\lambda$ and $s_N$ as \[\begin{align} B^T\lambda &amp;= c_B \Rightarrow \lambda = (B^T)^{-1}c_B\\ N^T\lambda + s_N &amp;= c_N \Rightarrow s_N = c_N - N^T\lambda = c_N - N^T(B^T)^{-1}c_B \label{pricing} \end{align}\] The computation of $s_N$ \eqref{pricing} is usually called as pricing. Now all the value of variables $x (x_B, x_N), \lambda$ and $s (s_B, s_N)$ is known given basis $\mathcal{B}$, concluded below \[\begin{align*} x_B &amp;= B^{-1}b, x_N = 0\\ \lambda &amp;= (B^T)^{-1}c_B\\ s_B &amp;= 0, s_N = c_N - (B^{-1}N)^T c_B \end{align*}\] By the process of value selection above, our $x, \lambda$ and $s$ satisfy \eqref{KKT1}, \eqref{KKT2} and \eqref{KKT5} (\eqref{KKT3} ($x \geq 0$) is also satisfied since we only deal with basic feasible points). Then the only condition that may not be satisfied is \eqref{KKT4} ($s \geq 0$). In fact, if $s_N$ calculated in \eqref{pricing} satisfy $s_N \geq 0$, then all KKT conditions are satisfied and we get the optimal solution. However, there may exist some index $q \in \mathcal{N}$ for which $s_q &lt; 0$ (thus \eqref{KKT4} is not satisfied. Notice that $s_B = 0$ so $q$ must be in $\mathcal{N}$), so our current $(x, \lambda, s)$ is still not optimal. A good news is that, by increasing the value of $x_q$ from 0 to certain value $x_q^+$ ($x_B$ will also change to satisfy $Ax = b$, until one of the component of $x_B$ is driven to zero), then the objective will decrease (proof is in (Nocedal and Wright 2006, p. 369)). Denote the next iteration of $x$ as $x^+$. Since both of them need to satisfy the equality constraint ($Ax = b$ and $Ax^+ = b$), we have \begin{equation} Ax^+ = (B, N)\begin{pmatrix}x^+_B\\0\\\vdots\\x^+_q\\\vdots\\0\end{pmatrix} = Bx^+_B + A_q x^+_q = Bx_B = Ax \end{equation} so \begin{equation} x^+_B = x_B - B^{-1}A_q x^+_q\label{x_B_update} \end{equation} Then we want to find the maximum $x^+_q$ so that $x^+_B \geq 0$. Denote $d = B^{-1}A_q$ (that is, the solution of $Bd = A_q$), then \[\begin{align*} \forall i \in \mathcal{B}, x_i - d_i x^+_q \geq 0\\ x^+_q \leq \frac{x_i}{d_i} (d_i &gt; 0) \end{align*}\] then $x^+_q = \min_{i \rvert i \in \mathcal{B}, d_i &gt; 0} \frac{x_i}{d_i}$ (use $p$ to denote the minimizing $i$. That is, the component of $x_B$ which is driven to zero). With $x^+_q$ known, we can update $x^+_B$ by \eqref{x_B_update} and update $x^+_N$ by $(0, \cdots, x^+_q, \cdots, 0)$. $\mathcal{B}$ is also updated by adding $q$ and removing $p$. Interior-Point Method Another way to optimize \eqref{lp}) is to just solve the KKT condition directly. That is, to find a solution that satisfies the three equality conditions \eqref{KKT1}\eqref{KKT2}\eqref{KKT5} while maintaining $(x, s) \geq 0$ (\eqref{KKT3} and \eqref{KKT4}. This is strictly satisfied in the whole solving process so it is called “interior-point” method). i.e., solve \begin{equation} \begin{pmatrix}A^T\lambda + s - c\\Ax - b\\x_i s_i\end{pmatrix} = 0 \end{equation} Define $F(x, \lambda, s) = \begin{pmatrix}A^T\lambda + s - c\\Ax - b\\x_i s_i\end{pmatrix} = \begin{pmatrix}A^T\lambda + s - c\\Ax - b\\XSe\end{pmatrix}$ (from $\mathbb{R}^{n+m+n}$ to $\mathbb{R}^{n+m+n}$, $X = \text{diag}(x)$, $S = \text{diag}(s)$, $e = (1, \cdots, 1)^T$), then we need to solve the equation $F(x, \lambda, s) = 0$. We can use Newton’s method to solve this equation (details can be found in Chapter 11 of (Nocedal and Wright 2006)). Given current iterate $z^k = (x^k, \lambda^k, s^k)$, we linearize the function $F$ on point $z^k$ as $m(p) = F(z^k + p) \approx F(z^k) + \nabla F(z^k)^T p$ and solve the approximated equation $m(p) = 0$ to find the step $p$. A tricky part is to different the function $F$ whose input and output are both multi-dimensional vectors (let’s say, $\mathbb{R}^n \rightarrow \mathbb{R}^m$). Actually, this is equivalent to different respecting to each component of the output separately (then we have $m$ $\mathbb{R}^n$ column vectors), and concatenate these vectors as a $n \times m$ matrix. More specifically, \begin{equation} \nabla F(x) = (\nabla F_1(x), \cdots, \nabla F_m(x)) = \begin{pmatrix} \frac{\partial F_1}{\partial x_1} &amp; \cdots &amp; \frac{\partial F_m}{\partial x_1} \\ \vdots &amp;&amp; \vdots \\ \frac{\partial F_1}{\partial x_n} &amp; \cdots &amp; \frac{\partial F_m}{\partial x_n} \end{pmatrix} \end{equation} Often, for notational convenience, we prefer to work with the transpose of the matrix (see (Nocedal and Wright 2006, p. 627), that is, $J(x) = \nabla F(x)^T$, which is called Jacobian matrix. Then the equation $m(p) = 0$ ($\nabla F(z^k)^T p = -F(z^k)$) becomes \[\begin{align} \begin{pmatrix} \frac{\partial A^T\lambda + s - c}{\partial x} &amp; \frac{\partial Ax - b}{\partial x} &amp; \frac{\partial XSe}{\partial x} \\ \frac{\partial A^T\lambda + s - c}{\partial \lambda} &amp; \frac{\partial Ax - b}{\partial \lambda} &amp; \frac{\partial XSe}{\partial \lambda} \\ \frac{\partial A^T\lambda + s - c}{\partial s} &amp; \frac{\partial Ax - b}{\partial s} &amp; \frac{\partial XSe}{\partial s} \end{pmatrix}^T p &amp;= - \begin{pmatrix} A^T\lambda + s - c\\Ax - b\\XSe \end{pmatrix}\nonumber\\ \begin{pmatrix} 0 &amp; A^T &amp; S \\ A &amp; 0 &amp; 0 \\ I &amp; 0 &amp; X \end{pmatrix}^T p &amp;= - \begin{pmatrix} A^T\lambda + s - c\\Ax - b\\XSe \end{pmatrix}\nonumber\\ \begin{pmatrix} 0 &amp; A &amp; I \\ A^T &amp; 0 &amp; 0 \\ S &amp; 0 &amp; X \end{pmatrix} p &amp;= - \begin{pmatrix} A^T\lambda + s - c\\Ax - b\\XSe \end{pmatrix} \end{align}\] Solve the equation and we get the (raw) direction $p = (\Delta x, \Delta \lambda, \Delta s)$. The next step is to find the step length $\alpha$ so that $(x^{k+1}, \lambda^{k+1}, s^{k+1}) = (x^k, \lambda^k, s^k) + \alpha (\Delta x, \Delta \lambda, \Delta s)$. A simple strategy is to find the largest $\alpha$ so that $(x, s) \geq 0$. Thus \[\begin{align*} \forall i = 1 \cdots n, x^k_i + \alpha^{\text{pri}}\Delta x_i \geq 0 &amp;\rightarrow \forall i = 1 \cdots n \text{ and } \Delta x_i &lt; 0, \alpha^{\text{pri}} \leq -\frac{x^k_i}{\Delta x_i}\\ \forall i = 1 \cdots m, s^k_i + \alpha^{\text{dual}}\Delta s_i \geq 0 &amp;\rightarrow \forall i = 1 \cdots n \text{ and } \Delta s_i &lt; 0, \alpha^{\text{dual}} \leq -\frac{s^k_i}{\Delta s_i} \end{align*}\] So $\alpha^{\text{pri}} = \min_{i: \Delta x_i &lt; 0}-\frac{x^k_i}{\Delta x_i}$ and $\alpha^{\text{dual}} = \min_{i: \Delta s_i &lt; 0}-\frac{s^k_i}{\Delta s_i}$. Practical step length will be slightly smaller than this (see (Nocedal and Wright 2006, p. 409)). Reference Nocedal, Jorge, and Stephen J. Wright. Numerical Optimization. 2nd ed. Springer Series in Operations Research. New York: Springer, 2006. Note Here we assume $\mathcal{B}$ is the first $m$ indices for easier understanding, which is not necessary. &#8617;]]></summary></entry><entry><title type="html">Introduction to ADMM</title><link href="https://snowkylin.github.io/blogs/introduction-to-ADMM.html" rel="alternate" type="text/html" title="Introduction to ADMM" /><published>2019-12-17T00:00:00+00:00</published><updated>2019-12-17T00:00:00+00:00</updated><id>https://snowkylin.github.io/blogs/introduction-to-ADMM</id><content type="html" xml:base="https://snowkylin.github.io/blogs/introduction-to-ADMM.html"><![CDATA[<script type="text/x-mathjax-config">

</script>

<ul id="markdown-toc">
  <li><a href="#duel-ascent" id="markdown-toc-duel-ascent">Duel Ascent</a></li>
  <li><a href="#method-of-multipliers" id="markdown-toc-method-of-multipliers">Method of Multipliers</a>    <ul>
      <li><a href="#augmented-lagrangian" id="markdown-toc-augmented-lagrangian">Augmented Lagrangian</a></li>
      <li><a href="#selection-of-step-size-alpha" id="markdown-toc-selection-of-step-size-alpha">Selection of step size $\alpha$</a></li>
    </ul>
  </li>
  <li><a href="#alternating-direction-method-of-multipliers-admm" id="markdown-toc-alternating-direction-method-of-multipliers-admm">Alternating Direction Method of Multipliers (ADMM)</a></li>
  <li><a href="#reference" id="markdown-toc-reference">Reference</a></li>
  <li><a href="#note" id="markdown-toc-note">Note</a></li>
</ul>

<h2 id="duel-ascent">Duel Ascent</h2>

<p>Consider the equality-constrained convex optimization problem:</p>

\[\begin{equation}
\begin{split}
    \min \; &amp; f(x) \\
    s.t. \; &amp; Ax = b 
\end{split}\label{eq:primal_problem}
\end{equation}\]

<p>Lagrangian function<sup id="fnref:1" role="doc-noteref"><a href="#fn:1" class="footnote" rel="footnote">1</a></sup></p>

\[\begin{equation*}
    L(x, y) = f(x) + y^T(Ax - b)
\end{equation*}\]

<p>Dual function<sup id="fnref:2" role="doc-noteref"><a href="#fn:2" class="footnote" rel="footnote">2</a></sup></p>

\[\begin{align*}
    g(y) = \min_x L(x, y) &amp;= \min_x (f(x) + y^T Ax - y^T b) \\
    &amp;= \min_x (f(x) + y^T Ax) - y^T b
\end{align*}\]

<p>Dual problem:</p>

\[\begin{align*}
    \max_y \; g(y) \\
\end{align*}\]

<p>So our task is to find the maximum of $g(y)$. In dual ascent method, we use gradient ascend to achieve this. That is:</p>

\[\begin{align*}
    y^{k+1} \leftarrow y^k + \alpha \nabla g(y^k)
\end{align*}\]

<p>Then we need to get the gradient $\nabla g(y)$</p>

\[\begin{align*}
    \nabla g(y) &amp;= \frac{\partial}{\partial y} [\min_x (f(x) + y^T Ax) - y^T b] \\
    &amp;= \frac{\partial}{\partial y} \min_x (f(x) + y^T Ax) - b
\end{align*}\]

<p>Assume that we already have $x^*$ (given $y$) as:</p>

\[\begin{align*}
    x^* \leftarrow \arg \min_x (f(x) + y^T Ax)
\end{align*}\]

<p>Then we can calculate $g(y)$ as:</p>

\[\begin{align*}
    \nabla g(y) &amp;= \frac{\partial}{\partial y} \min_x (f(x) + y^T Ax) - b \\
    &amp;= \frac{\partial}{\partial y} (f(x^*) + y^T Ax^*) - b \\
    &amp;= Ax^* - b
\end{align*}\]

<p>That means, if we have \(x^*\) given, $\nabla g(y)$ is simply $Ax^* - b$. So now we can update $y$ as:</p>

\[\begin{align*}
    y^{k+1} &amp;\leftarrow y^k + \alpha \nabla g(y^k) \\
    &amp;= y^k + \alpha (Ax^* - b)
\end{align*}\]

<p>And this is the dual ascend method to solve $\eqref{eq:primal_problem}$</p>

\[\begin{align*}
    x^* &amp;\leftarrow \arg \min_x (f(x) + (y^k)^T Ax) = \arg \min_x L(x, y^k) \\
    y^{k+1} &amp;\leftarrow y^k + \alpha (Ax^* - b)
\end{align*}\]

<h2 id="method-of-multipliers">Method of Multipliers</h2>

<h3 id="augmented-lagrangian">Augmented Lagrangian</h3>

<p>The dual ascend method is not very robust in practice. $\min_x L(x, y^k)$ can fail when $L$ is unbounded for $x$. e.g., $f(x) = ax + b$. Then we want to add robustness to the method, without assumption of strictly convexity of $f$. Therefore, we consider the <em>augmented Lagrangian</em> as:</p>

\[\begin{align*}
    L_\rho(x, y) &amp;= f(x) + y^T(Ax - b) + \frac{\rho}{2} \| Ax - b\|_2^2 \\
    &amp;= (f(x) + \frac{\rho}{2} \| Ax - b\|_2^2) + y^T(Ax - b)
\end{align*}\]

<p>in which $\rho &gt; 0$ is the penalty parameter. Notice that \(\frac{\rho}{2} \| Ax - b\|_2^2\) is a typical strictly convex function. Therefore, considering $f$ is convex, \(f(x) + \frac{\rho}{2} \| Ax - b\|_2^2\) is also strictly convex. The larger $\rho$ is, the more convex the Lagrangian function will be.</p>

<p>The above augmented Lagrangian can be derived from the following problem</p>

\[\begin{align}
\begin{split}
    \min \; &amp; f(x) + \frac{\rho}{2} \| Ax - b\|_2^2 \\
    s.t. \; &amp; Ax = b
\end{split}\label{eq:modified_primal_problem}
\end{align}\]

<p>This problem is just equaivalent to $\eqref{eq:primal_problem}$, since for all feasible $x$, $Ax = b$, then the added factor \(\frac{\rho}{2} \| Ax - b\|_2^2\) will be zero.</p>

<h3 id="selection-of-step-size-alpha">Selection of step size $\alpha$</h3>

<p>The next question is the selection of the step size $\alpha$. After getting \(x^* = \arg \min_x L_\rho(x, y^k)\), we hope to make a better selection of $\alpha$ so that given $y^k$ and \(x^*\), we can calculate \(y^{k+1} \leftarrow y^k + \alpha^* (Ax^* - b)\) which makes \(x^* = \arg \min_x L(x, y^{k+1})\) given $y^{k+1}$. Which means, if we suddenly switch the problem from $\eqref{eq:modified_primal_problem}$ to $\eqref{eq:primal_problem}$ after getting \(x^*\) and $y^{k+1}$ in step $k$, we do not need to calculate $x$ again since \(x^*\) in the former step $k$ is already the minimum of $L(x, y^{k+1})$. Or we can say, the dual feasibility<sup id="fnref:3" role="doc-noteref"><a href="#fn:3" class="footnote" rel="footnote">3</a></sup> of $\eqref{eq:primal_problem}$ always hold.</p>

<p>The tricky part is, by setting $\alpha^* = \rho$, we can achieve this goal. To see this, let’s assume \(x^* = \arg \min_x L(x, y^{k+1})\) when \(\alpha = \alpha^*\), then</p>

\[\begin{align}
    \frac{\partial L(x, y^{k+1})}{\partial x}\rvert_{x = x^*} &amp;= 0 \nonumber \\
    \frac{\partial}{\partial x}(f(x) + (y^{k+1})^T Ax - (y^{k+1})^T b)\rvert_{x = x^*} &amp;= 0 \nonumber \\
    \nabla_x f(x^*) + A^T(y^k + \alpha^*(Ax^* - b)) &amp;= 0 \label{eq:1.3}
\end{align}\]

<p>That means, if we can find \(\alpha^*\) that satisfy $\eqref{eq:1.3}$ then we can achieve our goal.</p>

<p>We already know that \(x^* = \arg \min_x L_\rho(x, y^k)\), so</p>

\[\begin{align}
    \frac{\partial L_\rho(x, y^k)}{\partial x}\rvert_{x = x^*} &amp;= 0 \nonumber \\
    \frac{\partial}{\partial x}(f(x) + (y^k)^T(Ax - b) + \frac{\rho}{2} \| Ax - b\|_2^2)\rvert_{x = x^*} &amp;= 0 \nonumber \\
    \nabla_x f(x^*) + A^Ty^k + \rho A^T(Ax^* - b) &amp;= 0 \label{eq:1.4}
\end{align}\]

<p>By $\eqref{eq:1.4}$ we can find that if we take \(\alpha^* = \rho\), then $\eqref{eq:1.3}$ is true.</p>

<p>If we apply dual ascend method to our modified problem $\eqref{eq:modified_primal_problem}$ (so the Lagrangian function is $L_\rho$) and set step size $\alpha = \rho$, we get the method of multipliers to solve $\eqref{eq:primal_problem}$:</p>

\[\begin{align*}
    x^* &amp;\leftarrow \arg \min_x L_\rho(x, y^k) \\
    y^{k+1} &amp;\leftarrow y^k + \rho (Ax^* - b)
\end{align*}\]

<h2 id="alternating-direction-method-of-multipliers-admm">Alternating Direction Method of Multipliers (ADMM)</h2>

<p>To decompose the original problem $\eqref{eq:primal_problem}$ into two blocks, we consider the following problem</p>

\[\begin{align}
\begin{split}
    \min &amp;f(x) + g(z) \\
    s.t. &amp;Ax + Bz = c
\end{split}\label{eq:admm_primal_problem}
\end{align}\]

<p>and we have the augmented Lagrangian function</p>

\[\begin{equation*}
    L(x, z, y) = f(x) + g(z) + y^T(Ax + By - c) + \frac{\rho}{2}\|Ax + By - c\|_2^2
\end{equation*}\]

<p>If we directly apply the method of multipliers to the above problem $\eqref{eq:admm_primal_problem}$, we get</p>

\[\begin{align*}
    (x^*, z^*) &amp;\leftarrow \arg \min_{x, z} L_\rho(x, z, y^k) \\
    y^{k+1} &amp;\leftarrow y^k + \rho (Ax^* + Bz^* - c)
\end{align*}\]

<p>Here we jointly minimize $x$ and $z$ in the first step. The trick is, we can consider to minimize $x$ and $z$ sequentially as below</p>

\[\begin{align*}
    x^* &amp;\leftarrow \arg \min_x L_\rho(x, z^k, y^k) \\
    z^* &amp;\leftarrow \arg \min_z L_\rho(x^*, z, y^k) \\
    y^{k+1} &amp;\leftarrow y^k + \rho (Ax^* + Bz^* - c)
\end{align*}\]

<p>then we get ADMM.</p>

<h2 id="reference">Reference</h2>

<ul>
  <li>Boyd, Stephen. “Distributed Optimization and Statistical Learning via the Alternating Direction Method of Multipliers.” Foundations and Trends® in Machine Learning 3, no. 1 (2010): 1–122. <a href="https://doi.org/10.1561/2200000016">https://doi.org/10.1561/2200000016</a>.</li>
  <li>Nocedal, Jorge, and Stephen J. Wright. Numerical Optimization. 2nd ed. Springer Series in Operations Research. New York: Springer, 2006.</li>
</ul>

<h2 id="note">Note</h2>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1" role="doc-endnote">
      <p>See page 330 of (Nocedal and Wright 2006) <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:2" role="doc-endnote">
      <p>See page 344 of (Nocedal and Wright 2006) <a href="#fnref:2" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
    <li id="fn:3" role="doc-endnote">
      <p>If we regard the primal feasibility of $\eqref{eq:primal_problem}$ as $Ax - b = 0$, then the dual feasibility of $\eqref{eq:primal_problem}$ can be regarded as $\nabla_x L(x, y) = 0$. <a href="#fnref:3" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Snowkylin</name></author><category term="ADMM" /><category term="optimization" /><summary type="html"><![CDATA[Duel Ascent Method of Multipliers Augmented Lagrangian Selection of step size $\alpha$ Alternating Direction Method of Multipliers (ADMM) Reference Note Duel Ascent Consider the equality-constrained convex optimization problem: \[\begin{equation} \begin{split} \min \; &amp; f(x) \\ s.t. \; &amp; Ax = b \end{split}\label{eq:primal_problem} \end{equation}\] Lagrangian function1 \[\begin{equation*} L(x, y) = f(x) + y^T(Ax - b) \end{equation*}\] Dual function2 \[\begin{align*} g(y) = \min_x L(x, y) &amp;= \min_x (f(x) + y^T Ax - y^T b) \\ &amp;= \min_x (f(x) + y^T Ax) - y^T b \end{align*}\] Dual problem: \[\begin{align*} \max_y \; g(y) \\ \end{align*}\] So our task is to find the maximum of $g(y)$. In dual ascent method, we use gradient ascend to achieve this. That is: \[\begin{align*} y^{k+1} \leftarrow y^k + \alpha \nabla g(y^k) \end{align*}\] Then we need to get the gradient $\nabla g(y)$ \[\begin{align*} \nabla g(y) &amp;= \frac{\partial}{\partial y} [\min_x (f(x) + y^T Ax) - y^T b] \\ &amp;= \frac{\partial}{\partial y} \min_x (f(x) + y^T Ax) - b \end{align*}\] Assume that we already have $x^*$ (given $y$) as: \[\begin{align*} x^* \leftarrow \arg \min_x (f(x) + y^T Ax) \end{align*}\] Then we can calculate $g(y)$ as: \[\begin{align*} \nabla g(y) &amp;= \frac{\partial}{\partial y} \min_x (f(x) + y^T Ax) - b \\ &amp;= \frac{\partial}{\partial y} (f(x^*) + y^T Ax^*) - b \\ &amp;= Ax^* - b \end{align*}\] That means, if we have \(x^*\) given, $\nabla g(y)$ is simply $Ax^* - b$. So now we can update $y$ as: \[\begin{align*} y^{k+1} &amp;\leftarrow y^k + \alpha \nabla g(y^k) \\ &amp;= y^k + \alpha (Ax^* - b) \end{align*}\] And this is the dual ascend method to solve $\eqref{eq:primal_problem}$ \[\begin{align*} x^* &amp;\leftarrow \arg \min_x (f(x) + (y^k)^T Ax) = \arg \min_x L(x, y^k) \\ y^{k+1} &amp;\leftarrow y^k + \alpha (Ax^* - b) \end{align*}\] Method of Multipliers Augmented Lagrangian The dual ascend method is not very robust in practice. $\min_x L(x, y^k)$ can fail when $L$ is unbounded for $x$. e.g., $f(x) = ax + b$. Then we want to add robustness to the method, without assumption of strictly convexity of $f$. Therefore, we consider the augmented Lagrangian as: \[\begin{align*} L_\rho(x, y) &amp;= f(x) + y^T(Ax - b) + \frac{\rho}{2} \| Ax - b\|_2^2 \\ &amp;= (f(x) + \frac{\rho}{2} \| Ax - b\|_2^2) + y^T(Ax - b) \end{align*}\] in which $\rho &gt; 0$ is the penalty parameter. Notice that \(\frac{\rho}{2} \| Ax - b\|_2^2\) is a typical strictly convex function. Therefore, considering $f$ is convex, \(f(x) + \frac{\rho}{2} \| Ax - b\|_2^2\) is also strictly convex. The larger $\rho$ is, the more convex the Lagrangian function will be. The above augmented Lagrangian can be derived from the following problem \[\begin{align} \begin{split} \min \; &amp; f(x) + \frac{\rho}{2} \| Ax - b\|_2^2 \\ s.t. \; &amp; Ax = b \end{split}\label{eq:modified_primal_problem} \end{align}\] This problem is just equaivalent to $\eqref{eq:primal_problem}$, since for all feasible $x$, $Ax = b$, then the added factor \(\frac{\rho}{2} \| Ax - b\|_2^2\) will be zero. Selection of step size $\alpha$ The next question is the selection of the step size $\alpha$. After getting \(x^* = \arg \min_x L_\rho(x, y^k)\), we hope to make a better selection of $\alpha$ so that given $y^k$ and \(x^*\), we can calculate \(y^{k+1} \leftarrow y^k + \alpha^* (Ax^* - b)\) which makes \(x^* = \arg \min_x L(x, y^{k+1})\) given $y^{k+1}$. Which means, if we suddenly switch the problem from $\eqref{eq:modified_primal_problem}$ to $\eqref{eq:primal_problem}$ after getting \(x^*\) and $y^{k+1}$ in step $k$, we do not need to calculate $x$ again since \(x^*\) in the former step $k$ is already the minimum of $L(x, y^{k+1})$. Or we can say, the dual feasibility3 of $\eqref{eq:primal_problem}$ always hold. The tricky part is, by setting $\alpha^* = \rho$, we can achieve this goal. To see this, let’s assume \(x^* = \arg \min_x L(x, y^{k+1})\) when \(\alpha = \alpha^*\), then \[\begin{align} \frac{\partial L(x, y^{k+1})}{\partial x}\rvert_{x = x^*} &amp;= 0 \nonumber \\ \frac{\partial}{\partial x}(f(x) + (y^{k+1})^T Ax - (y^{k+1})^T b)\rvert_{x = x^*} &amp;= 0 \nonumber \\ \nabla_x f(x^*) + A^T(y^k + \alpha^*(Ax^* - b)) &amp;= 0 \label{eq:1.3} \end{align}\] That means, if we can find \(\alpha^*\) that satisfy $\eqref{eq:1.3}$ then we can achieve our goal. We already know that \(x^* = \arg \min_x L_\rho(x, y^k)\), so \[\begin{align} \frac{\partial L_\rho(x, y^k)}{\partial x}\rvert_{x = x^*} &amp;= 0 \nonumber \\ \frac{\partial}{\partial x}(f(x) + (y^k)^T(Ax - b) + \frac{\rho}{2} \| Ax - b\|_2^2)\rvert_{x = x^*} &amp;= 0 \nonumber \\ \nabla_x f(x^*) + A^Ty^k + \rho A^T(Ax^* - b) &amp;= 0 \label{eq:1.4} \end{align}\] By $\eqref{eq:1.4}$ we can find that if we take \(\alpha^* = \rho\), then $\eqref{eq:1.3}$ is true. If we apply dual ascend method to our modified problem $\eqref{eq:modified_primal_problem}$ (so the Lagrangian function is $L_\rho$) and set step size $\alpha = \rho$, we get the method of multipliers to solve $\eqref{eq:primal_problem}$: \[\begin{align*} x^* &amp;\leftarrow \arg \min_x L_\rho(x, y^k) \\ y^{k+1} &amp;\leftarrow y^k + \rho (Ax^* - b) \end{align*}\] Alternating Direction Method of Multipliers (ADMM) To decompose the original problem $\eqref{eq:primal_problem}$ into two blocks, we consider the following problem \[\begin{align} \begin{split} \min &amp;f(x) + g(z) \\ s.t. &amp;Ax + Bz = c \end{split}\label{eq:admm_primal_problem} \end{align}\] and we have the augmented Lagrangian function \[\begin{equation*} L(x, z, y) = f(x) + g(z) + y^T(Ax + By - c) + \frac{\rho}{2}\|Ax + By - c\|_2^2 \end{equation*}\] If we directly apply the method of multipliers to the above problem $\eqref{eq:admm_primal_problem}$, we get \[\begin{align*} (x^*, z^*) &amp;\leftarrow \arg \min_{x, z} L_\rho(x, z, y^k) \\ y^{k+1} &amp;\leftarrow y^k + \rho (Ax^* + Bz^* - c) \end{align*}\] Here we jointly minimize $x$ and $z$ in the first step. The trick is, we can consider to minimize $x$ and $z$ sequentially as below \[\begin{align*} x^* &amp;\leftarrow \arg \min_x L_\rho(x, z^k, y^k) \\ z^* &amp;\leftarrow \arg \min_z L_\rho(x^*, z, y^k) \\ y^{k+1} &amp;\leftarrow y^k + \rho (Ax^* + Bz^* - c) \end{align*}\] then we get ADMM. Reference Boyd, Stephen. “Distributed Optimization and Statistical Learning via the Alternating Direction Method of Multipliers.” Foundations and Trends® in Machine Learning 3, no. 1 (2010): 1–122. https://doi.org/10.1561/2200000016. Nocedal, Jorge, and Stephen J. Wright. Numerical Optimization. 2nd ed. Springer Series in Operations Research. New York: Springer, 2006. Note See page 330 of (Nocedal and Wright 2006) &#8617; See page 344 of (Nocedal and Wright 2006) &#8617; If we regard the primal feasibility of $\eqref{eq:primal_problem}$ as $Ax - b = 0$, then the dual feasibility of $\eqref{eq:primal_problem}$ can be regarded as $\nabla_x L(x, y) = 0$. &#8617;]]></summary></entry><entry><title type="html">GSoC 2019 Summary</title><link href="https://snowkylin.github.io/blogs/gsoc2019.html" rel="alternate" type="text/html" title="GSoC 2019 Summary" /><published>2019-08-25T00:00:00+00:00</published><updated>2019-08-25T00:00:00+00:00</updated><id>https://snowkylin.github.io/blogs/gsoc2019</id><content type="html" xml:base="https://snowkylin.github.io/blogs/gsoc2019.html"><![CDATA[<ul id="markdown-toc">
  <li><a href="#an-extended-version-of-a-concise-handbook-of-tensorflow" id="markdown-toc-an-extended-version-of-a-concise-handbook-of-tensorflow">An Extended Version of “A Concise Handbook of TensorFlow”</a>    <ul>
      <li><a href="#new-content" id="markdown-toc-new-content">New Content</a></li>
      <li><a href="#updated-content" id="markdown-toc-updated-content">Updated Content</a></li>
      <li><a href="#highlights" id="markdown-toc-highlights">Highlights</a></li>
      <li><a href="#future-works" id="markdown-toc-future-works">Future Works</a></li>
    </ul>
  </li>
  <li><a href="#a-library-of-extended-keras-layers-for-tensorflow-20" id="markdown-toc-a-library-of-extended-keras-layers-for-tensorflow-20">A Library of Extended Keras Layers for TensorFlow 2.0</a>    <ul>
      <li><a href="#new-content-1" id="markdown-toc-new-content-1">New Content</a></li>
      <li><a href="#updated-content-1" id="markdown-toc-updated-content-1">Updated Content</a></li>
      <li><a href="#highlights-1" id="markdown-toc-highlights-1">Highlights</a></li>
      <li><a href="#future-works-1" id="markdown-toc-future-works-1">Future Works</a></li>
    </ul>
  </li>
</ul>

<h2 id="an-extended-version-of-a-concise-handbook-of-tensorflow">An Extended Version of “A Concise Handbook of TensorFlow”</h2>

<p>In August 2018, I released a TensorFlow handbook <a href="/blogs/a-concise-handbook-of-tensorflow.html">“A Concise Handbook of TensorFlow”</a>, which attracted wide attention including Jeff Dean’s retweet. In GSoC 2019, I made significant update and extension of this book for the upcoming release of TensorFlow 2.0.</p>

<p>Read online: <a href="https://tf.wiki">https://tf.wiki</a> (previous version: <a href="https://v1.tf.wiki">https://v1.tf.wiki</a> for comparison)</p>

<p>GitHub: <a href="https://github.com/snowkylin/tensorflow-handbook">https://github.com/snowkylin/tensorflow-handbook</a></p>

<h3 id="new-content">New Content</h3>

<ul>
  <li>TensorFlow Installation
    <ul>
      <li>Hardware requirement and update guide</li>
    </ul>
  </li>
  <li>TensorFlow Models
    <ul>
      <li>New introduction to basic ML concepts including fully connected layer, softmax, cross entropy, Multilayer Perceptron, CNN and RNN.</li>
      <li>Keras pipeline with sequential/functional API, <code class="language-plaintext highlighter-rouge">compile</code>, <code class="language-plaintext highlighter-rouge">fit</code> and <code class="language-plaintext highlighter-rouge">evaluate</code> to build a model</li>
      <li>Custom loss function and metrics</li>
    </ul>
  </li>
  <li>TensorFlow Modules
    <ul>
      <li><code class="language-plaintext highlighter-rouge">tf.data</code>: building a dataset, preprocessing and fetching data</li>
      <li><code class="language-plaintext highlighter-rouge">@tf.function</code> and AutoGraph</li>
      <li><code class="language-plaintext highlighter-rouge">tf.config</code> for GPU usage</li>
    </ul>
  </li>
  <li>Deployment
    <ul>
      <li>Export TensorFlow models to SavedModel files</li>
      <li>TensorFlow Serving: installation, deployment and Restful API (with Python and Node.js client)</li>
      <li>TensorFlow Lite (by Jinpeng Zhu)</li>
      <li>TensorFlow.js (by Huan Li)</li>
    </ul>
  </li>
  <li>Large-scale Training and Acceleration
    <ul>
      <li>Distributed TensorFlow (<code class="language-plaintext highlighter-rouge">MirroredStrategy</code> and <code class="language-plaintext highlighter-rouge">MultiWorkerMirroredStrategy</code>)</li>
      <li>TPU for Training (by Huan Li, in progress)</li>
    </ul>
  </li>
  <li>TensorFlow Extensions
    <ul>
      <li>TensorFlow Hub (by Jinpeng Zhu)</li>
      <li>TensorFlow Datasets</li>
      <li>TensorFlow in Swift (by Huan Li, in progress)</li>
      <li>TensorFlow in Julia (by Ziyang Wang)</li>
    </ul>
  </li>
  <li>Appendix
    <ul>
      <li>TensorFlow Docker installation guide for newbies</li>
      <li>TensorFlow on Cloud (with Colab, Google Cloud Platform and Aliyun)</li>
      <li>JupyterLab installation guide</li>
      <li>References</li>
    </ul>
  </li>
</ul>

<p>(Some sections are written by invited domain experts, whose names are attached after the section title. All sections without a name are written by me)</p>

<h3 id="updated-content">Updated Content</h3>

<ul>
  <li>All code samples are updated in compatible with TensorFlow 2.0 beta1.</li>
  <li>Updated installation and GPU environment configuation guide</li>
  <li>Updated basis and model guide with more detailed instructions.</li>
  <li>Additional textboxes for tips and warnings in all the book.</li>
</ul>

<h3 id="highlights">Highlights</h3>

<ul>
  <li>This handbook is serializing on <a href="https://mp.weixin.qq.com/mp/profile_ext?action=home&amp;__biz=MzU1OTMyNDcxMQ==&amp;scene=124#wechat_redirect">TensorFlow official WeChat account</a> and received favorable comments from readers. Two articles have been published below:
    <ul>
      <li><a href="https://mp.weixin.qq.com/s/7rNXFEC5HYe91RJ0-9CKdQ">TensorFlow 2.0 Installation Guide</a> (Aug 16, 2019)</li>
      <li><a href="https://mp.weixin.qq.com/s/6DmpLZ3Nklo17WY84hJYGA">TensorFlow 2.0 basis: Tensor, AutoDiff and Optimizer</a> (Aug 24, 2019)</li>
    </ul>
  </li>
  <li>This handbook will be shown on <a href="https://mp.weixin.qq.com/s/4tb36q01SRYAp_gIamU7TA">“TensorFlow China Roadmap” Activities</a> in Beijing, Shanghai and Shenzhen.</li>
</ul>

<h3 id="future-works">Future Works</h3>

<ul>
  <li>Translation to English (in progress)</li>
  <li>New Topics, including
    <ul>
      <li>TensorFlow on Respberry Pi</li>
      <li>Edge TPU <a href="https://cloud.google.com/edge-tpu/">https://cloud.google.com/edge-tpu/</a></li>
      <li>TensorFlow on Microcontrollers <a href="https://www.tensorflow.org/lite/microcontrollers/overview">https://www.tensorflow.org/lite/microcontrollers/overview</a></li>
    </ul>
  </li>
  <li>Code compatibility check at the time of TensorFlow 2.0’s official release</li>
</ul>

<h2 id="a-library-of-extended-keras-layers-for-tensorflow-20">A Library of Extended Keras Layers for TensorFlow 2.0</h2>

<p>In GSoC 2019, I implemented and updated several well-known neural network models, wrapped as layers in <code class="language-plaintext highlighter-rouge">tf.keras</code>. All of them are compatible with TensorFlow 2.0 beta1 and open-sourced on GitHub.</p>

<p>Currently, I am testing these implemented layers with my mentor to make sure that all of them have satisfactory performance. Once they passed the test, we will pull a request to <a href="https://github.com/tensorflow/addons">tensorflow/addons</a> on GitHub.</p>

<h3 id="new-content-1">New Content</h3>

<ul>
  <li>Graph Neural Networks <a href="https://github.com/snowkylin/gnn">https://github.com/snowkylin/gnn</a>
    <ul>
      <li>Graph Convolutional Network (GCN): <code class="language-plaintext highlighter-rouge">gnn.GCNLayer</code></li>
      <li>Graph Attention Network (GAT): <code class="language-plaintext highlighter-rouge">gnn.GATLayer</code> and <code class="language-plaintext highlighter-rouge">gnn.MultiHeadGATLayer</code></li>
    </ul>
  </li>
</ul>

<h3 id="updated-content-1">Updated Content</h3>

<ul>
  <li>Neural Turing Machines <a href="https://github.com/snowkylin/ntm">https://github.com/snowkylin/ntm</a>
    <ul>
      <li>Neural Turing Machines (NTM): <code class="language-plaintext highlighter-rouge">ntm.ntm_cell_v2.NTMCell</code></li>
      <li>Memory-Augmented Neural Network (MANN): <code class="language-plaintext highlighter-rouge">ntm.mann_cell_v2.MANNCell</code></li>
    </ul>
  </li>
</ul>

<h3 id="highlights-1">Highlights</h3>

<ul>
  <li>Clear implementation focusing on readibility and useability. Easy for researchers to understand and modify.</li>
</ul>

<h3 id="future-works-1">Future Works</h3>

<ul>
  <li>More tests for stability and performance</li>
  <li>Pull request to <a href="https://github.com/tensorflow/addons">tensorflow/addons</a></li>
</ul>]]></content><author><name>Snowkylin</name></author><category term="tensorflow" /><category term="google" /><summary type="html"><![CDATA[An Extended Version of “A Concise Handbook of TensorFlow” New Content Updated Content Highlights Future Works A Library of Extended Keras Layers for TensorFlow 2.0 New Content Updated Content Highlights Future Works An Extended Version of “A Concise Handbook of TensorFlow” In August 2018, I released a TensorFlow handbook “A Concise Handbook of TensorFlow”, which attracted wide attention including Jeff Dean’s retweet. In GSoC 2019, I made significant update and extension of this book for the upcoming release of TensorFlow 2.0. Read online: https://tf.wiki (previous version: https://v1.tf.wiki for comparison) GitHub: https://github.com/snowkylin/tensorflow-handbook New Content TensorFlow Installation Hardware requirement and update guide TensorFlow Models New introduction to basic ML concepts including fully connected layer, softmax, cross entropy, Multilayer Perceptron, CNN and RNN. Keras pipeline with sequential/functional API, compile, fit and evaluate to build a model Custom loss function and metrics TensorFlow Modules tf.data: building a dataset, preprocessing and fetching data @tf.function and AutoGraph tf.config for GPU usage Deployment Export TensorFlow models to SavedModel files TensorFlow Serving: installation, deployment and Restful API (with Python and Node.js client) TensorFlow Lite (by Jinpeng Zhu) TensorFlow.js (by Huan Li) Large-scale Training and Acceleration Distributed TensorFlow (MirroredStrategy and MultiWorkerMirroredStrategy) TPU for Training (by Huan Li, in progress) TensorFlow Extensions TensorFlow Hub (by Jinpeng Zhu) TensorFlow Datasets TensorFlow in Swift (by Huan Li, in progress) TensorFlow in Julia (by Ziyang Wang) Appendix TensorFlow Docker installation guide for newbies TensorFlow on Cloud (with Colab, Google Cloud Platform and Aliyun) JupyterLab installation guide References (Some sections are written by invited domain experts, whose names are attached after the section title. All sections without a name are written by me) Updated Content All code samples are updated in compatible with TensorFlow 2.0 beta1. Updated installation and GPU environment configuation guide Updated basis and model guide with more detailed instructions. Additional textboxes for tips and warnings in all the book. Highlights This handbook is serializing on TensorFlow official WeChat account and received favorable comments from readers. Two articles have been published below: TensorFlow 2.0 Installation Guide (Aug 16, 2019) TensorFlow 2.0 basis: Tensor, AutoDiff and Optimizer (Aug 24, 2019) This handbook will be shown on “TensorFlow China Roadmap” Activities in Beijing, Shanghai and Shenzhen. Future Works Translation to English (in progress) New Topics, including TensorFlow on Respberry Pi Edge TPU https://cloud.google.com/edge-tpu/ TensorFlow on Microcontrollers https://www.tensorflow.org/lite/microcontrollers/overview Code compatibility check at the time of TensorFlow 2.0’s official release A Library of Extended Keras Layers for TensorFlow 2.0 In GSoC 2019, I implemented and updated several well-known neural network models, wrapped as layers in tf.keras. All of them are compatible with TensorFlow 2.0 beta1 and open-sourced on GitHub. Currently, I am testing these implemented layers with my mentor to make sure that all of them have satisfactory performance. Once they passed the test, we will pull a request to tensorflow/addons on GitHub. New Content Graph Neural Networks https://github.com/snowkylin/gnn Graph Convolutional Network (GCN): gnn.GCNLayer Graph Attention Network (GAT): gnn.GATLayer and gnn.MultiHeadGATLayer Updated Content Neural Turing Machines https://github.com/snowkylin/ntm Neural Turing Machines (NTM): ntm.ntm_cell_v2.NTMCell Memory-Augmented Neural Network (MANN): ntm.mann_cell_v2.MANNCell Highlights Clear implementation focusing on readibility and useability. Easy for researchers to understand and modify. Future Works More tests for stability and performance Pull request to tensorflow/addons]]></summary></entry><entry><title type="html">A Concise Handbook of TensorFlow</title><link href="https://snowkylin.github.io/blogs/a-concise-handbook-of-tensorflow.html" rel="alternate" type="text/html" title="A Concise Handbook of TensorFlow" /><published>2018-08-29T00:00:00+00:00</published><updated>2018-08-29T00:00:00+00:00</updated><id>https://snowkylin.github.io/blogs/a-concise-handbook-of-tensorflow</id><content type="html" xml:base="https://snowkylin.github.io/blogs/a-concise-handbook-of-tensorflow.html"><![CDATA[<p><img style="float: right; width: 30%" src="https://snowkylin.github.io/assets/publications/tfhandbook.png" /></p>

<p><strong>A new version of this handbook for TensorFlow 2.0 is available as a GSoC 2019 project. See <a href="/blogs/gsoc2019.html">this blog</a> for details.</strong></p>

<p>This handbook is a concise introduction to TensorFlow based on Eager Execution mode, trying to help researchers and developers get started with TensorFlow quickly with some basic machine learning and Python knowledge. Supported by Google China Developer Relations team and TensorFlow engineering team. Both Chinese and English version are available online for free.</p>

<ul>
  <li><strong>Read Online: <a href="https://v1.tf.wiki">https://v1.tf.wiki</a></strong></li>
  <li>PDF Download:
    <ul>
      <li>English: <a href="https://github.com/snowkylin/TensorFlow-cn/releases">https://github.com/snowkylin/TensorFlow-cn/releases</a></li>
      <li>Chinese: <a href="https://www.tensorflowers.cn/t/6230">https://www.tensorflowers.cn/t/6230</a></li>
    </ul>
  </li>
  <li>Code: <a href="https://github.com/snowkylin/TensorFlow-cn/tree/master/source/_static/code">https://github.com/snowkylin/TensorFlow-cn/tree/master/source/_static/code</a></li>
  <li>GitHub Repo: <a href="https://github.com/snowkylin/TensorFlow-cn">https://github.com/snowkylin/TensorFlow-cn</a> (this is an open-source project!)</li>
</ul>

<p><strong>Update:</strong></p>

<ul>
  <li><strong>Sept. 2018</strong> - Thanks to Jeff Dean’s retweet, recommendation from TensorFlow offical twitter account and engineering lead, as well as support from Google China Developer Relations team, I will write an extended version of this online handbook for publication with three awesome GDEs (Zhuohuan Li, Jingtian Peng and Jinpeng Zhu).</li>
  <li><strong>Sept. 2018</strong> - Start using new domain <code class="language-plaintext highlighter-rouge">tf.wiki</code> donated by my friend Luke Cheng.</li>
  <li><strong>Aug. 2018</strong> - Thanks to three of my friends Zida Jin, Ming and Ji-An Li, the English version of this handbook is ready for release.</li>
</ul>]]></content><author><name>Snowkylin</name></author><category term="tensorflow" /><summary type="html"><![CDATA[A new version of this handbook for TensorFlow 2.0 is available as a GSoC 2019 project. See this blog for details. This handbook is a concise introduction to TensorFlow based on Eager Execution mode, trying to help researchers and developers get started with TensorFlow quickly with some basic machine learning and Python knowledge. Supported by Google China Developer Relations team and TensorFlow engineering team. Both Chinese and English version are available online for free. Read Online: https://v1.tf.wiki PDF Download: English: https://github.com/snowkylin/TensorFlow-cn/releases Chinese: https://www.tensorflowers.cn/t/6230 Code: https://github.com/snowkylin/TensorFlow-cn/tree/master/source/_static/code GitHub Repo: https://github.com/snowkylin/TensorFlow-cn (this is an open-source project!) Update: Sept. 2018 - Thanks to Jeff Dean’s retweet, recommendation from TensorFlow offical twitter account and engineering lead, as well as support from Google China Developer Relations team, I will write an extended version of this online handbook for publication with three awesome GDEs (Zhuohuan Li, Jingtian Peng and Jinpeng Zhu). Sept. 2018 - Start using new domain tf.wiki donated by my friend Luke Cheng. Aug. 2018 - Thanks to three of my friends Zida Jin, Ming and Ji-An Li, the English version of this handbook is ready for release.]]></summary></entry></feed>