# Post selection error

**URL:** <https://discuss.pennylane.ai/t/post-selection-error/3903>\
**Category:** PennyLane Help\
**Created:** [January 16, 2024, 7:18am UTC](https://discuss.pennylane.ai/t/post-selection-error/3903 "2024-01-16T07:18:07Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![Aaqib\_Ali](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/aaqib_ali/32/1771_2.png) [@Aaqib\_Ali](https://discuss.pennylane.ai/u/Aaqib_Ali)\
**Post date:** [January 16, 2024, 7:18am UTC](https://discuss.pennylane.ai/t/post-selection-error/3903/1 "2024-01-16T07:18:07Z")

</div>

I aim to perform post-selection on the first outcome of the third qubit. Subsequently, I wish to execute a partial trace on this third subsystem. However, I am facing a limitation: post-selection is only feasible with default.qubit, which, unfortunately, does not support the use of noisy channels. How can I effectively carry out post-selection with ‘‘default.mixed’’?’

```auto
import pennylane as qml
from pennylane import numpy as np

dev=qml.device('default.mixed',wires=3)
p=0.1

def circuit1(params):
    qml.Hadamard(wires=0)
    qml.CNOT(wires=[0,1])
    qml.U3(params[0],params[1],params[2],wires=1)
    qml.U3(params[3],params[4],params[5],wires=2)
    qml.CNOT(wires=[2,1])
    qml.RZ(params[6],wires=1)
    qml.RY(params[7],wires=2)
    qml.CNOT(wires=[1,2])
    qml.RY(params[8],wires=2)
    qml.CNOT(wires=[2,1])
    qml.U3(params[9],params[10],params[11],wires=1)
    qml.U3(params[12],params[13],params[14],wires=2)
    qml.PhaseDamping(p,wires=1)
    qml.PhaseDamping(p,wires=2)
    qml.adjoint(qml.U3(params[12],params[13],params[14],wires=2))
    qml.adjoint(qml.U3(params[9],params[10],params[11],wires=1))
    qml.adjoint(qml.CNOT(wires=[2,1]))
    qml.adjoint(qml.RY(params[8],wires=2))
    qml.adjoint(qml.CNOT(wires=[1,2]))
    qml.adjoint(qml.RY(params[7],wires=2))
    qml.adjoint(qml.RZ(params[6],wires=1))
    qml.adjoint(qml.CNOT(wires=[2,1]))
    qml.adjoint(qml.U3(params[3],params[4],params[5],wires=2))
    qml.adjoint(qml.U3(params[0],params[1],params[2],wires=1))
    
params = np.array(range(0, 15))
circuit_drawer = qml.draw_mpl(circuit1)(params)

pr = np.kron(np.eye(4), np.array([[1, 0], [0, 0]]))

@qml.qnode(dev)
def circuit2(params):
    np.dot(np.dot(pr.conj().T,circuit1(params)), pr)#Post selection 
    return qml.density_matrix(wires=[0,1])

```

error message

```auto
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[13], line 1
----> 1 print(circuit2(params))

File ~\anaconda3\Lib\site-packages\pennylane\qnode.py:976, in QNode. __call__ (self, *args, **kwargs)
    973 kwargs["shots"] = _get_device_shots(self._original_device)
    975 # construct the tape
--> 976 self.construct(args, kwargs)
    978 cache = self.execute_kwargs.get("cache", False)
    979 using_custom_cache = (
    980 hasattr(cache, " __getitem__")
    981 and hasattr(cache, " __setitem__")
    982 and hasattr(cache, " __delitem__")
    983 )

File ~\anaconda3\Lib\site-packages\pennylane\qnode.py:862, in QNode.construct(self, args, kwargs)
    859 self.interface = qml.math.get_interface(*args, *list(kwargs.values()))
    861 with qml.queuing.AnnotatedQueue() as q:
--> 862 self._qfunc_output = self.func(*args, **kwargs)
    864 self._tape = QuantumScript.from_queue(q, shots)
    866 params = self.tape.get_parameters(trainable_only=False)

Cell In[12], line 3, in circuit2(params)
      1 @qml.qnode(dev)
      2 def circuit2(params):
----> 3 np.dot(np.dot(pr.conj().T,circuit1(params)), pr)
      4 return qml.density_matrix(wires=[0,1])

File ~\anaconda3\Lib\site-packages\pennylane\numpy\wrapper.py:117, in tensor_wrapper.<locals>._wrapped(*args, **kwargs)
    114 tensor_kwargs["requires_grad"] = _np.any([i.requires_grad for i in tensor_args])
    116 # evaluate the original object
--> 117 res = obj(*args, **kwargs)
    119 if isinstance(res, _np.ndarray):
    120 # only if the output of the object is a ndarray,
    121 # then convert to a PennyLane tensor
    122 res = tensor(res, **tensor_kwargs)

File ~\anaconda3\Lib\site-packages\autograd\tracer.py:48, in primitive.<locals>.f_wrapped(*args, **kwargs)
     46 return new_box(ans, trace, node)
     47 else:
---> 48 return f_raw(*args, **kwargs)

File < __array_function__ internals>:180, in dot(*args, **kwargs)

File ~\anaconda3\Lib\site-packages\pennylane\numpy\tensor.py:155, in tensor. __array_ufunc__ (self, ufunc, method, *inputs, **kwargs)
    151 args = [i.unwrap() if hasattr(i, "unwrap") else i for i in inputs]
    153 # call the ndarray. __array_ufunc__ method to compute the result
    154 # of the vectorized ufunc
--> 155 res = super(). __array_ufunc__ (ufunc, method, *args, **kwargs)
    157 if isinstance(res, Operator):
    158 return res

TypeError: unsupported operand type(s) for *: 'float' and 'DensityMatrixMP'

```

---

<div class="post-metadata">

**Author:** ![isaacdevlugt](https://yyz2.discourse-cdn.com/flex012/user_avatar/discuss.pennylane.ai/isaacdevlugt/32/1159_2.png) [@isaacdevlugt](https://discuss.pennylane.ai/u/isaacdevlugt)\
**Post date:** [January 18, 2024, 1:25am UTC](https://discuss.pennylane.ai/t/post-selection-error/3903/2 "2024-01-18T01:25:53Z")

</div>

Hey @Aaqib_Ali, welcome to the forum!

The problem is with this line:

> [@Aaqib\_Ali](#):
>
> `np.dot(np.dot(pr.conj().T,circuit1(params)), pr)`

QNodes in PennyLane can’t have mathematical operations like this. Also, calling `circuit1(params)` here returns nothing because it’s just a quantum function with operations in it. Generally, how circuits work in PennyLane is by defining functions that have _quantum_ operations/instructions in them, return a measurement (like any of these: [Measurements — PennyLane 0.34.0 documentation](https://docs.pennylane.ai/en/stable/introduction/measurements.html)), and by decorating the function with `@qml.qnode`.

What you want to do is something like this:

```auto
@qml.qnode(dev)
def circuit2(params):
    circuit1(params) # makes circuit2 have all of your operations in circuit1
    qml.Projector(...) # some instance of a projector operator based on your desired output
    return qml.density_matrix(wires=[0,1])

```

Here, you might be able to accomplish what you want to do via `qml.Projector` ([qml.Projector — PennyLane 0.34.0 documentation](https://docs.pennylane.ai/en/stable/code/api/pennylane.Projector.html?highlight=qml%20projector#pennylane.Projector)) or `qml.QubitUnitary`  
([qml.QubitUnitary — PennyLane 0.34.0 documentation](https://docs.pennylane.ai/en/stable/code/api/pennylane.QubitUnitary.html?highlight=qml%20qubitunitary#pennylane.QubitUnitary)). You might also be able to accomplish post-selection more elegantly with `qml.measure`: [qml.measure — PennyLane 0.34.0 documentation](https://docs.pennylane.ai/en/stable/code/api/pennylane.measure.html?highlight=qml%20measure#pennylane.measure). Just use the `postselect` keyword argument 🙂.

Let me know if this helps!
