diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
index beaa3fc02..3bc705b0e 100644
--- a/.github/workflows/documentation.yml
+++ b/.github/workflows/documentation.yml
@@ -21,12 +21,23 @@ on:
- synchronize
- ready_for_review
+# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
+permissions:
+ contents: write
+ pages: write
+ id-token: write
+ statuses: write
+
+# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
+# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
+concurrency:
+ group: pages
+ cancel-in-progress: false
+
jobs:
+ # Build job
build:
runs-on: ubuntu-latest
- permissions:
- contents: write
- statuses: write
if: ${{ !github.event.pull_request.draft }}
steps:
- uses: actions/checkout@v4
@@ -37,11 +48,8 @@ jobs:
- uses: julia-actions/julia-buildpkg@v1
- uses: julia-actions/julia-docdeploy@v1
env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }}
- - run: |
- julia --project=docs -e '
- using Documenter: DocMeta, doctest
- using QuantumToolbox
- DocMeta.setdocmeta!(QuantumToolbox, :DocTestSetup, :(using QuantumToolbox); recursive=true)
- doctest(QuantumToolbox)'
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # For authentication with GitHub Actions token
+ DOCUMENTER_KEY: ${{ secrets.DOCUMENTER_KEY }} # For authentication with SSH deploy key
+ JULIA_DEBUG: "Documenter"
+ DATADEPS_ALWAYS_ACCEPT: true
+ # GKSwstype: "100" # for Plots.jl plots (if you have them)
diff --git a/.gitignore b/.gitignore
index edb4c3a5e..b07886a94 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,10 +4,10 @@
*.jl.cov
*.jl.mem
Manifest.toml
-docs/build/
.vscode
-*.json
+
+benchmarks/benchmarks_output.json
.ipynb_checkpoints
*.ipynb
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 8255db3fd..25cf0265e 100644
--- a/Makefile
+++ b/Makefile
@@ -12,13 +12,18 @@ docs:
${JULIA} --project=docs -e 'using Pkg; Pkg.develop(PackageSpec(path=pwd())); Pkg.instantiate()'
${JULIA} --project=docs docs/make.jl
-all: format test docs
+vitepress:
+ npm --prefix docs i
+ npm --prefix docs run docs:dev
+
+all: format test docs vitepress
help:
@echo "The following make commands are available:"
@echo " - make format: format codes with JuliaFormatter"
@echo " - make test: run the tests"
@echo " - make docs: instantiate and build the documentation"
+ @echo " - make vitepress: start Vitepress site of documentation"
@echo " - make all: run every commands in the above order"
-.PHONY: default format test docs all help
+.PHONY: default format test docs vitepress all help
diff --git a/README.md b/README.md
index 2661116be..8f01caf31 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
-

+
# QuantumToolbox.jl
@@ -65,7 +65,7 @@ QuantumToolbox.jl is equipped with a robust set of features:
- **Quantum State and Operator Manipulation:** Easily handle quantum states and operators with a rich set of tools, with the same functionalities as QuTiP.
- **Dynamical Evolution:** Advanced solvers for time evolution of quantum systems, thanks to the powerful [DifferentialEquations.jl](https://github.com/SciML/DifferentialEquations.jl) package.
-- **GPU Computing:** Leverage GPU resources for high-performance computing. For example, you run the master equation directly on the GPU with the same syntax as the CPU case.
+- **GPU Computing:** Leverage GPU resources for high-performance computing. Simulate quantum dynamics directly on the GPU with the same syntax as the CPU case.
- **Distributed Computing:** Distribute the computation over multiple nodes (e.g., a cluster). For example, you can run hundreds of quantum trajectories in parallel on a cluster, with, again, the same syntax as the simple case.
- **Easy Extension:** Easily extend the package, taking advantage of the Julia language features, like multiple dispatch and metaprogramming.
diff --git a/docs/.gitignore b/docs/.gitignore
new file mode 100644
index 000000000..778ffdc18
--- /dev/null
+++ b/docs/.gitignore
@@ -0,0 +1,4 @@
+build/
+node_modules/
+package-lock.json
+Manifest.toml
diff --git a/docs/Project.toml b/docs/Project.toml
index b61136e89..ef98b807e 100644
--- a/docs/Project.toml
+++ b/docs/Project.toml
@@ -3,4 +3,5 @@ BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf"
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
DocumenterCitations = "daee34ce-89f3-4625-b898-19384cb65244"
+DocumenterVitepress = "4710194d-e776-4893-9690-8d956a29c365"
QuantumToolbox = "6c2fb7c5-b903-41d2-bc5e-5a7c320b9fab"
diff --git a/docs/README.md b/docs/README.md
index 9fe1e761c..488aa85fb 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -1,4 +1,4 @@
-# How to build documentation locally ?
+# How to build documentation and start Vitepress site locally ?
## Working Directory
All the commands should be run under the root folder of the package: `/path/to/QuantumToolbox.jl/`
@@ -6,12 +6,19 @@ All the commands should be run under the root folder of the package: `/path/to/Q
The document pages will be generated in the directory: `/path/to/QuantumToolbox.jl/docs/build/` (which is ignored by git).
## Method 1: Run with `make` command
-Run the following command:
+Run the following command to instantiate and build the documentation:
```shell
make docs
```
-## Method 2: Run `julia` command manually
+Run the following command to start Vitepress site of documentation:
+> [!NOTE]
+> You need to install `Node.js` and `npm` first.
+```shell
+make vitepress
+```
+
+## Method 2: Run commands manually
### Build Pkg
Run the following command:
@@ -25,3 +32,17 @@ Run the following command:
```shell
julia --project=docs docs/make.jl
```
+
+### Start a local Vitepress site
+> [!NOTE]
+> You need to install `Node.js` and `npm` first.
+
+Install `npm` dependencies:
+```shell
+npm --prefix docs i
+```
+
+Run the following command:
+```shell
+npm --prefix docs run docs:dev
+```
\ No newline at end of file
diff --git a/docs/make.jl b/docs/make.jl
index 375ffec53..a60d1c39b 100644
--- a/docs/make.jl
+++ b/docs/make.jl
@@ -3,28 +3,22 @@
using QuantumToolbox
using Documenter
+using DocumenterVitepress
using DocumenterCitations
DocMeta.setdocmeta!(QuantumToolbox, :DocTestSetup, :(using QuantumToolbox); recursive = true)
const DRAFT = false # set `true` to disable cell evaluation
-bib = CitationBibliography(joinpath(@__DIR__, "src", "bibliography.bib"), style=:authoryear)
-
-const MathEngine = MathJax3(
- Dict(
- :loader => Dict("load" => ["[tex]/physics"]),
- :tex => Dict(
- "inlineMath" => [["\$", "\$"], ["\\(", "\\)"]],
- "tags" => "ams",
- "packages" => ["base", "ams", "autoload", "physics"],
- ),
- )
+bib = CitationBibliography(
+ joinpath(@__DIR__, "src", "resources", "bibliography.bib"),
+ style=:authoryear,
)
const PAGES = [
+ "Home" => "index.md",
"Getting Started" => [
- "Introduction" => "index.md",
+ "Brief Example" => "getting_started.md",
"Key differences from QuTiP" => "qutip_differences.md",
"The Importance of Type-Stability" => "type_stability.md",
# "Cite QuantumToolbox.jl" => "cite.md",
@@ -60,9 +54,11 @@ const PAGES = [
"tutorials/logo.md",
],
],
- "API" => "api.md",
- "Bibliography" => "bibliography.md",
- # "Change Log" => "changelog.md",
+ "Resources" => [
+ "API" => "resources/api.md",
+ # "Change Log" => "resources/changelog.md",
+ "Bibliography" => "resources/bibliography.md",
+ ],
]
makedocs(;
@@ -71,16 +67,17 @@ makedocs(;
repo = Remotes.GitHub("qutip", "QuantumToolbox.jl"),
sitename = "QuantumToolbox.jl",
pages = PAGES,
- format = Documenter.HTML(;
- prettyurls = get(ENV, "CI", "false") == "true",
- canonical = "https://qutip.github.io/QuantumToolbox.jl",
- edit_link = "main",
- assets = ["assets/favicon.ico"],
- mathengine = MathEngine,
- size_threshold_ignore = ["api.md"],
+ format = DocumenterVitepress.MarkdownVitepress(
+ repo = "github.com/qutip/QuantumToolbox.jl",
),
draft = DRAFT,
plugins = [bib],
)
-deploydocs(; repo = "github.com/qutip/QuantumToolbox.jl", devbranch = "main")
+deploydocs(;
+ repo = "github.com/qutip/QuantumToolbox.jl",
+ target = "build", # this is where Vitepress stores its output
+ devbranch = "main",
+ branch = "gh-pages",
+ push_preview = true,
+)
diff --git a/docs/package.json b/docs/package.json
new file mode 100644
index 000000000..5633b4976
--- /dev/null
+++ b/docs/package.json
@@ -0,0 +1,15 @@
+{
+ "scripts": {
+ "docs:dev": "vitepress dev build/.documenter",
+ "docs:build": "vitepress build build/.documenter",
+ "docs:preview": "vitepress preview build/.documenter"
+ },
+ "dependencies": {
+ "@shikijs/transformers": "^1.1.7",
+ "markdown-it": "^14.1.0",
+ "markdown-it-footnote": "^4.0.0",
+ "markdown-it-mathjax3": "^4.3.2",
+ "vitepress": "^1.1.4",
+ "vitepress-plugin-tabs": "^0.5.0"
+ }
+}
diff --git a/docs/src/.vitepress/config.mts b/docs/src/.vitepress/config.mts
new file mode 100644
index 000000000..42118b3df
--- /dev/null
+++ b/docs/src/.vitepress/config.mts
@@ -0,0 +1,66 @@
+import { defineConfig } from 'vitepress'
+import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs'
+import mathjax3 from "markdown-it-mathjax3";
+import footnote from "markdown-it-footnote";
+
+const navTemp = {
+ nav: 'REPLACE_ME_DOCUMENTER_VITEPRESS',
+}
+
+const nav = [
+ ...navTemp.nav,
+ { text: 'Benchmarks', link: 'https://qutip.org/QuantumToolbox.jl/benchmarks/' },
+ {
+ component: 'VersionPicker'
+ }
+]
+
+// https://vitepress.dev/reference/site-config
+export default defineConfig({
+ base: 'REPLACE_ME_DOCUMENTER_VITEPRESS',// TODO: replace this in makedocs!
+ title: 'REPLACE_ME_DOCUMENTER_VITEPRESS',
+ description: 'REPLACE_ME_DOCUMENTER_VITEPRESS',
+ lastUpdated: true,
+ cleanUrls: true,
+ outDir: 'REPLACE_ME_DOCUMENTER_VITEPRESS', // This is required for MarkdownVitepress to work correctly...
+ head: [['link', { rel: 'icon', href: 'REPLACE_ME_DOCUMENTER_VITEPRESS_FAVICON' }]],
+ ignoreDeadLinks: true,
+
+ markdown: {
+ math: true,
+
+ // options for @mdit-vue/plugin-toc
+ // https://github.com/mdit-vue/mdit-vue/tree/main/packages/plugin-toc#options
+ toc: { level: [1, 2] },
+
+ config(md) {
+ md.use(tabsMarkdownPlugin),
+ md.use(mathjax3),
+ md.use(footnote)
+ },
+ theme: {
+ light: "github-light",
+ dark: "github-dark"
+ }
+ },
+ themeConfig: {
+ outline: 'deep',
+ logo: 'REPLACE_ME_DOCUMENTER_VITEPRESS',
+ search: {
+ provider: 'local',
+ options: {
+ detailedView: true
+ }
+ },
+ nav,
+ sidebar: 'REPLACE_ME_DOCUMENTER_VITEPRESS',
+ editLink: 'REPLACE_ME_DOCUMENTER_VITEPRESS',
+ socialLinks: [
+ { icon: 'github', link: 'REPLACE_ME_DOCUMENTER_VITEPRESS' }
+ ],
+ footer: {
+ message: 'Made with Documenter.jl, VitePress and DocumenterVitepress.jl
Released under the BSD 3-Clause License. Powered by the Julia Programming Language.
',
+ copyright: `© Copyright ${new Date().getUTCFullYear()} QuTiP.org.`
+ }
+ }
+})
diff --git a/docs/src/.vitepress/theme/VersionPicker.vue b/docs/src/.vitepress/theme/VersionPicker.vue
new file mode 100644
index 000000000..ba744d8f4
--- /dev/null
+++ b/docs/src/.vitepress/theme/VersionPicker.vue
@@ -0,0 +1,64 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/docs/src/.vitepress/theme/index.ts b/docs/src/.vitepress/theme/index.ts
new file mode 100644
index 000000000..ae0c3d3a8
--- /dev/null
+++ b/docs/src/.vitepress/theme/index.ts
@@ -0,0 +1,21 @@
+// .vitepress/theme/index.ts
+import { h } from 'vue'
+import type { Theme } from 'vitepress'
+import DefaultTheme from 'vitepress/theme'
+import VersionPicker from "./VersionPicker.vue"
+
+import { enhanceAppWithTabs } from 'vitepress-plugin-tabs/client'
+import './style.css'
+
+export default {
+ extends: DefaultTheme,
+ Layout() {
+ return h(DefaultTheme.Layout, null, {
+ // https://vitepress.dev/guide/extending-default-theme#layout-slots
+ })
+ },
+ enhanceApp({ app, router, siteData }) {
+ enhanceAppWithTabs(app);
+ app.component('VersionPicker', VersionPicker);
+ }
+} satisfies Theme
diff --git a/docs/src/.vitepress/theme/style.css b/docs/src/.vitepress/theme/style.css
new file mode 100644
index 000000000..a520b4a11
--- /dev/null
+++ b/docs/src/.vitepress/theme/style.css
@@ -0,0 +1,269 @@
+/* Customize default theme styling by overriding CSS variables:
+https://github.com/vuejs/vitepress/blob/main/src/client/theme-default/styles/vars.css
+ */
+
+/* Layouts */
+
+/*
+ :root {
+ --vp-layout-max-width: 1440px;
+} */
+
+.VPHero .clip {
+ white-space: pre;
+ max-width: 500px;
+}
+
+/* Fonts */
+
+@font-face {
+ font-family: JuliaMono-Regular;
+ src: url("https://cdn.jsdelivr.net/gh/cormullion/juliamono/webfonts/JuliaMono-Regular.woff2");
+}
+
+:root {
+ /* Typography */
+ --vp-font-family-base: "Barlow", "Inter var experimental", "Inter var",
+ -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu,
+ Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
+
+ /* Code Snippet font */
+ --vp-font-family-mono: JuliaMono-Regular, monospace;
+
+}
+
+/*
+ Disable contextual alternates (kind of like ligatures but different) in monospace,
+ which turns `/>` to an up arrow and `|>` (the Julia pipe symbol) to an up arrow as well.
+ This is pretty bad for Julia folks reading even though copy+paste retains the same text.
+ */
+/* Target elements with class 'mono' */
+.mono-no-substitutions {
+ font-family: "JuliaMono-Light", monospace;
+ font-feature-settings: "calt" off;
+}
+
+/* Alternatively, you can use the following if you prefer: */
+.mono-no-substitutions-alt {
+ font-family: "JuliaMono-Light", monospace;
+ font-variant-ligatures: none;
+}
+
+/* If you want to apply this globally to all monospace text: */
+pre,
+code {
+ font-family: "JuliaMono-Light", monospace;
+ font-feature-settings: "calt" off;
+}
+
+/* Colors */
+
+:root {
+ --julia-blue: #4063D8;
+ --julia-purple: #9558B2;
+ --julia-red: #CB3C33;
+ --julia-green: #389826;
+
+ --vp-c-brand: #389826;
+ --vp-c-brand-light: #3dd027;
+ --vp-c-brand-lighter: #9499ff;
+ --vp-c-brand-lightest: #bcc0ff;
+ --vp-c-brand-dark: #535bf2;
+ --vp-c-brand-darker: #454ce1;
+ --vp-c-brand-dimm: #212425;
+}
+
+/* Component: Button */
+
+:root {
+ --vp-button-brand-border: var(--vp-c-brand-light);
+ --vp-button-brand-text: var(--vp-c-white);
+ --vp-button-brand-bg: var(--vp-c-brand);
+ --vp-button-brand-hover-border: var(--vp-c-brand-light);
+ --vp-button-brand-hover-text: var(--vp-c-white);
+ --vp-button-brand-hover-bg: var(--vp-c-brand-light);
+ --vp-button-brand-active-border: var(--vp-c-brand-light);
+ --vp-button-brand-active-text: var(--vp-c-white);
+ --vp-button-brand-active-bg: var(--vp-button-brand-bg);
+}
+
+/* Component: Home */
+
+:root {
+ --vp-home-hero-name-color: transparent;
+ --vp-home-hero-name-background: -webkit-linear-gradient(120deg,
+ #9558B2 30%,
+ #CB3C33);
+
+ --vp-home-hero-image-background-image: none; /* remove the blur background */
+ /* (default setting)
+ --vp-home-hero-image-background-image: linear-gradient(-45deg,
+ #9558B2 30%,
+ #389826 30%,
+ #CB3C33);
+ */
+ --vp-home-hero-image-filter: blur(40px);
+}
+
+@media (min-width: 640px) {
+ :root {
+ --vp-home-hero-image-filter: blur(56px);
+ }
+}
+
+@media (min-width: 960px) {
+ :root {
+ --vp-home-hero-image-filter: blur(72px);
+ }
+}
+
+/* Component: Custom Block */
+
+:root.dark {
+ --vp-custom-block-tip-border: var(--vp-c-brand);
+ --vp-custom-block-tip-text: var(--vp-c-brand-lightest);
+ --vp-custom-block-tip-bg: var(--vp-c-brand-dimm);
+
+ /* // Tweak the color palette for blacks and dark grays */
+ --vp-c-black: hsl(220 20% 9%);
+ --vp-c-black-pure: hsl(220, 24%, 4%);
+ --vp-c-black-soft: hsl(220 16% 13%);
+ --vp-c-black-mute: hsl(220 14% 17%);
+ --vp-c-gray: hsl(220 8% 56%);
+ --vp-c-gray-dark-1: hsl(220 10% 39%);
+ --vp-c-gray-dark-2: hsl(220 12% 28%);
+ --vp-c-gray-dark-3: hsl(220 12% 23%);
+ --vp-c-gray-dark-4: hsl(220 14% 17%);
+ --vp-c-gray-dark-5: hsl(220 16% 13%);
+
+ /* // Backgrounds */
+ /* --vp-c-bg: hsl(240, 2%, 11%); */
+ --vp-custom-block-info-bg: hsl(220 14% 17%);
+ /* --vp-c-gutter: hsl(220 20% 9%);
+
+ --vp-c-bg-alt: hsl(220 20% 9%);
+ --vp-c-bg-soft: hsl(220 14% 17%);
+ --vp-c-bg-mute: hsl(220 12% 23%);
+ */
+}
+
+/* Component: Algolia */
+
+.DocSearch {
+ --docsearch-primary-color: var(--vp-c-brand) !important;
+}
+
+/* Component: MathJax */
+
+mjx-container>svg {
+ display: block;
+ margin: auto;
+}
+
+mjx-container {
+ padding: 0.5rem 0;
+}
+
+mjx-container {
+ display: inline;
+ margin: auto 2px -2px;
+}
+
+mjx-container>svg {
+ margin: auto;
+ display: inline-block;
+}
+
+/**
+ * Colors links
+ * -------------------------------------------------------------------------- */
+
+:root {
+ --vp-c-brand-1: #CB3C33;
+ --vp-c-brand-2: #CB3C33;
+ --vp-c-brand-3: #CB3C33;
+ --vp-c-sponsor: #ca2971;
+ --vitest-c-sponsor-hover: #c13071;
+}
+
+.dark {
+ --vp-c-brand-1: #91dd33;
+ --vp-c-brand-2: #91dd33;
+ --vp-c-brand-3: #91dd33;
+ --vp-c-sponsor: #91dd33;
+ --vitest-c-sponsor-hover: #e51370;
+}
+
+/**
+ * Change images from light to dark theme
+ * -------------------------------------------------------------------------- */
+
+:root:not(.dark) .dark-only {
+ display: none;
+}
+
+:root:is(.dark) .light-only {
+ display: none;
+}
+
+/* https://bddxg.top/article/note/vitepress优化/一些细节上的优化.html#文档页面调整-加宽 */
+
+.VPDoc.has-aside .content-container {
+ max-width: 100% !important;
+}
+
+.aside {
+ max-width: 200px !important;
+ padding-left: 0 !important;
+}
+
+.VPDoc {
+ padding-top: 15px !important;
+ padding-left: 5px !important;
+
+}
+
+/* This one does the right menu */
+
+.VPDocOutlineItem li {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ max-width: 200px;
+}
+
+.VPNavBar .title {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+}
+
+@media (max-width: 960px) {
+ .VPDoc {
+ padding-left: 25px !important;
+ }
+}
+
+/* This one does the left menu */
+
+/* .VPSidebarItem .VPLink p {
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ max-width: 200px;
+ } */
+
+
+/* Component: Docstring Custom Block */
+
+.jldocstring.custom-block {
+ border: 1px solid var(--vp-c-gray-2);
+ color: var(--vp-c-text-1)
+}
+
+.jldocstring.custom-block summary {
+ font-weight: 700;
+ cursor: pointer;
+ user-select: none;
+ margin: 0 0 8px;
+}
\ No newline at end of file
diff --git a/docs/src/bibliography.bib b/docs/src/bibliography.bib
deleted file mode 100644
index 727766d5f..000000000
--- a/docs/src/bibliography.bib
+++ /dev/null
@@ -1,14 +0,0 @@
-@article{gravina2024adaptive,
- title = {{Adaptive variational low-rank dynamics for open quantum systems}},
- author = {Gravina, Luca and Savona, Vincenzo},
- journal = {Phys. Rev. Res.},
- volume = {6},
- issue = {2},
- pages = {023072},
- numpages = {18},
- year = {2024},
- month = {Apr},
- publisher = {American Physical Society},
- doi = {10.1103/PhysRevResearch.6.023072},
- url = {https://link.aps.org/doi/10.1103/PhysRevResearch.6.023072}
-}
diff --git a/docs/src/getting_started.md b/docs/src/getting_started.md
new file mode 100644
index 000000000..377f33ec9
--- /dev/null
+++ b/docs/src/getting_started.md
@@ -0,0 +1,76 @@
+```@meta
+CurrentModule = QuantumToolbox
+```
+
+## Brief Example
+
+We now provide a brief example to demonstrate the similarity between [QuantumToolbox.jl](https://github.com/qutip/QuantumToolbox.jl) and [QuTiP](https://github.com/qutip/qutip).
+
+Let's consider a quantum harmonic oscillator with a Hamiltonian given by:
+
+```math
+\hat{H} = \omega \hat{a}^\dagger \hat{a}
+```
+
+where ``\hat{a}`` and ``\hat{a}^\dagger`` are the annihilation and creation operators, respectively. We can define the Hamiltonian as follows:
+
+```julia
+using QuantumToolbox
+
+N = 20 # cutoff of the Hilbert space dimension
+ω = 1.0 # frequency of the harmonic oscillator
+
+a = destroy(N) # annihilation operator
+
+H = ω * a' * a
+```
+
+We now introduce some losses in a thermal environment, described by the Lindblad master equation:
+
+```math
+\frac{d \hat{\rho}}{dt} = -i [\hat{H}, \hat{\rho}] + \gamma \mathcal{D}[\hat{a}] \hat{\rho}
+```
+
+where ``\hat{\rho}`` is the density matrix, ``\gamma`` is the damping rate, and ``\mathcal{D}[\hat{a}]`` is the Lindblad dissipator, defined as:
+
+```math
+\mathcal{D}[\hat{a}]\hat{\rho} = \hat{a}\hat{\rho}\hat{a}^\dagger - \frac{1}{2}\hat{a}^\dagger\hat{a}\hat{\rho} - \frac{1}{2}\hat{\rho}\hat{a}^\dagger\hat{a}
+```
+
+We now compute the time evolution of the system using the [`mesolve`](@ref) function, starting from the initial state ``\ket{\psi (0)} = \ket{3}``:
+
+```julia
+γ = 0.1 # damping rate
+
+ψ0 = fock(N, 3) # initial state
+
+tlist = range(0, 10, 100) # time list
+
+c_ops = [sqrt(γ) * a]
+e_ops = [a' * a]
+
+sol = mesolve(H, ψ0, tlist, c_ops, e_ops = e_ops)
+```
+
+We can extract the expectation value of the number operator ``\hat{a}^\dagger \hat{a}`` with the command `sol.expect`, and the states with the command `sol.states`.
+
+### Support for GPU calculation
+
+We can easily pass the computation to the GPU, by simply passing all the `Qobj`s to the GPU:
+
+```julia
+using QuantumToolbox
+using CUDA
+CUDA.allowscalar(false) # Avoid unexpected scalar indexing
+
+a_gpu = cu(destroy(N)) # The only difference in the code is the cu() function
+
+H_gpu = ω * a_gpu' * a_gpu
+
+ψ0_gpu = cu(fock(N, 3))
+
+c_ops = [sqrt(γ) * a_gpu]
+e_ops = [a_gpu' * a_gpu]
+
+sol = mesolve(H_gpu, ψ0_gpu, tlist, c_ops, e_ops = e_ops)
+```
\ No newline at end of file
diff --git a/docs/src/index.md b/docs/src/index.md
index 7447af11b..47585fe81 100644
--- a/docs/src/index.md
+++ b/docs/src/index.md
@@ -1,24 +1,55 @@
-```@meta
-CurrentModule = QuantumToolbox
+```@raw html
+---
+# https://vitepress.dev/reference/default-theme-home-page
+layout: home
+
+hero:
+ name: "QuantumToolbox.jl"
+ tagline: A pure Julia framework designed for High-performance quantum physics simulations
+ image:
+ src: /logo.png
+ alt: QuantumToolbox
+ actions:
+ - theme: brand
+ text: Getting Started
+ link: /getting_started
+ - theme: alt
+ text: Users Guide
+ link: /users_guide/QuantumObject/QuantumObject
+ - theme: alt
+ text: View on Github
+ link: https://github.com/qutip/QuantumToolbox.jl
+ - theme: alt
+ text: API
+ link: /api
+ - theme: alt
+ text: Visit QuTiP.org
+ link: https://qutip.org/
+
+
+features:
+ - icon:
+ title: Dynamical Evolution
+ details: Advanced solvers for time evolution of quantum systems, thanks to the powerful DifferentialEquations.jl package.
+ link: /users_guide/time_evolution/intro
+ - icon:
+ title: GPU Computing
+ details: Leverage GPU resources for high-performance computing. Simulate quantum dynamics directly on the GPU with the same syntax as the CPU case.
+ link: /getting_started
+ - icon:
+ title: Distributed Computing
+ details: Distribute the computation over multiple nodes (e.g., a cluster). Simulate hundreds of quantum trajectories in parallel on a cluster, with, again, the same syntax as the simple case.
+ link: /users_guide/time_evolution/mcsolve
+---
```
-# QuantumToolbox.jl Documentation
+# [Introduction](@id doc:Introduction)
-[QuantumToolbox.jl](https://github.com/qutip/QuantumToolbox.jl) is a cutting-edge Julia package designed for quantum physics simulations, closely emulating the popular Python [QuTiP](https://github.com/qutip/qutip) package. It uniquely combines the simplicity and power of Julia with advanced features like GPU acceleration and distributed computing, making simulation of quantum systems more accessible and efficient.
+[QuantumToolbox.jl](https://github.com/qutip/QuantumToolbox.jl) is a cutting-edge Julia package designed for quantum physics simulations, closely emulating the popular Python [QuTiP](https://github.com/qutip/qutip) package. It uniquely combines the simplicity and power of Julia with advanced features like GPU acceleration and distributed computing, making simulation of quantum systems more accessible and efficient. Taking advantage of the Julia language features (like multiple dispatch and metaprogramming), QuantumToolbox.jl is designed to be easily extendable, allowing users to build upon the existing functionalities.
-*With this package, moving from Python to Julia for quantum physics simulations has never been easier*, due to the similar syntax and functionalities.
+*__With this package, moving from Python to Julia for quantum physics simulations has never been easier__*, due to the similar syntax and functionalities.
-## Features
-
-QuantumToolbox.jl is equipped with a robust set of features:
-
-- **Quantum State and Operator Manipulation:** Easily handle quantum states and operators with a rich set of tools, with the same functionalities as QuTiP.
-- **Dynamical Evolution:** Advanced solvers for time evolution of quantum systems, thanks to the powerful [DifferentialEquations.jl](https://github.com/SciML/DifferentialEquations.jl) package.
-- **GPU Computing:** Leverage GPU resources for high-performance computing. For example, you run the master equation directly on the GPU with the same syntax as the CPU case.
-- **Distributed Computing:** Distribute the computation over multiple nodes (e.g., a cluster). For example, you can run undreds of quantum trajectories in parallel on a cluster, with, again, the same syntax as the simple case.
-- **Easy Extension:** Easily extend the package, taking advantage of the Julia language features, like multiple dispatch and metaprogramming.
-
-## [Installation](@id doc:Installation)
+# [Installation](@id doc:Installation)
!!! note "Requirements"
`QuantumToolbox.jl` requires `Julia 1.10+`.
@@ -29,7 +60,7 @@ using Pkg
Pkg.add("QuantumToolbox")
```
Alternatively, this can also be done in Julia's [Pkg REPL](https://julialang.github.io/Pkg.jl/v1/getting-started/) by pressing the key `]` in the REPL to use the package mode, and then type the following command:
-```julia-REPL
+```julia-repl
(1.10) pkg> add QuantumToolbox
```
More information about `Julia`'s package manager can be found at [`Pkg.jl`](https://julialang.github.io/Pkg.jl/v1/).
@@ -40,76 +71,3 @@ using QuantumToolbox
QuantumToolbox.versioninfo()
QuantumToolbox.about()
```
-
-## Brief Example
-
-We now provide a brief example to demonstrate the similarity between [QuantumToolbox.jl](https://github.com/qutip/QuantumToolbox.jl) and [QuTiP](https://github.com/qutip/qutip).
-
-Let's consider a quantum harmonic oscillator with a Hamiltonian given by:
-
-```math
-\hat{H} = \omega \hat{a}^\dagger \hat{a}
-```
-
-where ``\hat{a}`` and ``\hat{a}^\dagger`` are the annihilation and creation operators, respectively. We can define the Hamiltonian as follows:
-
-```julia
-using QuantumToolbox
-
-N = 20 # cutoff of the Hilbert space dimension
-ω = 1.0 # frequency of the harmonic oscillator
-
-a = destroy(N) # annihilation operator
-
-H = ω * a' * a
-```
-
-We now introduce some losses in a thermal environment, described by the Lindblad master equation:
-
-```math
-\frac{d \hat{\rho}}{dt} = -i [\hat{H}, \hat{\rho}] + \gamma \mathcal{D}[\hat{a}] \hat{\rho}
-```
-
-where ``\hat{\rho}`` is the density matrix, ``\gamma`` is the damping rate, and ``\mathcal{D}[\hat{a}]`` is the Lindblad dissipator, defined as:
-
-```math
-\mathcal{D}[\hat{a}]\hat{\rho} = \hat{a}\hat{\rho}\hat{a}^\dagger - \frac{1}{2}\hat{a}^\dagger\hat{a}\hat{\rho} - \frac{1}{2}\hat{\rho}\hat{a}^\dagger\hat{a}
-```
-
-We now compute the time evolution of the system using the [`mesolve`](@ref) function, starting from the initial state ``\ket{\psi (0)} = \ket{3}``:
-
-```julia
-γ = 0.1 # damping rate
-
-ψ0 = fock(N, 3) # initial state
-
-tlist = range(0, 10, 100) # time list
-
-c_ops = [sqrt(γ) * a]
-e_ops = [a' * a]
-
-sol = mesolve(H, ψ0, tlist, c_ops, e_ops = e_ops)
-```
-
-We can extract the expectation value of the number operator ``\hat{a}^\dagger \hat{a}`` with the command `sol.expect`, and the states with the command `sol.states`.
-
-### Support for GPU calculation
-
-We can easily pass the computation to the GPU, by simply passing all the `Qobj`s to the GPU:
-
-```julia
-using QuantumToolbox
-using CUDA
-CUDA.allowscalar(false) # Avoid unexpected scalar indexing
-
-a_gpu = cu(destroy(N)) # The only difference in the code is the cu() function
-
-H_gpu = ω * a_gpu' * a_gpu
-
-ψ0_gpu = cu(fock(N, 3))
-
-c_ops = [sqrt(γ) * a_gpu]
-e_ops = [a_gpu' * a_gpu]
-
-sol = mesolve(H_gpu, ψ0_gpu, tlist, c_ops, e_ops = e_ops)
-```
diff --git a/docs/src/assets/favicon.ico b/docs/src/public/favicon.ico
similarity index 100%
rename from docs/src/assets/favicon.ico
rename to docs/src/public/favicon.ico
diff --git a/docs/src/assets/logo.png b/docs/src/public/logo.png
similarity index 100%
rename from docs/src/assets/logo.png
rename to docs/src/public/logo.png
diff --git a/docs/src/api.md b/docs/src/resources/api.md
similarity index 98%
rename from docs/src/api.md
rename to docs/src/resources/api.md
index 4dab36aff..59f4d22d6 100644
--- a/docs/src/api.md
+++ b/docs/src/resources/api.md
@@ -4,11 +4,9 @@ CurrentModule = QuantumToolbox
# [API](@id doc-API)
-## Contents
+**Table of contents**
-```@contents
-Pages = ["api.md"]
-```
+[[toc]]
## [Quantum object (Qobj) and type](@id doc-API:Quantum-object-and-type)
diff --git a/docs/src/resources/bibliography.bib b/docs/src/resources/bibliography.bib
new file mode 100644
index 000000000..931ea3bfb
--- /dev/null
+++ b/docs/src/resources/bibliography.bib
@@ -0,0 +1,36 @@
+@book{Nielsen-Chuang2011,
+ Author = {Michael A. Nielsen and Isaac L. Chuang},
+ Title = {Quantum Computation and Quantum Information: 10th Anniversary Edition},
+ Publisher = {Cambridge University Press},
+ Year = {2011},
+ ISBN = {9781107002173},
+ URL = {https://www.amazon.com/Quantum-Computation-Information-10th-Anniversary/dp/1107002176?SubscriptionId=AKIAIOBINVZYXZQZ2U3A&tag=chimbori05-20&linkCode=xm2&camp=2025&creative=165953&creativeASIN=1107002176}
+}
+
+@article{Jozsa1994,
+ author = {Richard Jozsa},
+ title = {Fidelity for Mixed Quantum States},
+ journal = {Journal of Modern Optics},
+ volume = {41},
+ number = {12},
+ pages = {2315--2323},
+ year = {1994},
+ publisher = {Taylor \& Francis},
+ doi = {10.1080/09500349414552171},
+ URL = {https://doi.org/10.1080/09500349414552171},
+}
+
+@article{gravina2024adaptive,
+ title = {{Adaptive variational low-rank dynamics for open quantum systems}},
+ author = {Gravina, Luca and Savona, Vincenzo},
+ journal = {Phys. Rev. Res.},
+ volume = {6},
+ issue = {2},
+ pages = {023072},
+ numpages = {18},
+ year = {2024},
+ month = {Apr},
+ publisher = {American Physical Society},
+ doi = {10.1103/PhysRevResearch.6.023072},
+ url = {https://link.aps.org/doi/10.1103/PhysRevResearch.6.023072}
+}
diff --git a/docs/src/bibliography.md b/docs/src/resources/bibliography.md
similarity index 62%
rename from docs/src/bibliography.md
rename to docs/src/resources/bibliography.md
index 74d56db57..45632c00e 100644
--- a/docs/src/bibliography.md
+++ b/docs/src/resources/bibliography.md
@@ -2,7 +2,5 @@
CurrentModule = QuantumToolbox
```
-# [Bibliography](@id doc:Bibliography)
-
```@bibliography
```
diff --git a/docs/src/users_guide/states_and_operators.md b/docs/src/users_guide/states_and_operators.md
index 85993c2c9..eaae89727 100644
--- a/docs/src/users_guide/states_and_operators.md
+++ b/docs/src/users_guide/states_and_operators.md
@@ -20,7 +20,7 @@ and then create a lowering operator ``\hat{a}`` corresponding to `5` number stat
a = destroy(5)
```
-Now lets apply the lowering operator `\hat{a}` to our vacuum state `vac`:
+Now lets apply the lowering operator ``\hat{a}`` to our vacuum state `vac`:
```@example states_and_operators
a * vac
@@ -172,7 +172,7 @@ z = thermal_dm(5, 0.125)
fidelity(x, y)
```
-Note that the definition of [`fidelity`](@ref) here is from **Nielsen & Chuang, "Quantum Computation and Quantum Information"**. It is the square root of the fidelity defined in **R. Jozsa, Journal of Modern Optics, 41:12, 2315 (1994)**. We also know that for two pure states, the trace distance (``T``) and the fidelity (``F``) are related by ``T = \sqrt{1-F^2}``:
+Note that the definition of [`fidelity`](@ref) here is from [Nielsen-Chuang2011](@cite). It is the square root of the fidelity defined in [Jozsa1994](@cite). We also know that for two pure states, the trace distance (``T``) and the fidelity (``F``) are related by ``T = \sqrt{1-F^2}``:
```@example states_and_operators
tracedist(x, y) ≈ sqrt(1 - (fidelity(x, y))^2)
diff --git a/docs/src/users_guide/time_evolution/intro.md b/docs/src/users_guide/time_evolution/intro.md
index 37488c956..2aaf3eeb0 100644
--- a/docs/src/users_guide/time_evolution/intro.md
+++ b/docs/src/users_guide/time_evolution/intro.md
@@ -2,18 +2,23 @@
**Table of contents**
-```@contents
-Pages = [
- "intro.md",
- "solution.md",
- "sesolve.md",
- "mesolve.md",
- "mcsolve.md",
- "stochastic.md",
- "time_dependent.md",
-]
-Depth = 1:2
-```
+- [Introduction](@ref doc-TE:Introduction)
+- [Time Evolution Solutions](@ref doc-TE:Time-Evolution-Solutions)
+ - [Solution](@ref doc-TE:Solution)
+ - [Multiple trajectories solution](@ref doc-TE:Multiple-trajectories-solution)
+ - [Accessing data in solutions](@ref doc-TE:Accessing-data-in-solutions)
+- [Schrödinger Equation Solver](@ref doc-TE:Schrödinger-Equation-Solver)
+ - [Unitary evolution](@ref doc-TE:Unitary-evolution)
+ - [Example: Spin dynamics](@ref doc-TE:Example:Spin-dynamics)
+- [Lindblad Master Equation Solver](@ref doc-TE:Lindblad-Master-Equation-Solver)
+ - [Von Neumann equation](@ref doc-TE:Von-Neumann-equation)
+ - [The Lindblad master equation](@ref doc-TE:The-Lindblad-master-equation)
+ - [Example: Dissipative Spin dynamics](@ref doc-TE:Example:Dissipative-Spin-dynamics)
+ - [Example: Harmonic oscillator in thermal bath](@ref doc-TE:Example:Harmonic-oscillator-in-thermal-bath)
+ - [Example: Two-level atom coupled to dissipative single-mode cavity](@ref doc-TE:Example:Two-level-atom-coupled-to-dissipative-single-mode-cavity)
+- [Monte-Carlo Solver](@ref doc-TE:Monte-Carlo-Solver)
+- [Stochastic Solver](@ref doc-TE:Stochastic-Solver)
+- [Solving Problems with Time-dependent Hamiltonians](@ref doc-TE:Solving-Problems-with-Time-dependent-Hamiltonians)
# [Introduction](@id doc-TE:Introduction)
diff --git a/docs/src/users_guide/time_evolution/mesolve.md b/docs/src/users_guide/time_evolution/mesolve.md
index fdda3e9bb..6c06c1568 100644
--- a/docs/src/users_guide/time_evolution/mesolve.md
+++ b/docs/src/users_guide/time_evolution/mesolve.md
@@ -4,7 +4,7 @@
using QuantumToolbox
```
-## Von Neumann equation
+## [Von Neumann equation](@id doc-TE:Von-Neumann-equation)
While the evolution of the state vector in a closed quantum system is deterministic (as we discussed in the previous section: [Schrödinger Equation Solver](@ref doc-TE:Schrödinger-Equation-Solver)), open quantum systems are stochastic in nature. The effect of an environment on the system of interest is to induce stochastic transitions between energy levels, and to introduce uncertainty in the phase difference between states of the system. The state of an open quantum system is therefore described in terms of ensemble averaged states using the density matrix formalism. A density matrix ``\hat{\rho}`` describes a probability distribution of quantum states ``|\psi_n\rangle`` in a matrix representation, namely
@@ -18,7 +18,6 @@ The time evolution of the density matrix ``\hat{\rho}(t)`` under closed system d
```math
\begin{equation}
-\label{von-Neumann-Eq}
\frac{d}{dt}\hat{\rho}(t) = -\frac{i}{\hbar}\left[\hat{H}, \hat{\rho}(t)\right],
\end{equation}
```
@@ -62,13 +61,12 @@ sol.expect
sol.states
```
-## The Lindblad master equation
+## [The Lindblad master equation](@id doc-TE:The-Lindblad-master-equation)
-The standard approach for deriving the equations of motion for a system interacting with its environment is to expand the scope of the system to include the environment. The combined quantum system is then closed, and its evolution is governed by the von Neumann equation given in Eq. \eqref{von-Neumann-Eq}
+The standard approach for deriving the equations of motion for a system interacting with its environment is to expand the scope of the system to include the environment. The combined quantum system is then closed, and its evolution is also governed by the von Neumann equation
```math
\begin{equation}
-\label{tot-von-Neumann-Eq}
\frac{d}{dt}\hat{\rho}_{\textrm{tot}}(t) = -\frac{i}{\hbar}\left[\hat{H}_{\textrm{tot}}, \hat{\rho}_{\textrm{tot}}(t)\right].
\end{equation}
```
@@ -79,27 +77,26 @@ Here, the total Hamiltonian
\hat{H}_{\textrm{tot}} = \hat{H}_{\textrm{sys}} + \hat{H}_{\textrm{env}} + \hat{H}_{\textrm{int}},
```
-includes the original system Hamiltonian ``\hat{H}_{\textrm{sys}}``, the Hamiltonian for the environment ``\hat{H}_{\textrm{env}}``, and a term representing the interaction between the system and its environment ``\hat{H}_{\textrm{int}}``. Since we are only interested in the dynamics of the system, we can, perform a partial trace over the environmental degrees of freedom in Eq. \eqref{tot-von-Neumann-Eq}, and thereby obtain a master equation for the motion of the original system density matrix ``\hat{\rho}_{\textrm{sys}}(t)=\textrm{Tr}_{\textrm{env}}[\hat{\rho}_{\textrm{tot}}(t)]``. The most general trace-preserving and completely positive form of this evolution is the Lindblad master equation for the reduced density matrix, namely
+includes the original system Hamiltonian ``\hat{H}_{\textrm{sys}}``, the Hamiltonian for the environment ``\hat{H}_{\textrm{env}}``, and a term representing the interaction between the system and its environment ``\hat{H}_{\textrm{int}}``. Since we are only interested in the dynamics of the system, we can, perform a partial trace over the environmental degrees of freedom, and thereby obtain a master equation for the motion of the original system density matrix ``\hat{\rho}_{\textrm{sys}}(t)=\textrm{Tr}_{\textrm{env}}[\hat{\rho}_{\textrm{tot}}(t)]``. The most general trace-preserving and completely positive form of this evolution is the Lindblad master equation for the reduced density matrix, namely
```math
\begin{equation}
-\label{Lindblad-master-Eq}
\frac{d}{dt}\hat{\rho}_{\textrm{sys}}(t) = -\frac{i}{\hbar}\left[\hat{H}_{\textrm{sys}}, \hat{\rho}_{\textrm{sys}}(t)\right] + \sum_n \hat{C}_n \hat{\rho}_{\textrm{sys}}(t) \hat{C}_n^\dagger - \frac{1}{2} \hat{C}_n^\dagger \hat{C}_n \hat{\rho}_{\textrm{sys}}(t) - \frac{1}{2} \hat{\rho}_{\textrm{sys}}(t) \hat{C}_n^\dagger \hat{C}_n
\end{equation}
```
-where ``\hat{C}_n \equiv \sqrt{\gamma_n}\hat{A}_n`` are the collapse operators, ``\hat{A}_n`` are the operators acting on the system in ``\hat{H}_{\textrm{int}}`` which describes the system-environment interaction, and ``\gamma_n`` are the corresponding rates. The derivation of Eq. \eqref{Lindblad-master-Eq} may be found in several sources, and will not be reproduced here. Instead, we emphasize the approximations that are required to arrive at the master equation in the form of Eq. \eqref{Lindblad-master-Eq} from physical arguments, and hence perform a calculation in `QuantumToolbox`:
+where ``\hat{C}_n \equiv \sqrt{\gamma_n}\hat{A}_n`` are the collapse operators, ``\hat{A}_n`` are the operators acting on the system in ``\hat{H}_{\textrm{int}}`` which describes the system-environment interaction, and ``\gamma_n`` are the corresponding rates. The derivation of Lindblad master equation may be found in several sources, and will not be reproduced here. Instead, we emphasize the approximations that are required to arrive at the above Lindblad master equation from physical arguments, and hence perform a calculation in `QuantumToolbox`:
- **Separability:** At ``t = 0``, there are no correlations between the system and environment, such that the total density matrix can be written as a tensor product, namely ``\hat{\rho}_{\textrm{tot}}(0)=\hat{\rho}_{\textrm{sys}}(0)\otimes\hat{\rho}_{\textrm{env}}(0)``.
- **Born approximation:** Requires: (i) the state of the environment does not significantly change as a result of the interaction with the system; (ii) the system and the environment remain separable throughout the evolution. These assumptions are justified if the interaction is weak, and if the environment is much larger than the system. In summary, ``\hat{\rho}_{\textrm{tot}}(t)\approx\hat{\rho}_{\textrm{sys}}(t)\otimes\hat{\rho}_{\textrm{env}}(0)``.
- **Markov approximation:** The time-scale of decay for the environment ``\tau_{\textrm{env}}`` is much shorter than the smallest time-scale of the system dynamics, i.e., ``\tau_{\textrm{sys}}\gg\tau_{\textrm{env}}``. This approximation is often deemed a “short-memory environment” as it requires the environmental correlation functions decay in a fast time-scale compared to those of the system.
-- **Secular approximation:** Stipulates that elements in the master equation corresponding to transition frequencies satisfy ``|\omega_{ab}-\omega_{cd}| \ll 1/\tau_{\textrm{sys}}``, i.e., all fast rotating terms in the interaction picture can be neglected. It also ignores terms that lead to a small renormalization of the system energy levels. This approximation is not strictly necessary for all master-equation formalisms (e.g., the Block-Redfield master equation), but it is required for arriving at the Lindblad form in Eq. \eqref{Lindblad-master-Eq} which is used in [`mesolve`](@ref).
+- **Secular approximation:** Stipulates that elements in the master equation corresponding to transition frequencies satisfy ``|\omega_{ab}-\omega_{cd}| \ll 1/\tau_{\textrm{sys}}``, i.e., all fast rotating terms in the interaction picture can be neglected. It also ignores terms that lead to a small renormalization of the system energy levels. This approximation is not strictly necessary for all master-equation formalisms (e.g., the Block-Redfield master equation), but it is required for arriving at the Lindblad form in the above equation which is used in [`mesolve`](@ref).
-For systems with environments satisfying the conditions outlined above, the Lindblad master equation in Eq. \eqref{Lindblad-master-Eq} governs the time-evolution of the system density matrix, giving an ensemble average of the system dynamics. In order to ensure that these approximations are not violated, it is important that the decay rates ``\gamma_n`` be smaller than the minimum energy splitting in the system Hamiltonian. Situations that demand special attention therefore include, for example, systems strongly coupled to their environment, and systems with degenerate or nearly degenerate energy levels.
+For systems with environments satisfying the conditions outlined above, the Lindblad master equation governs the time-evolution of the system density matrix, giving an ensemble average of the system dynamics. In order to ensure that these approximations are not violated, it is important that the decay rates ``\gamma_n`` be smaller than the minimum energy splitting in the system Hamiltonian. Situations that demand special attention therefore include, for example, systems strongly coupled to their environment, and systems with degenerate or nearly degenerate energy levels.
What is new in the master equation compared to the Schrödinger equation (or von Neumann equation) are processes that describe dissipation in the quantum system due to its interaction with an environment. For example, evolution that includes incoherent processes such as relaxation and dephasing. These environmental interactions are defined by the operators ``\hat{A}_n`` through which the system couples to the environment, and rates ``\gamma_n`` that describe the strength of the processes.
-In `QuantumToolbox`, the function [`mesolve`](@ref) can also be used for solving the master equation. This is done by passing a list of collapse operators (`c_ops`) as the fourth argument of the [`mesolve`](@ref) function in order to define the dissipation processes of the master equation in Eq. \eqref{Lindblad-master-Eq}. As we mentioned above, each collapse operator ``\hat{C}_n`` is the product of ``\sqrt{\gamma_n}`` (the square root of the rate) and ``\hat{A}_n`` (operator which describes the dissipation process).
+In `QuantumToolbox`, the function [`mesolve`](@ref) can also be used for solving the master equation. This is done by passing a list of collapse operators (`c_ops`) as the fourth argument of the [`mesolve`](@ref) function in order to define the dissipation processes of the Lindblad master equation. As we mentioned above, each collapse operator ``\hat{C}_n`` is the product of ``\sqrt{\gamma_n}`` (the square root of the rate) and ``\hat{A}_n`` (operator which describes the dissipation process).
Furthermore, `QuantumToolbox` solves the master equation in the [`SuperOperator`](@ref) formalism. That is, a Liouvillian [`SuperOperator`](@ref) will be generated internally in [`mesolve`](@ref) by the input system Hamiltonian ``\hat{H}_{\textrm{sys}}`` and the collapse operators ``\hat{C}_n``. One can also generate the Liouvillian [`SuperOperator`](@ref) manually for special purposes, and pass it as the first argument of the [`mesolve`](@ref) function. To do so, it is useful to read the section [Superoperators and Vectorized Operators](@ref doc:Superoperators-and-Vectorized-Operators), and also the docstrings of the following functions:
- [`spre`](@ref)
@@ -108,7 +105,7 @@ Furthermore, `QuantumToolbox` solves the master equation in the [`SuperOperator`
- [`liouvillian`](@ref)
- [`lindblad_dissipator`](@ref)
-## Example: Spin dynamics
+## [Example: Dissipative Spin dynamics](@id doc-TE:Example:Dissipative-Spin-dynamics)
Using the example with the dynamics of spin-``\frac{1}{2}`` from the previous section ([Schrödinger Equation Solver](@ref doc-TE:Schrödinger-Equation-Solver)), we can easily add a relaxation process (describing the dissipation of energy from the spin to the environment), by adding `[sqrt(γ) * sigmax()]` in the fourth parameter of the [`mesolve`](@ref) function.
@@ -143,7 +140,7 @@ axislegend(ax, position = :rt)
fig
```
-## Example: Harmonic oscillator in thermal bath
+## [Example: Harmonic oscillator in thermal bath](@id doc-TE:Example:Harmonic-oscillator-in-thermal-bath)
Consider a harmonic oscillator (single-mode cavity) couples to a thermal bath. If the single-mode cavity initially is in a `10`-photon [`fock`](@ref) state, the dynamics is calculated with the following code:
@@ -181,7 +178,7 @@ lines!(ax, tlist, Num)
fig
```
-## Example: Two-level atom coupled to dissipative single-mode cavity
+## [Example: Two-level atom coupled to dissipative single-mode cavity](@id doc-TE:Example:Two-level-atom-coupled-to-dissipative-single-mode-cavity)
Consider a two-level atom coupled to a dissipative single-mode cavity through a dipole-type interaction, which supports a coherent exchange of quanta between the two systems. If the atom initially is in its ground state and the cavity in a `5`-photon [`fock`](@ref) state, the dynamics is calculated with the following code:
diff --git a/docs/src/users_guide/time_evolution/sesolve.md b/docs/src/users_guide/time_evolution/sesolve.md
index fce63f7ac..f41df647d 100644
--- a/docs/src/users_guide/time_evolution/sesolve.md
+++ b/docs/src/users_guide/time_evolution/sesolve.md
@@ -1,6 +1,6 @@
# [Schrödinger Equation Solver](@id doc-TE:Schrödinger-Equation-Solver)
-## Unitary evolution
+## [Unitary evolution](@id doc-TE:Unitary-evolution)
The dynamics of a closed (pure) quantum system is governed by the Schrödinger equation
@@ -19,7 +19,7 @@ where ``|\psi(t)\rangle`` is the state vector, and the Hamiltonian ``\hat{H}`` i
The Schrödinger equation, which governs the time-evolution of closed quantum systems, is defined by its Hamiltonian and state vector. In the previous sections, [Manipulating States and Operators](@ref doc:Manipulating-States-and-Operators) and [Tensor Products and Partial Traces](@ref doc:Tensor-products-and-Partial-Traces), we showed how Hamiltonians and state vectors are constructed in `QuantumToolbox.jl`. Given a Hamiltonian, we can calculate the unitary (non-dissipative) time-evolution of an arbitrary initial state vector ``|\psi(0)\rangle`` using the `QuantumToolbox` time evolution problem [`sesolveProblem`](@ref) or directly call the function [`sesolve`](@ref). It evolves the state vector ``|\psi(t)\rangle`` and evaluates the expectation values for a set of operators `e_ops` at each given time points, using an ordinary differential equation solver provided by the powerful julia package [`DifferentialEquation.jl`](https://docs.sciml.ai/DiffEqDocs/stable/).
-## Example: Spin dynamics
+## [Example: Spin dynamics](@id doc-TE:Example:Spin-dynamics)
```@setup sesolve
using QuantumToolbox
diff --git a/docs/src/users_guide/time_evolution/solution.md b/docs/src/users_guide/time_evolution/solution.md
index 4ed7d1c37..455c94991 100644
--- a/docs/src/users_guide/time_evolution/solution.md
+++ b/docs/src/users_guide/time_evolution/solution.md
@@ -4,7 +4,7 @@
using QuantumToolbox
```
-## Solution
+## [Solution](@id doc-TE:Solution)
`QuantumToolbox` utilizes the powerful [`DifferentialEquation.jl`](https://docs.sciml.ai/DiffEqDocs/stable/) to simulate different kinds of quantum system dynamics. Thus, we will first look at the data structure used for returning the solution (`sol`) from [`DifferentialEquation.jl`](https://docs.sciml.ai/DiffEqDocs/stable/). The solution stores all the crucial data needed for analyzing and plotting the results of a simulation. A generic structure [`TimeEvolutionSol`](@ref) contains the following properties for storing simulation data:
| **Fields (Attributes)** | **Description** |
@@ -17,7 +17,7 @@ using QuantumToolbox
| `sol.reltol` | The relative tolerance which is used during the solving process. |
| `sol.retcode` (or `sol.converged`) | The returned status from the solver. |
-## Accessing data in solutions
+## [Accessing data in solutions](@id doc-TE:Accessing-data-in-solutions)
To understand how to access the data in solution, we will use an example as a guide, although we do not worry about the simulation details at this stage. The Schrödinger equation solver ([`sesolve`](@ref)) used in this example returns [`TimeEvolutionSol`](@ref):
@@ -86,6 +86,6 @@ Here, the solution contains only one (final) state. Because the `states` will be
Some other solvers can have other output.
-## Multiple trajectories solution
+## [Multiple trajectories solution](@id doc-TE:Multiple-trajectories-solution)
This part is still under construction, please visit [API](@ref doc-API) first.
\ No newline at end of file