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

[Feature] unroll_block_with_scalling does not always return proper decomposition of pauli terms with coeffs #11

Open
jpmoutinho opened this issue May 6, 2024 · 2 comments
Assignees
Labels

Comments

@jpmoutinho
Copy link

Porting an issue from Qadence related to the unroll_block_with_scaling. This is a function in Qadence that returns a tuple of blocks and their scaling. E.g.

block = add(4*kron(Z(0), Z(1)), 2*Z(0))
unroll_block_with_scaling(block)
> [(4, kron(Z(0), Z(1))), (2, Z(0))]

This is a routine used in a few different places, and I have also discussed it with @kaosmicadei and we concluded that we should have pretty equivalent functionality in the new block system.

Porting here the issue below opened by Raja:

obs = add(2*kron(2*Z(0), Z(1)), 4 * Z(0))
terms =[pauli[0] for pauli in unroll_block_with_scaling(obs)]
coeffs = torch.tensor(
    [pauli[1] for pauli in unroll_block_with_scaling(obs)], dtype=float
)
print("coeffs:", coeffs)
> coeffs: tensor([2., 4.])

The issue is that he expected the first coefficient to be 4, but it is 2. This is because unroll_block_with_scaling does not simplify anything inside the kron. I suspect this will not be an issue in the new version.

@kaosmicadei
Copy link
Contributor

Indeed, the distributive property is now applied by default, so 2 * (2 * Z(0) * Z(1) + 4 * Z(0)) is converted straight to 4 * Z(0) * Z(1) + 8 * Z(0), and an expression like (1 + cos(phi)) * Z(0) * Z(1) will be expanded into Z(0) * Z(1) + cos(phi) * Z(0) * Z(1).

The unroll_block_with_scaling is now called collect_operators and returns a dictionary of operator-coefficient.

expr = 4 * Z(0) * Z(1) + 8 * Z(0)
collect_operators(expr)
# -> {Z(0) * Z(1): 4, Z(0): 8}

expr = Z(0) * Z(1) + cos(phi) * Z(0) * Z(1)
collect_operators(expr)
# -> {Z(0) * Z(1): 1 + cos(phi)}

@RolandMacDoland
Copy link
Contributor

Indeed, the distributive property is now applied by default, so 2 * (2 * Z(0) * Z(1) + 4 * Z(0)) is converted straight to 4 * Z(0) * Z(1) + 8 * Z(0), and an expression like (1 + cos(phi)) * Z(0) * Z(1) will be expanded into Z(0) * Z(1) + cos(phi) * Z(0) * Z(1).

The unroll_block_with_scaling is now called collect_operators and returns a dictionary of operator-coefficient.

expr = 4 * Z(0) * Z(1) + 8 * Z(0)
collect_operators(expr)
# -> {Z(0) * Z(1): 4, Z(0): 8}

expr = Z(0) * Z(1) + cos(phi) * Z(0) * Z(1)
collect_operators(expr)
# -> {Z(0) * Z(1): 1 + cos(phi)}

What I think would be good is if we could search by Pauli words in the returned dict. Ie. searching for all operators that contain Z(0) or of a certain pattern like Z(0) * Z(1)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants