-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Examples] Add example to compute the expectation values
Signed-off-by: Shubhanshu Saxena <shubhanshu.e01@gmail.com>
- Loading branch information
1 parent
8e61dc7
commit bebb78f
Showing
3 changed files
with
95 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
## Benchmarking how far can we go simulating on classical computers | ||
|
||
**Problem:** How about computing exact expectation values in the form `<Ψ| Op |Ψ>`? | ||
|
||
### Instructions to run | ||
|
||
This script tries to simulate a 3-qubit system (011) and applies three different gates on the three qubits. Then we take `Op` as the Hadamard gate on the first qubit. | ||
|
||
```sh | ||
python examples/benchmark/speed_test.py | ||
``` | ||
|
||
Parameters: | ||
|
||
1. `--sim-type <tensor | vector> (-s)`: Select the simulation type for the system. Default: vector | ||
|
||
### Explanation | ||
|
||
In quantum mechanics, the expectation value of any operator for any normalized vector `Ψ` is given by `<Ψ| Op |Ψ>`. Ref: [Expectation value](<https://en.wikipedia.org/wiki/Expectation_value_(quantum_mechanics)>) | ||
|
||
So, first we need to normalize the state of the quantum system (tensor or vector states). | ||
|
||
To measure the expectation values of the `<Ψ| Op |Ψ>`. We need to prepare `Op` for the 3-qubit system here where the other two qubits can be applied a quantum wire or Identity matrix. The given expression can be understood as two parts: | ||
|
||
1. `<Ψ|` as the hermitian conjugate of `|Ψ>` -> complex conjugate of transpose of `|Ψ>` | ||
2. `Op |Ψ>` as the `Op` multiplied with `psi` -> applying the operator on `|Ψ>` normally | ||
|
||
Once we get these two, we take the inner product of these two matrices we get from the above steps to get the expectation value. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
import qcir_sim, argparse | ||
import numpy as np | ||
|
||
|
||
def parse_args(): | ||
parser = argparse.ArgumentParser(description="Benchmarking the simulation") | ||
parser.add_argument( | ||
"--sim-type", | ||
"-s", | ||
choices=["tensor", "vector"], | ||
default="vector", | ||
help="Type of simulation", | ||
) | ||
return parser.parse_args() | ||
|
||
|
||
def get_random_state(): | ||
choice = np.random.choice([0, 1]) | ||
if choice == 0: | ||
return qcir_sim.zero() | ||
return qcir_sim.one() | ||
|
||
|
||
def vector_expectation_value(sim: qcir_sim.VectorSimulation, gate: str, gate_idx: int): | ||
psi = sim.vector_state | ||
psi /= np.linalg.norm(psi) | ||
Op = sim._prepare_gate(gate, gate_idx) | ||
|
||
op_mul_psi = Op @ psi | ||
bra_notation = np.conjugate(np.transpose(psi)) | ||
|
||
expectation_value = bra_notation @ op_mul_psi | ||
print(f"Expectation Value: {expectation_value}") | ||
|
||
|
||
def tensor_expectation_value(sim: qcir_sim.TensorSimulation, gate: str, gate_idx: int): | ||
psi = sim.tensor_state | ||
psi /= np.linalg.norm(psi) | ||
Op = sim._prepare_gate(gate, gate_idx) | ||
|
||
op_mul_psi = np.einsum("ikj,ik->ij", Op, psi) | ||
bra_notation = np.conjugate(np.transpose(psi)) | ||
|
||
expectation_value = np.einsum("ij,ji", bra_notation, op_mul_psi) | ||
print(f"Expectation Value: {expectation_value}") | ||
|
||
|
||
if __name__ == "__main__": | ||
args = parse_args() | ||
simulation_type = args.sim_type | ||
print(f"Using {simulation_type} simulation") | ||
|
||
qubits = [qcir_sim.zero(), qcir_sim.one(), qcir_sim.one()] | ||
if args.sim_type == "tensor": | ||
sim = qcir_sim.TensorSimulation(qubits) | ||
else: | ||
sim = qcir_sim.VectorSimulation(qubits) | ||
|
||
sim.add_gate("H", 1) | ||
sim.add_gate("phase", 2) | ||
sim.add_gate("H", 3) | ||
|
||
if args.sim_type == "tensor": | ||
tensor_expectation_value(sim, "H", 1) | ||
else: | ||
vector_expectation_value(sim, "H", 1) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters