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});