API Reference
Data
Defines the qbmlib.data package.
- class qhbmlib.data.QHBMData(input_qhbm: qhbmlib.inference.qhbm.QHBM)[source]
QuantumData defined by a QHBM.
- expectation(observable: Union[tensorflow.python.framework.ops.Tensor, qhbmlib.models.hamiltonian.Hamiltonian])[source]
See base class docstring.
- class qhbmlib.data.QuantumData[source]
Interface for quantum datasets.
- abstract expectation(observable: Union[tensorflow.python.framework.ops.Tensor, qhbmlib.models.hamiltonian.Hamiltonian])[source]
Take the expectation value of an observable against this dataset.
- Parameters
observable – Hermitian operator to measure. If tf.Tensor, it is of type tf.string with shape [1], result of calling tfq.convert_to_tensor on a list of cirq.PauliSum, [op]. Otherwise, a Hamiltonian.
- Returns
- Scalar tf.Tensor which is the expectation value of observable against
this quantum data source.
Models
Defines the qhbmlib.models package.
- class qhbmlib.models.BernoulliEnergy(*args, **kwargs)[source]
Tensor product of coin flip distributions.
Note that we parameterize using the energy of a spin in a magnetic field, which is offset from the log probability of a typical Bernoulli.
- property logits
Returns the current logits of the distribution.
For our Bernoulli distribution, let $p$ be the probability of bit being 1. In this case, we have $p = frac{e^{theta}}{{e^{theta}+e^{-theta}}}$. Therefore, each independent logit is: $$logit = logfrac{p}{1-p} = logfrac{e^{theta}}{e^{-theta}}
= log{e^{2*theta}} = 2*theta$$
- property post_process
See base class description.
- class qhbmlib.models.BitstringEnergy(*args, **kwargs)[source]
Class for representing an energy function over bitstrings.
Keras Layer which can be interpreted as outputting an unnormalized log-probability for each given bit-string x, written E(x). Hence, this class implicitly defines a probability distribution over all bit-strings given by $$p(x) = frac{exp(-E(x))}{sum_x exp(-E(x))}.$$
Moving to its use in QHBMs: each bit-string can also be interpreted as an index for an entry of the diagonal eigenvalue matrix in the spectral representation of a density operator. Hence, for a QHBM, inference corresponds to sampling computational basis states $|x><x|$ for $x ~ p$, where $p$ is the probability distribution written above.
- property bits
Labels for the bits on which this distribution is supported.
- property energy_layers
List of keras layers which, when stacked, map bitstrings to energies.
This list of layers is where the caller would access model weights to be updated from a secondary model or hypernetwork.
- property num_bits
Number of bits on which this layer acts.
- class qhbmlib.models.DirectQuantumCircuit(*args, **kwargs)[source]
QuantumCircuit with direct map from model variables to circuit params.
- class qhbmlib.models.Hamiltonian(*args, **kwargs)[source]
Diagonalized (spectral) representation of a Hermitian operator.
- class qhbmlib.models.KOBE(*args, **kwargs)[source]
Kth Order Binary Energy function.
- operator_shards(qubits: List[cirq.devices.grid_qubit.GridQubit])[source]
See base class description.
- property post_process
See base class description.
- class qhbmlib.models.PauliMixin[source]
Mixin class to add a Pauli Z representation to BitstringEnergy.
- operator_expectation(expectation_shards: tensorflow.python.framework.ops.Tensor)[source]
Computes the average energy given operator shard expectation values.
- abstract operator_shards(qubits: List[cirq.devices.grid_qubit.GridQubit])[source]
Parameter independent Pauli Z strings to measure.
- Parameters
qubits – List of cirq.GridQubits. objects to measure.
- Returns
- List of PauliSum objects whose expectation values are fed to
operator_expectation to compute average energy.
- abstract property post_process
List of keras layers. Concatenation of these layers yields the trainable map from the operator shard expectations to a single scalar which is the average energy.
- class qhbmlib.models.QAIA(*args, **kwargs)[source]
Quantum circuit defined by a classical energy and a Hamiltonian.
This circuit model is intended for use with VQT.
- class qhbmlib.models.QuantumCircuit(*args, **kwargs)[source]
Class for representing a quantum circuit.
- build(input_shape)[source]
Builds the layers which calculate the values.
input_shape is unused because it is known to be the shape of self._value_layers_inputs.
- property pqc
TFQ tensor representation of the parameterized unitary circuit.
- property qubits
Sorted list of the qubits on which this circuit acts.
- property symbol_names
1D tensor of strings which are the free parameters of the circuit.
- property symbol_values
1D tf.Tensor of floats specifying the current values of the parameters.
This should be structured such that self.symbol_values[i] is the current value of self.symbol_names[i] in self.pqc and self.inverse_pqc.
- property value_layers
List of lists of Keras layers which calculate current parameter values.
This property (and value_layers_inputs) is where the caller would access model weights to be updated from a secondary model or hypernetwork.
- property value_layers_inputs
List of lists of variables which are inputs to value_layers.
This property (and value_layers) is where the caller would access model weights to be updated from a secondary model or hypernetwork.
Inference
Defines the qhbmlib.inference package.
- class qhbmlib.inference.AnalyticEnergyInference(*args, **kwargs)[source]
Uses an explicit categorical distribution to implement parent functions.
- property all_bitstrings
Returns every bitstring.
- property all_energies
Returns the energy of every bitstring.
- property distribution
Categorical distribution set during self._ready_inference.
- class qhbmlib.inference.AnalyticQuantumInference(*args, **kwargs)[source]
Analytic methods for inference on QuantumCircuit objects.
This class uses the TensorFlow Quantum Expectation layer to compute expectation values of observables. It uses adjoint gradients to compute the derivatives of those expectation values.
Why shouldn’t we use the ParameterShift differentiator with this class? First, in this class expectation values of observables are exact irrespective of the chosen differentiator. Second, parameter shift derivatives are exactly equal to the true derivative in the noiseless, exact-expectation regime. Thus using it would just increase computational overhead without gaining additional accuracy.
- class qhbmlib.inference.BernoulliEnergyInference(*args, **kwargs)[source]
Manages inference for a Bernoulli defined by spin energies.
- property distribution
Bernoulli distribution set during self._ready_inference.
- class qhbmlib.inference.EnergyInference(*args, **kwargs)[source]
Provides some default method implementations.
- class qhbmlib.inference.EnergyInferenceBase(*args, **kwargs)[source]
Defines the interface for inference on BitstringEnergy objects.
Let $E$ be the energy function defined by a given BitstringEnergy, and let $X$ be the set of bitstrings in the domain of $E$. Associated with $E$ is a probability distribution $$p(x) = frac{e^{-E(x)}}{sum_{yin X} e^{-E(y)}},$$ which we call the Energy Based Model (EBM) associated with $E$. Inference in this class means estimating quantities of interest relative to the EBM.
- property energy
The energy function which sets the probabilities for this EBM.
- expectation(function)[source]
Returns an estimate of the expectation value of the given function.
- Parameters
function – Mapping from a 2D tensor of bitstrings to a possibly nested structure. The structure must have atomic elements all of which are float tensors with the same batch size as the input bitstrings.
- sample(num_samples: int)[source]
Returns samples from the EBM corresponding to self.energy.
- Parameters
num_samples – Number of samples to draw from the EBM.
- property seed
Current TFP compatible seed controlling sampling behavior.
PRNG seed; see tfp.random.sanitize_seed for details. This seed will be used in the sample method. If None, the seed is updated after every inference call. Otherwise, the seed is fixed.
- property variables_updated
Returns True if tracked variables do not have the checkpointed values.
- class qhbmlib.inference.GibbsWithGradientsInference(*args, **kwargs)[source]
Manages inference using a Gibbs With Gradients kernel.
- class qhbmlib.inference.QHBM(*args, **kwargs)[source]
Methods for inference involving normalized exponentials of Hamiltonians.
We also call the normalized exponential of a Hamiltonian a “thermal state”. Here we formalize some aspects of thermal states, which will be used later to explain particular methods of this class.
# TODO(#119): add reference to updated QHBM paper.
Each method takes as input some modular Hamiltonian $$K_{thetaphi} = U_phi K_theta U_phi^dagger.$$ The [thermal state][1] corresponding to the model is $$ rho_T = Z^{-1} e^{-beta K_{thetaphi}}.$$ For QHBMs, we assume $beta = 1$, effectively absorbing it into the definition of the modular Hamiltonian. Then $rho_T$ can be expanded as $$rho_T = sum_x p_theta(x)U_phiket{x}bra{x}U_phi^dagger,$$ where the probability is given by $$p_theta(x) = tr[exp(-K_theta)]bra{x}exp(-K_theta)ket{x}$$ for $xin{1, ldots, dim(K_{thetaphi})} = mathcal{X}$. Note that each $U_phiket{x}$ is an eigenvector of both $rho_T$ and $K_{thetaphi}$.
Corresponding to this density operator is an [ensemble of quantum states][2]. Using the terms above, we define the particular ensemble $$mathcal{E} = {p_theta(x), U_phiket{x}}_{xinmathcal{X}},$$ also known as the [canonical ensemble][2] corresponding to $rho_T$. Each method of this class implicitly samples from this ensemble, then post-processes to perform a particular inference task.
#### References [1]: Nielsen, Michael A. and Chuang, Isaac L. (2010).
Quantum Computation and Quantum Information. Cambridge University Press.
- [2]: Wilde, Mark M. (2017).
Quantum Information Theory (second edition). Cambridge University Press.
- circuits(num_samples: int)[source]
Draws thermally distributed eigenstates from the model Hamiltonian.
Here we explain the algorithm. First, construct $X$ to be a classical random variable with probability distribution $p_theta(x)$ set by model.e_inference.energy. Then, draw $n = $`num_samples` bitstrings, $S={x_1, ldots, x_n}$, from $X$. For each unique $x_iin S$, set states[i] to the TFQ string representation of $U_phiket{x_i}$, where $U_phi$ is set by self.q_inference.circuit. Finally, set counts[i] equal to the number of times $x_i$ occurs in $S$.
- Parameters
model – The modular Hamiltonian whose normalized exponential is the density operator governing the ensemble of states from which to sample.
num_samples – Number of states to draw from the ensemble.
- Returns
- 1D tf.Tensor of dtype tf.string. Each entry is a TFQ string
representation of an eigenstate of self.modular_hamiltonian.
- counts: 1D tf.Tensor of dtype tf.int32. counts[i] is the number of
times states[i] was drawn from the ensemble.
- Return type
states
- property e_inference
The object used for inference on density operator eigenvalues.
- expectation(observables: Union[tensorflow.python.framework.ops.Tensor, qhbmlib.models.hamiltonian.Hamiltonian])[source]
Estimates observable expectation values against the density operator.
- TODO(#119): add expectation and derivative equations and discussions
from updated paper.
Implicitly sample pure states from the canonical ensemble corresponding to the thermal state defined by self.modular_hamiltonian. For each such state |psi>, estimate the expectation value <psi|op_j|psi> for each ops[j]. Then, average these expectation values over the sampled states.
- Parameters
model – The modular Hamiltonian whose normalized exponential is the density operator against which expectation values will be estimated.
obervables – Hermitian operators to measure. See docstring of QuantumInference.expectation for details.
- Returns
tf.Tensor with shape [n_ops] whose entries are are the sample averaged expectation values of each entry in ops.
- property modular_hamiltonian
The modular Hamiltonian defining this QHBM.
- property q_inference
The object used for inference on density operator eigenvectors.
- class qhbmlib.inference.SampledQuantumInference(*args, **kwargs)[source]
Sampling methods for inference on QuantumCircuit objects.
This class uses the TensorFlow Quantum SampledExpectation and Sample layers to compute expectation values of observables. It uses parameter shift gradients to compute derivatives of those expectation values.
- qhbmlib.inference.density_matrix(model: qhbmlib.models.hamiltonian.Hamiltonian)[source]
Returns the thermal state corresponding to a modular Hamiltonian.
Given a modular Hamiltonian $K_{thetaphi} = U_phi K_theta U_phi^dagger$, the corresponding thermal state is
- begin{align*}
rho &= (text{tr}[e^{-K_{thetaphi}}])^{-1} e^{-K_{thetaphi}} \&= Z_theta^{-1} U_phi e^{-K_theta} U_phi^dagger \&= U_phi P_theta U_phi^dagger
end{align*} where we defined the diagonal matrix $P_theta$ as $$
- langle x|P_theta|yrangle = begin{cases}
p_theta(x), & text{if}x = y \ 0, & text{otherwise}
end{cases}
$$ Continuing, using the definition of matrix multiplication, we have begin{align*}
end{align*}
- Parameters
model – Modular Hamiltonian whose corresponding thermal state is the density matrix to be calculated.
- qhbmlib.inference.fidelity(model: qhbmlib.models.hamiltonian.Hamiltonian, sigma: tensorflow.python.framework.ops.Tensor)[source]
Calculate the fidelity between a QHBM and a density matrix.
Definition of the fidelity between two quantum states $rho$ and $sigma$ is $$ F(rho, sigma) = left(text{tr}sqrt{sqrt{rho}sigmasqrt{rho}}right)^2. $$ When the first argument is a QHBM, we can write $$
$$ By the definition of matrix functions, we can pull the unitaries outside the square root, and use cyclicity of trace to remove them. Then we have $$
$$ Let $omega = sqrt{K_theta}U_phi^daggersigma U_phisqrt{K_theta}$, and let $WD W^dagger$ be a unitary diagonalization of $omega$. Note that $U_phi^daggersigma U_phi$ is Hermitian since it is a unitary conjugation of a Hermitian matrix. Also, for Hermitian matrices A and B, we have $$
- (ABA)^dagger = (BA)^dagger A^dagger
= A^dagger B^dagger A^dagger = ABA.
$$ Therefore $ABA$ is also Hermitian. Thus $omega$ is Hermitian, which allows the use of faster eigenvalue finding routines. Then we have $$
- F(rho, sigma) = left(text{tr}sqrt{D}right)^2
= left(sum_isqrt{D_{ii}}right)^2.
$$
- Parameters
model – Modular Hamiltonian whose corresponding thermal state is to be compared to sigma, as the left density matrix in fidelity.
sigma – 2-D tf.Tensor of a numeric dtype representing the right density matrix in the fidelity calculation.
- Returns
- A scalar tf.Tensor which is the fidelity between the density matrix
represented by this QHBM and sigma.
- qhbmlib.inference.probabilities(input_energy: qhbmlib.models.energy.BitstringEnergy)[source]
Returns the probabilities of the EBM.
- Parameters
input_energy – The energy function defining the EBM.
- qhbmlib.inference.qmhl(data: qhbmlib.data.quantum_data.QuantumData, input_qhbm: qhbmlib.inference.qhbm.QHBM)[source]
Calculate the QMHL loss of the QHBM against the quantum data.
See equation 21 in the appendix.
- Parameters
data – The data mixed state to learn.
input_qhbm – QHBM being trained to approximate data.
- Returns
The quantum cross-entropy between the data and the model.
- qhbmlib.inference.unitary(input_circuit: qhbmlib.models.circuit.QuantumCircuit)[source]
Returns the unitary matrix corresponding to the given circuit.
- Parameters
input_circuit – Quantum circuit whose unitary matrix is to be calculated.
- qhbmlib.inference.vqt(input_qhbm: qhbmlib.inference.qhbm.QHBM, target_hamiltonian: Union[tensorflow.python.framework.ops.Tensor, qhbmlib.models.hamiltonian.Hamiltonian], beta: tensorflow.python.framework.ops.Tensor)[source]
Computes the VQT loss of a given QHBM and Hamiltonian.
This function is differentiable within a tf.GradientTape scope.
- Parameters
input_qhbm – Inference methods for the model.
target_hamiltonian – The Hamiltonian whose thermal state is to be learned. If it is a tf.Tensor, it is of type tf.string with shape [1], result of calling tfq.convert_to_tensor on a list of cirq.PauliSum, [op]. Otherwise, a Hamiltonian.
beta – A scalar tf.Tensor which is the inverse temperature at which the loss is calculated.
- Returns
The VQT loss.
Utils
Utilities used across more than one file.
- qhbmlib.utils.expand_unique_results(y, idx)[source]
Inverse of unique_bitstrings_with_counts.
- Parameters
y – Values to pick according to idx.
idx – The index at which to place each value of y in the output.
- Returns
tf.Tensor such that expanded[i] == y[idx[i]].
- Return type
expanded
- qhbmlib.utils.unique_bitstrings_with_counts(bitstrings, out_idx=tf.int32)[source]
Extract the unique bitstrings in the given bitstring tensor.
- Parameters
bitstrings – 2-D tf.Tensor, interpreted as a list of bitstrings.
out_idx – An optional tf.DType from: tf.int32, tf.int64. Defaults to tf.int32. Specifies the type of count output.
- Returns
- 2-D tf.Tensor of same dtype as bitstrings, containing the unique
0-axis entries of bitstrings.
idx: The index of each value of the input in the unique output y. count: 1-D tf.Tensor of dtype out_idx such that count[i] is the
number of occurences of y[i] in bitstrings.
- Return type
y
- qhbmlib.utils.weighted_average(counts: tensorflow.python.framework.ops.Tensor, values: tensorflow.python.framework.ops.Tensor)[source]
Returns the weighted average of input values.
Subtensor i of values is multiplied by counts[i] resulting in a weighted version of values; the mean is then taken across the first dimension.
- Parameters
counts – Non-negative integers of shape [batch_size].
values – Floats of shape [batch_size, …].
- Returns
Tensor of shape […] which is the weighted average.