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

Computing expval and var with LightningTensor using quimb MPS #686

Merged
merged 155 commits into from
May 7, 2024
Merged
Show file tree
Hide file tree
Changes from 151 commits
Commits
Show all changes
155 commits
Select commit Hold shift + click to select a range
06f1285
empty commit (triggering CI)
PietropaoloFrisoni Apr 3, 2024
6ffe0be
Auto update version
github-actions[bot] Apr 3, 2024
95d2bf7
Definition of the two front-end classes
PietropaoloFrisoni Apr 3, 2024
3a35a09
adding the `lightning_tensor` string to the supported backends in `se…
PietropaoloFrisoni Apr 3, 2024
568df4c
adding `__init__.py` file to directly import the `lightning_tensor` d…
PietropaoloFrisoni Apr 4, 2024
ac3a397
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 4, 2024
2fcf200
re-naming file
PietropaoloFrisoni Apr 4, 2024
2a6cabd
Auto update version
github-actions[bot] Apr 4, 2024
f3b8e8f
Creating the first prototype of initial MPS state tensor using `quimb`
PietropaoloFrisoni Apr 4, 2024
98891cb
providing the `backend`, `method` parameters and making `wires` optional
PietropaoloFrisoni Apr 5, 2024
9f3c094
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 8, 2024
a63241e
Changing names and structure
PietropaoloFrisoni Apr 8, 2024
10e5d22
Auto update version
github-actions[bot] Apr 8, 2024
68f4296
adding method required by the new device API design
PietropaoloFrisoni Apr 9, 2024
f78c2f8
Auto update version
github-actions[bot] Apr 9, 2024
f5ba10f
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 9, 2024
5f64582
using the `kwargs` parameter in `LightningTensor` and `CircuitMPS` in…
PietropaoloFrisoni Apr 9, 2024
621082c
taking some further inputs from the new device API
PietropaoloFrisoni Apr 9, 2024
6395940
Perhaps decided the overall structure of `LIghtningTensor`
PietropaoloFrisoni Apr 10, 2024
8de1a46
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 10, 2024
3e89306
Auto update version
github-actions[bot] Apr 10, 2024
9510eb2
adding docs to methods
PietropaoloFrisoni Apr 10, 2024
a16f7de
temporary changes so that `pylint` does not complain at this stage
PietropaoloFrisoni Apr 10, 2024
295aee7
running `isort`
PietropaoloFrisoni Apr 10, 2024
710dffd
re-running formatter after `isort`
PietropaoloFrisoni Apr 10, 2024
870e0e4
re-running formatter after `isort`
PietropaoloFrisoni Apr 10, 2024
34b23a9
Applying suggested formatting change from CI
PietropaoloFrisoni Apr 10, 2024
f5eb35a
adding tmp unit tests
PietropaoloFrisoni Apr 10, 2024
95839b9
Adding `quimb` in `requirements.txt`
PietropaoloFrisoni Apr 10, 2024
72a54d4
runing `isort` on mps test
PietropaoloFrisoni Apr 10, 2024
a235592
removing `quimb` from requirement and deleting unit tests for `lightn…
PietropaoloFrisoni Apr 10, 2024
6d7d879
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 10, 2024
4139412
Auto update version
github-actions[bot] Apr 10, 2024
b0a55b3
re-inserting unit tests with an additional `yml` file
PietropaoloFrisoni Apr 10, 2024
ed1ba39
running isort on quimb test
PietropaoloFrisoni Apr 10, 2024
6da1c94
changing name of yml file
PietropaoloFrisoni Apr 10, 2024
54d430d
preventing error in import
PietropaoloFrisoni Apr 10, 2024
943af7b
updating yml file
PietropaoloFrisoni Apr 10, 2024
9c6d5e6
inserting `quimb` package in requirements-dev
PietropaoloFrisoni Apr 10, 2024
a7e7327
strange error with `quimb`
PietropaoloFrisoni Apr 10, 2024
73428a6
strange error with `quimb`
PietropaoloFrisoni Apr 10, 2024
9729440
specifying scipy version
PietropaoloFrisoni Apr 10, 2024
1d0bce7
removing installation of scipy from yml file
PietropaoloFrisoni Apr 10, 2024
2a4b1cd
removing the new `yml` file
PietropaoloFrisoni Apr 10, 2024
706dc93
testing if tests are tested
PietropaoloFrisoni Apr 10, 2024
b5c0a63
Covering all lines in tests
PietropaoloFrisoni Apr 10, 2024
50928ad
forgot final line for formatter
PietropaoloFrisoni Apr 10, 2024
1ed59a3
Python formatter on CI complaints
PietropaoloFrisoni Apr 10, 2024
8108cfd
covering missing lines
PietropaoloFrisoni Apr 10, 2024
c9c3cb2
formatter on CI complaints
PietropaoloFrisoni Apr 10, 2024
69f9ce0
Trying not to skip test if Cpp is enabled
PietropaoloFrisoni Apr 10, 2024
159418b
skipping tests if Cpp is enabled
PietropaoloFrisoni Apr 11, 2024
8789d5c
removing the only line not covered by tests so far
PietropaoloFrisoni Apr 11, 2024
a033eac
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 12, 2024
2df5486
Auto update version
github-actions[bot] Apr 12, 2024
b470af1
Applying suggestions from code review and making the `state` attribut…
PietropaoloFrisoni Apr 12, 2024
754dae1
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 12, 2024
eb348b3
Python formatter
PietropaoloFrisoni Apr 12, 2024
cdc585b
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 12, 2024
f9dc84e
removing params from `QuimbMPS`
PietropaoloFrisoni Apr 12, 2024
651730d
Auto update version
github-actions[bot] Apr 12, 2024
eb84ded
removing `**kwargs` from `QuimbMPS`
PietropaoloFrisoni Apr 12, 2024
36effb4
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 12, 2024
3925d37
removing unnecessary param at this stage
PietropaoloFrisoni Apr 12, 2024
da0518b
covering test line
PietropaoloFrisoni Apr 12, 2024
df2350d
formatter...
PietropaoloFrisoni Apr 12, 2024
017a924
removing param description
PietropaoloFrisoni Apr 15, 2024
ba89c13
Making `pylint` happy
PietropaoloFrisoni Apr 15, 2024
505e54a
forgot new arg in test
PietropaoloFrisoni Apr 15, 2024
c0a9df9
Updating base class and `preprocess` function
PietropaoloFrisoni Apr 16, 2024
34e84df
empty commit
PietropaoloFrisoni Apr 16, 2024
6bdd937
Core structure (TODO: add tests)
PietropaoloFrisoni Apr 16, 2024
5665ec2
Running `isort`
PietropaoloFrisoni Apr 16, 2024
364ff80
Updating `LightningTensor` class with new names from more advanced PR
PietropaoloFrisoni Apr 16, 2024
9f94fc6
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 16, 2024
9d25624
Adding unit tests for the `expval` calculation
PietropaoloFrisoni Apr 16, 2024
1629675
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 17, 2024
aebfd13
Auto update version
github-actions[bot] Apr 17, 2024
f3c5f40
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 17, 2024
6333163
Auto update version
github-actions[bot] Apr 17, 2024
dd60aa9
Triggering CI
PietropaoloFrisoni Apr 17, 2024
e2558a7
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 17, 2024
8c9237b
Adding Hamiltonian expval (`pylint` keeps complaining about my format…
PietropaoloFrisoni Apr 17, 2024
f62400d
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 17, 2024
b419e86
Auto update version
github-actions[bot] Apr 17, 2024
74c6562
Trying to remove pin from `quimb` in `requirements.dev`
PietropaoloFrisoni Apr 18, 2024
c5446af
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 18, 2024
cad8e60
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 19, 2024
d13d373
Auto update version
github-actions[bot] Apr 19, 2024
5286592
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 19, 2024
5487b57
Auto update version
github-actions[bot] Apr 19, 2024
5e47874
Removing infos on derivatives and using config options to pass parame…
PietropaoloFrisoni Apr 19, 2024
6945ae7
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 19, 2024
804df34
Usual `pylint` failures
PietropaoloFrisoni Apr 19, 2024
b1fbe3e
Trying to solve formatting errors
PietropaoloFrisoni Apr 19, 2024
7f7574e
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 19, 2024
3452d28
Style and format update
PietropaoloFrisoni Apr 19, 2024
9dcff51
typo in docstring
PietropaoloFrisoni Apr 19, 2024
68606ec
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 19, 2024
50fa0e1
Sunday update: improved docstrings and structure
PietropaoloFrisoni Apr 21, 2024
ec2bfa4
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 21, 2024
689440e
Support for expval and var plus some tests
PietropaoloFrisoni Apr 21, 2024
a39c2d2
Removing comments from lines in tests
PietropaoloFrisoni Apr 21, 2024
0d4c870
Removing method that was supposed to be in next PR
PietropaoloFrisoni Apr 21, 2024
e08afb0
removing old TODO comment
PietropaoloFrisoni Apr 21, 2024
6d46194
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 21, 2024
0031757
Adding API skip lines in test
PietropaoloFrisoni Apr 21, 2024
25fb985
removing old TODO comment
PietropaoloFrisoni Apr 21, 2024
9d988b1
Forgot function from forked repo
PietropaoloFrisoni Apr 22, 2024
2c1f524
Removing lines in tests
PietropaoloFrisoni Apr 22, 2024
eaa6e8d
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 22, 2024
e3ed59f
Removing changes from the `setup.py` file
PietropaoloFrisoni Apr 22, 2024
11fae6d
restoring previous format to `setup.py`
PietropaoloFrisoni Apr 22, 2024
9c3d630
Auto update version from '0.36.0-dev34' to '0.36.0-dev41'
ringo-but-quantum Apr 25, 2024
2bff970
Merge branch 'master' into lightning-tensor-device
PietropaoloFrisoni Apr 25, 2024
2e91195
Auto update version from '0.36.0-dev40' to '0.36.0-dev41'
ringo-but-quantum Apr 25, 2024
149d126
Removing kwargs as suggested from code review
PietropaoloFrisoni Apr 25, 2024
c592710
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 25, 2024
9ef5625
Addressing comments from CR
PietropaoloFrisoni Apr 25, 2024
6a894ca
Skipping tests if CPP binary is available
PietropaoloFrisoni Apr 25, 2024
dccccd5
Merge branch 'lightning-tensor-device' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 25, 2024
7a855b8
-am "[ci skip]"
PietropaoloFrisoni Apr 25, 2024
2b11b30
-am "[ci skip]"
PietropaoloFrisoni Apr 25, 2024
5a44917
-am "[ci skip]"
PietropaoloFrisoni Apr 25, 2024
f8facd7
-am "[ci skip]"
PietropaoloFrisoni Apr 25, 2024
2d5977a
Removing the `draw` function
PietropaoloFrisoni Apr 25, 2024
4631925
Added changelog
PietropaoloFrisoni Apr 25, 2024
d260cef
Added statement in docstring
PietropaoloFrisoni Apr 25, 2024
abe1c08
Renaming description in files and removing comments
PietropaoloFrisoni Apr 25, 2024
edab75c
Typo in docstring
PietropaoloFrisoni Apr 26, 2024
bf0a2c2
Merge branch 'master' of https://github.com/PennyLaneAI/pennylane-lig…
PietropaoloFrisoni Apr 30, 2024
cfdc3c9
Merging from master (now that the first PR has been merged)
PietropaoloFrisoni Apr 30, 2024
5bd9b94
Auto update version from '0.36.0-dev45' to '0.36.0-dev46'
ringo-but-quantum Apr 30, 2024
49c6400
Suggestions from CodeFactor (slipped during merging from master)
PietropaoloFrisoni Apr 30, 2024
9b901d8
Merge branch 'lightning-tensor-expval' of https://github.com/PennyLan…
PietropaoloFrisoni Apr 30, 2024
2a1f84b
Suggestions from code review
PietropaoloFrisoni Apr 30, 2024
b424e2a
Removing `Arg` from the `preprocess` function in the interface
PietropaoloFrisoni Apr 30, 2024
63f1532
applying suggestion by calling `expval` in `var`
PietropaoloFrisoni May 1, 2024
9c49601
Modified changelog and removed variations from supported operations
PietropaoloFrisoni May 2, 2024
fd4a547
Switching to `quimb 1.8.1`, adding `contract` option to kwargs, remov…
PietropaoloFrisoni May 2, 2024
09ba2ef
removing `recursive decomposition` from the source dode
PietropaoloFrisoni May 2, 2024
6aea3ec
Suggestions from CR
PietropaoloFrisoni May 2, 2024
37102cc
Trying to make `Codecov` happy by inserting # pragma: no cover (altho…
PietropaoloFrisoni May 3, 2024
954e0b6
Merge branch 'master' into lightning-tensor-expval
PietropaoloFrisoni May 3, 2024
33258a3
Auto update version from '0.36.0-dev46' to '0.36.0-dev47'
ringo-but-quantum May 3, 2024
3b251e0
Usual formatting check that I forgot
PietropaoloFrisoni May 3, 2024
1ac7964
"[skip ci]"
PietropaoloFrisoni May 3, 2024
e7bbf5f
Auto update version from '0.36.0-dev47' to '0.36.0-dev48'
ringo-but-quantum May 3, 2024
99d79f1
Merge branch 'master' into lightning-tensor-expval
PietropaoloFrisoni May 5, 2024
7c37859
Trying to make Codecov happy with # pragma: no cover, even though lin…
PietropaoloFrisoni May 5, 2024
ab874a9
Removing # pragma - no cover since Codecov is not happy anyway
PietropaoloFrisoni May 5, 2024
83aa52e
Merge branch 'master' into lightning-tensor-expval
PietropaoloFrisoni May 7, 2024
9a0e4c1
Auto update version from '0.37.0-dev2' to '0.37.0-dev3'
ringo-but-quantum May 7, 2024
03ba08d
Updating changelog
PietropaoloFrisoni May 7, 2024
3d05c84
Merge branch 'lightning-tensor-expval' of https://github.com/PennyLan…
PietropaoloFrisoni May 7, 2024
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 support for `qml.expval` and `qml.var` in the `lightning.tensor` device for the `quimb` interface and the MPS method.
[(#686)](https://github.com/PennyLaneAI/pennylane-lightning/pull/686)

* Add Python class for the `lightning.tensor` device which uses the new device API and the interface for `quimb` based on the MPS method.
[(#671)](https://github.com/PennyLaneAI/pennylane-lightning/pull/671)

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.36.0-dev47"
__version__ = "0.36.0-dev48"
289 changes: 280 additions & 9 deletions pennylane_lightning/lightning_tensor/backends/quimb/_mps.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,104 @@
"""
Class implementation for the Quimb MPS interface for simulating quantum circuits while keeping the state always in MPS form.
"""
import copy
from typing import Callable, Sequence, Union

import numpy as np
import pennylane as qml
import quimb.tensor as qtn
from pennylane import numpy as np
from pennylane.devices import DefaultExecutionConfig, ExecutionConfig
from pennylane.devices.preprocess import (
decompose,
validate_device_wires,
validate_measurements,
validate_observables,
)
from pennylane.measurements import ExpectationMP, MeasurementProcess, StateMeasurement, VarianceMP
from pennylane.tape import QuantumScript, QuantumTape
from pennylane.transforms.core import TransformProgram
from pennylane.typing import Result, ResultBatch, TensorLike
from pennylane.wires import Wires

_operations = frozenset({}) # pragma: no cover
Result_or_ResultBatch = Union[Result, ResultBatch]
QuantumTapeBatch = Sequence[QuantumTape]
QuantumTape_or_Batch = Union[QuantumTape, QuantumTapeBatch]
PostprocessingFn = Callable[[ResultBatch], Result_or_ResultBatch]

_operations = frozenset(
{
"Identity",
"QubitUnitary",
"ControlledQubitUnitary",
"MultiControlledX",
"DiagonalQubitUnitary",
"PauliX",
"PauliY",
"PauliZ",
"MultiRZ",
"GlobalPhase",
"Hadamard",
"S",
"T",
"SX",
"CNOT",
"SWAP",
"ISWAP",
"PSWAP",
"SISWAP",
"SQISW",
"CSWAP",
"Toffoli",
"CY",
"CZ",
"PhaseShift",
"ControlledPhaseShift",
"CPhase",
"RX",
"RY",
"RZ",
"Rot",
"CRX",
"CRY",
"CRZ",
"CRot",
"IsingXX",
"IsingYY",
"IsingZZ",
"IsingXY",
"SingleExcitation",
"SingleExcitationPlus",
"SingleExcitationMinus",
"DoubleExcitation",
"QubitCarry",
"QubitSum",
"OrbitalRotation",
"QFT",
"ECR",
"BlockEncode",
}
)
# The set of supported operations.

_observables = frozenset({}) # pragma: no cover

_observables = frozenset(
{
"PauliX",
"PauliY",
"PauliZ",
"Hadamard",
"Hermitian",
"Identity",
"Projector",
"SparseHamiltonian",
"Hamiltonian",
"LinearCombination",
"Sum",
"SProd",
"Prod",
"Exp",
}
)
# The set of supported observables.


Expand Down Expand Up @@ -57,15 +145,15 @@ def __init__(self, num_wires, interf_opts, dtype=np.complex128):
self._wires = Wires(range(num_wires))
self._dtype = dtype

self._init_state_ops = {
self._init_state_opts = {
"binary": "0" * max(1, len(self._wires)),
"dtype": self._dtype.__name__,
"tags": [str(l) for l in self._wires.labels],
}

self._gate_opts = {
"contract": "swap+split",
"parametrize": None,
"contract": interf_opts["contract"],
"cutoff": interf_opts["cutoff"],
"max_bond": interf_opts["max_bond_dim"],
}
Expand All @@ -79,22 +167,205 @@ def __init__(self, num_wires, interf_opts, dtype=np.complex128):
self._circuitMPS = qtn.CircuitMPS(psi0=self._initial_mps())

@property
def state(self):
"""Current MPS handled by the interface."""
def interface_name(self) -> str:
"""The name of this interface."""
return "QuimbMPS interface"

@property
def state(self) -> qtn.MatrixProductState:
"""Return the current MPS handled by the interface."""
return self._circuitMPS.psi

def state_to_array(self) -> np.ndarray:
"""Contract the MPS into a dense array."""
return self._circuitMPS.to_dense()

def _reset_state(self) -> None:
"""Reset the MPS."""
self._circuitMPS = qtn.CircuitMPS(psi0=self._initial_mps())

def _initial_mps(self) -> qtn.MatrixProductState:
r"""
Returns an initial state to :math:`\ket{0}`.
Return an initial state to :math:`\ket{0}`.

Internally, it uses `quimb`'s `MPS_computational_state` method.

Returns:
MatrixProductState: The initial MPS of a circuit.
"""
return qtn.MPS_computational_state(**self._init_state_opts)

def preprocess(self) -> TransformProgram:
"""This function defines the device transform program to be applied for this interface.

Returns:
TransformProgram: A transform program that when called returns :class:`~.QuantumTape`'s that the
device can natively execute as well as a postprocessing function to be called after execution.

This interface:

* Supports any one or two-qubit operations that provide a matrix.
* Supports any three or four-qubit operations that provide a decomposition method.
* Currently does not support finite shots.
"""

program = TransformProgram()

program.add_transform(validate_measurements, name=self.interface_name)
program.add_transform(validate_observables, accepted_observables, name=self.interface_name)
program.add_transform(validate_device_wires, self._wires, name=self.interface_name)
program.add_transform(
decompose,
stopping_condition=stopping_condition,
skip_initial_state_prep=True,
name=self.interface_name,
)
program.add_transform(qml.transforms.broadcast_expand)

return program

# pylint: disable=unused-argument
def execute(
self,
circuits: QuantumTape_or_Batch,
execution_config: ExecutionConfig = DefaultExecutionConfig,
) -> Result_or_ResultBatch:
"""Execute a circuit or a batch of circuits and turn it into results.

Args:
circuits (Union[QuantumTape, Sequence[QuantumTape]]): the quantum circuits to be executed
execution_config (ExecutionConfig): a datastructure with additional information required for execution

Returns:
TensorLike, tuple[TensorLike], tuple[tuple[TensorLike]]: A numeric result of the computation.
"""

results = []
for circuit in circuits:
circuit = circuit.map_to_standard_wires()
results.append(self.simulate(circuit))

return tuple(results)

def simulate(self, circuit: QuantumScript) -> Result:
"""Simulate a single quantum script. This function assumes that all operations provide matrices.

Args:
circuit (QuantumScript): The single circuit to simulate.

Returns:
Tuple[TensorLike]: The results of the simulation.
"""

self._reset_state()

for op in circuit.operations:
self._apply_operation(op)

if not circuit.shots:
if len(circuit.measurements) == 1:
return self.measurement(circuit.measurements[0])
return tuple(self.measurement(mp) for mp in circuit.measurements)

raise NotImplementedError # pragma: no cover

def _apply_operation(self, op: qml.operation.Operator) -> None:
"""Apply a single operator to the circuit, keeping the state always in a MPS form.

Internally it uses `quimb`'s `apply_gate` method.

Args:
op (Operator): The operation to apply.
"""

self._circuitMPS.apply_gate(op.matrix().astype(self._dtype), *op.wires, **self._gate_opts)

def measurement(self, measurementprocess: MeasurementProcess) -> TensorLike:
"""Measure the measurement required by the circuit over the MPS.

Args:
measurementprocess (MeasurementProcess): measurement to apply to the state.

Returns:
TensorLike: the result of the measurement.
"""

return self._get_measurement_function(measurementprocess)(measurementprocess)

def _get_measurement_function(
self, measurementprocess: MeasurementProcess
) -> Callable[[MeasurementProcess, TensorLike], TensorLike]:
"""Get the appropriate method for performing a measurement.

Args:
measurementprocess (MeasurementProcess): measurement process to apply to the state

Returns:
Callable: function that returns the measurement result
"""
if isinstance(measurementprocess, StateMeasurement):
if isinstance(measurementprocess, ExpectationMP):
return self.expval

if isinstance(measurementprocess, VarianceMP):
return self.var

raise NotImplementedError # pragma: no cover

def expval(self, measurementprocess: MeasurementProcess) -> float:
"""Expectation value of the supplied observable contained in the MeasurementProcess.

Args:
measurementprocess (StateMeasurement): measurement to apply to the MPS.

Returns:
Expectation value of the observable.
"""

obs = measurementprocess.obs

result = self._local_expectation(obs.matrix(), tuple(obs.wires))
PietropaoloFrisoni marked this conversation as resolved.
Show resolved Hide resolved

return result

def var(self, measurementprocess: MeasurementProcess) -> float:
"""Variance of the supplied observable contained in the MeasurementProcess.

Args:
measurementprocess (StateMeasurement): measurement to apply to the MPS.

Returns:
Variance of the observable.
"""

obs = measurementprocess.obs

obs_mat = obs.matrix()
expect_op = self.expval(measurementprocess)
expect_squar_op = self._local_expectation(obs_mat @ obs_mat.conj().T, tuple(obs.wires))

return expect_squar_op - np.square(expect_op)

def _local_expectation(self, matrix, wires) -> float:
"""Compute the local expectation value of a matrix on the MPS.

Internally, it uses `quimb`'s `local_expectation` method.

Args:
matrix (array): the matrix to compute the expectation value of.
wires (tuple[int]): the wires the matrix acts on.

Returns:
Local expectation value of the matrix on the MPS.
"""

# We need to copy the MPS to avoid modifying the original state
PietropaoloFrisoni marked this conversation as resolved.
Show resolved Hide resolved
qc = copy.deepcopy(self._circuitMPS)

exp_val = qc.local_expectation(
matrix,
wires,
**self._expval_opts,
)

return qtn.MPS_computational_state(**self._init_state_ops)
return float(np.real(exp_val))
Loading
Loading