-
Notifications
You must be signed in to change notification settings - Fork 123
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
expectation and gradient calculation for <A|H|B> form? #365
Comments
It is easy to design one with the |
Hi @GiggleLiu
Very good point! I just double-checked the system I am working on, it turns out actually I just need the gradient of Also, I only need the gradient path of the right circuit, so I want to set the parameters in the left circuit to have no gradient during the backpropagation. Is this achievable in |
In your case, the best solution is combining it with an AD engine like Zygote. If you can paste a code sample, I can show you how to do it. |
Hi @GiggleLiu """
expect(op::AbstractBlock, reg) -> Vector
expect(op::AbstractBlock, reg => circuit) -> Vector
expect(op::AbstractBlock, density_matrix) -> Vector
Get the expectation value of an operator, the second parameter can be a register `reg` or a pair of input register and circuit `reg => circuit`.
""" Below is my trial of the minimal example using Yao
n_qubits = 3
hterm = put(n_qubits, 1=>Z)
hterm *= put(n_qubits, 2=>X)
hterm *= put(n_qubits, 3=>Y)
hterm += put(n_qubits, 1=>X)
circ_left = chain(put(n_qubits, 1=>X),
put(n_qubits, 1=>Rx(0.1)),
put(n_qubits, 2=>Ry(0.1)),
put(n_qubits, 1=>Rz(0.1)))
circ_right = chain(put(n_qubits, 1=>Rx(0.1)),
put(n_qubits, 2=>Ry(0.1)),
put(n_qubits, 1=>Rz(0.1)))
expectation = expect(hterm, zero_state(n_qubits) |> circ_left, zero_state(n_qubits) |> circ_right) If I could calculate the expectation this way, then I would like to take the imaginary part of the expectation(or real part, it depends on the code) and do the backpropagation, just like the pseudo-code below value = gradient(imag(expectation), parameters(circ_right)) Note that it is natural to use the parameter-shift rule or Hadamard test to get the Hessian-like matrix, but for |
Just try defining a loss and differentiate it with Zygote. The loss should use non-inplace functions like using Yao
using Zygote
n_qubits = 3
hterm = put(n_qubits, 1=>Z)
hterm *= put(n_qubits, 2=>X)
hterm *= put(n_qubits, 3=>Y)
hterm += put(n_qubits, 1=>X)
circ_left = chain(put(n_qubits, 1=>X),
put(n_qubits, 1=>Rx(0.1)),
put(n_qubits, 2=>Ry(0.1)),
put(n_qubits, 1=>Rz(0.1)))
circ_right = chain(put(n_qubits, 1=>Rx(0.1)),
put(n_qubits, 2=>Ry(0.1)),
put(n_qubits, 1=>Rz(0.1)))
function loss(pl, pr)
cl = dispatch(circ_left, pl)
cr = dispatch(circ_right, pr)
regl = apply(zero_state(n_qubits), cl)
regr = apply(apply(zero_state(n_qubits), cr), hterm)
expectation = regl' * regr
return real(expectation)
end
loss(randn(3), randn(3))
Zygote.gradient(loss, randn(3), randn(3)) Let me know if it solves your issue. You probably want to check the gradients with the parameter shift rule. |
Hi @GiggleLiu Just for double-checking, I noticed that the loss function you defined is based on the One thing I'm not sure about is that, doing so, the circuit is not evaluated in an delayed order(or so called lazy evaluation), where some symbolic cancellation may help simplify the computation. Another thing is that, it seems Am I right about this? And how do you think? |
Zygote uses ChainRules which will go through our rules that uses reversibility.
tho there are symbolic expressions, but circuit compilation is not handled by current releases of Yao. |
Hi,
I am working on the algorithms of natural gradient descent and ansatz-based imaginary time evolution, in which I want to calculate the hessian with respect to parameters in a forward-reverse hybrid mode(for more details, see link). To achieve this, a method to calculate expectation and gradient calculation for <A|H|B> form are necessary. In mindquantum, it could be easily achieved using
grad_ops = sim.get_expectation_with_grad(ham, circ_right, circ_left)
. I'm wondering if there are any ways to achieve this inYao.jl
?Currently, I only know the piece of code like this(in Yao's document)
The text was updated successfully, but these errors were encountered: