# Copyright 2021-2024 Cambridge Quantum Computing Ltd.## Licensed under the Apache License, Version 2.0 (the "License");# you may not use this file except in compliance with the License.# You may obtain a copy of the License at## http://www.apache.org/licenses/LICENSE-2.0## Unless required by applicable law or agreed to in writing, software# distributed under the License is distributed on an "AS IS" BASIS,# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.# See the License for the specific language governing permissions and# limitations under the License."""Tket Model==========Module based on a quantum backend, using `tket`."""from__future__importannotationsfromtypingimportAnyimportnumpyasnpfromlambeq.backend.quantumimportDiagramasCircuit,Id,Measurefromlambeq.backend.tensorimportDiagramfromlambeq.training.quantum_modelimportQuantumModel
[docs]classTketModel(QuantumModel):"""Model based on `tket`. This can run either shot-based simulations of a quantum pipeline or experiments run on quantum hardware using `tket`. """
[docs]def__init__(self,backend_config:dict[str,Any])->None:"""Initialise TketModel based on the `t|ket>` backend. Other Parameters ---------------- backend_config : dict Dictionary containing the backend configuration. Must include the fields `backend`, `compilation` and `shots`. Raises ------ KeyError If `backend_config` is not provided or has missing fields. """super().__init__()fields=('backend','compilation','shots')missing_fields=[fforfinfieldsiffnotinbackend_config]ifmissing_fields:raiseKeyError('Missing arguments in backend configuation. 'f'Missing arguments: {missing_fields}.')self.backend_config=backend_configself.rng=np.random.default_rng()
[docs]defget_diagram_output(self,diagrams:list[Diagram])->np.ndarray:"""Return the prediction for each diagram using t|ket>. Parameters ---------- diagrams : list of :py:class:`~lambeq.backend.quantum.Diagram The :py:class:`Circuits <lambeq.backend.quantum.Diagram>` to be evaluated. Raises ------ ValueError If `model.weights` or `model.symbols` are not initialised. Returns ------- np.ndarray Resulting array. """iflen(self.weights)==0ornotself.symbols:raiseValueError('Weights and/or symbols not initialised. ''Instantiate through ''`TketModel.from_diagrams()` first, ''then call `initialise_weights()`, or load ''from pre-trained checkpoint.')measured=[diagram>>Id().tensor(*[Measure()]*len(diagram.cod))fordiagramindiagrams]# noqa: E501measured=self._fast_subs(measured,self.weights)tensors=Circuit.eval(*measured,# type: ignore[arg-type]**self.backend_config,seed=self._randint())self.backend_config['backend'].empty_cache()# lambeq evals a single diagram into a single result# and not a list of resultsiflen(diagrams)==1:result=self._normalise_vector(tensors)returnresult.reshape(1,*result.shape)returnnp.array([self._normalise_vector(t)fortintensors])
[docs]defforward(self,x:list[Diagram])->np.ndarray:"""Perform default forward pass of a lambeq quantum model. In case of a different datapoint (e.g. list of tuple) or additional computational steps, please override this method. Parameters ---------- x : list of :py:class:`~lambeq.backend.quantum.Diagram` The :py:class:`Circuits <lambeq.backend.quantum.Diagram>` to be evaluated. Returns ------- np.ndarray Array containing model's prediction. """returnself.get_diagram_output(x)