Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sample prob var with shot support #561

Merged
merged 79 commits into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
79 commits
Select commit Hold shift + click to select a range
8b61616
init commit with PauliX,Y,Z, Hardmard support
multiphaseCFD Nov 7, 2023
fba9221
add unit tests & sample
multiphaseCFD Nov 8, 2023
5c8c286
add PauliX, Y, Z & Hadamard support
multiphaseCFD Nov 9, 2023
56f02e8
move expval shots to base class
multiphaseCFD Nov 9, 2023
d9cacbc
Auto update version
github-actions[bot] Nov 9, 2023
b3a21d1
add MPI support
multiphaseCFD Nov 9, 2023
62b3714
add samples_to_counts to measurement base class
multiphaseCFD Nov 9, 2023
05cfb89
tidy up tests
multiphaseCFD Nov 9, 2023
ddfdb72
move tests to measurement base
multiphaseCFD Nov 9, 2023
44df765
move mpi tests to measurement base class
multiphaseCFD Nov 9, 2023
b3931e9
make format
multiphaseCFD Nov 9, 2023
3a52184
add python layer
multiphaseCFD Nov 10, 2023
d714e0e
add mpi tests
multiphaseCFD Nov 10, 2023
9d1a418
remove else
multiphaseCFD Nov 10, 2023
d9d7a7d
add tensor product support
multiphaseCFD Nov 12, 2023
5745f4f
add more tests for tensor prod obs shots
multiphaseCFD Nov 12, 2023
bcb46d1
make format
multiphaseCFD Nov 12, 2023
68f2865
add Hamiltonian support
multiphaseCFD Nov 14, 2023
bc58332
make format
multiphaseCFD Nov 14, 2023
5288491
quick fix
multiphaseCFD Nov 14, 2023
c7f5ea2
add hamiltonian tests
multiphaseCFD Nov 14, 2023
4b56805
add more py tests for tensorprod
multiphaseCFD Nov 14, 2023
f09342f
remove changes made in py layer
multiphaseCFD Nov 15, 2023
d13e9f2
revert more changes in py layer
multiphaseCFD Nov 15, 2023
9ef8dac
tidy up code
multiphaseCFD Nov 15, 2023
bd8fd5a
update measurement base and kokkos
multiphaseCFD Nov 15, 2023
15d8244
make format
multiphaseCFD Nov 15, 2023
1bc196f
refactor and add _sample_state method
multiphaseCFD Nov 15, 2023
e5b64a0
for loop sum to accumulate sum
multiphaseCFD Nov 15, 2023
6fda049
refactor and add _preprocess_state() method
multiphaseCFD Nov 15, 2023
2949500
add more unit tests for LK backend
multiphaseCFD Nov 16, 2023
70637dc
Merge branch 'master' into add_shot_expval
multiphaseCFD Nov 16, 2023
2cbd160
Auto update version
github-actions[bot] Nov 16, 2023
5595a8a
tidy up docstring
multiphaseCFD Nov 16, 2023
d41f2b2
remove samples() and samples2counts method
multiphaseCFD Nov 16, 2023
ebf80f0
fix typo
multiphaseCFD Nov 16, 2023
3238a08
quick fix
multiphaseCFD Nov 16, 2023
35065d1
update LQRaw object creation
multiphaseCFD Nov 16, 2023
264481f
fix for multiple backends
multiphaseCFD Nov 16, 2023
2d3cf11
update format
multiphaseCFD Nov 16, 2023
b12885d
format fix
multiphaseCFD Nov 16, 2023
ad1e11d
format update
multiphaseCFD Nov 16, 2023
288e01e
make format & trigger MPI CI
multiphaseCFD Nov 16, 2023
e08cb85
add changelog and codecov for expval(obs) method
multiphaseCFD Nov 16, 2023
2e495db
add shot_range coverage
multiphaseCFD Nov 16, 2023
0acc096
tidy up code
multiphaseCFD Nov 16, 2023
4f5f634
add more unit tests
multiphaseCFD Nov 16, 2023
fe042f6
fix typos
multiphaseCFD Nov 16, 2023
06ecd06
add MPI Hamiltonian tests for shots
multiphaseCFD Nov 17, 2023
602f16c
add HamBase tests for applyInPlaceShots
multiphaseCFD Nov 17, 2023
e839cf2
update based on comments
multiphaseCFD Nov 17, 2023
7408813
add more unit tests
multiphaseCFD Nov 17, 2023
00be785
move tests for non-distributed backends to base
multiphaseCFD Nov 17, 2023
6c4dfbd
move all unit tests into the base class
multiphaseCFD Nov 17, 2023
0d07d9c
move getTotalNumQubits to base and tidy up code
multiphaseCFD Nov 17, 2023
055d6b3
tidy up code
multiphaseCFD Nov 17, 2023
1a92ebf
revert changes in Test_MeasurementLQ
multiphaseCFD Nov 17, 2023
2c29713
initial commit
multiphaseCFD Nov 17, 2023
42ab1cc
tidy up code
multiphaseCFD Nov 17, 2023
6a5c5fe
Merge branch 'master' into add_sample_prob_var_obs
multiphaseCFD Nov 17, 2023
92571cb
Auto update version
github-actions[bot] Nov 17, 2023
77cba24
add var obs tests
multiphaseCFD Nov 18, 2023
ecf4683
add tests for prob for all backend and var for MPI
multiphaseCFD Nov 20, 2023
38748b3
quick fix
multiphaseCFD Nov 20, 2023
e3bb395
add unit tests for counts & samples obs
multiphaseCFD Nov 20, 2023
0ee73cb
add more sample() & counts() unit tests
multiphaseCFD Nov 20, 2023
531f386
add sample counts tests for mpi backend
multiphaseCFD Nov 20, 2023
e23a349
make format
multiphaseCFD Nov 20, 2023
a8cb9bc
Trigger MPI CI
multiphaseCFD Nov 20, 2023
f2c7923
tidy up code
multiphaseCFD Nov 21, 2023
17539d9
add changelogs and tidy up unit tests
multiphaseCFD Nov 21, 2023
b42d42d
update docstring
multiphaseCFD Nov 21, 2023
674dc8c
fix typo
multiphaseCFD Nov 21, 2023
3f70c2a
update return type of counts & tidy up code
multiphaseCFD Nov 24, 2023
ac4cb28
Merge branch 'master' into add_sample_prob_var_obs
multiphaseCFD Nov 24, 2023
70b208d
Auto update version
github-actions[bot] Nov 24, 2023
20366b9
update brief of probs(obs)
multiphaseCFD Nov 24, 2023
7101e5f
update based on comments
multiphaseCFD Nov 28, 2023
76317e1
fix typo
multiphaseCFD Nov 28, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

### New features since last release

* Add shots support for variance value, probs, sample, counts calculation for given observables (`NamedObs`, `TensorProd` and `Hamiltonian`) based on Pauli words, `Identity` and `Hadamard` in the C++ layer. All Lightning backends support this support feature.
[(#561)](https://github.com/PennyLaneAI/pennylane-lightning/pull/561)

* Add shots support for expectation value calculation for given observables (`NamedObs`, `TensorProd` and `Hamiltonian`) based on Pauli words, `Identity` and `Hadamard` in the C++ layer by adding `measure_with_samples` to the measurement interface. All Lightning backends support this support feature.
[(#556)](https://github.com/PennyLaneAI/pennylane-lightning/pull/556)

Expand Down
2 changes: 1 addition & 1 deletion pennylane_lightning/core/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@
Version number (major.minor.patch[-label])
"""

__version__ = "0.34.0-dev10"
__version__ = "0.34.0-dev11"
152 changes: 152 additions & 0 deletions pennylane_lightning/core/src/measurements/MeasurementsBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,158 @@ template <class StateVectorT, class Derived> class MeasurementsBase {
return obs_samples;
}

/**
* @brief Calculate the variance for an observable with the number of shots.
*
* @param obs An observable object.
* @param num_shots Number of shots used to generate samples
*
* @return Variance of the given observable.
*/
auto var(const Observable<StateVectorT> &obs, const size_t &num_shots) {
if (obs.getObsName().find("Hamiltonian") == std::string::npos) {
// Branch for NamedObs and TensorProd observables
auto square_mean = expval(obs, num_shots, {});
PrecisionT result =
1 - square_mean *
square_mean; //`1` used here is because Eigenvalues for
// Paulis, Hadamard and Identity are {-1,
// 1}. Need to change based on eigen values
// when add Hermitian support.
multiphaseCFD marked this conversation as resolved.
Show resolved Hide resolved
return result;
}
// Branch for Hamiltonian observables
auto coeffs = obs.getCoeffs();
PrecisionT result{0.0};
size_t obs_term_idx = 0;
for (const auto &coeff : coeffs) {
std::vector<size_t> shot_range = {};
auto obs_samples =
measure_with_samples(obs, num_shots, shot_range, obs_term_idx);
multiphaseCFD marked this conversation as resolved.
Show resolved Hide resolved
PrecisionT expval_per_term =
std::accumulate(obs_samples.begin(), obs_samples.end(), 0.0);
auto term_mean = expval_per_term / obs_samples.size();
multiphaseCFD marked this conversation as resolved.
Show resolved Hide resolved

result +=
coeff * coeff *
(1 - term_mean *
term_mean); //`1` used here is because Eigenvalues for
// Paulis, Hadamard and Identity are {-1,
// 1}. Need to change based on eigen values
// when add Hermitian support.
obs_term_idx++;
}
return result;
}

/**
* @brief Probabilities to measure rotated basis states.
*
* @param obs An observable object.
*
* @return Floating point std::vector with probabilities.
* The basis columns are rearranged according to wires.
*/
auto probs(const Observable<StateVectorT> &obs) {
multiphaseCFD marked this conversation as resolved.
Show resolved Hide resolved
PL_ABORT_IF(
obs.getObsName().find("Hamiltonian") != std::string::npos,
"Hamiltonian and Sparse Hamiltonian do not support samples().");
std::vector<size_t> obs_wires;
std::vector<size_t> identity_wires;
auto sv = _preprocess_state(obs, obs_wires, identity_wires);
Derived measure(sv);
return measure.probs(obs_wires);
}

/**
* @brief Return samples drawn from eigenvalues of the observable
*
* @param obs The observable object to sample
* @param num_shots Number of shots used to generate samples
*
* @return Samples of eigenvalues of the observable
*/
auto sample(const Observable<StateVectorT> &obs, const size_t &num_shots)
-> std::vector<PrecisionT> {
PL_ABORT_IF(
obs.getObsName().find("Hamiltonian") != std::string::npos,
"Hamiltonian and Sparse Hamiltonian do not support samples().");
std::vector<size_t> obs_wires;
std::vector<size_t> identity_wires;
std::vector<size_t> shot_range = {};
size_t term_idx = 0;

return measure_with_samples(obs, num_shots, shot_range, term_idx);
}

/**
* @brief Return the raw basis state samples
*
* @param num_shots Number of shots used to generate samples
*
* @return Raw basis state samples
*/
auto sample(const size_t &num_shots) -> std::vector<size_t> {
Derived measure(_statevector);
return measure.generate_samples(num_shots);
}

/**
* @brief Groups the eigenvalues of samples into a dictionary showing
* number of occurences for each possible outcome with the number of shots.
*
* @param obs The observable to sample
* @param num_shots Number of wires the sampled observable was performed on
*
* @return std::unordered_map<PrecisionT, size_t> with format
* ``{'EigenValue': num_occurences}``
*/
auto counts(const Observable<StateVectorT> &obs, const size_t &num_shots)
-> std::unordered_map<PrecisionT, size_t> {
std::unordered_map<PrecisionT, size_t> outcome_map;
auto sample_data = sample(obs, num_shots);
for (size_t i = 0; i < num_shots; i++) {
auto key = sample_data[i];
auto it = outcome_map.find(key);
if (it != outcome_map.end()) {
it->second += 1;
} else {
outcome_map[key] = 1;
}
}
return outcome_map;
}

/**
* @brief Groups the samples into a dictionary showing number of occurences
* for each possible outcome with the number of shots.
*
* @param num_shots Number of wires the sampled observable was performed on
*
* @return std::unordered_map<size_t, size_t> with format ``{'outcome':
* num_occurences}``
*/
auto counts(const size_t &num_shots) -> std::unordered_map<size_t, size_t> {
std::unordered_map<size_t, size_t> outcome_map;
auto sample_data = sample(num_shots);

size_t num_wires = _statevector.getTotalNumQubits();
for (size_t i = 0; i < num_shots; i++) {
size_t key = 0;
for (size_t j = 0; j < num_wires; j++) {
key += sample_data[i * num_wires + j] << (num_wires - 1 - j);
}

auto it = outcome_map.find(key);
if (it != outcome_map.end()) {
it->second += 1;
} else {
outcome_map[key] = 1;
}
}
return outcome_map;
}

private:
/**
* @brief Return preprocess state with a observable
Expand Down
Loading
Loading