# GRAPE's method in Quantum Control (GRAPE.jl)

**URL:** <https://discourse.julialang.org/t/grapes-method-in-quantum-control-grape-jl/88208>\
**Category:** New to Julia\
**Tags:** question\
**Created:** [October 4, 2022, 4:37am UTC](https://discourse.julialang.org/t/grapes-method-in-quantum-control-grape-jl/88208 "2022-10-04T04:37:33Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![saba](https://avatars.discourse-cdn.com/v4/letter/s/d2c977/32.png) [@saba](https://discourse.julialang.org/u/saba)\
**Post date:** [October 4, 2022, 4:37am UTC](https://discourse.julialang.org/t/grapes-method-in-quantum-control-grape-jl/88208/1 "2022-10-04T04:37:33Z")

</div>

Hi. I’m working with QuantumControl.jl and I’m trying to learn about GRAPE method in this package. There is an example of [Optimization of a State-to-State Transfer in a Two-Level-System](https://juliaquantumcontrol.github.io/GRAPE.jl/stable/examples/simple_state_to_state/). I can run this code but I need to access to the controls in each iteration It should be a list containing 4 arrays with 499 elements.  
In krotov module in python there is a same list named all\_pulses for this particular example.  
Would you please help me how can I find this list in QuantumControl.jl package?

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [October 4, 2022, 6:02am UTC](https://discourse.julialang.org/t/grapes-method-in-quantum-control-grape-jl/88208/2 "2022-10-04T06:02:35Z")

</div>

You should probably tag me directly for any questions about QuantumControl.jl, or ask questions like this at [Discussions · JuliaQuantumControl/QuantumControl.jl · GitHub](https://github.com/JuliaQuantumControl/QuantumControl.jl/discussions). Not that there’s anything wrong with Discourse, but I might not see the question.

The way to get any kind of data out of each iteration in the optimization is to use a custom `info_hook` (let’s call it `store_pulses`) and pass that to the `optimize` function ([see the documentation about the `info_hook` parameter](https://juliaquantumcontrol.github.io/GRAPE.jl/stable/api/#GRAPE.optimize_grape-Tuple%7BAny%7D)). In the specific example you link to, you’d be adding `store_pulses` to the existing hooks (where you see `chain_infohooks`). The `store_pulses` should return a tuple of the optimized pulses. These will then be available in `result.records`, where `result` is the object returned by the `optimize` routine.

Something like this should do it (not tested):

```julia
function store_pulses(wrk, iteration, _...)
    L = length(wrk.controls)
    ϵ_opt = reshape(wrk.pulsevals, L, :)
    opt_pulses = [discretize_on_midpoints(ϵ_opt[l, :], res.tlist) for l=1:L]
    return Tuple(opt_pulses)
end

```

I realize the documentation didn’t tell you which parameters the `store_pulses` should get, or which properties `wrk` has. Hopefully, that will get better in future versions. In the meantime, custom `info_hooks` probably will require looking at the source code of the package.

I should also mention that probably in the next major release of GRAPE.jl, the layout of `wrk.pulsevals` will be transposed, so you’d have to reshape it as `reshape(wrk.pulsevals, :, L)` and then access `ϵ_opt[:, l]`.

You could use [`discretize`](https://juliaquantumcontrol.github.io/QuantumControl.jl/stable/api/quantum_propagators/#QuantumPropagators.Controls.discretize) instead of [`discretize_on_midpoints`](https://juliaquantumcontrol.github.io/QuantumControl.jl/stable/api/quantum_propagators/#QuantumPropagators.Controls.discretize_on_midpoints) if you want to get the optimized controls on the points of the time grid instead of the “pulses” defined on the midpoints of the time grid, but that would introduce additional overhead to do the conversion in each iteration. Or, you could also just return a tuple with `wrk.pulsevals` as the only element, and then sort it out later.

Since what you’re trying to do is probably quite common, we should include this information in the documentation: [Add a Howto on how to access the optimized pulses in each iteration · Issue #18 · JuliaQuantumControl/QuantumControl.jl · GitHub](https://github.com/JuliaQuantumControl/QuantumControl.jl/issues/18)

---

<div class="post-metadata">

**Author:** ![saba](https://avatars.discourse-cdn.com/v4/letter/s/d2c977/32.png) [@saba](https://discourse.julialang.org/u/saba)\
**Post date:** [October 4, 2022, 8:27am UTC](https://discourse.julialang.org/t/grapes-method-in-quantum-control-grape-jl/88208/3 "2022-10-04T08:27:50Z")

</div>

> [@goerz](#):
>
> `store_pulses(wrk, iteration, _...)`

Thanks for your response.  
I tried to follow these steps. But I have some questions as I faced some errors.

1. Is wrk= GRAPE.GrapeWrk(problem;) ?
2. What dose the “iteration” that you defined in the “store\_pulses(wrk, iteration, \_…)” do?

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [October 4, 2022, 10:43am UTC](https://discourse.julialang.org/t/grapes-method-in-quantum-control-grape-jl/88208/4 "2022-10-04T10:43:14Z")

</div>

> 1. Is wrk= GRAPE.GrapeWrk(problem;)

Yes, exactly.

> 1. What does the “iteration” that you defined in the `store_pulses(wrk, iteration, _…)` do

That’s just the iteration number (as an integer)

In general, you can temporarily put e.g. `@show iteration` or `@show typeof(wrk)` somewhere in your `store_pulses` function. Julia is very good at “print-debugging”.

---

<div class="post-metadata">

**Author:** ![saba](https://avatars.discourse-cdn.com/v4/letter/s/d2c977/32.png) [@saba](https://discourse.julialang.org/u/saba)\
**Post date:** [October 4, 2022, 11:53am UTC](https://discourse.julialang.org/t/grapes-method-in-quantum-control-grape-jl/88208/5 "2022-10-04T11:53:14Z")

</div>

I wrote this:

```julia
function store_pulses(wrk)
    L = length(wrk.controls)
    ϵ_opt = reshape(wrk.pulsevals, L, :)
    opt_pulses = [QuantumPropagators.Controls.discretize_on_midpoints(ϵ_opt[l, :], tlist) for l=1:L]
    return Tuple(opt_pulses)
end

```

and it is the optimization part:

```julia
opt_result_LBFGSB, file = @optimize_or_load(
    datadir("TLS"),
    problem,
    method = :grape,
    force = true,
    filename = "opt_result_LBFGSB.jld2",
    info_hook = chain_infohooks(
        GRAPELinesearchAnalysis.plot_linesearch(datadir("TLS", "Linesearch", "LBFGSB")),
        QuantumControl.GRAPE.print_table,
        store_pulses(wrk)
    )
);

```

and I got this error: _MethodError: objects of type Tuple{Vector{Float64}} are not callable_

---

<div class="post-metadata">

**Author:** ![goerz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/goerz/32/3269_2.png) [@goerz](https://discourse.julialang.org/u/goerz)\
**Post date:** [October 4, 2022, 4:04pm UTC](https://discourse.julialang.org/t/grapes-method-in-quantum-control-grape-jl/88208/6 "2022-10-04T16:04:12Z")

</div>

There’s two points where you didn’t follow my instructions 😉 :

1. You’re not using the correct signature for `store_pulses`. It has to be `store_pulses(wrk, iteration, _...)`
2. You’re not passing `store_pulses` as an `info_hook`, but the result of `store_pulses(wrk)`, which is where your error originates.

Here is a complete working example:

> **[Jupyter Notebook Viewer](https://nbviewer.org/gist/goerz/3cfce8bb21412a9ce9335a443cb8be6b)**
>
> Check out this Jupyter notebook!

---

<div class="post-metadata">

**Author:** ![saba](https://avatars.discourse-cdn.com/v4/letter/s/d2c977/32.png) [@saba](https://discourse.julialang.org/u/saba)\
**Post date:** [October 4, 2022, 9:45pm UTC](https://discourse.julialang.org/t/grapes-method-in-quantum-control-grape-jl/88208/7 "2022-10-04T21:45:21Z")

</div>

I appreciate the information you have provided me with, and I appreciate your prompt reply.
