Two-State Computation
Note
This is a work in progress. This page is a stub, and needs to be completed.
This page will describe how the two-state model is computed, and provide acceptable parameter ranges.
Spectrum Broadening
These docs aren’t yet written! For now, read descriptions from the source docstrings:
- quantumspectra_2024.models.two_state.TwoStateComputation.broaden_peaks(sample_points: Float[Array, 'num_points'], peak_energies: Float[Array, 'num_peaks'], peak_intensities: Float[Array, 'num_peaks'], distribution_broadening: float) Float[Array, 'num_points'][source]
Broadens a set of peaks with given sample points into an absorption spectrum.
This function first computes a set of Gaussian distributions centered at each peak energy, with a specified broadening. Then, each spectrum is scaled by the peak intensity and summed to form the final absorption spectrum.
See compute_gaussians for more information on the Gaussian distributions.
- Parameters:
- sample_pointsFloat[Array, “num_points”]
Sample points at which the absorption spectrum will be computed.
- peak_energiesFloat[Array, “num_peaks”]
Peak energies corresponding to the center of each Gaussian distribution.
- peak_intensitiesFloat[Array, “num_peaks”]
Peak intensities to scale each Gaussian distribution.
- distribution_broadeningfloat
Standard deviation of the Gaussian distributions.
- Returns:
- Float[Array, “num_points”]
Computed absorption spectrum.
- quantumspectra_2024.models.two_state.TwoStateComputation.compute_gaussians(sample_points: Float[Array, 'num_points'], peak_energies: Float[Array, 'num_peaks'], distribution_broadening: float) Float[Array, 'num_points num_peaks'][source]
Computes the Gaussian distributions for a set of sample points and peak energies.
This function calculates the value of Gaussian functions for each combination of sample points and peak energies, considering a specified distribution broadening. It is jax JIT-compiled to improve performance.
- Parameters:
- sample_pointsFloat[Array, “num_points”]
Sample points at which the Gaussian functions will be evaluated. Each point represents a position on the x-axis of the Gaussian distribution.
- peak_energiesFloat[Array, “num_peaks”]
Peak energies corresponding to the mean (center) of each Gaussian distribution. Each peak energy defines a different Gaussian function to be evaluated at the sample points.
- distribution_broadeningfloat
A scalar value representing the standard deviation (sigma) of the Gaussian distributions, which determines the broadening of the distributions. This value is the same for all Gaussian distributions computed by this function.
- Returns:
- Float[Array, “num_points num_peaks”]
Computed Gaussian values for each combination of sample points and peak energies.
- quantumspectra_2024.models.two_state.TwoStateComputation.compute_peaks(eigenvalues: Float[Array, 'matrix_size'], eigenvectors: Float[Array, 'matrix_size matrix_size'], transfer_integral: float, temperature_kelvin: float) tuple[Float[Array, 'num_peaks'], Float[Array, 'num_peaks']][source]
Computes the absorption spectrum peak energies and intensities for a two-state system.
Diagonalized eigenvalues and eigenvectors are first used to compute peak energies and intensities. See compute_peak_energies and compute_peak_intensities for more information.
Intensities are scaled by probability scalars if the temperature is not 0. See compute_peak_probability_scalars for more information.
Energies and intensities are then constrained only to pair combinations between a range of first eigenvectors and all other elevated energy levels. First eigenvector range is 1 with 0 temperature, or 50 with non-zero temperature. See filter_peaks for more information.
- Parameters:
- eigenvaluesFloat[Array, “matrix_size”]
Eigenvalues of the Hamiltonian.
- eigenvectorsFloat[Array, “matrix_size matrix_size”]
Eigenvectors of the Hamiltonian.
- transfer_integralfloat
Transfer integral between the two states.
- temperature_kelvinfloat
System’s temperature in Kelvin.
- Returns:
- tuple[Float[Array, “num_peaks”], Float[Array, “num_peaks”]]
Computed absorption spectrum peak energies and intensities.
- quantumspectra_2024.models.two_state.TwoStateComputation.compute_peak_energies(eigenvalues: Float[Array, 'matrix_size']) Float[Array, 'matrix_size/2 matrix_size'][source]
Compute all raw spectrum peak energy values.
Energy values are the differences between two state’s eigenvalues. This function computes all differences between eigenvalues and returns a matrix of differences. The matrix follows the form where index i,j represents the difference between the ith and jth eigenvalues.
Because only the first state will be used for pairs, only the first half of the differences are necessary and returned.
- Parameters:
- eigenvaluesFloat[Array, “matrix_size”]
Eigenvalues of the Hamiltonian.
- Returns:
- Float[Array, “matrix_size/2 matrix_size”]
difference matrix of eigenvalues.
- quantumspectra_2024.models.two_state.TwoStateComputation.compute_peak_intensities(eigenvectors: Float[Array, 'matrix_size matrix_size'], transfer_integral: float) Float[Array, 'matrix_size/2 matrix_size'][source]
Compute all raw spectrum peak intensity values.
Intensity values are the dot product of two sets of sliced eigenvectors, squared. This function computes all squared dot products between pairs of eigenvectors and returns a matrix of intensities. The matrix follows the form where index i,j represents the intensity between the ith and jth eigenvectors.
Because only the first state will be used for pairs, only the first half of the intensities are necessary and returned.
- The second eigenvalue in the computation is sliced in half depending on transfer_integral value:
if transfer_integral is not 0, the top half of the eigenvectors are used
if transfer_integral is 0, the bottom half of the eigenvectors are used
- Parameters:
- eigenvectorsFloat[Array, “matrix_size matrix_size”]
Eigenvectors of the Hamiltonian.
- transfer_integralfloat
Transfer integral between the two states.
- Returns:
- Float[Array, “matrix_size/2 matrix_size”]
intensity matrix of eigenvectors.
- quantumspectra_2024.models.two_state.TwoStateComputation.compute_peak_probability_scalars(eigenvalues: Float[Array, 'matrix_size'], temperature_wavenumbers: float) Float[Array, 'matrix_size/2'][source]
Computes a probability scalars for peak intensities.
Computes a normalized exponential probability distribution based on the differences between the first half of the eigenvalues and the first eigenvalue, scaled by a given temperature.
This function first calculates the differences between the first half of eigenvalues and the first eigenvalue. Then, it computes the exponential of the negative of these differences, divided by the temperature in wavenumbers. Finally, it normalizes these exponentials to sum to one, forming a probability distribution.
The probability scalars are returned as a vector of the same size as the first half of the eigenvalues. The probability scalars are used to scale the intensities of the peaks in the absorption spectrum.
- Parameters:
- eigenvaluesFloat[Array, “matrix_size”]
Eigenvalues of the Hamiltonian.
- temperature_wavenumbersfloat
Temperature in wavenumbers.
- Returns:
- Float[Array, “matrix_size/2”]
probability scalars for peak intensities.
- quantumspectra_2024.models.two_state.TwoStateComputation.filter_peaks(peak_energies: Float[Array, 'matrix_size/2 matrix_size'], peak_intensities: Float[Array, 'matrix_size/2 matrix_size'], first_eigenvector_range: int) tuple[Float[Array, 'num_peaks'], Float[Array, 'num_peaks']][source]
Filters peak energies and intensities by selecting unique and correct pair combinations and filtering negative values.
This function uses upper-triangular matrix indices to select only peaks that have been computed with unique pair combinations between first eigenvectors in the given first_eigenvector_range and all other elevated energy levels. It also filters out negative energy or intensity values.
- Parameters:
- peak_energiesFloat[Array, “matrix_size/2 matrix_size”]
peak energies computed by compute_peak_energies.
- peak_intensitiesFloat[Array, “matrix_size/2 matrix_size”]
peak intensities computed by compute_peak_intensities.
- first_eigenvector_rangeint
the range of first eigenvectors to consider for pair combinations.
- Returns:
- tuple[Float[Array, “num_peaks”], Float[Array, “num_peaks”]]
filtered peak energies and intensities.
Hamiltonian Model
These docs aren’t yet written! For now, read descriptions from the source docstrings:
- quantumspectra_2024.common.hamiltonian.HamiltonianComputation.diagonalize_matrix(matrix: Float[Array, 'matrix_size matrix_size']) tuple[Float[Array, 'matrix_size'], Float[Array, 'matrix_size matrix_size']][source]
Diagonalizes a matrix and returns the eigenvalues and eigenvectors in a tuple.
- Parameters:
- matrixFloat[Array, “matrix_size matrix_size”]
a matrix to diagonalize.
- Returns:
- tuple[Float[Array, “matrix_size”], Float[Array, “matrix_size matrix_size”]]
tuple containing the eigenvalues and eigenvectors.
- quantumspectra_2024.common.hamiltonian.HamiltonianComputation.build_matrix(state_energies: Float[Array, 'num_states'], transfer_integral: float, mode_basis_sets: Int[Array, 'num_modes'], mode_localities: Bool[Array, 'num_modes'], mode_frequencies: Float[Array, 'num_modes'], mode_state_couplings: Float[Array, 'num_modes num_states']) Float[Array, 'matrix_size matrix_size'][source]
Builds a full Hamiltonian matrix for a system of states and modes.
Hamiltonians are built with a combination of blocks. Each block represents a single state. States along the diagonal are so-called ‘local’ states, while offdiagonal states are ‘nonlocal’. See documentation for build_local_state_block and build_nonlocal_state_block for more information.
- Parameters:
- state_energiesFloat[Array, “num_states”]
energies of all local states.
- transfer_integralfloat
transfer integral between states.
- mode_basis_setsInt[Array, “num_modes”]
basis set size per mode.
- mode_localitiesBool[Array, “num_modes”]
locality of each mode.
- mode_frequenciesFloat[Array, “num_modes”]
frequency per mode.
- mode_state_couplingsFloat[Array, “num_modes num_states”]
coupling per mode and local state.
- Returns:
- Float[Array, “matrix_size matrix_size”]
fully constructed matrix in jax array.
Notes
TODO: * Implement multiple transfer integrals for more than two states.
- quantumspectra_2024.common.hamiltonian.HamiltonianComputation.build_local_state_block(state_index: int, state_energies: Float[Array, 'num_states'], mode_basis_sets: Int[Array, 'num_modes'], mode_localities: Bool[Array, 'num_modes'], mode_frequencies: Float[Array, 'num_modes'], mode_state_couplings: Float[Array, 'num_modes num_states']) Float[Array, 'block_size block_size'][source]
Builds a local state block.
To see how block are built, see build_state_block. To build a local state block, the following steps are taken. * Calculate the state’s diagonal values with calculate_state_local_diagonals. * Calculate the state’s offdiagonal values with calculate_state_offdiagonals. * Build the state block.
- Parameters:
- state_indexint
index of the state.
- state_energiesFloat[Array, “num_states”]
energies of all local states.
- mode_basis_setsInt[Array, “num_modes”]
basis set size per mode.
- mode_localitiesBool[Array, “num_modes”]
locality of each mode.
- mode_frequenciesFloat[Array, “num_modes”]
frequency per mode.
- mode_state_couplingsFloat[Array, “num_modes num_states”]
coupling per mode and local state.
- Returns:
- Float[Array, “block_size block_size”]
constructed matrix block.
- quantumspectra_2024.common.hamiltonian.HamiltonianComputation.build_nonlocal_state_block(state_index: int, transfer_integral: float, mode_basis_sets: Int[Array, 'num_modes'], mode_localities: Bool[Array, 'num_modes'], mode_frequencies: Float[Array, 'num_modes'], mode_state_couplings: Float[Array, 'num_modes num_states'])[source]
Builds a nonlocal state block.
To see how blocks are built, see build_state_block. To build a nonlocal state block, the following steps are taken. * The state’s offdiagonal values are all set to the transfer integral. * Calculate the state’s diagonal values with calculate_state_local_diagonals. * Build the state block.
- Parameters:
- state_indexint
index of the state.
- transfer_integralfloat
transfer integral between states.
- mode_basis_setsInt[Array, “num_modes”]
basis set size per mode.
- mode_localitiesBool[Array, “num_modes”]
locality of each mode.
- mode_frequenciesFloat[Array, “num_modes”]
frequency per mode.
- mode_state_couplingsFloat[Array, “num_modes num_states”]
coupling per mode and local state.
- Returns:
- Float[Array, “block_size block_size”]
constructed matrix block.
- quantumspectra_2024.common.hamiltonian.HamiltonianComputation.build_state_block(all_diagonal_values: Float[Array, 'block_size'], all_mode_offdiagonal_values: tuple[Float[Array, '_']], mode_basis_sets: Float[Array, 'num_modes']) Float[Array, 'block_size block_size'][source]
Builds a single block of the full Hamiltonian matrix for a single state.
- Blocks have the form:
diagonal values go across the main diagonal
- state blocks are broken into inner blocks for each state.
From there, the diagonals one above and below the main diagonal (designated ‘offdiagonals’) are filled with values corresponding to the mode’s offdiagonal components, where the diagonal’s lower index is used in generation. Offdiagonal values are repeated to evenly fill the offdiagonal.
For instance, two modes of basis set 3 will create the following block:
- [ d_0, m_0, 0, n_0, 0, 0, 0, 0, 0
m_0, d_1, m_1, 0, n_0, 0, 0, 0, 0 0, m_1, d_2, 0, 0, n_0, 0, 0, 0 n_0, 0, 0, d_3, m_0, 0, n_1, 0, 0 0, n_0, 0, m_0, d_4, m_1, 0, n_1, 0 0, 0, n_0, 0, m_1, d_5, 0, 0, n_1 0, 0, 0, n_1, 0, 0, d_6, m_0, 0 0, 0, 0, 0, n_1, 0, m_0, d_7, m_1 0, 0, 0, 0, 0, n_1, 0, m_1, d_8 ]
Where d_i is the diagonal value at index i, m_i is the offdiagonal value for the last mode at subindex i n_i is the offdiagonal value for the last mode at subindex i
- Parameters:
- all_diagonal_valuesFloat[Array, “block_size”]
all state diagonal values.
- all_mode_offdiagonal_valuestuple[Float[Array, “_”]]
all offdiagonal values for the state block per mode.
- mode_basis_setsFloat[Array, “num_modes”]
basis set sizes per mode.
- Returns:
- Float[Array, “block_size block_size”]
constructed matrix block.
- quantumspectra_2024.common.hamiltonian.HamiltonianComputation.calculate_state_local_diagonals(state_energy: float, mode_frequencies: Float[Array, 'num_modes'], mode_couplings: Float[Array, 'num_modes'], mode_basis_sets: Int[Array, 'num_modes']) Float[Array, 'block_size'][source]
Calculate all diagonal values for a state block in a single array. Only calculated for local blocks.
Diagonal values are calculated with a sum of contributions from each mode, plus the state energy. Contributions for each mode are summed with all combinations of values between 1 and their basis set size - 1. To see how individual mode contributions are calculated, see calculate_mode_local_diagonal_component.
- Parameters:
- state_energyfloat
energy of the state.
- mode_frequenciesFloat[Array, “num_modes”]
frequencies of each mode.
- mode_couplingsFloat[Array, “num_modes”]
couplings of each mode.
- mode_basis_setsInt[Array, “num_modes”]
basis set size of each mode.
- Returns:
- Float[Array, “block_size”]
all diagonal values for the state block.
- quantumspectra_2024.common.hamiltonian.HamiltonianComputation.calculate_state_offdiagonals(state_locality: bool, mode_basis_sets: Int[Array, 'num_modes'], mode_localities: Bool[Array, 'num_modes'], mode_frequencies: Float[Array, 'num_modes'], mode_couplings: Float[Array, 'num_modes']) tuple[Float[Array, '_mode_offdiagonal_size']][source]
Calculate all unqiue offdiagonal values for a state block per mode. Each mode’s set of offdiagonals is contained in a tuple.
Offdiagonal values are an array of calculated values that range from 1 to the basis set size of the mode - 1. Thus, each array in the tuple will have a length of mode_basis_set. If the mode doesn’t match the locality of the state, the offdiagonals are all set to zero. To see how individual mode offdiagonal values are calculated, see calculate_mode_offdiagonal_component.
- Parameters:
- state_localitybool
the locality of the state.
- mode_basis_setsInt[Array, “num_modes”]
basis set size of each mode.
- mode_localitiesBool[Array, “num_modes”]
locality of each mode.
- mode_frequenciesFloat[Array, “num_modes”]
frequencies of each mode.
- mode_couplingsFloat[Array, “num_modes”]
couplings of each mode.
- Returns:
- tuple[Float[Array, “_mode_offdiagonal_size”]]
all offdiagonal values for the state block per mode.
- quantumspectra_2024.common.hamiltonian.HamiltonianComputation.calculate_mode_local_diagonal_component(component_index: int, mode_frequency: float, mode_coupling: float) float[source]
Computes a single diagonal contribution component for a mode.
- Diagonal contributions are calculated as follows:
The mode frequency is multiplied by the component index plus one half
This value is then multiplied by the square of the mode coupling, divided by two.
- Parameters:
- component_indexint
the index of the component.
- mode_frequencyfloat
the frequency of the mode.
- mode_couplingfloat
the coupling of the mode.
- Returns:
- float
the computed diagonal contribution component.
- quantumspectra_2024.common.hamiltonian.HamiltonianComputation.calculate_mode_offdiagonal_component(component_index: int, mode_frequency: float, mode_coupling: float) float[source]
Computes a single offdiagonal contribution component for a mode.
- Offdiagonal contributions are calculated as follows:
The mode frequency is multiplied by the square root of the component index plus one, divided by two.
This value is then multiplied by the mode coupling.
- Parameters:
- component_indexint
the index of the component.
- mode_frequencyfloat
the frequency of the mode.
- mode_couplingfloat
the coupling of the mode.
- Returns:
- float
the computed offdiagonal contribution component.
- quantumspectra_2024.common.hamiltonian.HamiltonianComputation.outer_sum(*arrays: tuple[Float[Array, '*']]) Float[Array, '*'][source]
Computes the outer sum of multiple JAX arrays.
This function takes multiple JAX arrays as input and computes their outer sum. It starts with the first array and iteratively adds each subsequent array to it in a way that’s similar to computing the outer product, but with summation instead. This is done by reshaping the arrays for broadcasting, ensuring dimensions are aligned correctly for the sum.
- Parameters:
- *arrays: tuple[Float[Array, “*”]]
Variable number of JAX array arguments. Each array should be compatible for broadcasting. There should be at least one array passed to this function.
- Returns:
- Float[Array, “*”]
A JAX array containing the outer sum of the input arrays.
- Raises:
- ValueError
If no arrays are provided as input.
Notes
The function requires at least one input array and all input arrays must be compatible for broadcasting following the JAX rules.
Examples
>>> import jax.numpy as jnp >>> a = jnp.array([1, 2]) >>> b = jnp.array([3, 4]) >>> outer_sum(a, b) DeviceArray([[4, 5], [5, 6]], dtype=int32)