Source code for WaveBlocksND.BasisTransformationWF

r"""The WaveBlocks Project

This file contains the class for basis transformations of wavefunctions
between the canonical basis and the basis spanned by the eigenvectors
of the potential.

@author: R. Bourquin
@copyright: Copyright (C) 2012 R. Bourquin
@license: Modified BSD License
"""

from __future__ import absolute_import

import numpy

from WaveBlocksND.BasisTransformation import BasisTransformation

__all__ = ["BasisTransformationWF"]


[docs]class BasisTransformationWF(BasisTransformation): r"""This class implements basis transformations of wavefunctions :math:`\psi(x)` between the canonical basis of and the basis :math:`\Lambda(x)` spanned by the eigenvectors :math:`\nu_i(x)` of the potential :math:`V(x)`. """
[docs] def __init__(self, potential, grid=None): r"""Create a new :py:class:`BasisTransformation` instance for a given potential matrix :math:`V(x)`. :param potential: The potential underlying the basis transformation. :type potential: A :py:class:`MatrixPotential` instance. :param grid: The grid. :type grid: A :py:class:`Grid` subclass instance. """ # Keep a reference to the potential self._potential = potential # Precompute eigenvectors is case it is necessary self._potential.calculate_eigenvectors() if grid is not None: self.set_grid(grid)
[docs] def set_grid(self, grid): r"""Set the grid :math:`\Gamma` containing the nodes :math:`\gamma` on which the wavefunction :math:`\psi` was evaluated. The :math:`N` eigenvectors :math:`\nu_i` will be evaluated on the same grid nodes. :param grid: The grid :type grid: A :py:class:`Grid` subclass instance. """ # Keep a reference to the grid self._grid = grid # Evaluate the eigenvectors of the potential self._ev = self._potential.evaluate_eigenvectors_at(grid)
[docs] def transform_to_canonical(self, wavefunction): r"""Transform the evaluated wavefunction :math:`\psi(\Gamma)` given in the eigenbasis to the canonical basis. :param wavefunction: The wavefunction to transform. :type wavefunction: A :py:class:`WaveFunction` instance. :return: Another :py:class:`WaveFunction` instance containing the transformed wavefunction :math:`\psi^\prime(\Gamma)`. """ # No transformation for potentials with a single energy level. # The canonical and eigenbasis are identical here. if self._potential.get_number_components() == 1: return # Unpack the values from the wavefunction values = wavefunction.get_values() # Reshape to match eigenvectores oshapes = [value.shape for value in values] values = [value.flatten() for value in values] # The basis transformation, essentially a matrix multiplication N = wavefunction.get_number_components() result = [] for i in range(N): tmp = numpy.zeros(values[0].shape, dtype=numpy.complexfloating) for j in range(N): tmp += self._ev[j][i, :] * values[j] result.append(tmp) # Reshape back result = [item.reshape(shape) for item, shape in zip(result, oshapes)] # Pack values back to wavefunction object wavefunction.set_values(result)
[docs] def transform_to_eigen(self, wavefunction): r"""Transform the evaluated wavefunction :math:`\psi^\prime(\Gamma)` given in the canonical basis to the eigenbasis. :param wavefunction: The wavefunction to transform. :type wavefunction: A :py:class:`WaveFunction` instance. :return: Another :py:class:`WaveFunction` instance containing the transformed wavefunction :math:`\psi(\Gamma)`. """ # No transformation for potentials with a single energy level. # The canonical and eigenbasis are identical here. if self._potential.get_number_components() == 1: return # Unpack the values from the wavefunction values = wavefunction.get_values() # Reshape to match eigenvectores oshapes = [value.shape for value in values] values = [value.flatten() for value in values] # The basis transformation, essentially a matrix multiplication N = wavefunction.get_number_components() result = [] for i in range(N): tmp = numpy.zeros(values[0].shape, dtype=numpy.complexfloating) for j in range(N): tmp += self._ev[i][j, :] * values[j] result.append(tmp) # Reshape back result = [item.reshape(shape) for item, shape in zip(result, oshapes)] # Pack values back to wavefunction object wavefunction.set_values(result)