From 8e3277e012d1eabfa2a1c0ea4daae1c0efa510bc Mon Sep 17 00:00:00 2001 From: Eduard Valeyev Date: Mon, 20 May 2024 00:03:25 -0400 Subject: [PATCH] [skip ci] revising README.md (to be continued) most SeQuant LaTeX output will not render correctly in GitHub markdown (seemingly due to GH issues, since MacDown renders it correctly) ... trying workaround from https://github.com/github/markup/issues/1575 --- README.md | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index a04b85ed5..3216e2cfa 100644 --- a/README.md +++ b/README.md @@ -22,11 +22,14 @@ See file INSTALL.md . ## Build harness To use SeQuant from within an existing codebase that has a CMake harness (the only case considered here) it should be sufficient to do this: + ```cmake find_package(SeQuant CONFIG REQUIRED) target_link_libraries(your_executable_or_library_target PUBLIC SeQuant::SeQuant) ``` + It is often desirable to build SeQuant from source within a standalone codebase; this case be done using the FetchContent CMake module as follows: + ```cmake find_package(SeQuant CONFIG) if (NOT TARGET SeQuant::SeQuant) @@ -42,12 +45,14 @@ target_link_libraries(your_executable_or_library_target PUBLIC SeQuant::SeQuant) ## Using +SeQuant is a general-purpose symbolic tensor algebra, but the primary use case is in quantum many-body physics. The following is a brief tutorial on using SeQuant for this purpose. + ### Getting Started To get started let's use SeQuant to apply Wick's theorem to a simple product of elementary (creation and annihilation) fermionic operators: -![a_{p_3} a_{p_4} a^\dagger_{p_1} a^\dagger_{p_2}](doc/images/tut-expr1.svg). +$$a_{p_3} a_{p_4} a^\dagger_{p_1} a^\dagger_{p_2}.$$ This is achieved by the following SeQuant program: @@ -77,17 +82,20 @@ N.B. All _core_ user-facing SeQuant code lives in C++ namespace `sequant`, from Running this program should produce a LaTeX expression for this formula: -![{{a^{}_{{p_3}}}{a^{}_{{p_4}}}{a^{{p_1}}_{}}{a^{{p_2}}_{}}} = { \bigl( - {{a^{{p_1}{p_2}}_{{p_3}{p_4}}}} - {{s^{{p_1}}_{{p_3}}}{s^{{p_2}}_{{p_4}}}} + {{s^{{p_1}}_{{p_3}}}{a^{{p_2}}_{{p_4}}}} - {{s^{{p_1}}_{{p_4}}}{a^{{p_2}}_{{p_3}}}} + {{s^{{p_2}}_{{p_3}}}{s^{{p_1}}_{{p_4}}}} - {{s^{{p_2}}_{{p_3}}}{a^{{p_1}}_{{p_4}}}} + {{s^{{p_2}}_{{p_4}}}{a^{{p_1}}_{{p_3}}}}\bigr) }](doc/images/tut-expr1-result1.svg) +$$ +{{a_ {{p_3}}}{a_ {{p_4}}}{a^{{p_1}}}{a^{{p_2}}}} = { \bigl( - {{a^{{p_1}{p_2}}_ {{p_3}{p_4}}}} - {{s^{{p_1}}_ {{p_3}}}{s^{{p_2}}_ {{p_4}}}} + {{s^{{p_1}}_ {{p_3}}}{a^{{p_2}}_ {{p_4}}}} - {{s^{{p_1}}_ {{p_4}}}{a^{{p_2}}_ {{p_3}}}} + {{s^{{p_2}}_ {{p_3}}}{s^{{p_1}}_ {{p_4}}}} - {{s^{{p_2}}_ {{p_3}}}{a^{{p_1}}_ {{p_4}}}} + {{s^{{p_2}}_ {{p_4}}}{a^{{p_1}}_ {{p_3}}}}\bigr) }, +$$ -, where the tensor notation is used to denote elementary and composite _normal_ operators, +where the tensor notation is used to denote elementary and composite _normal_ operators: -![a^p \equiv \, & a_p^\dagger \\ a^{p_1 p_2 \dots p_c}_{q_1 q_2 \dots q_a} \equiv \, & a_{p_1}^\dagger a_{p_2}^\dagger \dots a_{p_c}^\dagger a_{q_a} \dots a_{q_2} a_{q_1}](doc/images/tut-notation-eq1.svg) +$$a^p \equiv a_p^\dagger,$$ -, and +$$ +a^{p_1 p_2 \dots p_c}_ {q_1 q_2 \dots q_a} \equiv a_ {p_1}^\dagger a_ {p_2}^\dagger \dots a_ {p_c}^\dagger a_ {q_a} \dots a_ {q_2} a_ {q_1}, +$$ -![s^p_q \equiv \langle q | p \rangle](doc/images/tut-notation-eq2.svg) -denotes 1-particle state inner products (overlaps). Wick's theorem can of course be applied to directly to products of normal composite operators, e.g, +$s^p_q \equiv \langle q | p \rangle$ denotes inner products (overlaps) of 1-particle states. Wick's theorem can of course be applied directly to products of normal composite operators, e.g, ```c++ auto nop1 = ex(std::array{p1, p2}, std::array{p3, p4}); @@ -104,15 +112,19 @@ denotes 1-particle state inner products (overlaps). Wick's theorem can of course produces -![{{a^{{p_1}{p_2}}_{{p_3}{p_4}}}{a^{\textvisiblespace\,{p_5}}_{{p_6}{p_7}}}} = { \bigl({a^{\textvisiblespace\,{p_1}{p_2}{p_5}}_{{p_3}{p_4}{p_6}{p_7}}} - {{s^{{p_5}}_{{p_4}}}{a^{\textvisiblespace\,{p_1}{p_2}}_{{p_3}{p_6}{p_7}}}} + {{s^{{p_5}}_{{p_3}}}{a^{\textvisiblespace\,{p_1}{p_2}}_{{p_4}{p_6}{p_7}}}}\bigr) }](doc/images/tut-expr2-result1.svg) +$$ +{{a^{{p_1}{p_2}}_ {{p_3}{p_4}}}{a^{␣\,{p_5}}_ {{p_6}{p_7}}}} = { \bigl({a^{␣\,{p_1}{p_2}{p_5}}_ {{p_3}{p_4}{p_6}{p_7}}} - {{s^{{p_5}}_ {{p_4}}}{a^{␣\,{p_1}{p_2}}_ {{p_3}{p_6}{p_7}}}} + {{s^{{p_5}}_ {{p_3}}}{a^{␣\,{p_1}{p_2}}_ {{p_4}{p_6}{p_7}}}}\bigr) }, +$$ -, where `␣` is used in number-nonconserving operators to point out the empty "slots". +where $␣$ is used in number-nonconserving operators to point out the empty "slots". Of course, same manipulations can be used for bosons: -![{{b^{{p_1}{p_2}}_{{p_3}{p_4}}}{b^{{p_5}{p_6}}_{\textvisiblespace\,{p_7}}}} = { \bigl({b^{{p_5}{p_1}{p_2}{p_6}}_{\textvisiblespace\,{p_3}{p_4}{p_7}}} + {{s^{{p_6}}_{{p_3}}}{b^{{p_5}{p_2}{p_1}}_{\textvisiblespace\,{p_4}{p_7}}}} + {{s^{{p_5}}_{{p_3}}}{b^{{p_1}{p_2}{p_6}}_{\textvisiblespace\,{p_4}{p_7}}}} + {{s^{{p_6}}_{{p_4}}}{b^{{p_5}{p_1}{p_2}}_{\textvisiblespace\,{p_3}{p_7}}}} + {{s^{{p_5}}_{{p_4}}}{b^{{p_2}{p_1}{p_6}}_{\textvisiblespace\,{p_3}{p_7}}}} + {{s^{{p_5}}_{{p_3}}}{s^{{p_6}}_{{p_4}}}{b^{{p_1}{p_2}}_{\textvisiblespace\,{p_7}}}} + {{s^{{p_6}}_{{p_3}}}{s^{{p_5}}_{{p_4}}}{b^{{p_2}{p_1}}_{\textvisiblespace\,{p_7}}}}\bigr) }](doc/images/tut-expr3-result1.svg) +$$ +{{b^{{p_1}{p_2}}_ {{p_3}{p_4}}}{b^{{p_5}{p_6}}_ {␣\,{p_7}}}} = { \bigl( {b^{{p_5}{p_1}{p_2}{p_6}}_ {␣\,{p_3}{p_4}{p_7}}} + {{s^{{p_6}}_ {{p_3}}}{b^{{p_5}{p_2}{p_1}}_ {␣\,{p_4}{p_7}}}} + {{s^{{p_5}}_ {{p_3}}}{b^{{p_1}{p_2}{p_6}}_ {␣\,{p_4}{p_7}}}} + {{s^{{p_6}}_ {{p_4}}}{b^{{p_5}{p_1}{p_2}}_ {␣\,{p_3}{p_7}}}} + {{s^{{p_5}}_ {{p_4}}}{b^{{p_2}{p_1}{p_6}}_ {␣\,{p_3}{p_7}}}} + {{s^{{p_5}}_ {{p_3}}}{s^{{p_6}}_ {{p_4}}}{b^{{p_1}{p_2}}_ {␣\,{p_7}}}} + {{s^{{p_6}}_ {{p_3}}}{s^{{p_5}}_ {{p_4}}}{b^{{p_2}{p_1}}_ {␣\,{p_7}}}} \bigr) }, +$$ -, where `b` denotes normal bosonic operators constructed analogously with the normal fermionic operators `a`, is obtained via +where $b$ denotes normal bosonic operators constructed analogously with the normal fermionic operators $a$, is obtained via ```c++ auto nop3 = ex(std::array{p1, p2}, std::array{p3, p4});