wavepacket

A package for solving Schrödinger and Liouville von Neumann equations.

Submodules

Exceptions

BadFunctionCall

Signals that a function was called incorrectly.

BadGridError

An invalid grid was supplied.

BadStateError

An invalid state was supplied.

ExecutionError

An unrecoverable problem was encountered in foreign code.

InvalidValueError

A function argument was incorrect, for example out of bounds.

Functions

log(→ None)

Prints some data about the state for inspection.

dvr_density(→ wavepacket.typing.RealData)

Returns the density of the input state at the DVR grid points.

fbr_density(→ wavepacket.typing.RealData)

Returns the FBR density of the input state at the FBR grid points.

normalize(→ wavepacket.grid.State)

Normalizes the input state.

orthonormalize(→ list[wavepacket.grid.State])

Orthogonalizes and normalizes a set of linearly independent wave functions.

population(→ float)

Calculates how much a target state is populated in a given state.

trace(→ float)

Returns the trace of the supplied input state.

diagonalize(→ Iterator[tuple[float, ...)

Calculates the eigenstates and -values of an operator.

expectation_value(→ complex)

Calculates the expectation value of an operator for a given state.

Package Contents

exception wavepacket.BadFunctionCall

Bases: Exception

Signals that a function was called incorrectly.

A typical but rare use-case would be a function that was called with incorrect parameters.

exception wavepacket.BadGridError

Bases: Exception

An invalid grid was supplied.

Most often, you attempt an operation between objects that must be defined on the same grid. For example, the addition of two operators defined on different grids is not a useful operation. The grid may also miss required properties, for example an operation may expect a specific degree of freedom type along some index.

exception wavepacket.BadStateError

Bases: Exception

An invalid state was supplied.

Either the state is completely invalid (neither wave function nor density operator), or you supplied the wrong type of state to a function, for example passing a density operator where a wave function was required.

exception wavepacket.ExecutionError

Bases: Exception

An unrecoverable problem was encountered in foreign code.

The main example is the wavepacket.solver.odesolver getting an error back while integrating.

exception wavepacket.InvalidValueError

Bases: Exception

A function argument was incorrect, for example out of bounds.

wavepacket.log(t: float, state: wavepacket.grid.State, precision: int = 6) None

Prints some data about the state for inspection.

The idea is that you call this function during every solver step and get a log with the most important values about the propagation, for example the state trace (if it deviates from one, this may be caused by poor convergence).

Parameters:
tfloat

The time at which you log.

statewp.grid.State

The state to log.

precisionint, default=6

How many decimal places should be printed.

wavepacket.dvr_density(state: wavepacket.grid.State, dof_index: int | None = None) wavepacket.typing.RealData

Returns the density of the input state at the DVR grid points.

The density is returned as a real-valued coefficient array with the same shape as the underlying grid. The density is mostly a dead end: useful for plotting and inspection, but not for further computations.

Note that this function returns the density in DVR, that is, the raw density values without grid weights or such. These are not useful for computations, but can be plotted or otherwise inspected.

Parameters:
statewp.grid.State

The state (wave function or density operator) whose density should be computed.

dof_index: int|None, default=None

If set, return the reduced density, i.e., the density integrated over all degrees of freedom except the one with the given index.

Returns:
wpt.RealData

The coefficient array of the density values at the DVR grid points.

Raises:
wp.BadStateError

If the supplied state is neither a wave function nor a density operator.

IndexError

If the dof_index is out of range.

wavepacket.fbr_density(state: wavepacket.grid.State, dof_index: int | None = None) wavepacket.typing.RealData

Returns the FBR density of the input state at the FBR grid points.

The density is returned as a real-valued coefficient array with the same shape as the underlying grid. The density is mostly a dead end: useful for plotting and inspection, but not for further computations.

Note that this function returns the FBR density, i.e., the coefficients or diagonal when expanding the wave function or density operator in the underlying grid’s basis, respectively.

Parameters:
statewp.grid.State

The state (wave function or density operator) whose FBR density should be computed.

dof_index: int | None, default=None

If set, return the reduced density, i.e., the density integrated over all degrees of freedom except the one with the given index.

Returns:
wpt.RealData

The coefficient array of the FBR density values at the FBR grid points.

Raises:
wp.BadStateError

If the supplied state is neither a wave function nor a density operator.

IndexError

If the dof_index is out of range.

wavepacket.normalize(state: wavepacket.grid.State) wavepacket.grid.State

Normalizes the input state.

Parameters:
statewp.grid.State

The state (wave function or density operator) that should be normalized.

Returns:
wp.grid.State

The normalized input state.

Raises:
wp.BadStateError

If the supplied state is neither a wave function nor a density operator.

wavepacket.orthonormalize(states: collections.abc.Sequence[wavepacket.grid.State]) list[wavepacket.grid.State]

Orthogonalizes and normalizes a set of linearly independent wave functions.

This function does a simple Gram-Schmidt orthogonalization followed by a normalization of the resulting orthogonal vectors. As such, it is not efficient for a large number of vectors, and produces artifacts for linearly dependent vectors.

Parameters:
states: Sequence[wp.grid.State]

The wave functions to orthonormalize. Must be linearly independent. May be empty or contain only one element, in which case the normalized wave function is returned.

Returns:
list[State]

A set of wave functions that span the same subspace as the input, but are normalized and orthogonal. The first element is just the normalized state of the first input, the second element has the first input projected out, the third element has the first two inputs projected out etc.

Raises:
wp.BadGridError

Raised if the input states are defined on different grids.

wp.BadStateError

Raised if any input state is either not a wave function or has zero trace.

wavepacket.population(state: wavepacket.grid.State, target: wavepacket.grid.State) float

Calculates how much a target state is populated in a given state.

The return value is simply the absolute square of the scalar product of the two states. The target state is normalized before the calculation. This operation can be thought of as a shortcut for creating a wp.operator.Projection with the target and calculating the wp.expectation_value() of the input state.

Parameters:
state: wp.grid.State

The state that is projected onto the target state

target: wp.grid.State

The wave function onto which the input state is projected. This function is normalized before use.

Raises:
wp.BadGridError

Raised if the input and the target state are defined on different grids.

wp.BadStateError

Raised if the target is not a wave function.

See also

wavepacket.operator.Projection

For advanced calculations

wavepacket.trace(state: wavepacket.grid.State) float

Returns the trace of the supplied input state.

For density operators, this is the usual trace norm, i.e., sum over the diagonal elements. For wave functions, it is the square of the usual L2 norm.

Parameters:
statewp.grid.State

The state (wave function or density operator) for which to calculate the trace.

Returns:
float

The trace of the input state.

Raises:
wp.BadStateError

If the supplied state is neither a wave function nor a density operator.

wavepacket.diagonalize(op: wavepacket.operator.OperatorBase, t: float | None = None) Iterator[tuple[float, wavepacket.typing.ComplexData]]

Calculates the eigenstates and -values of an operator.

See Calculating eigenstates and -energies of operators for a discussion of this topic.

This function is a wrapper around numpy.linalg.eigh that calculates a matrix representation of the operator transforms the calculated eigenstates into a wp.grid.State for easier consumption, and provides a generator for looping instead of a matrix with all eigenvalues in one go. This function diagonalizes a full, dense operator matrix, so it requires

Typically, you solve the eigenproblem for time-independent operators, but you can also calculate instantaneous states and energies by specifying a time value.

Parameters:
op: wp.operator.OperatorBase

The operator whose eigenstates and -values are calculated.

t: float | None = None

The time at which the operator is evaluated. Required only for time-dependent operators.

Yields:
Tuples consisting of the eigenenergy and the eigenstate of the operator.
The output is sorted by the eigenvalues.
Raises:
wp.InvalidValueError

If no time was supplied for a time-dependent operator

Examples

Iterate over the eigenvalues and -vectors

>>> hamiltonian = ...
>>> for energy, state in wp.diagonalize(hamiltonian):
>>>     print(f'E = {energy}, trace norm = {wp.trace(state)}')
wavepacket.expectation_value(op: wavepacket.operator.OperatorBase, state: wavepacket.grid.State, t: float | None = None) complex

Calculates the expectation value of an operator for a given state.

Parameters:
opwp.operator.OperatorBase

The operator whose expectation value is calculated.

statewp.grid.State

The wave function or density operator that is used for the calculation.

tfloat | None
The time at which the operator should be evaluated.

Only required for time-dependent operators.

Raises:
InvalidValueError

If a time-dependent operator was supplied, but no time value was given.