# How do I operate between to different measurement processes for my loss function?

Hello! I’m trying to calculate a certain quantity for my loss function. This quantity involves operating between two different measurement processes. For example, my loss function is

``````S_x = (1/2)*sum([qml.PauliX(i) for i in range(qnn_layer.n_qubits)])
S_z = (1/2)*sum([qml.PauliZ(i) for i in range(qnn_layer.n_qubits)])

def get_loss_function(qnn_layer, ts, S_x, S_z, dev):

@jax.jit
@qml.qnode(dev, interface="jax")
def loss(param_vector):

# hamitlonian_params = dictionary_to_hamiltonian_parameters(params_dict)

param_list = qnn_layer.vector_to_hamiltonian_parameters(param_vector)

qml.evolve(qnn_layer.H)(param_list, ts)

return (-1) * qnn_layer.n_qubits * (qml.var(S_z) / qml.expval(S_x))

return loss

# Getting the loss_function
loss = get_loss_function(qnn_layer, ts, S_x, S_z, dev)

# Initializing parameters
param_vector  = qnn_layer.get_random_parameter_vector(seed)

print(f'Initial parameters: {param_vector}')

print(f'Initial loss: {loss(param_vector)}')
``````

However, I get an error that tells me that I cannot operate (in this case, divide) between two different measurement processes, namely ‘VarianceMP’ and ‘ExpectationMP’.

``````---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[17], line 9
5 param_vector  = qnn_layer.get_random_parameter_vector(seed)
7 print(f'Initial parameters: {param_vector}')
----> 9 print(f'Initial loss: {loss(param_vector)}')

[... skipping hidden 11 frame]

File ~/.../pennylane/workflow/qnode.py:1164, in QNode.__call__(self, *args, **kwargs)
1162 if qml.capture.enabled():
1163     return qml.capture.qnode_call(self, *args, **kwargs)
-> 1164 return self._impl_call(*args, **kwargs)

File ~/.../pennylane/workflow/qnode.py:1144, in QNode._impl_call(self, *args, **kwargs)
1141     override_shots = kwargs["shots"]
1143 # construct the tape
-> 1144 self.construct(args, kwargs)

File ~/.../pennylane/logging/decorators.py:61, in log_string_debug_func.<locals>.wrapper_entry(*args, **kwargs)
54     s_caller = "::L".join(
55         [str(i) for i in inspect.getouterframes(inspect.currentframe(), 2)[1][1:3]]
56     )
57     lgr.debug(
58         f"Calling {f_string} from {s_caller}",
59         **_debug_log_kwargs,
60     )
---> 61 return func(*args, **kwargs)

File ~/.../pennylane/workflow/qnode.py:966, in QNode.construct(self, args, kwargs)
964 with pldb_device_manager(self.device):
965     with qml.queuing.AnnotatedQueue() as q:
--> 966         self._qfunc_output = self.func(*args, **kwargs)
968 self._tape = QuantumScript.from_queue(q, shots)
970 params = self.tape.get_parameters(trainable_only=False)

Cell In[14], line 13
9 param_list = qnn_layer.vector_to_hamiltonian_parameters(param_vector)
11 qml.evolve(qnn_layer.H)(param_list, ts)
--> 13 return (-1) * qnn_layer.n_qubits * (qml.var(S_z) / qml.expval(S_x))

TypeError: unsupported operand type(s) for /: 'VarianceMP' and 'ExpectationMP'
``````

How do I make this sort of quantity of interest feasible in my loss function? Thanks! My `qml.about()` is as follows:

``````Version: 0.37.0
Summary: PennyLane is a cross-platform Python library for quantum computing, quantum machine learning, and quantum chemistry. Train a quantum computer the same way as a neural network.
Home-page: https://github.com/PennyLaneAI/pennylane
Author:
Author-email:
Location: /.../python3.11/site-packages
Requires: appdirs, autograd, autoray, cachetools, networkx, numpy, packaging, pennylane-lightning, requests, rustworkx, scipy, semantic-version, toml, typing-extensions
Required-by: PennyLane_Lightning

Platform info:           macOS-14.5-x86_64-i386-64bit
Python version:          3.11.7
Numpy version:           1.26.4
Scipy version:           1.14.0
Installed devices:
- lightning.qubit (PennyLane_Lightning-0.37.0)
- default.clifford (PennyLane-0.37.0)
- default.gaussian (PennyLane-0.37.0)
- default.mixed (PennyLane-0.37.0)
- default.qubit (PennyLane-0.37.0)
- default.qubit.jax (PennyLane-0.37.0)
- default.qubit.legacy (PennyLane-0.37.0)
- default.qubit.tf (PennyLane-0.37.0)
- default.qubit.torch (PennyLane-0.37.0)
- default.qutrit (PennyLane-0.37.0)
- default.qutrit.mixed (PennyLane-0.37.0)
- default.tensor (PennyLane-0.37.0)
- null.qubit (PennyLane-0.37.0)
``````

Hi @NickGut0711 ! That would be a great PL feature but for now this would be an alternative:

``````def get_loss_function():

@qml.qnode(qml.device("default.qubit"))
def circuit(param):

qml.RX(param, wires = 0)

return qml.var(qml.X(0)), qml.expval(qml.Z(0))

def loss(param):
var, exp = circuit(param)
return var / exp

return loss
``````

I hope that helps!

1 Like

Hi @Guillermo_Alonso! Thank you so much for the prompt, and helpful, reply! I’ll try that now