PageSourceSearch

https://www.manopt.org/gettingstarted.html

html manopt.org collected 2026-09-24 10:04:20 UTC 39,191 bytes, 1,103 lines download raw bytes

1<!DOCTYPE html>
2<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
3
4<meta charset="utf-8">
5<meta name="generator" content="quarto-1.4.557">
6
7<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
8
9
10<title>Manopt - Getting started</title>
11<style>
12code{white-space: pre-wrap;}
13span.smallcaps{font-variant: small-caps;}
14div.columns{display: flex; gap: min(4vw, 1.5em);}
15div.column{flex: auto; overflow-x: auto;}
16div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
17ul.task-list{list-style: none;}
18ul.task-list li input[type="checkbox"] {
19  width: 0.8em;
20  margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */ 
21  vertical-align: middle;
22}
23</style>
24
25
26<script src="site_libs/quarto-nav/quarto-nav.js"></script>
vendor: 1 bytes, line 26
26
27<script src="site_libs/quarto-nav/headroom.min.js"></script>
vendor: 1 bytes, line 27
27
28<script src="site_libs/clipboard/clipboard.min.js"></script>
vendor: 1 bytes, line 28
28
29<script src="site_libs/quarto-search/autocomplete.umd.js"></script>
vendor: 1 bytes, line 29
29
30<script src="site_libs/quarto-search/fuse.min.js"></script>
vendor: 1 bytes, line 30
30
31<script src="site_libs/quarto-search/quarto-search.js"></script>
31
32<meta name="quarto:offset" content="./">
33<link href="./icon.png" rel="icon" type="image/png">
34<script src="site_libs/cookie-consent/cookie-consent.js"></script>
34
35<link href="site_libs/cookie-consent/cookie-consent.css" rel="stylesheet">
36<script src="site_libs/quarto-html/quarto.js"></script>
vendor: 1 bytes, line 36
36
37<script src="site_libs/quarto-html/popper.min.js"></script>
vendor: 1 bytes, line 37
37
38<script src="site_libs/quarto-html/tippy.umd.min.js"></script>
vendor: 1 bytes, line 38
38
39<script src="site_libs/quarto-html/anchor.min.js"></script>
39
40<link href="site_libs/quarto-html/tippy.css" rel="stylesheet">
41<link href="site_libs/quarto-html/quarto-syntax-highlighting.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-text-highlighting-styles">
42<link href="site_libs/quarto-html/quarto-syntax-highlighting-dark.css" rel="prefetch" class="quarto-color-scheme quarto-color-alternate" id="quarto-text-highlighting-styles">
43<script src="site_libs/bootstrap/bootstrap.min.js"></script>
43
44<link href="site_libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
45<link href="site_libs/bootstrap/bootstrap.min.css" rel="stylesheet" class="quarto-color-scheme" id="quarto-bootstrap" data-mode="light">
46<link href="site_libs/bootstrap/bootstrap-dark.min.css" rel="prefetch" class="quarto-color-scheme quarto-color-alternate" id="quarto-bootstrap" data-mode="dark">
47<script id="quarto-search-options" type="application/json">{
48  "location": "navbar",
49  "copy-button": false,
50  "collapse-after": 3,
51  "panel-placement": "end",
52  "type": "overlay",
53  "limit": 50,
54  "keyboard-shortcut": [
55    "f",
56    "/",
57    "s"
58  ],
59  "language": {
60    "search-no-results-text": "No results",
61    "search-matching-documents-text": "matching documents",
62    "search-copy-link-title": "Copy link to search",
63    "search-hide-matches-text": "Hide additional matches",
64    "search-more-match-text": "more match in this document",
65    "search-more-matches-text": "more matches in this document",
66    "search-clear-button-title": "Clear",
67    "search-text-placeholder": "",
68    "search-detached-cancel-button-title": "Cancel",
69    "search-submit-button-title": "Submit",
70    "search-label": "Search"
71  }
72}</script>
vendor: 67 bytes, lines 72-73
72
73<script async="" src="https://www.googletagmanager.com/gtag/js?id=
73G-71FCE8T97E
vendor: 13 bytes, lines 73-74
73"></script>
74
75<script type="text/plain" cookie-consent="tracking">
76
vendor: 127 bytes, lines 77-80
77window.dataLayer = window.dataLayer || [];
78function gtag(){dataLayer.push(arguments);}
79gtag('js', new Date());
80gtag('config', '
80G-71FCE8T97E
vendor: 29 bytes, line 80
80', { 'anonymize_ip': true});
81</script>
81
82
83<script type="text/javascript" charset="UTF-8">
84document.addEventListener('DOMContentLoaded', function () {
85cookieconsent.run({
86  "notice_banner_type":"simple",
87  "consent_type":"express",
88  "palette":"light",
89  "language":"en",
90  "page_load_consent_levels":["strictly-necessary"],
91  "notice_banner_reject_button_hide":false,
92  "preferences_center_close_button_hide":false,
93  "website_name":""
94  ,
95"language":"en"
96  });
97});
98</script>
98 
99  
100<style>html{ scroll-behavior: smooth; }</style>
101<script>
102
103window.MathJax = {
104
105    tex: {
106
107      inlineMath: [['$', '$'], ['\\(', '\\)']],
108
109      macros: {
110
111        reals: "\\mathbb{R}",
112
113        inner: ["\\left\\langle #1, #2 \\right\\rangle", 2],
114
115        smallinner: ["\\langle #1, #2 \\rangle", 2],
116
117        innersmall: ["\\langle #1, #2 \\rangle", 2],
118
119        innerbig: ["\\big\\langle #1, #2 \\big\\rangle", 2],
120
121        sqfrobnorm: ["\\left\\|#1\\right\\|_{\\mathrm{F}}^2", 1],
122
123        sqfrobnormsmall: ["\\|#1\\|_{\\mathrm{F}}^2", 1],
124
125        sqfrobnormbig: ["\\big\\|#1\\big\\|_{\\mathrm{F}}^2", 1],
126
127        calM: "\\mathcal{M}",
128
129        calN: "\\mathcal{N}",
130
131        calA: "\\mathcal{A}",
132
133        calX: "\\mathcal{X}",
134
135        T: "\\mathrm{T}",
136
137        skeww: "\\mathrm{skew}",
138
139        symm: "\\mathrm{sym}",
140
141        Sym: "\\mathrm{Sym}",
142
143        Proj: "\\mathrm{Proj}",
144
145        grad: "\\mathrm{grad}",
146
147        Hess: "\\mathrm{Hess}",
148
149        Retr: "\\mathrm{R}",
150
151        D: "\\mathrm{D}",
152
153        calE: "\\mathcal{E}",
154
155        Stnp: "\\mathrm{St}(n,p)",
156
157        Rnp: "\\mathbb{R}^{n \\times p}",
158
159        Rmp: "\\mathbb{R}^{m \\times p}",
160
161        Rnr: "\\mathbb{R}^{n \\times r}",
162
163        Rrn: "\\mathbb{R}^{r \\times n}",
164
165        Rmr: "\\mathbb{R}^{m \\times r}",
166
167        Rnn: "\\mathbb{R}^{n \\times n}",
168
169        Rmn: "\\mathbb{R}^{m \\times n}",
170
171        Rnm: "\\mathbb{R}^{n \\times m}",
172
173        Rpp: "\\mathbb{R}^{p \\times p}",
174
175        Rmnr: "\\mathbb{R}^{m \\times n}_r",
176
177        Rmnlr: "\\mathbb{R}^{m \\times n}_{\\leq r}",
178
179        Rn: "\\mathbb{R}^{n}",
180
181        Rm: "\\mathbb{R}^{m}",
182
183        Rp: "\\mathbb{R}^{p}",
184
185        Rd: "\\mathbb{R}^{d}",
186
187        Rk: "\\mathbb{R}^{k}",
188
189        Sn: "\\mathbb{S}^{n-1}",
190
191        Sm: "\\mathbb{S}^{m-1}",
192
193        Sd: "\\mathbb{S}^{d-1}",
194
195        trace: "\\mathrm{Tr}",
196
197        Trace: "\\mathrm{Tr}",
198
199        diag: "\\mathrm{diag}",
200
201        sign: "\\mathrm{sign}",
202
203        Od: "\\mathrm{O}(d)",
204
205        On: "\\mathrm{O}(n)",
206
207        Om: "\\mathrm{O}(m)",
208
209        SOd: "\\mathrm{SO}(d)",
210
211        SOn: "\\mathrm{SO}(n)",
212
213        rank: "\\mathrm{rank}",
214
215        frakX: "\\mathfrak{X}",
216
217        frakF: "\\mathfrak{F}",
218
219        One: "\\mathbf{1}",
220
221        dist: "\\mathrm{dist}",
222
223        calP: "\\mathcal{P}",
224
225        calK: "\\mathcal{K}",
226
227        Rdd: "\\mathbb{R}^{d \\times d}",
228
229        calU: "\\mathcal{U}",
230
231        calV: "\\mathcal{V}",
232
233        calW: "\\mathcal{W}",
234
235        Exp: "\\mathrm{Exp}",
236
237        Log: "\\mathrm{Log}",
238
239        inj: "\\mathrm{inj}",
240
241        dom: "\\operatorname{dom}",
242
243        bigger: "<",
244
245        dt: "\\mathrm{d}t",
246
247        transpose: "^\\top\\! ",
248
249        sigmamax: "\\sigma_{\\mathrm{max}}",
250
251        sigmamin: "\\sigma_{\\mathrm{min}}",
252
253        lambdamax: "\\lambda_{\\mathrm{max}}",
254
255        lambdamin: "\\lambda_{\\mathrm{min}}",
256
257        TODO: ["\\textcolor{red}{[\\textrm{#1}]}", 1]
258
259      }
260
261    },
262
263    svg: {
264
265      fontCache: 'global'
266
267    }
268
269  };
270
271</script>
271
272
273
274
275<script>
276
277  window.addEventListener('load', function() {
278
279    document.getElementById("cc-nb-title").innerHTML = "May we use cookies for anonymized analytics?";
280
281    // to improve your browsing experience on our website, 
282
283    document.getElementById("cc-nb-text").innerHTML = "We would like to use cookies to analyze our website traffic, and to understand where our visitors are coming from.";
284
285  });
286
287</script>
287
288
289
290
291<link rel="stylesheet" href="styles.css">
292<meta property="og:title" content="Manopt - Getting started">
293<meta property="og:description" content="">
294<meta property="og:site_name" content="Manopt">
295</head>
296
297<body class="nav-sidebar docked nav-fixed fullcontent">
298
299<div id="quarto-search-results"></div>
300  <header id="quarto-header" class="headroom fixed-top">
301    <nav class="navbar navbar-expand-lg " data-bs-theme="dark">
302      <div class="navbar-container container-fluid">
303      <div class="navbar-brand-container mx-auto">
304    <a class="navbar-brand" href="./index.html">
305    <span class="navbar-title">Manopt</span>
306    </a>
307  </div>
308            <div id="quarto-search" class="" title="Search"></div>
309          <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
310  <span class="navbar-toggler-icon"></span>
311</button>
312          <div class="collapse navbar-collapse" id="navbarCollapse">
313            <ul class="navbar-nav navbar-nav-scroll me-auto">
314  <li class="nav-item">
315    <a class="nav-link" href="./index.html"> 
316<span class="menu-text">Home</span></a>
317  </li>  
318  <li class="nav-item dropdown ">
319    <a class="nav-link dropdown-toggle" href="#" id="nav-menu-tutorial" role="button" data-bs-toggle="dropdown" aria-expanded="false">
320 <span class="menu-text">Tutorial</span>
321    </a>
322    <ul class="dropdown-menu" aria-labelledby="nav-menu-tutorial">    
323        <li>
324    <a class="dropdown-item" href="./gettingstarted.html">
325 <span class="dropdown-text">Getting started</span></a>
326  </li>  
327        <li>
328    <a class="dropdown-item" href="./firstexample.html">
329 <span class="dropdown-text">A first example</span></a>
330  </li>  
331        <li>
332    <a class="dropdown-item" href="./manifolds.html">
333 <span class="dropdown-text">Manifolds</span></a>
334  </li>  
335        <li>
336    <a class="dropdown-item" href="./costdescription.html">
337 <span class="dropdown-text">Cost functions</span></a>
338  </li>  
339        <li>
340    <a class="dropdown-item" href="./solvers.html">
341 <span class="dropdown-text">Solvers</span></a>
342  </li>  
343        <li>
344    <a class="dropdown-item" href="./tools.html">
345 <span class="dropdown-text">Helpful tools</span></a>
346  </li>  
347        <li>
348    <a class="dropdown-item" href="./lifts.html">
349 <span class="dropdown-text">Lifts</span></a>
350  </li>  
351        <li>
352    <a class="dropdown-item" href="./core.html">
353 <span class="dropdown-text">Core tools</span></a>
354  </li>  
355    </ul>
356  </li>
357  <li class="nav-item">
358    <a class="nav-link" href="./learning.html"> 
359<span class="menu-text">Learning</span></a>
360  </li>  
361  <li class="nav-item">
362    <a class="nav-link" href="./downloads.html"> 
363<span class="menu-text">Downloads</span></a>
364  </li>  
365  <li class="nav-item">
366    <a class="nav-link" href="./forum.html"> 
367<span class="menu-text">Forum</span></a>
368  </li>  
369  <li class="nav-item">
370    <a class="nav-link" href="./about.html"> 
371<span class="menu-text">About</span></a>
372  </li>  
373</ul>
374            <ul class="navbar-nav navbar-nav-scroll ms-auto">
375  <li class="nav-item compact">
376    <a class="nav-link" href="https://github.com/NicolasBoumal/manopt" target="_blank"> <i class="bi bi-github" role="img">
377</i> 
378<span class="menu-text"></span></a>
379  </li>  
380  <li class="nav-item compact">
381    <a class="nav-link" href="mailto:[email protected]"> <i class="bi bi-envelope-at" role="img" aria-label="E-mail">
382</i> 
383<span class="menu-text"></span></a>
384  </li>  
385</ul>
386          </div> <!-- /navcollapse -->
387          <div class="quarto-navbar-tools">
388  <a href="" class="quarto-color-scheme-toggle quarto-navigation-tool  px-1" onclick="window.quartoToggleColorScheme(); return false;" title="Toggle dark mode"><i class="bi"></i></a>
389</div>
390      </div> <!-- /container-fluid -->
391    </nav>
392  <nav class="quarto-secondary-nav">
393    <div class="container-fluid d-flex">
394      <button type="button" class="quarto-btn-toggle btn" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">
395        <i class="bi bi-layout-text-sidebar-reverse"></i>
396      </button>
397        <nav class="quarto-page-breadcrumbs" aria-label="breadcrumb"><ol class="breadcrumb"><li class="breadcrumb-item"><a href="./gettingstarted.html">Getting started</a></li></ol></nav>
398        <a class="flex-grow-1" role="button" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item" aria-controls="quarto-sidebar" aria-expanded="false" aria-label="Toggle sidebar navigation" onclick="if (window.quartoToggleHeadroom) { window.quartoToggleHeadroom(); }">      
399        </a>
400    </div>
401  </nav>
402</header>
403<!-- content -->
404<div id="quarto-content" class="quarto-container page-columns page-rows-contents page-layout-article page-navbar">
405<!-- sidebar -->
406  <nav id="quarto-sidebar" class="sidebar collapse collapse-horizontal quarto-sidebar-collapse-item sidebar-navigation docked overflow-auto">
407    <div class="sidebar-menu-container"> 
408    <ul class="list-unstyled mt-1">
409        <li class="sidebar-item">
410  <div class="sidebar-item-container"> 
411  <a href="./gettingstarted.html" class="sidebar-item-text sidebar-link active">
412 <span class="menu-text">Getting started</span></a>
413  </div>
414</li>
415        <li class="sidebar-item">
416  <div class="sidebar-item-container"> 
417  <a href="./firstexample.html" class="sidebar-item-text sidebar-link">
418 <span class="menu-text">A first example</span></a>
419  </div>
420</li>
421        <li class="sidebar-item">
422  <div class="sidebar-item-container"> 
423  <a href="./manifolds.html" class="sidebar-item-text sidebar-link">
424 <span class="menu-text">Manifolds</span></a>
425  </div>
426</li>
427        <li class="sidebar-item">
428  <div class="sidebar-item-container"> 
429  <a href="./costdescription.html" class="sidebar-item-text sidebar-link">
430 <span class="menu-text">Cost functions</span></a>
431  </div>
432</li>
433        <li class="sidebar-item">
434  <div class="sidebar-item-container"> 
435  <a href="./solvers.html" class="sidebar-item-text sidebar-link">
436 <span class="menu-text">Solvers</span></a>
437  </div>
438</li>
439        <li class="sidebar-item">
440  <div class="sidebar-item-container"> 
441  <a href="./tools.html" class="sidebar-item-text sidebar-link">
442 <span class="menu-text">Helpful tools</span></a>
443  </div>
444</li>
445        <li class="sidebar-item">
446  <div class="sidebar-item-container"> 
447  <a href="./lifts.html" class="sidebar-item-text sidebar-link">
448 <span class="menu-text">Lifts</span></a>
449  </div>
450</li>
451        <li class="sidebar-item">
452  <div class="sidebar-item-container"> 
453  <a href="./core.html" class="sidebar-item-text sidebar-link">
454 <span class="menu-text">Core tools</span></a>
455  </div>
456</li>
457    </ul>
458    </div>
459</nav>
460<div id="quarto-sidebar-glass" class="quarto-sidebar-collapse-item" data-bs-toggle="collapse" data-bs-target=".quarto-sidebar-collapse-item"></div>
461<!-- margin-sidebar -->
462    
463<!-- main -->
464<main class="content" id="quarto-document-content">
465
466<header id="title-block-header" class="quarto-title-block default">
467<div class="quarto-title">
468<h1 class="title">Getting started</h1>
469</div>
470
471
472
473<div class="quarto-title-meta">
474
475    
476  
477    
478  </div>
479  
480
481
482</header>
483
484
485<section id="manopts-purpose-and-design" class="level2">
486<h2 class="anchored" data-anchor-id="manopts-purpose-and-design">Manopt’s purpose and design</h2>
487<p>With Manopt, you can solve optimization problems on manifolds and on linear spaces (e.g., matrix spaces) using state-of-the-art algorithms, with minimal effort. The toolbox targets great flexibility in the problem description and comes with advanced features, such as caching and automatic differentiation.</p>
488<p>The toolbox architecture is based on a separation of the manifolds, the solvers and the problem descriptions. For basic use, one only needs to pick a manifold from the library, describe the cost function (and possible derivatives) and pass it on to a solver. Accompanying tools help the user in common tasks such as numerically checking the derivatives, plotting the cost function, computing eigenvalues of the Hessian etc.</p>
489<p>This is a prototyping toolbox, built on the premise that the costly part of solving an optimization problem is querying the cost function, and not the inner machinery of the solver. It is also work in progress: feedback and contributions are welcome!</p>
490<p><a href="https://docs.google.com/forms/d/1U9Ntex_rWI8NfCLPP_b8uE5xDnKXgXG-HVvpHdq1PFo/viewform?usp=send_form" class="btn btn-info">Mailing list</a> Consider registering as a user to hear about updates.</p>
491</section>
492<section id="download" class="level2">
493<h2 class="anchored" data-anchor-id="download">Download</h2>
494<p>There are two ways to get Manopt:</p>
495<p><a href="./download.html" class="btn btn-primary">Download</a> Download the latest packaged version (v8.0, July 5, 2024).</p>
496<p><a href="https://github.com/NicolasBoumal/manopt" class="btn btn-secondary"><i class="bi bi-github"></i> GitHub</a> Clone the GitHub repository to use the latest updates as they roll out.</p>
497</section>
498<section id="install" class="level2">
499<h2 class="anchored" data-anchor-id="install">Install</h2>
500<ol type="1">
501<li>Either git-clone or unzip the whole <code>manopt</code> directory you just downloaded in a location of your choice, say, in <code>/my/directory/</code>.</li>
502<li>Go to <code>/my/directory/manopt/</code> at the Matlab prompt and execute <code>importmanopt</code>.</li>
503<li>You will be asked whether you want to save this path for your next Matlab sessions. If you reply <code>Y</code> (yes) and you have the rights to run <code>savepath</code>, then you won’t need to go through these steps next time you open Matlab.</li>
504</ol>
505</section>
506<section id="check" class="level2">
507<h2 class="anchored" data-anchor-id="check">Check</h2>
508<p>Go to <code>/my/directory/manopt/</code> and run the script <code>checkinstall.m</code>. If there are no errors, you are done! Otherwise, feel free to <a href="./forum.html">report issues on the forum</a>.</p>
509</section>
510<section id="move-on-to-the-first-example" class="level2">
511<h2 class="anchored" data-anchor-id="move-on-to-the-first-example">Move on to the first example</h2>
512<p>This tutorial provides detailed instructions from zero to the advanced features of Manopt. Check out <a href="./firstexample.html">
512a first example</a> to get a feel for how things work, then continue through the detailed documentation.</p>
513</section>
514<section id="dig-into-more-advanced-examples" class="level2">
515<h2 class="anchored" data-anchor-id="dig-into-more-advanced-examples">Dig into more advanced examples</h2>
516<p>You may find it helpful to look through the <a href="https://github.com/NicolasBoumal/manopt/tree/master/examples">examples</a> that ship with Manopt.</p>
517</section>
518<section id="learn-more-of-the-math" class="level2">
519<h2 class="anchored" data-anchor-id="learn-more-of-the-math">Learn more of the math</h2>
520<p>See our pointers for helpful <a href="./learning.html">learning resources</a> including video lectures and books.</p>
521
522
523</section>
524
525</main> <!-- /main -->
526<script id="quarto-html-after-body" type="application/javascript">
527window.document.addEventListener("DOMContentLoaded", function (event) {
528  const toggleBodyColorMode = (bsSheetEl) => {
529    const mode = bsSheetEl.getAttribute("data-mode");
530    const bodyEl = window.document.querySelector("body");
531    if (mode === "dark") {
532      bodyEl.classList.add("quarto-dark");
533      bodyEl.classList.remove("quarto-light");
534    } else {
535      bodyEl.classList.add("quarto-light");
536      bodyEl.classList.remove("quarto-dark");
537    }
538  }
539  const toggleBodyColorPrimary = () => {
540    const bsSheetEl = window.document.querySelector("link#quarto-bootstrap");
541    if (bsSheetEl) {
542      toggleBodyColorMode(bsSheetEl);
543    }
544  }
545  toggleBodyColorPrimary();  
546  const disableStylesheet = (stylesheets) => {
547    for (let i=0; i < stylesheets.length; i++) {
548      const stylesheet = stylesheets[i];
549      stylesheet.rel = 'prefetch';
550    }
551  }
552  const enableStylesheet = (stylesheets) => {
553    for (let i=0; i < stylesheets.length; i++) {
554      const stylesheet = stylesheets[i];
555      stylesheet.rel = 'stylesheet';
556    }
557  }
558  const manageTransitions = (selector, allowTransitions) => {
559    const els = window.document.querySelectorAll(selector);
560    for (let i=0; i < els.length; i++) {
561      const el = els[i];
562      if (allowTransitions) {
563        el.classList.remove('notransition');
564      } else {
565        el.classList.add('notransition');
566      }
567    }
568  }
569  const toggleGiscusIfUsed = (isAlternate, darkModeDefault) => {
570    const baseTheme = document.querySelector('#giscus-base-theme')?.value ?? 'light';
571    const alternateTheme = document.querySelector('#giscus-alt-theme')?.value ?? 'dark';
572    let newTheme = '';
573    if(darkModeDefault) {
574      newTheme = isAlternate ? baseTheme : alternateTheme;
575    } else {
576      newTheme = isAlternate ? alternateTheme : baseTheme;
577    }
578    const changeGiscusTheme = () => {
579      // From: https://github.com/giscus/giscus/issues/336
580      const sendMessage = (message) => {
581        const iframe = document.querySelector('iframe.giscus-frame');
582        if (!iframe) return;
583        iframe.contentWindow.postMessage({ giscus: message }, 'https://giscus.app');
584      }
585      sendMessage({
586        setConfig: {
587          theme: newTheme
588        }
589      });
590    }
591    const isGiscussLoaded = window.document.querySelector('iframe.giscus-frame') !== null;
592    if (isGiscussLoaded) {
593      changeGiscusTheme();
594    }
595  }
596  const toggleColorMode = (alternate) => {
597    // Switch the stylesheets
598    const alternateStylesheets = window.document.querySelectorAll('link.quarto-color-scheme.quarto-color-alternate');
599    manageTransitions('#quarto-margin-sidebar .nav-link', false);
600    if (alternate) {
601      enableStylesheet(alternateStylesheets);
602      for (const sheetNode of alternateStylesheets) {
603        if (sheetNode.id === "quarto-bootstrap") {
604          toggleBodyColorMode(sheetNode);
605        }
606      }
607    } else {
608      disableStylesheet(alternateStylesheets);
609      toggleBodyColorPrimary();
610    }
611    manageTransitions('#quarto-margin-sidebar .nav-link', true);
612    // Switch the toggles
613    const toggles = window.document.querySelectorAll('.quarto-color-scheme-toggle');
614    for (let i=0; i < toggles.length; i++) {
615      const toggle = toggles[i];
616      if (toggle) {
617        if (alternate) {
618          toggle.classList.add("alternate");     
619        } else {
620          toggle.classList.remove("alternate");
621        }
622      }
623    }
624    // Hack to workaround the fact that safari doesn't
625    // properly recolor the scrollbar when toggling (#1455)
626    if (navigator.userAgent.indexOf('Safari') > 0 && navigator.userAgent.indexOf('Chrome') == -1) {
627      manageTransitions("body", false);
628      window.scrollTo(0, 1);
629      setTimeout(() => {
630        window.scrollTo(0, 0);
631        manageTransitions("body", true);
632      }, 40);  
633    }
634  }
635  const isFileUrl = () => { 
636    return window.location.protocol === 'file:';
637  }
638  const hasAlternateSentinel = () => {  
639    let styleSentinel = getColorSchemeSentinel();
640    if (styleSentinel !== null) {
641      return styleSentinel === "alternate";
642    } else {
643      return false;
644    }
645  }
646  const setStyleSentinel = (alternate) => {
647    const value = alternate ? "alternate" : "default";
648    if (!isFileUrl()) {
649      window.localStorage.setItem("quarto-color-scheme", value);
650    } else {
651      localAlternateSentinel = value;
652    }
653  }
654  const getColorSchemeSentinel = () => {
655    if (!isFileUrl()) {
656      const storageValue = window.localStorage.getItem("quarto-color-scheme");
657      return storageValue != null ? storageValue : localAlternateSentinel;
658    } else {
659      return localAlternateSentinel;
660    }
661  }
662  const darkModeDefault = false;
663  let localAlternateSentinel = darkModeDefault ? 'alternate' : 'default';
664  // Dark / light mode switch
665  window.quartoToggleColorScheme = () => {
666    // Read the current dark / light value 
667    let toAlternate = !hasAlternateSentinel();
668    toggleColorMode(toAlternate);
669    setStyleSentinel(toAlternate);
670    toggleGiscusIfUsed(toAlternate, darkModeDefault);
671  };
672  // Ensure there is a toggle, if there isn't float one in the top right
673  if (window.document.querySelector('.quarto-color-scheme-toggle') === null) {
674    const a = window.document.createElement('a');
675    a.classList.add('top-right');
676    a.classList.add('quarto-color-scheme-toggle');
677    a.href = "";
678    a.onclick = function() { try { window.quartoToggleColorScheme(); } catch {} return false; };
679    const i = window.document.createElement("i");
680    i.classList.add('bi');
681    a.appendChild(i);
682    window.document.body.appendChild(a);
683  }
684  // Switch to dark mode if need be
685  if (hasAlternateSentinel()) {
686    toggleColorMode(true);
687  } else {
688    toggleColorMode(false);
689  }
690  const icon = "";
691  const anchorJS = new window.AnchorJS();
692  anchorJS.options = {
693    placement: 'right',
694    icon: icon
695  };
696  anchorJS.add('.anchored');
697  const isCodeAnnotation = (el) => {
698    for (const clz of el.classList) {
699      if (clz.startsWith('code-annotation-')) {                     
700        return true;
701      }
702    }
703    return false;
704  }
705  const clipboard = new window.ClipboardJS('.code-copy-button', {
706    text: function(trigger) {
707      const codeEl = trigger.previousElementSibling.cloneNode(true);
708      for (const childEl of codeEl.children) {
709        if (isCodeAnnotation(childEl)) {
710          childEl.remove();
711        }
712      }
713      return codeEl.innerText;
714    }
715  });
716  clipboard.on('success', function(e) {
717    // button target
718    const button = e.trigger;
719    // don't keep focus
720    button.blur();
721    // flash "checked"
722    button.classList.add('code-copy-button-checked');
723    var currentTitle = button.getAttribute("title");
724    button.setAttribute("title", "Copied!");
725    let tooltip;
726    if (window.bootstrap) {
727      button.setAttribute("data-bs-toggle", "tooltip");
728      button.setAttribute("data-bs-placement", "left");
729      button.setAttribute("data-bs-title", "Copied!");
730      tooltip = new bootstrap.Tooltip(button, 
731        { trigger: "manual", 
732          customClass: "code-copy-button-tooltip",
733          offset: [0, -8]});
734      tooltip.show();    
735    }
736    setTimeout(function() {
737      if (tooltip) {
738        tooltip.hide();
739        button.removeAttribute("data-bs-title");
740        button.removeAttribute("data-bs-toggle");
741        button.removeAttribute("data-bs-placement");
742      }
743      button.setAttribute("title", currentTitle);
744      button.classList.remove('code-copy-button-checked');
745    }, 1000);
746    // clear code selection
747    e.clearSelection();
748  });
749    var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
750    var mailtoRegex = new RegExp(/^mailto:/);
751      var filterRegex = new RegExp("https:\/\/www\.manopt\.org");
752    var isInternal = (href) => {
753        return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
754    }
755    // Inspect non-navigation links and adorn them if external
756 	var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool)');
757    for (var i=0; i<links.length; i++) {
758      const link = links[i];
759      if (!isInternal(link.href)) {
760        // undo the damage that might have been done by quarto-nav.js in the case of
761        // links that we want to consider external
762        if (link.dataset.originalHref !== undefined) {
763          link.href = link.dataset.originalHref;
764        }
765          // target, if specified
766          link.setAttribute("target", "_blank");
767          if (link.getAttribute("rel") === null) {
768            link.setAttribute("rel", "noopener");
769          }
770      }
771    }
772  function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
773    const config = {
774      allowHTML: true,
775      maxWidth: 500,
776      delay: 100,
777      arrow: false,
778      appendTo: function(el) {
779          return el.parentElement;
780      },
781      interactive: true,
782      interactiveBorder: 10,
783      theme: 'quarto',
784      placement: 'bottom-start',
785    };
786    if (contentFn) {
787      config.content = contentFn;
788    }
789    if (onTriggerFn) {
790      config.onTrigger = onTriggerFn;
791    }
792    if (onUntriggerFn) {
793      config.onUntrigger = onUntriggerFn;
794    }
795    window.tippy(el, config); 
796  }
797  const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
798  for (var i=0; i<noterefs.length; i++) {
799    const ref = noterefs[i];
800    tippyHover(ref, function() {
801      // use id or data attribute instead here
802      let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
803      try { href = new URL(href).hash; } catch {}
804      const id = href.replace(/^#\/?/, "");
805      const note = window.document.getElementById(id);
806      if (note) {
807        return note.innerHTML;
808      } else {
809        return "";
810      }
811    });
812  }
813  const xrefs = window.document.querySelectorAll('a.quarto-xref');
814  const processXRef = (id, note) => {
815    // Strip column container classes
816    const stripColumnClz = (el) => {
817      el.classList.remove("page-full", "page-columns");
818      if (el.children) {
819        for (const child of el.children) {
820          stripColumnClz(child);
821        }
822      }
823    }
824    stripColumnClz(note)
825    if (id === null || id.startsWith('sec-')) {
826      // Special case sections, only their first couple elements
827      const container = document.createElement("div");
828      if (note.children && note.children.length > 2) {
829        container.appendChild(note.children[0].cloneNode(true));
830        for (let i = 1; i < note.children.length; i++) {
831          const child = note.children[i];
832          if (child.tagName === "P" && child.innerText === "") {
833            continue;
834          } else {
835            container.appendChild(child.cloneNode(true));
836            break;
837          }
838        }
839        if (window.Quarto?.typesetMath) {
840          window.Quarto.typesetMath(container);
841        }
842        return container.innerHTML
843      } else {
844        if (window.Quarto?.typesetMath) {
845          window.Quarto.typesetMath(note);
846        }
847        return note.innerHTML;
848      }
849    } else {
850      // Remove any anchor links if they are present
851      const anchorLink = note.querySelector('a.anchorjs-link');
852      if (anchorLink) {
853        anchorLink.remove();
854      }
855      if (window.Quarto?.typesetMath) {
856        window.Quarto.typesetMath(note);
857      }
858      // TODO in 1.5, we should make sure this works without a callout special case
859      if (note.classList.contains("callout")) {
860        return note.outerHTML;
861      } else {
862        return note.innerHTML;
863      }
864    }
865  }
866  for (var i=0; i<xrefs.length; i++) {
867    const xref = xrefs[i];
868    tippyHover(xref, undefined, function(instance) {
869      instance.disable();
870      let url = xref.getAttribute('href');
871      let hash = undefined; 
872      if (url.startsWith('#')) {
873        hash = url;
874      } else {
875        try { hash = new URL(url).hash; } catch {}
876      }
877      if (hash) {
878        const id = hash.replace(/^#\/?/, "");
879        const note = window.document.getElementById(id);
880        if (note !== null) {
881          try {
882            const html = processXRef(id, note.cloneNode(true));
883            instance.setContent(html);
884          } finally {
885            instance.enable();
886            instance.show();
887          }
888        } else {
889          // See if we can fetch this
890          fetch(url.split('#')[0])
891          .then(res => res.text())
892          .then(html => {
893            const parser = new DOMParser();
894            const htmlDoc = parser.parseFromString(html, "text/html");
895            const note = htmlDoc.getElementById(id);
896            if (note !== null) {
897              const html = processXRef(id, note);
898              instance.setContent(html);
899            } 
900          }).finally(() => {
901            instance.enable();
902            instance.show();
903          });
904        }
905      } else {
906        // See if we can fetch a full url (with no hash to target)
907        // This is a special case and we should probably do some content thinning / targeting
908        fetch(url)
909        .then(res => res.text())
910        .then(html => {
911          const parser = new DOMParser();
912          const htmlDoc = parser.parseFromString(html, "text/html");
913          const note = htmlDoc.querySelector('main.content');
914          if (note !== null) {
915            // This should only happen for chapter cross references
916            // (since there is no id in the URL)
917            // remove the first header
918            if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
919              note.children[0].remove();
920            }
921            const html = processXRef(null, note);
922            instance.setContent(html);
923          } 
924        }).finally(() => {
925          instance.enable();
926          instance.show();
927        });
928      }
929    }, function(instance) {
930    });
931  }
932      let selectedAnnoteEl;
933      const selectorForAnnotation = ( cell, annotation) => {
934        let cellAttr = 'data-code-cell="' + cell + '"';
935        let lineAttr = 'data-code-annotation="' +  annotation + '"';
936        const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
937        return selector;
938      }
939      const selectCodeLines = (annoteEl) => {
940        const doc = window.document;
941        const targetCell = annoteEl.getAttribute("data-target-cell");
942        const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
943        const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
944        const lines = annoteSpan.getAttribute("data-code-lines").split(",");
945        const lineIds = lines.map((line) => {
946          return targetCell + "-" + line;
947        })
948        let top = null;
949        let height = null;
950        let parent = null;
951        if (lineIds.length > 0) {
952            //compute the position of the single el (top and bottom and make a div)
953            const el = window.document.getElementById(lineIds[0]);
954            top = el.offsetTop;
955            height = el.offsetHeight;
956            parent = el.parentElement.parentElement;
957          if (lineIds.length > 1) {
958            const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
959            const bottom = lastEl.offsetTop + lastEl.offsetHeight;
960            height = bottom - top;
961          }
962          if (top !== null && height !== null && parent !== null) {
963            // cook up a div (if necessary) and position it 
964            let div = window.document.getElementById("code-annotation-line-highlight");
965            if (div === null) {
966              div = window.document.createElement("div");
967              div.setAttribute("id", "code-annotation-line-highlight");
968              div.style.position = 'absolute';
969              parent.appendChild(div);
970            }
971            div.style.top = top - 2 + "px";
972            div.style.height = height + 4 + "px";
973            div.style.left = 0;
974            let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
975            if (gutterDiv === null) {
976              gutterDiv = window.document.createElement("div");
977              gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
978              gutterDiv.style.position = 'absolute';
979              const codeCell = window.document.getElementById(targetCell);
980              const gutter = codeCell.querySelector('.code-annotation-gutter');
981              gutter.appendChild(gutterDiv);
982            }
983            gutterDiv.style.top = top - 2 + "px";
984            gutterDiv.style.height = height + 4 + "px";
985          }
986          selectedAnnoteEl = annoteEl;
987        }
988      };
989      const unselectCodeLines = () => {
990        const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
991        elementsIds.forEach((elId) => {
992          const div = window.document.getElementById(elId);
993          if (div) {
994            div.remove();
995          }
996        });
997        selectedAnnoteEl = undefined;
998      };
999        // Handle positioning of the toggle
1000    window.addEventListener(
1001      "resize",
1002      throttle(() => {
1003        elRect = undefined;
1004        if (selectedAnnoteEl) {
1005          selectCodeLines(selectedAnnoteEl);
1006        }
1007      }, 10)
1008    );
1009    function throttle(fn, ms) {
1010    let throttle = false;
1011    let timer;
1012      return (...args) => {
1013        if(!throttle) { // first call gets through
1014            fn.apply(this, args);
1015            throttle = true;
1016        } else { // all the others get throttled
1017            if(timer) clearTimeout(timer); // cancel #2
1018            timer = setTimeout(() => {
1019              fn.apply(this, args);
1020              timer = throttle = false;
1021            }, ms);
1022        }
1023      };
1024    }
1025      // Attach click handler to the DT
1026      const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
1027      for (const annoteDlNode of annoteDls) {
1028        annoteDlNode.addEventListener('click', (event) => {
1029          const clickedEl = event.target;
1030          if (clickedEl !== selectedAnnoteEl) {
1031            unselectCodeLines();
1032            const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
1033            if (activeEl) {
1034              activeEl.classList.remove('code-annotation-active');
1035            }
1036            selectCodeLines(clickedEl);
1037            clickedEl.classList.add('code-annotation-active');
1038          } else {
1039            // Unselect the line
1040            unselectCodeLines();
1041            clickedEl.classList.remove('code-annotation-active');
1042          }
1043        });
1044      }
1045  const findCites = (el) => {
1046    const parentEl = el.parentElement;
1047    if (parentEl) {
1048      const cites = parentEl.dataset.cites;
1049      if (cites) {
1050        return {
1051          el,
1052          cites: cites.split(' ')
1053        };
1054      } else {
1055        return findCites(el.parentElement)
1056      }
1057    } else {
1058      return undefined;
1059    }
1060  };
1061  var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
1062  for (var i=0; i<bibliorefs.length; i++) {
1063    const ref = bibliorefs[i];
1064    const citeInfo = findCites(ref);
1065    if (citeInfo) {
1066      tippyHover(citeInfo.el, function() {
1067        var popup = window.document.createElement('div');
1068        citeInfo.cites.forEach(function(cite) {
1069          var citeDiv = window.document.createElement('div');
1070          citeDiv.classList.add('hanging-indent');
1071          citeDiv.classList.add('csl-entry');
1072          var biblioDiv = window.document.getElementById('ref-' + cite);
1073          if (biblioDiv) {
1074            citeDiv.innerHTML = biblioDiv.innerHTML;
1075          }
1076          popup.appendChild(citeDiv);
1077        });
1078        return popup.innerHTML;
1079      });
1080    }
1081  }
1082});
1083</script>
1083
1084</div> <!-- /content -->
1085<footer class="footer">
1086  <div class="nav-footer">
1087    <div class="nav-footer-left">
1088      &nbsp;
1089    </div>   
1090    <div class="nav-footer-center">
1091
1092<div class="cookie-consent-footer"><a href="#" id="open_preferences_center">Cookie preferences -- it helps us to know which pages are read the most</a></div></div>
1093    <div class="nav-footer-right">
1094      &nbsp;
1095    </div>
1096  </div>
1097</footer>
1098
1099
1100
1101
1102<script src="site_libs/quarto-html/zenscroll-min.js"></script>
1102
1103</body></html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.