-
Notifications
You must be signed in to change notification settings - Fork 29
/
09_howto.html
652 lines (521 loc) · 57 KB
/
09_howto.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>How-Tos — Krotov 7c20d3f documentation</title>
<script type="text/javascript" src="_static/js/modernizr.min.js"></script>
<script type="text/javascript" id="documentation_options" data-url_root="./" src="_static/documentation_options.js"></script>
<script type="text/javascript" src="_static/jquery.js"></script>
<script type="text/javascript" src="_static/underscore.js"></script>
<script type="text/javascript" src="_static/doctools.js"></script>
<script type="text/javascript" src="_static/language_data.js"></script>
<script type="text/javascript" src="_static/version-alert.js"></script>
<script crossorigin="anonymous" integrity="sha256-Ae2Vz/4ePdIu6ZyI/5ZGsYnb+m0JlOmKPjt6XZ9JJkA=" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/require.js/2.3.4/require.min.js"></script>
<script async="async" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js"></script>
<script type="text/x-mathjax-config">MathJax.Hub.Config({"extensions": ["tex2jax.js"], "jax": ["input/TeX", "output/SVG"], "TeX": {"extensions": ["AMSmath.js", "AMSsymbols.js"], "Macros": {"tr": ["{\\operatorname{tr}}", 0], "diag": ["{\\operatorname{diag}}", 0], "abs": ["{\\operatorname{abs}}", 0], "pop": ["{\\operatorname{pop}}", 0], "ee": ["{\\text{e}}", 0], "ii": ["{\\text{i}}", 0], "aux": ["{\\text{aux}}", 0], "opt": ["{\\text{opt}}", 0], "tgt": ["{\\text{tgt}}", 0], "init": ["{\\text{init}}", 0], "lab": ["{\\text{lab}}", 0], "rwa": ["{\\text{rwa}}", 0], "bra": ["{\\langle#1\\vert}", 1], "ket": ["{\\vert#1\\rangle}", 1], "Bra": ["{\\left\\langle#1\\right\\vert}", 1], "Braket": ["{\\left\\langle #1\\vphantom{#2} \\mid #2\\vphantom{#1}\\right\\rangle}", 2], "ketbra": ["{\\vert#1\\rangle\\!\\langle#2\\vert}", 2], "Ket": ["{\\left\\vert#1\\right\\rangle}", 1], "mat": ["{\\mathbf{#1}}", 1], "op": ["{\\hat{#1}}", 1], "Op": ["{\\hat{#1}}", 1], "dd": ["{\\,\\text{d}}", 0], "daggered": ["{^{\\dagger}}", 0], "transposed": ["{^{\\text{T}}}", 0], "Liouville": ["{\\mathcal{L}}", 0], "DynMap": ["{\\mathcal{E}}", 0], "identity": ["{\\mathbf{1}}", 0], "Norm": ["{\\left\\lVert#1\\right\\rVert}", 1], "norm": ["{\\lVert#1\\rVert}", 1], "Abs": ["{\\left\\vert#1\\right\\vert}", 1], "avg": ["{\\langle#1\\rangle}", 1], "Avg": ["{\\left\\langle#1\\right\\rangle}", 1], "AbsSq": ["{\\left\\vert#1\\right\\vert^2}", 1], "Re": ["{\\operatorname{Re}}", 0], "Im": ["{\\operatorname{Im}}", 0], "Real": ["{\\mathbb{R}}", 0], "Complex": ["{\\mathbb{C}}", 0], "Integer": ["{\\mathbb{N}}", 0]}}, "tex2jax": {"inlineMath": [["$", "$"], ["\\(", "\\)"]], "processEscapes": true, "ignoreClass": "document", "processClass": "math|output_area"}})</script>
<script type="text/javascript" src="_static/js/theme.js"></script>
<link rel="stylesheet" href="_static/css/theme.css" type="text/css" />
<link rel="stylesheet" href="_static/pygments.css" type="text/css" />
<link rel="stylesheet" href="_static/graphviz.css" type="text/css" />
<link rel="stylesheet" href="_static/mycss.css" type="text/css" />
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Other Optimization Methods" href="10_other_methods.html" />
<link rel="prev" title="Optimization with numpy Arrays" href="notebooks/09_example_numpy.html" />
</head>
<body class="wy-body-for-nav">
<div class="wy-grid-for-nav">
<nav data-toggle="wy-nav-shift" class="wy-nav-side">
<div class="wy-side-scroll">
<div class="wy-side-nav-search" >
<a href="index.html" class="icon icon-home"> Krotov
</a>
<div class="version">
0.4.0
</div>
<div role="search">
<form id="rtd-search-form" class="wy-form" action="search.html" method="get">
<input type="text" name="q" placeholder="Search docs" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
</div>
<div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
<p class="caption"><span class="caption-text">Contents:</span></p>
<ul class="current">
<li class="toctree-l1"><a class="reference internal" href="01_overview.html">Krotov Python Package</a></li>
<li class="toctree-l1"><a class="reference internal" href="02_contributing.html">Contributing</a></li>
<li class="toctree-l1"><a class="reference internal" href="03_authors.html">Credits</a></li>
<li class="toctree-l1"><a class="reference internal" href="04_features.html">Features</a></li>
<li class="toctree-l1"><a class="reference internal" href="05_history.html">History</a></li>
<li class="toctree-l1"><a class="reference internal" href="06_krotovs_method.html">Krotov’s Method</a></li>
<li class="toctree-l1"><a class="reference internal" href="07_qutip_usage.html">Using Krotov with QuTiP</a></li>
<li class="toctree-l1"><a class="reference internal" href="08_examples.html">Examples</a></li>
<li class="toctree-l1 current"><a class="current reference internal" href="#">How-Tos</a><ul>
<li class="toctree-l2"><a class="reference internal" href="#how-to-optimize-towards-a-quantum-gate">How to optimize towards a quantum gate</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-optimize-complex-valued-control-fields">How to optimize complex-valued control fields</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-stop-the-optimization-when-the-error-crosses-some-threshold">How to stop the optimization when the error crosses some threshold</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-exclude-a-control-from-the-optimization">How to exclude a control from the optimization</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-define-a-new-optimization-functional">How to define a new optimization functional</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-penalize-population-in-a-forbidden-subspace">How to penalize population in a forbidden subspace</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-optimize-towards-a-two-qubit-gate-up-to-single-qubit-corrections">How to optimize towards a two-qubit gate up to single-qubit corrections</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-optimize-towards-an-arbitrary-perfect-entangler">How to optimize towards an arbitrary perfect entangler</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-optimize-in-a-dissipative-system">How to optimize in a dissipative system</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-optimize-for-robust-pulses">How to optimize for robust pulses</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-apply-spectral-constraints">How to apply spectral constraints</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-limit-the-amplitude-of-the-controls">How to limit the amplitude of the controls</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-parallelize-the-optimization">How to parallelize the optimization</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-prevent-losing-an-optimization-result">How to prevent losing an optimization result</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-continue-from-a-previous-optimization">How to continue from a previous optimization</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-maximize-numerical-efficiency">How to maximize numerical efficiency</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-deal-with-the-optimization-running-out-of-memory">How to deal with the optimization running out of memory</a></li>
<li class="toctree-l2"><a class="reference internal" href="#how-to-avoid-the-overhead-of-qutip-objects">How to avoid the overhead of QuTiP objects</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="10_other_methods.html">Other Optimization Methods</a></li>
<li class="toctree-l1"><a class="reference internal" href="99_bibliography.html">References</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="API/krotov.html">API of the Krotov package</a></li>
</ul>
</div>
</div>
</nav>
<section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">
<nav class="wy-nav-top" aria-label="top navigation">
<i data-toggle="wy-nav-top" class="fa fa-bars"></i>
<a href="index.html">Krotov</a>
</nav>
<div class="wy-nav-content">
<div class="rst-content">
<div role="navigation" aria-label="breadcrumbs navigation">
<ul class="wy-breadcrumbs">
<li><a href="index.html">Docs</a> »</li>
<li>How-Tos</li>
<li class="wy-breadcrumbs-aside">
</li>
</ul>
<hr/>
</div>
<div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
<div itemprop="articleBody">
<style>
/* CSS overrides for sphinx_rtd_theme */
/* 24px margin */
.nbinput.nblast.container,
.nboutput.nblast.container {
margin-bottom: 19px; /* padding has already 5px */
}
/* ... except between code cells! */
.nblast.container + .nbinput.container {
margin-top: -19px;
}
.admonition > p:before {
margin-right: 4px; /* make room for the exclamation icon */
}
/* Fix math alignment, see https://github.com/rtfd/sphinx_rtd_theme/pull/686 */
.math {
text-align: unset;
}
</style>
<div class="section" id="how-tos">
<h1>How-Tos<a class="headerlink" href="#how-tos" title="Permalink to this headline">¶</a></h1>
<div class="section" id="how-to-optimize-towards-a-quantum-gate">
<h2>How to optimize towards a quantum gate<a class="headerlink" href="#how-to-optimize-towards-a-quantum-gate" title="Permalink to this headline">¶</a></h2>
<p>To optimize towards a quantum gate <span class="math notranslate nohighlight">\(\Op{O}\)</span> in a <em>closed</em> quantum system,
set one <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective" title="krotov.objectives.Objective"><code class="xref py py-class docutils literal notranslate"><span class="pre">Objective</span></code></a> for each state in the logical basis, with the basis
state <span class="math notranslate nohighlight">\(\ket{\phi_k}\)</span> as the <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective.initial_state" title="krotov.objectives.Objective.initial_state"><code class="xref py py-attr docutils literal notranslate"><span class="pre">initial_state</span></code></a> and
<span class="math notranslate nohighlight">\(\Op{O} \ket{\phi_k}\)</span> as the <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective.target" title="krotov.objectives.Objective.target"><code class="xref py py-attr docutils literal notranslate"><span class="pre">target</span></code></a>.</p>
<p>You may use <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.gate_objectives" title="krotov.objectives.gate_objectives"><code class="xref py py-func docutils literal notranslate"><span class="pre">krotov.gate_objectives()</span></code></a>
to construct the appropriate list of objectives. See the
<a class="reference internal" href="notebooks/05_example_transmon_xgate.html"><span class="std std-ref">Optimization of an X-Gate for a Transmon Qubit</span></a> for an example. For more
advanced gate optimizations, also see <a class="reference internal" href="#howtolioptimization"><span class="std std-ref">How to optimize towards a two-qubit gate up to single-qubit corrections</span></a>,
<a class="reference internal" href="#howtopeoptimization"><span class="std std-ref">How to optimize towards an arbitrary perfect entangler</span></a>, <a class="reference internal" href="#howtodissipativeoptimization"><span class="std std-ref">How to optimize in a dissipative system</span></a>, and
<a class="reference internal" href="#howtorobustoptimization"><span class="std std-ref">How to optimize for robust pulses</span></a>.</p>
</div>
<div class="section" id="how-to-optimize-complex-valued-control-fields">
<h2>How to optimize complex-valued control fields<a class="headerlink" href="#how-to-optimize-complex-valued-control-fields" title="Permalink to this headline">¶</a></h2>
<p>This implementation of Krotov’s method requires real-valued control fields. You
must rewrite your Hamiltonian to contain the real part and the imaginary part
of the field as two independent controls. This is always possible. For example,
for a driven harmonic oscillator in the rotating wave approximation, the
interaction Hamiltonian is given by</p>
<div class="math notranslate nohighlight">
\[\Op{H}_\text{int}
= \epsilon^*(t) \Op{a} + \epsilon(t) \Op{a}^\dagger
= \epsilon_{\text{re}}(t) (\Op{a} + \Op{a}^\dagger) + \epsilon_{\text{im}}(t) (i \Op{a}^\dagger - i \Op{a})\,,\]</div>
<p>where <span class="math notranslate nohighlight">\(\epsilon_{\text{re}}(t)= \Re[\epsilon(t)]\)</span> and
<span class="math notranslate nohighlight">\(\epsilon_{\text{im}}(t) = \Im[\epsilon(t)]\)</span> are considered as two
independent (real-valued) controls.</p>
<p>See the <a class="reference internal" href="notebooks/02_example_lambda_system_rwa_complex_pulse.html"><span class="std std-ref">Optimization of a State-to-State Transfer in a Lambda System in the RWA</span></a> for an example.</p>
</div>
<div class="section" id="how-to-stop-the-optimization-when-the-error-crosses-some-threshold">
<h2>How to stop the optimization when the error crosses some threshold<a class="headerlink" href="#how-to-stop-the-optimization-when-the-error-crosses-some-threshold" title="Permalink to this headline">¶</a></h2>
<p>By default, an optimization stops after a predefined number of iterations
(<cite>iter_stop</cite> parameter in <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a>). However, through the
interplay of the <cite>info_hook</cite> and the <cite>check_convergence</cite> routine passed to
<a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a>, the optimization can be stopped based on the
optimization success or the rate of convergence: The <cite>info_hook</cite> routine should
return the value of the optimization functional or error, which is accessible to
<cite>check_convergence</cite> via the <a class="reference internal" href="API/krotov.result.html#krotov.result.Result.info_vals" title="krotov.result.Result.info_vals"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Result.info_vals</span></code></a> attribute, see
<a class="reference internal" href="API/krotov.convergence.html#module-krotov.convergence" title="krotov.convergence"><code class="xref py py-mod docutils literal notranslate"><span class="pre">krotov.convergence</span></code></a> for details.</p>
<p>Generally, you should use the <a class="reference internal" href="API/krotov.info_hooks.html#krotov.info_hooks.print_table" title="krotov.info_hooks.print_table"><code class="xref py py-func docutils literal notranslate"><span class="pre">krotov.info_hooks.print_table()</span></code></a> function as
an <cite>info_hook</cite>, which receives a function to evaluate the optimization
functional <span class="math notranslate nohighlight">\(J_T\)</span> as a parameter. Then, use
<a class="reference internal" href="API/krotov.convergence.html#krotov.convergence.value_below" title="krotov.convergence.value_below"><code class="xref py py-func docutils literal notranslate"><span class="pre">krotov.convergence.value_below()</span></code></a> as a <cite>check_convergence</cite> routine to stop
the optimization when <span class="math notranslate nohighlight">\(J_T\)</span> falls below some given threshold.</p>
<p>See the <a class="reference internal" href="notebooks/02_example_lambda_system_rwa_complex_pulse.html"><span class="std std-ref">Optimization of a State-to-State Transfer in a Lambda System in the RWA</span></a> for
an example.</p>
</div>
<div class="section" id="how-to-exclude-a-control-from-the-optimization">
<h2>How to exclude a control from the optimization<a class="headerlink" href="#how-to-exclude-a-control-from-the-optimization" title="Permalink to this headline">¶</a></h2>
<p>In order to force the optimization to leave any particular control field
unchanged, set its update shape to <a class="reference internal" href="API/krotov.shapes.html#krotov.shapes.zero_shape" title="krotov.shapes.zero_shape"><code class="xref py py-func docutils literal notranslate"><span class="pre">krotov.shapes.zero_shape()</span></code></a>
in the <cite>pulse_options</cite> that you pass to <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a>.</p>
</div>
<div class="section" id="how-to-define-a-new-optimization-functional">
<h2>How to define a new optimization functional<a class="headerlink" href="#how-to-define-a-new-optimization-functional" title="Permalink to this headline">¶</a></h2>
<p>In order to define a new optimization functional <span class="math notranslate nohighlight">\(J_T\)</span>:</p>
<ul>
<li><p>Decide on what should go in <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective.target" title="krotov.objectives.Objective.target"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Objective.target</span></code></a> to best describe the
<em>physical</em> control target. If the control target is reached when the
<a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective.initial_state" title="krotov.objectives.Objective.initial_state"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Objective.initial_state</span></code></a> evolves to a specific target state under the
optimal control fields, that target state should be included in
<a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective.target" title="krotov.objectives.Objective.target"><code class="xref py py-attr docutils literal notranslate"><span class="pre">target</span></code></a>.</p></li>
<li><p>Define a function <cite>chi_constructor</cite> that calculates the boundary
condition for the backward-propagation in Krotov’s method,</p>
<div class="math notranslate nohighlight">
\[\ket{\chi_k(T)} \equiv - \left. \frac{\partial J_T}{\partial \bra{\phi_k(T)}} \right\vert_{\ket{\phi_k(T)}}\,,\]</div>
<p>or the equivalent experession in Liouville space. This function should
calculate the states <span class="math notranslate nohighlight">\(\ket{\chi_k}\)</span> based on the forward-propagated
states <span class="math notranslate nohighlight">\(\ket{\phi_k(T)}\)</span> and the list of objectives. For convenience,
when <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective.target" title="krotov.objectives.Objective.target"><code class="xref py py-attr docutils literal notranslate"><span class="pre">target</span></code></a> contains a target state, <cite>chi_constructor</cite>
will also receive <cite>tau_vals</cite> containing the overlaps <span class="math notranslate nohighlight">\(\tau_k =
\Braket{\phi_k^{\tgt}}{\phi_k(T)}\)</span>. See <a class="reference internal" href="API/krotov.functionals.html#krotov.functionals.chis_re" title="krotov.functionals.chis_re"><code class="xref py py-func docutils literal notranslate"><span class="pre">chis_re()</span></code></a> for an example.</p>
</li>
<li><p>Optionally, define a function that can be used as an <cite>info_hook</cite>
in <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a> which returns the value
<span class="math notranslate nohighlight">\(J_T\)</span>. This is not required to run an optimization since the
functional is entirely implicit in <cite>chi_constructor</cite>. However, calculating
the value of the functional is useful for convergence analysis
(<cite>check_convergence</cite> in <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a>)</p></li>
</ul>
<p>See <a class="reference internal" href="API/krotov.functionals.html#module-krotov.functionals" title="krotov.functionals"><code class="xref py py-mod docutils literal notranslate"><span class="pre">krotov.functionals</span></code></a> for some standard functionals. An example for a
more advanced functional is the <a class="reference internal" href="notebooks/07_example_PE.html"><span class="std std-ref">Optimization towards a Perfect Entangler</span></a>.</p>
</div>
<div class="section" id="how-to-penalize-population-in-a-forbidden-subspace">
<h2>How to penalize population in a forbidden subspace<a class="headerlink" href="#how-to-penalize-population-in-a-forbidden-subspace" title="Permalink to this headline">¶</a></h2>
<p>In principle, <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a> has a <cite>state_dependent_constraint</cite>.
However, this has some caveats. Most notably, it results in an inhomogeneous
equation of motion, which is currently not implemented.</p>
<p>The recommended “workaround” is to place artificially high dissipation on the
levels in the forbidden subspace. A non-Hermitian Hamiltonian is usually a
good way to realize this. See the
<a class="reference internal" href="notebooks/03_example_lambda_system_rwa_non_hermitian.html"><span class="std std-ref">Optimization of a Dissipative State-to-State Transfer in a Lambda System</span></a>
for an example.</p>
</div>
<div class="section" id="how-to-optimize-towards-a-two-qubit-gate-up-to-single-qubit-corrections">
<span id="howtolioptimization"></span><h2>How to optimize towards a two-qubit gate up to single-qubit corrections<a class="headerlink" href="#how-to-optimize-towards-a-two-qubit-gate-up-to-single-qubit-corrections" title="Permalink to this headline">¶</a></h2>
<p>Use <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.gate_objectives" title="krotov.objectives.gate_objectives"><code class="xref py py-func docutils literal notranslate"><span class="pre">krotov.objectives.gate_objectives()</span></code></a> with <code class="docutils literal notranslate"><span class="pre">local_invariants=True</span></code> in
order to construct a list of objectives suitable for an optimization using a
“local-invariant functional” <a class="bibtex reference internal" href="99_bibliography.html#mullerpra11" id="id1">[19]</a>. This optimizes towards a
point in the <a class="reference external" href="https://weylchamber.readthedocs.io/en/latest/tutorial.html">Weyl chamber</a>.</p>
<p>The <a class="reference external" href="https://github.com/qucontrol/weylchamber"><code class="docutils literal notranslate"><span class="pre">weylchamber</span></code> package</a> contains the suitable <cite>chi_constructor</cite> routines to
pass to <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a>.</p>
</div>
<div class="section" id="how-to-optimize-towards-an-arbitrary-perfect-entangler">
<span id="howtopeoptimization"></span><h2>How to optimize towards an arbitrary perfect entangler<a class="headerlink" href="#how-to-optimize-towards-an-arbitrary-perfect-entangler" title="Permalink to this headline">¶</a></h2>
<p>Closely related to an optimization towards a point in the Weyl chamber is the
optimization towards an arbitrary perfectly entangling two-qubit gate.
Geometrically, this means optimizing towards the polyhedron of perfect
entanglers in the <a class="reference external" href="https://weylchamber.readthedocs.io/en/latest/tutorial.html">Weyl chamber</a>.</p>
<p>Use <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.gate_objectives" title="krotov.objectives.gate_objectives"><code class="xref py py-func docutils literal notranslate"><span class="pre">krotov.objectives.gate_objectives()</span></code></a> with <code class="docutils literal notranslate"><span class="pre">gate='PE'</span></code> in
order to construct a list of objectives suitable for an optimization using a
“perfect entanglers” functional <a class="bibtex reference internal" href="99_bibliography.html#wattspra2015" id="id2">[17]</a><a class="bibtex reference internal" href="99_bibliography.html#goerzpra2015" id="id3">[18]</a>.
This is illustrated in the <a class="reference internal" href="notebooks/07_example_PE.html"><span class="std std-ref">Optimization towards a Perfect Entangler</span></a>.</p>
<p>Again, the <cite>chi_constructor</cite> is available in the <a class="reference external" href="https://github.com/qucontrol/weylchamber"><code class="docutils literal notranslate"><span class="pre">weylchamber</span></code> package</a>.</p>
</div>
<div class="section" id="how-to-optimize-in-a-dissipative-system">
<span id="howtodissipativeoptimization"></span><h2>How to optimize in a dissipative system<a class="headerlink" href="#how-to-optimize-in-a-dissipative-system" title="Permalink to this headline">¶</a></h2>
<p>To optimize a dissipative system, it is sufficient to set an <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective" title="krotov.objectives.Objective"><code class="xref py py-class docutils literal notranslate"><span class="pre">Objective</span></code></a>
with a density matrix for the <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective.initial_state" title="krotov.objectives.Objective.initial_state"><code class="xref py py-attr docutils literal notranslate"><span class="pre">initial_state</span></code></a> and
<a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective.target" title="krotov.objectives.Objective.target"><code class="xref py py-attr docutils literal notranslate"><span class="pre">target</span></code></a>, and a Liouvillian in <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective.H" title="krotov.objectives.Objective.H"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Objective.H</span></code></a>.
See the <a class="reference internal" href="notebooks/04_example_dissipative_qubit_reset.html"><span class="std std-ref">Optimization of Dissipative Qubit Reset</span></a> for an
example.</p>
<p>Instead of a Liouvillian, it is also possible to set <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective.H" title="krotov.objectives.Objective.H"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Objective.H</span></code></a> to
the system Hamiltonian, and <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective.c_ops" title="krotov.objectives.Objective.c_ops"><code class="xref py py-attr docutils literal notranslate"><span class="pre">Objective.c_ops</span></code></a> to the appropriate
Lindblad operators. However, it is generally much more efficient to use
<a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.liouvillian" title="krotov.objectives.liouvillian"><code class="xref py py-func docutils literal notranslate"><span class="pre">krotov.objectives.liouvillian()</span></code></a> to convert a time-dependent Hamiltonian
and a list of Lindblad operators into a time-dependent Liouvillian. In either
case, the <cite>propagate</cite> routine passed to <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a>
must be aware of and compatible with the convention for the objectives.</p>
<p>Specifically for gate optimization, the routine
<a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.gate_objectives" title="krotov.objectives.gate_objectives"><code class="xref py py-func docutils literal notranslate"><span class="pre">gate_objectives()</span></code></a>
can be used to automatically set appropriate objectives for an optimization in
Liouville space. The parameter <cite>liouville_states_set</cite> indicates that the system
dynamics are in Liouville space and sets an appropriate choice of matrices that
track the optimization according to Ref. <a class="bibtex reference internal" href="99_bibliography.html#goerznjp2014" id="id4">[14]</a>.
See the <a class="reference internal" href="notebooks/06_example_3states.html"><span class="std std-ref">Optimization of a Dissipative Quantum Gate</span></a> for an example.</p>
<p>For weak dissipation, it may also be possible to avoid the use of density
matrices altogether, and to instead use a non-Hermitian Hamiltonian. For example, you may
use the effective Hamiltonian from the MCWF method <a class="bibtex reference internal" href="99_bibliography.html#pleniormp1998" id="id5">[20]</a>,</p>
<div class="math notranslate nohighlight">
\[\Op{H}_{\text{eff}} = \Op{H} - \frac{i}{2} \sum_k \Op{L}_k^\dagger \Op{L}_k\,,\]</div>
<p>for the Hermitian Hamiltonian <span class="math notranslate nohighlight">\(\Op{H}\)</span> and the Lindblad operators
<span class="math notranslate nohighlight">\(\Op{L}_k\)</span>. Propagating <span class="math notranslate nohighlight">\(\Op{H}_{\text{eff}}\)</span> (without quantum
jumps) will lead to a decay in the norm of the state corresponding to how much
dissipation the state is subjected to. Numerically, this will usually increase
the value of the optimization functional (that is, the error). Thus the
optimization can be pushed towards avoiding decoherence, without explicitly
performing the optimization in Liouville space. See the
<a class="reference internal" href="notebooks/03_example_lambda_system_rwa_non_hermitian.html"><span class="std std-ref">Optimization of a Dissipative State-to-State Transfer in a Lambda System</span></a> for an
example.</p>
</div>
<div class="section" id="how-to-optimize-for-robust-pulses">
<span id="howtorobustoptimization"></span><h2>How to optimize for robust pulses<a class="headerlink" href="#how-to-optimize-for-robust-pulses" title="Permalink to this headline">¶</a></h2>
<p>Control pulses can be made robust with respect to variations in the system by
doing an ensemble optimization, as proposed in Ref. <a class="bibtex reference internal" href="99_bibliography.html#goerzpra2014" id="id6">[21]</a>. The
idea if to sample a representative selection of possible system Hamiltonians,
and to optimize over an <em>average</em> of the entire ensemble.</p>
<p>An appropriate set of objectives can be generated with the
<a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.ensemble_objectives" title="krotov.objectives.ensemble_objectives"><code class="xref py py-func docutils literal notranslate"><span class="pre">ensemble_objectives()</span></code></a> function.</p>
</div>
<div class="section" id="how-to-apply-spectral-constraints">
<span id="howtospectralconstraints"></span><h2>How to apply spectral constraints<a class="headerlink" href="#how-to-apply-spectral-constraints" title="Permalink to this headline">¶</a></h2>
<p>In principle, Krotov’s method can include spectral constraints while
maintaining the guarantee for monotonic convergence <a class="bibtex reference internal" href="99_bibliography.html#reichjmo14" id="id7">[22]</a> .
However, the calculation of the pulse update with such spectral constraints
requires solving a Fredholm equation of the second kind, which has not yet been
implemented numerically. Thus, the <code class="docutils literal notranslate"><span class="pre">krotov</span></code> package does not support this
approach (and no such support is planned).</p>
<p>A “cheap” alternative that usually yields good results is to apply a spectral
filter to the optimized pulses after each iteration. The
<a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a> function allows this via the
<cite>modify_params_after_iter</cite> argument.</p>
<p>For example, the following function restricts the spectrum of each pulse to a
given range:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">apply_spectral_filter</span><span class="p">(</span><span class="n">tlist</span><span class="p">,</span> <span class="n">w0</span><span class="p">,</span> <span class="n">w1</span><span class="p">):</span>
<span class="sd">"""Spectral filter for real-valued pulses.</span>
<span class="sd"> The resulting filter function performs a Fast-Fourier-Transform (FFT) of</span>
<span class="sd"> each optimized pulse, and sets spectral components for angular</span>
<span class="sd"> frequencies below `w0` or above `w1` to zero. The filtered pulse is then</span>
<span class="sd"> the result of the inverse FFT, and multiplying again with the update</span>
<span class="sd"> shape for the pulse, to ensure that the filtered pulse still fulfills</span>
<span class="sd"> the required boundary conditions.</span>
<span class="sd"> Args:</span>
<span class="sd"> tlist (numpy.ndarray): Array of time grid values. All pulses must be</span>
<span class="sd"> defined on the intervals of this time grid</span>
<span class="sd"> w0 (float): The lowest allowed (angular) frequency</span>
<span class="sd"> w1 (float): The highest allowed (angular) frequency</span>
<span class="sd"> Returns:</span>
<span class="sd"> callable: A function that can be passed to</span>
<span class="sd"> `modify_params_after_iter` to apply the spectral filter.</span>
<span class="sd"> """</span>
<span class="n">dt</span> <span class="o">=</span> <span class="n">tlist</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">-</span> <span class="n">tlist</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="c1"># assume equi-distant time grid</span>
<span class="n">n</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="n">tlist</span><span class="p">)</span> <span class="o">-</span> <span class="mi">1</span> <span class="c1"># = len(pulse)</span>
<span class="c1"># remember that pulses are defined on intervals of tlist</span>
<span class="n">w</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">abs</span><span class="p">(</span><span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">fftfreq</span><span class="p">(</span><span class="n">n</span><span class="p">,</span> <span class="n">d</span><span class="o">=</span><span class="n">dt</span> <span class="o">/</span> <span class="p">(</span><span class="mf">2.0</span> <span class="o">*</span> <span class="n">np</span><span class="o">.</span><span class="n">pi</span><span class="p">)))</span>
<span class="c1"># the normalization factor 2π means that w0 and w1 are angular</span>
<span class="c1"># frequencies, corresponding directly to energies in the Hamiltonian</span>
<span class="c1"># (ħ = 1).</span>
<span class="n">flt</span> <span class="o">=</span> <span class="p">(</span><span class="n">w0</span> <span class="o"><=</span> <span class="n">w</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">w</span> <span class="o"><=</span> <span class="n">w1</span><span class="p">)</span>
<span class="c1"># flt is the (boolean) filter array, equivalent to an array of values 0</span>
<span class="c1"># and 1</span>
<span class="k">def</span> <span class="nf">_filter</span><span class="p">(</span><span class="o">**</span><span class="n">kwargs</span><span class="p">):</span>
<span class="c1"># same interface as an `info_hook` function</span>
<span class="n">pulses</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">'optimized_pulses'</span><span class="p">]</span>
<span class="n">shape_arrays</span> <span class="o">=</span> <span class="n">kwargs</span><span class="p">[</span><span class="s1">'shape_arrays'</span><span class="p">]</span>
<span class="k">for</span> <span class="p">(</span><span class="n">pulse</span><span class="p">,</span> <span class="n">shape</span><span class="p">)</span> <span class="ow">in</span> <span class="nb">zip</span><span class="p">(</span><span class="n">pulses</span><span class="p">,</span> <span class="n">shape_arrays</span><span class="p">):</span>
<span class="n">spectrum</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">fft</span><span class="p">(</span><span class="n">pulse</span><span class="p">)</span>
<span class="c1"># apply the filter by element-wise multiplication</span>
<span class="n">spectrum</span><span class="p">[:]</span> <span class="o">*=</span> <span class="n">flt</span><span class="p">[:]</span>
<span class="c1"># after the inverse fft, we should also multiply with the</span>
<span class="c1"># update shape function. Otherwise, there is no guarantee that</span>
<span class="c1"># the filtered pulse will be zero at t=0 and t=T (assuming that</span>
<span class="c1"># is what the update shape is supposed to enforce). Also, it is</span>
<span class="c1"># important that we overwrite `pulse` in-place (pulse[:] = ...)</span>
<span class="n">pulse</span><span class="p">[:]</span> <span class="o">=</span> <span class="n">np</span><span class="o">.</span><span class="n">fft</span><span class="o">.</span><span class="n">ifft</span><span class="p">(</span><span class="n">spectrum</span><span class="p">)</span><span class="o">.</span><span class="n">real</span> <span class="o">*</span> <span class="n">shape</span>
<span class="k">return</span> <span class="n">_filter</span>
</pre></div>
</div>
<p>This function is passed to <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a> as e.g.
<code class="docutils literal notranslate"><span class="pre">modify_params_after_iter=apply_spectral_filter(tlist,</span> <span class="pre">0,</span> <span class="pre">7)</span></code> to constraining
the spectrum of the pulse to angular frequencies <span class="math notranslate nohighlight">\(\omega \in [0, 7]\)</span>.
You may want to explore how such a filter behaves in the example of the
<a class="reference internal" href="notebooks/05_example_transmon_xgate.html"><span class="std std-ref">Optimization of an X-Gate for a Transmon Qubit</span></a>.</p>
<p>Modifying the optimized pulses “manually” through a
<code class="docutils literal notranslate"><span class="pre">modify_params_after_iter</span></code> function means that we lose all guarantees of
monotonic convergence. If the optimization with a spectral filter does not
converge, you should increase the value of <span class="math notranslate nohighlight">\(\lambda_a\)</span> in the <cite>pulse_options</cite>
that are passed to <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a>. A larger value of <span class="math notranslate nohighlight">\(\lambda_a\)</span>
results in smaller updates in each iteration. This should also translate into
the filter pulses being closer to the unfiltered pulses, increasing the
probability that the changes due to the filter do not undo the monotonic
convergence. You may also find that the optimization fails if the control
problem physically cannot be solved with controls in the desired spectral
range. Without a good physical intuition, trial and error may be
required.</p>
</div>
<div class="section" id="how-to-limit-the-amplitude-of-the-controls">
<h2>How to limit the amplitude of the controls<a class="headerlink" href="#how-to-limit-the-amplitude-of-the-controls" title="Permalink to this headline">¶</a></h2>
<p>Amplitude constraints on the control can be realized indirectly through
parametrization <a class="bibtex reference internal" href="99_bibliography.html#muellerpra2011" id="id8">[23]</a>. For example, consider the physical
Hamiltonian <span class="math notranslate nohighlight">\(\Op{H} = \Op{H}_0 + \epsilon(t) \Op{H}_1\)</span>.</p>
<p>There are several possible parametrizations of <span class="math notranslate nohighlight">\(\epsilon(t)\)</span>
in terms of an unconstrained function <span class="math notranslate nohighlight">\(u(t)\)</span>:</p>
<ul>
<li><p>For <span class="math notranslate nohighlight">\(\epsilon(t) \ge 0\)</span>:</p>
<blockquote>
<div><div class="math notranslate nohighlight">
\[\epsilon(t) = u^2(t)\]</div>
</div></blockquote>
</li>
<li><p>For <span class="math notranslate nohighlight">\(0 \le \epsilon(t) < \epsilon_{\max}\)</span>:</p>
<blockquote>
<div><div class="math notranslate nohighlight">
\[\epsilon(t) = \epsilon_{\max} \tanh^2\left(u(t)\right)\]</div>
</div></blockquote>
</li>
<li><p>For <span class="math notranslate nohighlight">\(\epsilon_{\min} < \epsilon(t) < \epsilon_{\max}\)</span>:</p>
<blockquote>
<div><div class="math notranslate nohighlight">
\[\epsilon(t)
= \frac{\epsilon_{\max} - \epsilon_{\min}}{2}
\tanh\left(u(t)\right)
+ \frac{\epsilon_{\max} + \epsilon_{\min}}{2}\]</div>
</div></blockquote>
</li>
</ul>
<p>Krotov’s method can now calculate the update <span class="math notranslate nohighlight">\(\Delta u(t)\)</span> in each
iteration, and then <span class="math notranslate nohighlight">\(\Delta \epsilon(t)\)</span> via the above equations.</p>
<p>There is a caveat: In the update equation <a class="reference internal" href="06_krotovs_method.html#equation-krotov-first-order-update">(8)</a>, we
now have the term</p>
<div class="math notranslate nohighlight">
\[\begin{split}\Bigg(
\left.\frac{\partial \Op{H}}{\partial u}\right\vert_{{\scriptsize \begin{matrix}\phi^{(i+1)}(t)\\u^{(i+1)}(t)\end{matrix}}}
\Bigg)
=
\Bigg(
\left.\frac{\partial \epsilon}{\partial u}\frac{\partial \Op{H}}{\partial \epsilon}\right\vert_{{\scriptsize \begin{matrix}\phi^{(i+1)}(t)\\u^{(i+1)}(t)\end{matrix}}}
\Bigg)\end{split}\]</div>
<p>on the right hand side. As the dependendence of <span class="math notranslate nohighlight">\(\epsilon(t)\)</span> on
<span class="math notranslate nohighlight">\(u(t)\)</span> is non-linear, we are left with a dependency on the unknown
updated parametrization <span class="math notranslate nohighlight">\(u^{(i+1)}(t)\)</span>. We resolve this by approximating
<span class="math notranslate nohighlight">\(u^{(i+1)}(t) \approx u^{(i)}(t)\)</span>, or equivalently <span class="math notranslate nohighlight">\(\Delta u(t) \ll
u(t)\)</span>, which can be enforced by choosing a sufficiently large value of
<span class="math notranslate nohighlight">\(\lambda_a\)</span> in the <cite>pulse_options</cite> that are passed to
<a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a>.</p>
<p>Currently, the <code class="docutils literal notranslate"><span class="pre">krotov</span></code> package does not yet support parametrizations in the
above form, although this is a <a class="reference external" href="https://github.com/qucontrol/krotov/issues/23">planned feature</a>.
In the meantime, you could modify the control to fit within the desired
amplitude constaints in the same way as applying spectral constaints, see
<a class="reference internal" href="#howtospectralconstraints"><span class="std std-ref">How to apply spectral constraints</span></a>.</p>
</div>
<div class="section" id="how-to-parallelize-the-optimization">
<h2>How to parallelize the optimization<a class="headerlink" href="#how-to-parallelize-the-optimization" title="Permalink to this headline">¶</a></h2>
<p>Krotov’s method is inherently parallel across different objectives. See
<a class="reference internal" href="API/krotov.parallelization.html#module-krotov.parallelization" title="krotov.parallelization"><code class="xref py py-mod docutils literal notranslate"><span class="pre">krotov.parallelization</span></code></a>, and the
<a class="reference internal" href="notebooks/05_example_transmon_xgate.html"><span class="std std-ref">Optimization of an X-Gate for a Transmon Qubit</span></a> for an example.</p>
</div>
<div class="section" id="how-to-prevent-losing-an-optimization-result">
<span id="howtostoreresult"></span><h2>How to prevent losing an optimization result<a class="headerlink" href="#how-to-prevent-losing-an-optimization-result" title="Permalink to this headline">¶</a></h2>
<p>Optimizations usually take several hundred to several thousand iterations to
fully converge. Thus, the <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a> routine may require
significant runtime (often multiple days for large problems). Once an
optimization has completed, you are strongly encouraged to store the result to
disk, using <a class="reference internal" href="API/krotov.result.html#krotov.result.Result.dump" title="krotov.result.Result.dump"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Result.dump()</span></code></a>. You may also consider using
<a class="reference internal" href="API/krotov.convergence.html#krotov.convergence.dump_result" title="krotov.convergence.dump_result"><code class="xref py py-func docutils literal notranslate"><span class="pre">dump_result()</span></code></a> during the <cite>check_convergence</cite> step to dump the current
state of the optimization to disk at regular intervals. This protects you from
losing work if the optimization is interrupted in any way, like an unexpected
crash.</p>
<p>In order to continue after such a crash, you can restore a <a class="reference internal" href="API/krotov.result.html#krotov.result.Result" title="krotov.result.Result"><code class="xref py py-class docutils literal notranslate"><span class="pre">Result</span></code></a>
object containing the recent state of the optimization using
<a class="reference internal" href="API/krotov.result.html#krotov.result.Result.load" title="krotov.result.Result.load"><code class="xref py py-meth docutils literal notranslate"><span class="pre">Result.load()</span></code></a> (with the original <cite>objectives</cite> and <code class="docutils literal notranslate"><span class="pre">finalize=True</span></code> if
the dump file originates from <a class="reference internal" href="API/krotov.convergence.html#krotov.convergence.dump_result" title="krotov.convergence.dump_result"><code class="xref py py-func docutils literal notranslate"><span class="pre">dump_result()</span></code></a>). You may then call
<a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a> and pass the loaded <a class="reference internal" href="API/krotov.result.html#krotov.result.Result" title="krotov.result.Result"><code class="xref py py-class docutils literal notranslate"><span class="pre">Result</span></code></a> object as
<cite>continue_from</cite>. The new optimization will start from the most recent
optimized controls as a guess, and continue to count iterations from the
previous result. See <a class="reference internal" href="#howtocontinueoptimization"><span class="std std-ref">How to continue from a previous optimization</span></a> for further details.</p>
</div>
<div class="section" id="how-to-continue-from-a-previous-optimization">
<span id="howtocontinueoptimization"></span><h2>How to continue from a previous optimization<a class="headerlink" href="#how-to-continue-from-a-previous-optimization" title="Permalink to this headline">¶</a></h2>
<p>See <a class="reference internal" href="#howtostoreresult"><span class="std std-ref">How to prevent losing an optimization result</span></a> for how to continue from an optimization that ended
(crashed) prematurely. Even when an optimization has completed normally, you
may still want to continue with further iterations – either because you find
that the original <cite>iter_stop</cite> was insufficient to reach full convergence, or
because you would like to modify some parameters, like the λₐ values for
each control. In this case, you can again call <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a> and
pass the <a class="reference internal" href="API/krotov.result.html#krotov.result.Result" title="krotov.result.Result"><code class="xref py py-class docutils literal notranslate"><span class="pre">Result</span></code></a> object from the previous optimization as
<cite>continue_from</cite>. Note that while you are free to change the <cite>pulse_options</cite>
between the two optimization, the <cite>objectives</cite> must remain the same. The
functional (<cite>chi_constructor</cite>) and the <cite>info_hook</cite> should also remain the same
(otherwise, you may and up with inconsistencies in your <a class="reference internal" href="API/krotov.result.html#krotov.result.Result" title="krotov.result.Result"><code class="xref py py-class docutils literal notranslate"><span class="pre">Result</span></code></a>). The
<a class="reference internal" href="API/krotov.result.html#krotov.result.Result" title="krotov.result.Result"><code class="xref py py-class docutils literal notranslate"><span class="pre">Result</span></code></a> object returned by the second optimization will include all
the data from the first optimization.</p>
</div>
<div class="section" id="how-to-maximize-numerical-efficiency">
<h2>How to maximize numerical efficiency<a class="headerlink" href="#how-to-maximize-numerical-efficiency" title="Permalink to this headline">¶</a></h2>
<p>For systems of non-trivial size, the main numerical effort should be in the
simulation of the system dynamics. Every iteration of Krotov’s method requires
a full backward propagation and a full forward propagation of the states associated with each
objective, see <a class="reference internal" href="API/krotov.propagators.html#module-krotov.propagators" title="krotov.propagators"><code class="xref py py-mod docutils literal notranslate"><span class="pre">krotov.propagators</span></code></a>. Therefore, the best numerical
efficiency can be achieved by optimizing the performance of the <cite>propagator</cite>
that is passed to <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a>.</p>
<p>One possibility is to implement problem-specific propagators, such as
<a class="reference internal" href="API/krotov.propagators.html#krotov.propagators.DensityMatrixODEPropagator" title="krotov.propagators.DensityMatrixODEPropagator"><code class="xref py py-class docutils literal notranslate"><span class="pre">krotov.propagators.DensityMatrixODEPropagator</span></code></a>. Going further, you
might consider implementing the propagator with the help of lower-level instructions, e.g.,
by using <a class="reference external" href="https://cython.org">Cython</a>.</p>
</div>
<div class="section" id="how-to-deal-with-the-optimization-running-out-of-memory">
<h2>How to deal with the optimization running out of memory<a class="headerlink" href="#how-to-deal-with-the-optimization-running-out-of-memory" title="Permalink to this headline">¶</a></h2>
<p>Krotov’s method requires the storage of at least one set of propagated state
over the entire time grid, for each objective. For the second-order update
equation, up to three sets of stored states per objective may be required. In
particular for larger systems and dynamics in Liouville space, the memory
required for storing these states may be prohibitively expensive.</p>
<p>The <a class="reference internal" href="API/krotov.optimize.html#krotov.optimize.optimize_pulses" title="krotov.optimize.optimize_pulses"><code class="xref py py-func docutils literal notranslate"><span class="pre">optimize_pulses()</span></code></a> accepts a <cite>storage</cite> parameter
to which a constructor for an array-like container can be passed wherein the
propagated states will be stored. It is possible to pass custom out-of-memory
storage objects, such as <a class="reference external" href="http://docs.dask.org/en/latest/">Dask</a> arrays. This may carry a significant penalty in
runtime, however, as states will have to be read from disk, or across the
network.</p>
</div>
<div class="section" id="how-to-avoid-the-overhead-of-qutip-objects">
<h2>How to avoid the overhead of QuTiP objects<a class="headerlink" href="#how-to-avoid-the-overhead-of-qutip-objects" title="Permalink to this headline">¶</a></h2>
<p>If you know what you are doing, it is possible to set up an <a class="reference internal" href="API/krotov.objectives.html#krotov.objectives.Objective" title="krotov.objectives.Objective"><code class="xref py py-class docutils literal notranslate"><span class="pre">Objective</span></code></a>
without any <a class="reference external" href="http://qutip.org/docs/latest/apidoc/classes.html#qutip.Qobj" title="(in QuTiP: Quantum Toolbox in Python v4.4)"><code class="xref py py-class docutils literal notranslate"><span class="pre">qutip.Qobj</span></code></a> instances, using arbitrary low-level objects
instead. See the <a class="reference internal" href="notebooks/09_example_numpy.html"><span class="std std-ref">Optimization with numpy Arrays</span></a> for an example.</p>
</div>
</div>
</div>
</div>
<footer>
<div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
<a href="10_other_methods.html" class="btn btn-neutral float-right" title="Other Optimization Methods" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right"></span></a>
<a href="notebooks/09_example_numpy.html" class="btn btn-neutral float-left" title="Optimization with numpy Arrays" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left"></span> Previous</a>
</div>
<hr/>
<div role="contentinfo">
<p>
© Copyright 2019, Michael Goerz et al.
<span class="lastupdated">
Last updated on Dec 14, 2019.
</span>
</p>
</div>
Built with <a href="http://sphinx-doc.org/">Sphinx</a> using a <a href="https://github.com/rtfd/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
</div>
</div>
</section>
</div>
<script type="text/javascript">
jQuery(function () {
SphinxRtdTheme.Navigation.enable(true);
});
</script>
</body>
</html>