# Open-loop optimal controlΒΆ

In order to improve the gate from the previous example Setup of a two-qubit chip with C^3, we create the optimizer object for open-loop optimal control. Examining the previous dynamics .. image:: dyn_singleX.png

in addition to over-rotation, we notice some leakage into the \(|2,0>\) state and enable a DRAG option. Details on DRAG can be found here. The main principle is adding a phase-shifted component proportional to the derivative of the original signal. With automatic differentiation, our AWG can perform this operation automatically for arbitrary shapes.

```
generator.devices['awg'].options = 'drag_2'
```

At the moment there are two implementations of DRAG, variant 2 is independent of the AWG resolution.

To define which parameters we optimize, we write the gateset_opt_map, a nested list of tuples that identifies each parameter.

```
opt_gates = ["X90p:Id"]
gateset_opt_map=[
[
("X90p:Id", "d1", "gauss", "amp"),
],
[
("X90p:Id", "d1", "gauss", "freq_offset"),
],
[
("X90p:Id", "d1", "gauss", "xy_angle"),
],
[
("X90p:Id", "d1", "gauss", "delta"),
]
]
```

We can look at the parameter values this opt_map specified with

```
exp.gateset.get_parameters(gateset_opt_map)
```

```
[<tf.Tensor: shape=(), dtype=float64, numpy=0.5>,
<tf.Tensor: shape=(), dtype=float64, numpy=-333008821.28051805>,
<tf.Tensor: shape=(), dtype=float64, numpy=-4.440892098500626e-16>,
<tf.Tensor: shape=(), dtype=float64, numpy=0.0>]
```

More human friendly output is generated by

```
print(exp.gateset.print_parameters(gateset_opt_map))
```

```
X90p:Id-d1-gauss-amp : 500.000 mV
X90p:Id-d1-gauss-freq_offset: -53.000 MHz 2pi
X90p:Id-d1-gauss-xy_angle : -444.089 arad
X90p:Id-d1-gauss-delta : 0.000
```

```
from c3.optimizers.c1 import C1
import c3.libraries.algorithms as algorithms
```

The C1 object will handle the optimization for us. As a fidelity function we choose average fidelity as well as LBFG-S (a wrapper of the scipy implementation) from our library. See those libraries for how these functions are defined and how to supply your own, if necessary.

```
opt = C1(
dir_path="/tmp/c3log/",
fid_func=fidelities.average_infid_set,
fid_subspace=["Q1", "Q2"],
gateset_opt_map=gateset_opt_map,
opt_gates=opt_gates,
algorithm=algorithms.lbfgs,
options={"maxfun" : 10},
run_name="better_X90"
)
```

Finally we supply our defined experiment.

```
opt.set_exp(exp)
```

Everything is in place to start the optimization.

```
opt.optimize_controls()
```

After a few steps we have improved the gate significantly, as we can check with

```
opt.current_best_goal
```

```
0.0006394
```

And by looking at the same sequences as before.

```
exp.plot_dynamics(init_state, barely_a_seq, debug=True)
```

```
exp.plot_dynamics(init_state, barely_a_seq * 5, debug=True)
```

Compared to before the optimization.