qutip · diff
git:20260611.1b8fae3 to v1.1
237 added, 235 removed. Audit A to A.
---
name: qutip
- description: Quantum physics simulation library for open quantum systems. Use when studying master equations, Lindblad dynamics, decoherence, quantum optics, or cavity QED. Best for physics research, open system dynamics, and educational simulations. NOT for circuit-based quantum computing—use qiskit, cirq, or pennylane for quantum algorithms and hardware execution.
- license: BSD-3-Clause license
- metadata: {"version": "1.0", "skill-author": "K-Dense Inc."}
+ description: Simulate and audit closed and open quantum-system models with QuTiP 5, including deterministic, trajectory, steady-state, spectral, and phase-space workflows. Use for local quantum-dynamics work where physical assumptions, dimensions, and numerical convergence must be explicit.
+ license: MIT
+ compatibility: Requires Python 3.11+, uv, and qutip==5.3.0 for executable simulations. Bundled planners and all script help run with the Python standard library; plotting requires the pinned graphics extra. No network service or credentials are used.
+ metadata:
+ version: "1.1"
+ skill-author: K-Dense Inc.
+ last-reviewed: "2026-07-23"
---
- # QuTiP: Quantum Toolbox in Python
+ # QuTiP 5
- ## Overview
+ ## Scope
- QuTiP provides comprehensive tools for simulating and analyzing quantum mechanical systems. It handles both closed (unitary) and open (dissipative) quantum systems with multiple solvers optimized for different scenarios.
+ Use QuTiP for finite-dimensional quantum mechanics, quantum optics, Lindblad
+ dynamics, trajectories, weak-coupling Bloch-Redfield models, and specialized
+ Floquet, HEOM, and permutational-invariance methods. It is not a hardware
+ execution SDK. Circuit and control functionality moved to separate QuTiP family
+ packages.
- ## Installation
+ This skill targets **QuTiP 5.3.0**, released 2026-05-22. QuTiP 5.3 requires
+ Python 3.11 or newer. Its required distributions are NumPy (`>=1.23.2`), SciPy
+ (`>=1.9.2`, excluding `1.16.0` and `1.17.0`), and `packaging`.
+ ## Reproducible uv snapshot
+
+ Create a dedicated environment and pin every direct distribution:
+
```bash
- uv pip install qutip
+ uv venv --python 3.11
+ uv pip install "qutip==5.3.0"
```
- Optional packages for additional functionality:
+ For plots:
```bash
- # Quantum information processing (circuits, gates)
- uv pip install qutip-qip
-
- # Quantum trajectory viewer
- uv pip install qutip-qtrl
+ uv pip install "qutip[graphics]==5.3.0"
```
- ## Quick Start
+ Optional QuTiP family packages are independently versioned:
- ```python
- from qutip import *
- import numpy as np
- import matplotlib.pyplot as plt
+ ```bash
+ uv pip install "qutip-qip==0.4.2"
+ uv pip install "qutip-qtrl==0.2.0"
+ uv pip install "qutip-jax==0.1.1"
+ ```
- # Create quantum state
- psi = basis(2, 0) # |0⟩ state
+ - `qutip-qip` 0.4.2 (2026-06-23) is the production/stable circuit, gate, and
+ noisy-device simulation package. Import from `qutip_qip`, not `qutip.qip`.
+ - `qutip-qtrl` 0.2.0 (2026-06-23) provides GRAPE and CRAB **quantum optimal
+ control**. It is not a trajectory viewer. Import from `qutip_qtrl`, not
+ `qutip.control`; PyPI still classifies it pre-alpha.
+ - `qutip-jax` 0.1.1 (2025-05-29) is the official JAX data backend for GPU and
+ automatic-differentiation experiments. It is explicitly pre-alpha.
+ - `qutip-cupy` is an official QuTiP-organization repository, but it has no PyPI
+ release and its own README says it is not officially released. Do not put an
+ unreleased Git install into a reproducible workflow.
- # Create operator
- H = sigmaz() # Hamiltonian
+ Use a project lockfile or a hash-generating `uv pip compile` workflow when
+ transitive dependency identity must also be frozen.
- # Time evolution
- tlist = np.linspace(0, 10, 100)
- result = sesolve(H, psi, tlist, e_ops=[sigmaz()])
+ ## Non-negotiable model contract
- # Plot results
- plt.plot(tlist, result.expect[0])
- plt.xlabel('Time')
- plt.ylabel('⟨σz⟩')
- plt.show()
- ```
+ Before solving, record:
- ## Core Capabilities
+ 1. **Units and convention.** QuTiP equations normally set \(\hbar=1\).
+ Hamiltonian entries are angular frequencies and rates have reciprocal-time
+ units. Convert cyclic frequency with \(2\pi f\); never mix Hz and rad/s.
+ 2. **Subsystem order.** `tensor(A, B, C)` fixes subsystem indices `0, 1, 2`.
+ Preserve that order in every state, operator, collapse channel, and partial
+ trace. `obj.ptrace([0, 2])` keeps those subsystems; it does not trace them.
+ 3. **State validity.** Check ket norm or density-matrix Hermiticity, unit trace,
+ and eigenvalues above a stated negative tolerance. Tiny negative values may
+ be numerical; material negativity invalidates a claimed state.
+ 4. **Generator meaning.** A Lindblad channel with rate `gamma` is represented
+ by `sqrt(gamma) * A`, not `gamma * A`. Define what each rate measures. For
+ example, `sqrt(gamma_phi / 2) * sigmaz()` gives coherence decay
+ `exp(-gamma_phi * t)`.
+ 5. **Approximations.** State rotating-wave, Born-Markov, secular, weak-coupling,
+ bath-equilibrium, truncation, symmetry, and initial-factorization assumptions
+ wherever used.
+ 6. **Numerics.** Justify Hilbert truncation, output grid, integration method,
+ tolerances, trajectory count, and random seeds. Report `result.stats`.
+ 7. **Convergence.** Sweep every artificial cutoff: Fock dimension, time/frequency
+ window and spacing, ODE tolerances, trajectories, Floquet harmonics, HEOM
+ depth and bath exponents, or PIQS representation as applicable.
- ### 1. Quantum Objects and States
+ ## Qobj, dimensions, and tensor order
- Create and manipulate quantum states and operators:
+ Prefer explicit imports and inspect both shape and structured dimensions:
```python
- # States
- psi = basis(N, n) # Fock state |n⟩
- psi = coherent(N, alpha) # Coherent state |α⟩
- rho = thermal_dm(N, n_avg) # Thermal density matrix
+ from qutip import basis, qeye, sigmaz, tensor
- # Operators
- a = destroy(N) # Annihilation operator
- H = num(N) # Number operator
- sx, sy, sz = sigmax(), sigmay(), sigmaz() # Pauli matrices
+ psi = tensor(basis(2, 0), basis(3, 1))
+ z_on_first = tensor(sigmaz(), qeye(3))
- # Composite systems
- psi_AB = tensor(psi_A, psi_B) # Tensor product
+ assert psi.shape == (6, 1)
+ assert psi.dims == [[2, 3], [1]]
+ assert z_on_first.dims == [[2, 3], [2, 3]]
+ rho_first = psi.proj().ptrace(0) # keep subsystem 0
```
- **See** `references/core_concepts.md` for comprehensive coverage of quantum objects, states, operators, and tensor products.
-
- ### 2. Time Evolution and Dynamics
-
- Multiple solvers for different scenarios:
-
- ```python
- # Closed systems (unitary evolution)
- result = sesolve(H, psi0, tlist, e_ops=[num(N)])
-
- # Open systems (dissipation)
- c_ops = [np.sqrt(0.1) * destroy(N)] # Collapse operators
- result = mesolve(H, psi0, tlist, c_ops, e_ops=[num(N)])
+ Matrix shape alone is insufficient: two objects can both be 6-by-6 but encode
+ different tensor factorizations. Read `references/core_concepts.md` before
+ building composite, superoperator, or channel models.
- # Quantum trajectories (Monte Carlo)
- result = mcsolve(H, psi0, tlist, c_ops, ntraj=500, e_ops=[num(N)])
- ```
+ ## Choose the solver by physics
- **Solver selection guide:**
- - `sesolve`: Pure states, unitary evolution
- - `mesolve`: Mixed states, dissipation, general open systems
- - `mcsolve`: Quantum jumps, photon counting, individual trajectories
- - `brmesolve`: Weak system-bath coupling
- - `fmmesolve`: Time-periodic Hamiltonians (Floquet)
+ | Model | Current API | Required justification |
+ |---|---|---|
+ | Closed, pure, unitary | `sesolve` | Hermitian Hamiltonian; no dissipation |
+ | Lindblad/open or mixed | `mesolve` | Markovian completely positive model and channel rates |
+ | Quantum jumps | `mcsolve` | Unravelling, trajectory convergence, seeds |
+ | Microscopic weak bath | `brmesolve` | Born-Markov/weak coupling, spectra, secular choice |
+ | Diffusive measurement | `ssesolve`, `smesolve` | monitored versus unmonitored channels |
+ | Periodic drive | `FloquetBasis`, `fsesolve`, `fmmesolve` | verified period and Floquet convergence |
+ | Structured non-Markovian bath | `qutip.solver.heom` | bath expansion and hierarchy convergence |
+ | Symmetric spin ensemble | `qutip.piqs` | permutation symmetry and basis choice |
- **See** `references/time_evolution.md` for detailed solver documentation, time-dependent Hamiltonians, and advanced options.
+ Do not select a more specialized solver merely because it exists.
- ### 3. Analysis and Measurement
+ ## Deterministic open-system example
- Compute physical quantities:
+ QuTiP 5.3 uses ordinary option dictionaries. Solver controls, `e_ops`, and
+ `args` are keyword-only; the old mutable options object is gone.
```python
- # Expectation values
- n_avg = expect(num(N), psi)
-
- # Entropy measures
- S = entropy_vn(rho) # Von Neumann entropy
- C = concurrence(rho) # Entanglement (two qubits)
+ import numpy as np
+ from qutip import basis, mesolve, sigmam, sigmaz
- # Fidelity and distance
- F = fidelity(psi1, psi2)
- D = tracedist(rho1, rho2)
+ omega = 2.0
+ gamma = 0.15
+ tlist = np.linspace(0.0, 20.0, 401)
+ excited = basis(2, 0)
- # Correlation functions
- corr = correlation_2op_1t(H, rho0, taulist, c_ops, A, B)
- w, S = spectrum_correlation_fft(taulist, corr)
+ result = mesolve(
+ 0.5 * omega * sigmaz(),
+ excited,
+ tlist,
+ c_ops=[np.sqrt(gamma) * sigmam()],
+ e_ops={"sigma_z": sigmaz(), "excited": excited.proj()},
+ options={
+ "method": "adams",
+ "atol": 1e-10,
+ "rtol": 1e-8,
+ "store_final_state": True,
+ "progress_bar": "",
+ },
+ )
- # Steady states
- rho_ss = steadystate(H, c_ops)
+ population = np.asarray(result.e_data["excited"])
+ assert np.max(np.abs(population - np.exp(-gamma * tlist))) < 2e-6
+ assert isinstance(result.stats, dict)
```
- **See** `references/analysis.md` for entropy, fidelity, measurements, correlation functions, and steady state calculations.
+ If the problem is stiff, compare `bdf` or `lsoda`; do not change an integrator
+ without rerunning tolerance and invariant checks. QuTiP 5.3 also supports
+ `options={"matrix_form": True}` in `mesolve`; benchmark and validate it before
+ using it as a default.
- ### 4. Visualization
+ ## Time-dependent systems
- Visualize quantum states and dynamics:
+ Prefer trusted Pythonic callables or numeric coefficient arrays. Do not create
+ coefficient source strings from user input.
```python
- # Bloch sphere
- b = Bloch()
- b.add_states(psi)
- b.show()
-
- # Wigner function (phase space)
- xvec = np.linspace(-5, 5, 200)
- W = wigner(psi, xvec, xvec)
- plt.contourf(xvec, xvec, W, 100, cmap='RdBu')
+ import numpy as np
+ from qutip import QobjEvo, sigmax, sigmaz
- # Fock distribution
- plot_fock_distribution(psi)
+ def envelope(t, amplitude, center, width):
+ return amplitude * np.exp(-0.5 * ((t - center) / width) ** 2)
- # Matrix visualization
- hinton(rho) # Hinton diagram
- matrix_histogram(H.full()) # 3D bars
+ H = QobjEvo(
+ [0.5 * sigmaz(), [sigmax(), envelope]],
+ args={"amplitude": 0.2, "center": 5.0, "width": 1.0},
+ )
+ instantaneous_H = H(5.0)
+ H.arguments(amplitude=0.1)
```
- **See** `references/visualization.md` for Bloch sphere animations, Wigner functions, Q-functions, and matrix visualizations.
-
- ### 5. Advanced Methods
+ The older `f(t, args)` coefficient signature is deprecated in 5.3 and is
+ scheduled for removal in 5.5. See `references/time_evolution.md`.
- Specialized techniques for complex scenarios:
+ ## Trajectories and stochastic solvers
```python
- # Floquet theory (periodic Hamiltonians)
- T = 2 * np.pi / w_drive
- f_modes, f_energies = floquet_modes(H, T, args)
- result = fmmesolve(H, psi0, tlist, c_ops, T=T, args=args)
-
- # HEOM (non-Markovian, strong coupling)
- from qutip.nonmarkov.heom import HEOMSolver, BosonicBath
- bath = BosonicBath(Q, ck_real, vk_real)
- hsolver = HEOMSolver(H_sys, [bath], max_depth=5)
- result = hsolver.run(rho0, tlist)
+ import numpy as np
+ from qutip import basis, mcsolve, sigmam, sigmaz
- # Permutational invariance (identical particles)
- psi = dicke(N, j, m) # Dicke states
- Jz = jspin(N, 'z') # Collective operators
+ tlist = np.linspace(0.0, 10.0, 201)
+ result = mcsolve(
+ 0.5 * sigmaz(),
+ basis(2, 0),
+ tlist,
+ [np.sqrt(0.2) * sigmam()],
+ e_ops=[basis(2, 0).proj()],
+ ntraj=400,
+ seeds=20260723,
+ options={"keep_runs_results": False, "progress_bar": ""},
+ )
```
- **See** `references/advanced.md` for Floquet theory, HEOM, permutational invariance, stochastic solvers, superoperators, and performance optimization.
-
- ## Common Workflows
+ Report `ntraj`, `result.seeds`, uncertainty or repeated-seed sensitivity, and
+ whether individual runs were retained. Reuse `seeds=previous_result.seeds` only
+ when paired trajectories are intentional. `ssesolve` and `smesolve` use the
+ boolean `heterodyne` argument, not legacy integer noise codes.
- ### Simulating a Damped Harmonic Oscillator
+ ## Steady states, spectra, and phase space
```python
- # System parameters
- N = 20 # Hilbert space dimension
- omega = 1.0 # Oscillator frequency
- kappa = 0.1 # Decay rate
-
- # Hamiltonian and collapse operators
- H = omega * num(N)
- c_ops = [np.sqrt(kappa) * destroy(N)]
-
- # Initial state
- psi0 = coherent(N, 3.0)
+ import numpy as np
+ from qutip import QFunc, liouvillian, operator_to_vector, qfunc, steadystate
- # Time evolution
- tlist = np.linspace(0, 50, 200)
- result = mesolve(H, psi0, tlist, c_ops, e_ops=[num(N)])
+ rho_ss = steadystate(H, c_ops, method="direct")
+ residual = (liouvillian(H, c_ops) * operator_to_vector(rho_ss)).norm()
+ assert residual < 1e-9
- # Visualize
- plt.plot(tlist, result.expect[0])
- plt.xlabel('Time')
- plt.ylabel('⟨n⟩')
- plt.title('Photon Number Decay')
- plt.show()
+ xvec = np.linspace(-5.0, 5.0, 151)
+ Q_once = qfunc(rho_ss, xvec, xvec)
+ q_many = QFunc(xvec, xvec)
+ Q_again = q_many(rho_ss)
+ assert Q_once.shape == (len(xvec), len(xvec))
```
- ### Two-Qubit Entanglement Dynamics
-
- ```python
- # Create Bell state
- psi0 = bell_state('00')
-
- # Local dephasing on each qubit
- gamma = 0.1
- c_ops = [
- np.sqrt(gamma) * tensor(sigmaz(), qeye(2)),
- np.sqrt(gamma) * tensor(qeye(2), sigmaz())
- ]
-
- # Track entanglement
- def compute_concurrence(t, psi):
- rho = ket2dm(psi) if psi.isket else psi
- return concurrence(rho)
-
- tlist = np.linspace(0, 10, 100)
- result = mesolve(qeye([2, 2]), psi0, tlist, c_ops)
-
- # Compute concurrence for each state
- C_t = [concurrence(state.proj()) for state in result.states]
-
- plt.plot(tlist, C_t)
- plt.xlabel('Time')
- plt.ylabel('Concurrence')
- plt.title('Entanglement Decay')
- plt.show()
- ```
+ For `wigner`, `qfunc`, and `QFunc`, array element `[j, k]` corresponds to
+ `yvec[j]`, `xvec[k]`. In QuTiP 5.3, `QFunc` is initialized with fixed
+ coordinates and called with a state; it has no `.eval` method. This skill never
+ uses Python dynamic-code execution. Prefer `plot_wigner`, `Result.plot_expect`,
+ or explicit Matplotlib axes as documented in `references/visualization.md`.
- ### Jaynes-Cummings Model
+ Direct `spectrum` is a stationary steady-state spectrum. An FFT of a finite
+ correlation requires explicit checks for tail decay, timestep aliasing,
+ frequency resolution, window sensitivity, and transform convention. See
+ `references/analysis.md`.
- ```python
- # System parameters
- N = 10 # Cavity Fock space
- wc = 1.0 # Cavity frequency
- wa = 1.0 # Atom frequency
- g = 0.05 # Coupling strength
+ ## Advanced boundaries
- # Operators
- a = tensor(destroy(N), qeye(2)) # Cavity
- sm = tensor(qeye(N), sigmam()) # Atom
+ - Import HEOM from `qutip.solver.heom`; the legacy QuTiP 4 nonmarkov HEOM
+ namespace is stale.
+ - Use `FloquetBasis` for modes and quasi-energies. Verify
+ `H(t + T) == H(t)` numerically and sweep basis/truncation choices.
+ - Access PIQS with `from qutip import piqs`. `Dicke.pisolve` is only the
+ optimized diagonal-state/diagonal-Hamiltonian route; general Dicke-basis
+ dynamics use the Liouvillian with `mesolve`.
+ - `brmesolve` can violate positivity, especially without secularization. Check
+ density-matrix eigenvalues over time.
+ - QIP and optimal control are extension-package concerns. Never present local
+ simulation as quantum-hardware execution.
- # Hamiltonian (RWA)
- H = wc * a.dag() * a + wa * sm.dag() * sm + g * (a.dag() * sm + a * sm.dag())
+ See `references/advanced.md` for HEOM, Floquet, PIQS, stochastic, and extension
+ boundaries.
- # Initial state: cavity in coherent state, atom in ground state
- psi0 = tensor(coherent(N, 2), basis(2, 0))
+ ## Safe local CLIs
- # Dissipation
- kappa = 0.1 # Cavity decay
- gamma = 0.05 # Atomic decay
- c_ops = [np.sqrt(kappa) * a, np.sqrt(gamma) * sm]
+ All bundled tools are local-only, emit strict JSON, reject non-finite JSON and
+ unknown keys, and never load pickle files or executable model code. Simulation
+ imports are lazy, so every `--help` works without QuTiP installed.
- # Observables
- n_cav = a.dag() * a
- n_atom = sm.dag() * sm
+ | Script | Purpose |
+ |---|---|
+ | `scripts/qobj_model_validator.py` | Validate bounded Qobj model JSON, dimensions, states, rates, and role compatibility |
+ | `scripts/two_level_simulation.py` | Run a bounded two-level Lindblad or jump simulation |
+ | `scripts/solver_config_planner.py` | Select a current solver and option/checklist plan |
+ | `scripts/convergence_sweep.py` | Sweep tolerances/grid size or trajectory count on a synthetic model |
+ | `scripts/result_audit.py` | Audit JSON output without deserializing Python objects |
+ | `scripts/steady_state_spectrum_planner.py` | Plan bounded steady-state and direct/FFT spectral checks |
- # Evolve
- tlist = np.linspace(0, 50, 200)
- result = mesolve(H, psi0, tlist, c_ops, e_ops=[n_cav, n_atom])
+ Example:
- # Plot
- fig, axes = plt.subplots(2, 1, figsize=(8, 6), sharex=True)
- axes[0].plot(tlist, result.expect[0])
- axes[0].set_ylabel('⟨n_cavity⟩')
- axes[1].plot(tlist, result.expect[1])
- axes[1].set_ylabel('⟨n_atom⟩')
- axes[1].set_xlabel('Time')
- plt.tight_layout()
- plt.show()
+ ```bash
+ python skills/qutip/scripts/two_level_simulation.py --help
+ python skills/qutip/scripts/two_level_simulation.py \
+ --decay-rate 0.2 --t-final 10 --time-points 201 \
+ --output two-level.json
+ python skills/qutip/scripts/result_audit.py two-level.json
```
- ## Tips for Efficient Simulations
-
- 1. **Truncate Hilbert spaces**: Use smallest dimension that captures dynamics
- 2. **Choose appropriate solver**: `sesolve` for pure states is faster than `mesolve`
- 3. **Time-dependent terms**: String format (e.g., `'cos(w*t)'`) is fastest
- 4. **Store only needed data**: Use `e_ops` instead of storing all states
- 5. **Adjust tolerances**: Balance accuracy with computation time via `Options`
- 6. **Parallel trajectories**: `mcsolve` automatically uses multiple CPUs
- 7. **Check convergence**: Vary `ntraj`, Hilbert space size, and tolerances
-
- ## Troubleshooting
-
- **Memory issues**: Reduce Hilbert space dimension, use `store_final_state` option, or consider Krylov methods
-
- **Slow simulations**: Use string-based time-dependence, increase tolerances slightly, or try `method='bdf'` for stiff problems
-
- **Numerical instabilities**: Decrease time steps (`nsteps` option), increase tolerances, or check Hamiltonian/operators are properly defined
+ ## Completion checklist
- **Import errors**: Ensure QuTiP is installed correctly; quantum gates require `qutip-qip` package
+ - Record units, \(\hbar\), tensor order, initial state, channels, and model
+ assumptions.
+ - Validate Hermiticity, norm/trace, positivity, dimensions, and generator units.
+ - Pin QuTiP and direct extensions; record platform, Python, NumPy, and SciPy.
+ - Inspect result options and stats; do not assume states were stored.
+ - Perform cutoff, grid, tolerance/integrator, and stochastic convergence sweeps.
+ - Save portable numeric/configuration summaries as JSON or text. Do not load
+ untrusted QuTiP object/result files because object serialization can execute
+ code.
## References
- This skill includes detailed reference documentation:
-
- - **`references/core_concepts.md`**: Quantum objects, states, operators, tensor products, composite systems
- - **`references/time_evolution.md`**: All solvers (sesolve, mesolve, mcsolve, brmesolve, etc.), time-dependent Hamiltonians, solver options
- - **`references/visualization.md`**: Bloch sphere, Wigner functions, Q-functions, Fock distributions, matrix plots
- - **`references/analysis.md`**: Expectation values, entropy, fidelity, entanglement measures, correlation functions, steady states
- - **`references/advanced.md`**: Floquet theory, HEOM, permutational invariance, stochastic methods, superoperators, performance tips
+ - `references/core_concepts.md` — Qobj, dimensions, tensor products, states,
+ channels, and unit conventions
+ - `references/time_evolution.md` — current solver signatures, options, results,
+ QobjEvo, trajectories, and numerical controls
+ - `references/analysis.md` — physical-state audits, steady states,
+ correlations, spectra, and convergence
+ - `references/visualization.md` — Wigner, Q functions, `QFunc`, Bloch, result,
+ and matrix plots
+ - `references/advanced.md` — Bloch-Redfield, stochastic, Floquet, HEOM, PIQS,
+ and QuTiP family package boundaries
- ## External Resources
+ ## Dated official sources
- - Documentation: https://qutip.readthedocs.io/
- - Tutorials: https://qutip.org/qutip-tutorials/
- - API Reference: https://qutip.readthedocs.io/en/stable/apidoc/apidoc.html
- - GitHub: https://github.com/qutip/qutip
+ Verified **2026-07-23**:
+ - [QuTiP 5.3.0 PyPI metadata](https://pypi.org/project/qutip/)
+ - [QuTiP 5.3.0 release](https://github.com/qutip/qutip/releases/tag/v5.3.0)
+ - [QuTiP 5.3 changelog](https://qutip.readthedocs.io/en/stable/changelog.html)
+ - [QuTiP 5.3 API](https://qutip.readthedocs.io/en/stable/apidoc/apidoc.html)
+ - [QuTiP version-5 tutorials](https://github.com/qutip/qutip-tutorials/tree/main/tutorials-v5)
+ - [qutip-qip PyPI](https://pypi.org/project/qutip-qip/)
+ - [qutip-qtrl PyPI](https://pypi.org/project/qutip-qtrl/)
+ - [qutip-jax PyPI](https://pypi.org/project/qutip-jax/)
+ - [official unreleased qutip-cupy repository](https://github.com/qutip/qutip-cupy)