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

Question/Bug: Not able to apply channel correctly #144

Closed
stephendiadamo opened this issue Apr 28, 2023 · 13 comments · Fixed by #155
Closed

Question/Bug: Not able to apply channel correctly #144

stephendiadamo opened this issue Apr 28, 2023 · 13 comments · Fixed by #155
Assignees
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@stephendiadamo
Copy link

stephendiadamo commented Apr 28, 2023

Expected Behavior

I'm trying to apply a channel to a state, but the channel is not preserving the trace. Could I be using the functions incorrectly or is there a bug? Thanks.

from toqito import states, channels, channel_ops, matrix_props, channel_props
import numpy as np

ind = 0

# Density matrix of the first Bell pair
state = np.outer(states.bell(ind), states.bell(ind))
# Depolarizing channel with p=0.5
dep_chan = channels.depolarizing(4, param_p=0.5)
# This prints True
print(channel_props.is_quantum_channel(dep_chan))
d = channel_ops.apply_channel(state, dep_chan)
# This prints False, but I expect it to be True.
print(matrix_props.is_density(d))

Specifications

  • Version: toqito~=1.0.5
  • Platform: Mac
@vprusso vprusso added bug Something isn't working help wanted Extra attention is needed labels Apr 28, 2023
@vprusso
Copy link
Owner

vprusso commented Apr 28, 2023

Hi @stephendiadamo

Thank you for the report and for flagging this.

Indeed, your workflow here seems to make sense. My first thought is that perhaps there is some normalization condition that needs to be considered within the apply_channel function, but I'm not entirely sure. This seems to also be the case for the dephasing channel as well.

If you have any other test cases and information to share about what you are doing here that might shine light on where the issue is, that would be much obliged. Thanks again for flagging.

@stephendiadamo
Copy link
Author

Thanks for the response. My use case is pretty simple. Mainly I just want to generate different values of p and compute the fidelity against a Bell state after the noise is applied. Once I apply the noise (i.e., apply the channel), I can't compute fidelity because it is no longer a density matrix. Maybe there's another way to apply depolarizing noise?

@vprusso
Copy link
Owner

vprusso commented Apr 28, 2023

It's also possible that one could try the same apply_channel function, but instead of passing in a Choi matrix as it done presently, one could pass in a collection of Kraus operators. As the apply_channel function supports both input as either a Choi matrix or a set of Kraus operators, it is possible that the Kraus approach will work. If you are able to give that a try, that may work, or at the very least, may guide us as to where the problem here is.

@stephendiadamo
Copy link
Author

Would this approach make sense?

from toqito import matrix_ops, state_metrics, states, channels, channel_ops, matrix_props, random, channel_props
import numpy as np

ind = 0
state = np.outer(states.bell(ind), states.bell(ind))
p = 0.5

dep_chan = channels.depolarizing(4, param_p=p)
print(channel_props.is_quantum_channel(dep_chan))

d = channel_ops.apply_channel(state, dep_chan)
print(matrix_props.is_density(d))

kraus = channel_ops.choi_to_kraus(dep_chan)
d = channel_ops.apply_channel(state, kraus)
print(matrix_props.is_density(d))

Maybe again my mistake, but the second to last line throws an exception:

site-packages/toqito/channel_ops/apply_channel.py:117, in apply_channel(mat, phi_op)
    114     phi_0_list.append(phi_op[i][0])
    115     phi_1_list.append(phi_op[i][1])
--> 117 k_1 = np.concatenate(phi_0_list, axis=1)
    118 k_2 = np.concatenate(phi_1_list, axis=0)
    120 a_mat = np.kron(np.identity(len(phi_op)), mat)

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

AxisError: axis 1 is out of bounds for array of dimension 1

@vprusso
Copy link
Owner

vprusso commented Apr 28, 2023

Hmm. I actually think the apply_channel function for Choi matrices is working okay. For instance, consider the following example.

import numpy as np
from toqito import (
    channel_ops,
    channels,
    matrix_props
)

# Define the Bell state. 
test_input_mat = np.array(
    [[1 / 2, 0, 0, 1 / 2], [0, 0, 0, 0], [0, 0, 0, 0], [1 / 2, 0, 0, 1 / 2]]
)

# The depolarizing channel should map every density operator to the maximally mixed state.
res = channel_ops.apply_channel(test_input_mat, channels.depolarizing(4))

# Returns `False`.
print(matrix_props.is_density(res))

We should not expect the result of this to be a density operator by definition, right? Maybe my brain isn't working properly right now, but this is my current train of thought anyway.

In any case, the Kraus approach definitely seems to need fixing. The input there should be a list of two lists representing the Kraus ops. One would expect that the choi_to_kraus function would return a list of this form, but it does not appear to.

@stephendiadamo
Copy link
Author

For me, a channel should be CPTP, and therefore would map density operators to density operators. An application of a channel should, in my understanding, result in a state which is the channel effect applied to the input state.

I use other tools like Pennylane, for example ,which have built in depolarizing channels. I can do an input-output fidelity pretty easily with that so that's why I was expecting I could do an input/output fidelity check of the before state and the state after the channel is applied.

Do you think there is a way to do that here? Thanks for the help and time.

@vprusso
Copy link
Owner

vprusso commented May 2, 2023

Hi @stephendiadamo . Thanks for continuing the thread here.

Hmm, let's see. The apply_map function in toqito is based upon the ApplyMap function in QETLAB (here). The two examples provided on the wiki page are test cases within the apply_map function (here).

Now, certainly, as you say, your intuition there aligns with mine, that is, applying a CPTP map to a density operator should give you a density operator right back. I presume that QETLAB does not have this issue and works as expected (although I don't have a MATLAB license to verify this).

In this case, there is probably an issue with the way that the toqito function is handling things. If you look at the code between the toqito version of apply_map and the QETLAB version of ApplyMap, the code to accomplish this result is nearly one-to-one.

Line 38 in ApplyMap has quite a lot going on that could be easily messed up in the toqito version. There's also tricky conditions where MATLAB and Python have some subtle differences in the way in which they orient matrix columns, index into arrays, etc. which makes comparing this tricky.

I can attempt to spend some time trying to figure out what the difference is here, but without a MATLAB license, that might be tricky.

Alternatively, I suppose we could consider toqito calling into Pennylane (or similar) to perform the work of apply_map. Would you know of a similar routine/set of code that would accomplish this apply map functionality there that you think would be a good candidate for replacement?

@stephendiadamo
Copy link
Author

stephendiadamo commented May 5, 2023

Hi @vprusso, thanks for all that info. I don't know if Pennylane would be the best choice yet... I mainly use depolarizing channels in my work and it happens to have that built in. For arbitrary channels, I'm not sure if it supports that. I think it very well could though. I'll have a look to see if it could be used.

I also don't have a MATLAB licence, but maybe I can figure out a way to get one. Let's see.

For now, since I'm again using a depolarizing channel for two qubits, I just used matrix operations as a workaround.

@vprusso
Copy link
Owner

vprusso commented May 8, 2023

Hi @stephendiadamo.

Thank you for the update and your patience on the matter. I'm glad you found a workaround, but indeed, this is something I will be prioritizing fixing. As UnitaryHack is approaching, I think this would be an excellent issue for someone to triage and squash.

Thank you again for flagging this, and if I can lend a hand in any other way in using toqtio, please do not hesitate to reach out!

@georgios-ts georgios-ts mentioned this issue May 28, 2023
1 task
@vprusso
Copy link
Owner

vprusso commented May 28, 2023

Tagging @georgios-ts here so I can assign them to claim the bounty for UnitaryHack.

@vprusso
Copy link
Owner

vprusso commented May 29, 2023

Pinging @stephendiadamo on the above issue.

Thanks to the work of @georgios-ts, this issue that you pointed out should be fixed. Thank you again to @stephendiadamo for bringing this issue up and to @georgios-ts for the, as usual, outstanding work and contribution. Cheers!

@stephendiadamo
Copy link
Author

Thank you @vprusso and @georgios-ts for the help and addressing my issue.

@georgios-ts
Copy link
Contributor

@vprusso
It's always fun to contribute to toqito!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants