View source on GitHub |
This is a basic data structure for use in the FQE.
fqe.fqe_data.FqeData(
nalpha: int,
nbeta: int,
norb: int,
fcigraph: Optional[fqe.fci_graph.FciGraph
] = None,
dtype=numpy.complex128
) -> None
Args | |
---|---|
nalpha (int) - the number of alpha electrons nbeta (int) - the number of beta electrons norb (int) - the number of spatial orbitals fcigraph (optional, ...) |
Methods
alpha_map
alpha_map(
iorb: int,
jorb: int
) -> List[Tuple[int, int, int]]
Access the mapping for a singlet excitation from the current sector for alpha orbitals
apply
apply(
array: Tuple['Nparray']
) -> "Nparray"
API for application of dense operators (1- through 4-body operators) to the wavefunction self.
apply_cos_sin
apply_cos_sin(
time: float,
ncoeff: complex,
opa: List[int],
oha: List[int],
opb: List[int],
ohb: List[int]
) -> Tuple['FqeData', 'FqeData']
Utility internal function that performs part of the operations in evolve_inplace_individual_nbody_nontrivial. Isolated because it is also used in the counterpart in FqeDataSet.
apply_diagonal_inplace
apply_diagonal_inplace(
array: "Nparray"
) -> None
Iterate over each element and perform apply operation in place
apply_individual_nbody
apply_individual_nbody(
coeff: complex,
daga: List[int],
undaga: List[int],
dagb: List[int],
undagb: List[int]
) -> "FqeData"
Apply function with an individual operator represented in arrays. It is assumed that the operator is spin conserving
apply_inplace
apply_inplace(
array: Tuple['Nparray', ...]
) -> None
API for application of dense operators (1- through 4-body operators) to the wavefunction self.
apply_inplace_s2
apply_inplace_s2() -> None
Apply the S squared operator to self.
ax_plus_y
ax_plus_y(
sval: complex,
other: "FqeData"
) -> "FqeData"
Scale and add the data in the fqedata structure
= sval*coeff + other
beta_inversion
beta_inversion()
Return the coefficients with an inversion of the beta strings.
beta_map
beta_map(
iorb: int,
jorb: int
) -> List[Tuple[int, int, int]]
Access the mapping for a singlet excitation from the current sector for beta orbitals
calculate_coeff_spin_with_dvec
calculate_coeff_spin_with_dvec(
dvec: Tuple['Nparray', 'Nparray']
) -> "Nparray"
Generate
.. math::
C_I = \sum_J \langle I|a^\dagger_i a_j|J\rangle D^J_{ij}
calculate_dvec_spatial
calculate_dvec_spatial() -> "Nparray"
Generate
.. math:: D^J_{ij} = \sum_I \langle J|a^\dagger_i a_j|I\rangle C_I
using self.coeff as an input
calculate_dvec_spatial_compressed
calculate_dvec_spatial_compressed() -> "Nparray"
Generate
.. math::
D^J_{i<j} = \sum_I \langle J|a^\dagger_i a_j|I\rangle C_I
calculate_dvec_spatial_fixed_j
calculate_dvec_spatial_fixed_j(
jorb: int
) -> "Nparray"
Generate, for a fixed j,
.. math:: D^J_{ij} = \sum_I \langle J|a^\dagger_i a_j|I\rangle C_I
using self.coeff as an input
calculate_dvec_spin
calculate_dvec_spin() -> Tuple['Nparray', 'Nparray']
Generate a pair of
.. math:: D^J_{ij} = \sum_I \langle J|a^\dagger_i a_j|I\rangle C_I
using self.coeff as an input. Alpha and beta are seperately packed in the tuple to be returned
calculate_dvec_spin_fixed_j
calculate_dvec_spin_fixed_j(
jorb: int
) -> "Nparray"
Generate a pair of the following, for a fixed j
.. math:: D^J_{ij} = \sum_I \langle J|a^\dagger_i a_j|I\rangle C_I
using self.coeff as an input. Alpha and beta are seperately packed in the tuple to be returned
conj
conj() -> None
Conjugate the coefficients
diagonal_coulomb
diagonal_coulomb(
diag: "Nparray",
array: "Nparray",
inplace: bool = False
) -> "Nparray"
Iterate over each element and return the scaled wavefunction.
evolve_diagonal
evolve_diagonal(
array: "Nparray",
inplace: bool = False
) -> "Nparray"
Iterate over each element and return the exponential scaled contribution.
evolve_inplace_individual_nbody_nontrivial
evolve_inplace_individual_nbody_nontrivial(
time: float,
coeff: complex,
daga: List[int],
undaga: List[int],
dagb: List[int],
undagb: List[int]
) -> None
This code time-evolves a wave function with an individual n-body
generator which is spin-conserving. It is assumed that hat{T}^2 = 0.
Using :math:TT = 0
and :math:TT^\dagger
is diagonal in the determinant
space, one could evaluate as
.. math:: \exp(-i(T+T^\dagger)t) &= 1 + i(T+T^\dagger)t - \frac{1}{2}(TT^\dagger + T^\dagger T)t^2
- i\frac{1}{6}(TT^\dagger T + T^\dagger TT^\dagger)t^3 + \cdots \\
&= -1 + \cos(t\sqrt{TT^\dagger}) + \cos(t\sqrt{T^\dagger T})
- iT\frac{\sin(t\sqrt{T^\dagger T})}{\sqrt{T^\dagger T} }
- iT^\dagger\frac{\sin(t\sqrt{TT^\dagger})}{\sqrt{TT^\dagger} }
evolve_inplace_individual_nbody_trivial
evolve_inplace_individual_nbody_trivial(
time: float,
coeff: complex,
opa: List[int],
opb: List[int]
) -> None
This is the time evolution code for the cases where individual nbody becomes number operators (hence hat{T}^2 is nonzero) coeff includes parity due to sorting. opa and opb are integer arrays
fill
fill(
value: complex
)
Fills the wavefunction with the value specified
generator
generator()
Iterate over the elements of the sector as alpha string, beta string coefficient
get_aa_tpdm
get_aa_tpdm()
Get the alpha-alpha block of the 2-RDM
tensor[i, j, k, l] =
get_ab_tpdm
get_ab_tpdm()
Get the alpha-beta block of the 2-RDM
tensor[i, j, k, l] =
get_bb_tpdm
get_bb_tpdm()
Get the beta-beta block of the 2-RDM
tensor[i, j, k, l] =
get_fcigraph
get_fcigraph() -> "FciGraph"
Returns the underlying FciGraph object
get_openfermion_rdms
get_openfermion_rdms()
Generate spin-rdms and return in openfermion format
get_spin_opdm
get_spin_opdm()
estimate the alpha-alpha and beta-beta block of the 1-RDM
get_three_pdm
get_three_pdm()
get_three_spin_blocks_rdm
get_three_spin_blocks_rdm()
Generate 3-RDM in the spin-orbital basis.
3-RDM has Sz spin-blocks (aaa, aab, abb, bbb). The strategy is to use this blocking to generate the minimal number of p^ q r^ s t^ u blocks and then generate the other components of the 3-RDM through symmeterization. For example,
p^ r^ t^ q s u = -p^ q r^ s t^ u - d(q, r) p^ t^ s u + d(q, t)p^ r^ s u
- d(s, t)p^ r^ q u + d(q,r)d(s,t)p^ u
It is formulated in this way so we can use the dvec calculation.
Given:
~D(p, j, Ia, Ib)(t, u) = \sum{Ka, Kb}\sum{LaLb}
then: p^ q r^ s t^ u = \sum_{Ia, Ib}D(p, q, Ia, Ib).conj(), ~D(p, j, Ia, Ib)(t, u)
Example:
p, q, r, s, t, u = 5, 5, 0, 4, 5, 1
.. code-block:: python
tdveca, tdvecb = fqe_data._calculate_dvec_spin_with_coeff(dveca[5, 1, :, :])
test_ccc = np.einsum('liab,ab->il', dveca.conj(), tdveca[0, 4, :, :])[5, 5]
lena
lena() -> int
Length of the alpha configuration space
lenb
lenb() -> int
Length of the beta configuration space
n_electrons
n_electrons() -> int
Particle number getter
nalpha
nalpha() -> int
Number of alpha electrons
nbeta
nbeta() -> int
Number of beta electrons
norb
norb() -> int
Number of beta electrons
norm
norm() -> float
Return the norm of the the sector wavefunction
print_sector
print_sector(
pformat=None, threshold=0.0001
)
Iterate over the strings and coefficients and print then using the print format
rdm1
rdm1(
bradata: Optional['FqeData'] = None
) -> "Nparray"
API for calculating 1-particle RDMs given a wave function. When bradata is given, it calculates transition RDMs. Depending on the filling, the code selects an optimal algorithm.
rdm12
rdm12(
bradata: Optional['FqeData'] = None
) -> numpy.ndarray
API for calculating 1- and 2-particle RDMs given a wave function. When bradata is given, it calculates transition RDMs. Depending on the filling, the code selects an optimal algorithm.
rdm123
rdm123(
bradata: Optional['FqeData'] = None,
dvec: "Nparray" = None,
dvec2: "Nparray" = None,
evec2: "Nparray" = None
) -> "Nparray"
Calculates 1- through 3-particle RDMs given a wave function. When bradata is given, it calculates transition RDMs.
rdm1234
rdm1234(
bradata: Optional['FqeData'] = None
) -> "Nparray"
Calculates 1- through 4-particle RDMs given a wave function. When bradata is given, it calculates transition RDMs.
scale
scale(
sval: complex
)
Scale the wavefunction by the value sval
Args | |
---|---|
sval (complex) - value to scale by |
Returns | |
---|---|
nothing - Modifies the wavefunction in place |
set_wfn
set_wfn(
strategy: Optional[str] = None,
raw_data: "Nparray" = numpy.empty(0)
) -> None
Set the values of the fqedata wavefunction based on a strategy
Args | |
---|---|
strategy (string) - the procedure to follow to set the coeffs
raw_data (numpy.array(dim(self.lena(), self.lenb()), dtype=numpy.complex128)) - the values to use if setting from data. If vrange is supplied, the first column in data will correspond to the first index in vrange |
Returns | |
---|---|
nothing - modifies the wavefunction in place |
__getitem__
__getitem__(
key: Tuple[int, int]
) -> complex
Get an item from the fqe data structure by using the knowles-handy pointers.