Wavefunction
============

The :class:`~qdk_chemistry.data.Wavefunction` class in QDK/Chemistry represents quantum mechanical wavefunctions for molecular systems.
This class provides access to wavefunction coefficients, determinants, reduced density matrices (:term:`RDM`), orbital entropies :cite:`Boguslawski2015`, and other quantum chemical properties.

Overview
--------

A wavefunction in quantum chemistry describes the quantum state of a molecular system.
In QDK/Chemistry, the :class:`~qdk_chemistry.data.Wavefunction` class encapsulates various wavefunction types, from simple single-determinant Hartree-Fock wavefunctions to complex multi-reference wavefunctions.

The class uses a container-based design where different wavefunction types (Slater determinants, configuration interaction, coupled cluster, etc.) are implemented as specialized container classes, while the main :class:`~qdk_chemistry.data.Wavefunction` class provides a unified interface.

Mathematical representation
~~~~~~~~~~~~~~~~~~~~~~~~~~~
Wavefunctions are represented as linear combinations of determinants:

.. math::

   |\Psi\rangle = \sum_I c_I |\Phi_I\rangle

where :math:`c_I` are expansion coefficients and :math:`|\Phi_I\rangle` are Slater determinants.

For post-Hartree-Fock methods like coupled cluster, the wavefunction is expressed in terms of cluster operators:

.. math::

   |\Psi_{CC}\rangle = e^{\hat{T}} |\Phi_0\rangle

where :math:`\hat{T} = \hat{T}_1 + \hat{T}_2 + ...` is the cluster operator and :math:`|\Phi_0\rangle` is the reference determinant.


Container types
---------------

QDK/Chemistry supports different wavefunction container types for various quantum chemistry methods:

Slater determinant container
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Single-determinant wavefunctions (e.g., from Hartree-Fock calculations).

.. tab:: Python API

   .. literalinclude:: ../../../_static/examples/python/wavefunction_container.py
      :language: python
      :start-after: # start-cell-create-slater
      :end-before: # end-cell-create-slater

.. tab:: C++ API

   .. literalinclude:: ../../../_static/examples/cpp/wavefunction_container.cpp
      :language: cpp
      :start-after: // start-cell-create-slater
      :end-before: // end-cell-create-slater

SCI wavefunction container
~~~~~~~~~~~~~~~~~~~~~~~~~~

Sparse multi-determinant wavefunctions for Selected Configuration Interaction methods.

.. tab:: Python API

   .. literalinclude:: ../../../_static/examples/python/wavefunction_container.py
      :language: python
      :start-after: # start-cell-create-sci
      :end-before: # end-cell-create-sci

.. tab:: C++ API

   .. literalinclude:: ../../../_static/examples/cpp/wavefunction_container.cpp
      :language: cpp
      :start-after: // start-cell-create-sci
      :end-before: // end-cell-create-sci

CAS wavefunction container
~~~~~~~~~~~~~~~~~~~~~~~~~~

A multi-determinant wavefunction from Complete Active Space methods (:term:`CASSCF`/:term:`CASCI`).

.. tab:: Python API

   .. literalinclude:: ../../../_static/examples/python/wavefunction_container.py
      :language: python
      :start-after: # start-cell-create-cas
      :end-before: # end-cell-create-cas

.. tab:: C++ API

   .. literalinclude:: ../../../_static/examples/cpp/wavefunction_container.cpp
      :language: cpp
      :start-after: // start-cell-create-cas
      :end-before: // end-cell-create-cas

Amplitude wavefunction container
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

A single container, :class:`~qdk_chemistry.data.AmplitudeContainer`, represents amplitude-based correlated wavefunctions such as :term:`MP2` and coupled cluster.
It stores a reference wavefunction together with T1/T2 excitation amplitudes, and records which correlated method produced them via :class:`~qdk_chemistry.data.AmplitudeType` (``MP2``, ``CCSD``, or ``Unspecified``).
It is pure storage: the amplitudes are supplied by the producing algorithm and are not expanded into a determinant/coefficient representation, so determinant-, coefficient-, and :term:`RDM`-based accessors raise.

The following example tags the amplitudes as :term:`MP2` (T1 is zero for MP2):

.. tab:: Python API

   .. literalinclude:: ../../../_static/examples/python/wavefunction_container.py
      :language: python
      :start-after: # start-cell-create-mp2
      :end-before: # end-cell-create-mp2

.. tab:: C++ API

   .. literalinclude:: ../../../_static/examples/cpp/wavefunction_container.cpp
      :language: cpp
      :start-after: // start-cell-create-mp2
      :end-before: // end-cell-create-mp2

The same container holds coupled cluster amplitudes when tagged as ``CCSD``:

.. tab:: Python API

   .. literalinclude:: ../../../_static/examples/python/wavefunction_container.py
      :language: python
      :start-after: # start-cell-create-cc
      :end-before: # end-cell-create-cc

.. tab:: C++ API

   .. literalinclude:: ../../../_static/examples/cpp/wavefunction_container.cpp
      :language: cpp
      :start-after: // start-cell-create-cc
      :end-before: // end-cell-create-cc

Properties
~~~~~~~~~~

The :class:`~qdk_chemistry.data.Wavefunction` class provides access to various quantum chemical properties. Availability depends on the specific container type:


.. list-table:: Property availability by container type
   :header-rows: 1
   :widths: 30 15 15 15 15 15

   * - Property
     - Slater determinant
     - :term:`CAS`
     - :term:`SCI`
     - :term:`MP2`
     - Coupled cluster

   * - **Coefficients**
     - ✓
     - ✓
     - ✓
     - ✗
     - ✗

   * - **Determinants**
     - ✓
     - ✓
     - ✓
     - ✗
     - ✗

   * - **Electron counts**
     - ✓
     - ✓
     - ✓
     - ✓
     - ✓

   * - **Orbital occupations**
     - ✓
     - ✓
     - ✓
     - ✗
     - ✓

   * - **1-RDMs (spin-dependent)**
     - ✓
     - ✓
     - ✓
     - ✗
     - ✓

   * - **1-RDMs (spin-traced)**
     - ✓
     - ✓
     - ✓
     - ✗
     - ✓

   * - **2-RDMs (spin-dependent)**
     - ✓
     - ✓*
     - ✓*
     - ✗
     - ✓

   * - **2-RDMs (spin-traced)**
     - ✓
     - ✓*
     - ✓*
     - ✗
     - ✓

   * - **Orbital entropies**
     - ✓
     - ✓*
     - ✓*
     - ✗
     - ✓

   * - **T1/T2 amplitudes**
     - ✗
     - ✗
     - ✗
     - ✓
     - ✓

   * - **Overlap calculations**
     - ✗
     - ✓
     - ✗
     - ✗
     - ✗

   * - **Norm calculations**
     - ✓
     - ✓
     - ✗
     - ✗
     - ✗




Legend:

- ✓ Available and implemented

- ✗ Not available (method not implemented)

- ✓* Implemented and available only if 2-RDMs were provided during construction

Accessing wavefunction data
---------------------------

The :class:`~qdk_chemistry.data.Wavefunction` class provides methods to access coefficients, determinants, and derived properties:

.. tab:: Python API

   .. literalinclude:: ../../../_static/examples/python/wavefunction_container.py
      :language: python
      :start-after: # start-cell-access-data
      :end-before: # end-cell-access-data

.. tab:: C++ API

   .. literalinclude:: ../../../_static/examples/cpp/wavefunction_container.cpp
      :language: cpp
      :start-after: // start-cell-access-data
      :end-before: // end-cell-access-data

Accessing cluster amplitudes
----------------------------

For :term:`MP2` and coupled cluster wavefunctions, one can access T1 and T2 cluster amplitudes.

.. tab:: Python API

   .. literalinclude:: ../../../_static/examples/python/wavefunction_container.py
      :language: python
      :start-after: # start-cell-access-amplitudes
      :end-before: # end-cell-access-amplitudes

.. tab:: C++ API

   .. literalinclude:: ../../../_static/examples/cpp/wavefunction_container.cpp
      :language: cpp
      :start-after: // start-cell-access-amplitudes
      :end-before: // end-cell-access-amplitudes

Related classes
---------------

- :doc:`Serialization <serialization>`: Data serialization and deserialization
- :doc:`Settings <../algorithms/settings>`: Configuration settings for algorithms
- :doc:`Active space methods <../algorithms/active_space>`: Active space selection from wavefunctions
- :doc:`Structure <structure>`: Molecular structure that defines the system
- :doc:`Orbitals <orbitals>`: Orbital basis set for the wavefunction
- :doc:`Hamiltonian <hamiltonian>`: Electronic Hamiltonian constructed from wavefunction
- :doc:`ScfSolver <../algorithms/scf_solver>`: Algorithm that produces :term:`SCF` wavefunctions
- :doc:`MCCalculator <../algorithms/mc_calculator>`: Algorithm for multi-configuration wavefunctions

Further reading
---------------

- :doc:`Settings <../algorithms/settings>`: Configuration settings for algorithms
- :doc:`Serialization <../data/serialization>`: Data serialization and deserialization
- :doc:`Active space methods <../algorithms/active_space>`: Active space selection from wavefunctions
