QuantumToolbox.jl

repository·main·Indexed 41 days ago

https://github.com/qutip/quantumtoolbox.jl

A high-performance Julia-native package for quantum physics simulations, designed as a faster alternative to QuTiP. It supports GPU acceleration via CUDA.jl, distributed computing, and differentiable programming. The ecosystem includes QuantumToolboxCore.jl for fundamental data structures and QuantumToolboxVisual.jl for visualizing Wigner distributions, Bloch spheres, and Fock distributions. Key features include the `mesolve` function for solving the Lindblad master equation and tools for constructing quantum states like Fock and coherent states.

Tokens
36.6K
Snippets
107
Records
137
Agent score
51%

What's inside QuantumToolbox.jl

  1. Overview of Time Evolution Solvers in QuantumToolbox.jl

    main

    QuantumToolbox.jl provides several solvers to model the dynamics of quantum systems, depending on whether the system is closed (described by a state vector) or open (requiring a density matrix).

    Solver Selection Guide

    Equation TypeFunction CallProblem TypeReturned Solution Type
    Unitary evolution (Schrödinger)sesolvesesolveProblemTimeEvolutionSol
    Lindblad or Von Neumann master eqn.mesolvemesolveProblemTimeEvolutionSol
    Monte Carlo evolutionmcsolvemcsolveProblem or mcsolveEnsembleProblemTimeEvolutionMCSol
    Stochastic Schrödinger equationssesolvessesolveProblem or ssesolveEnsembleProblemTimeEvolutionStochasticSol
    Stochastic master equationsmesolvesmesolveProblem or smesolveEnsembleProblemTimeEvolutionStochasticSol
    Bloch-Redfield master equationbrmesolve-TimeEvolutionSol

    Solving Methods

    You can solve dynamics using two patterns:

    1. Direct Function Calls: Pass operators (like the Hamiltonian and collapse operators) directly into the solver functions.
    2. Problem Objects: Generate a problem object (e.g., using sesolveProblem) and pass that single object into the solver (e.g., sesolve(prob)).
  2. Overview of QuantumToolbox.jl features

    main

    QuantumToolbox.jl is a high-performance Julia framework for quantum physics simulations, designed to emulate the Python QuTiP package. Key capabilities include:

    • Quantum State and Operator Manipulation: Tools for handling quantum states and operators.
    • Dynamical Evolution: Advanced solvers for time evolution using DifferentialEquations.jl.
    • GPU Computing: High-performance simulation on GPUs using the same syntax as CPU simulations.
    • Distributed Computing: Parallel simulation of quantum trajectories across multiple nodes or clusters.
    • Differentiable Programming: Support for gradient-based optimization via automatic differentiation.
    • Arbitrary Precision: Ability to resolve exponentially small quantities (like tunneling splittings) using precision beyond Float64.
  3. Key features of QuantumToolbox.jl

    main

    QuantumToolbox.jl is a high-performance Julia package for quantum physics simulations with the following capabilities:

    • Quantum State and Operator Manipulation: Tools for handling states and operators similar to QuTiP.
    • Dynamical Evolution: Solvers powered by DifferentialEquations.jl.
    • GPU Computing: High-performance simulation directly on the GPU.
    • Distributed Computing: Ability to distribute computations (e.g., running hundreds of trajectories) over multiple nodes/clusters.
    • Differentiable Programming: Support for automatic differentiation to compute gradients of quantum dynamics for optimization.
    • Arbitrary Precision: Support for Double64 or BigFloat to resolve exponentially small quantities like tunneling splittings.
    • Easy Extension: Leverages Julia's multiple dispatch and metaprogramming.
  4. Automatic Differentiation in QuantumToolbox.jl

    main

    QuantumToolbox.jl provides experimental support for Automatic Differentiation (AD), allowing users to compute exact gradients of observables or cost functionals involving the time evolution of open quantum systems.

    Many core functions are compatible with several Julia AD engines:

    • ForwardDiff.jl: Best for functions with few inputs and many outputs (Forward Mode).
    • Mooncake.jl: Best for functions with many inputs and few outputs (Reverse Mode), often used in optimization and machine learning.
    • Zygote.jl and Enzyme.jl are also supported.

    !!! warning "Experimental Functionality" This functionality is considered experimental. Not all parts of the library are AD-compatible.

  5. Perform mathematical operations on Qobj

    main

    Mathematical operations on QuantumObject follow standard linear algebra rules.

    Supported Operations

    • Arithmetic: Addition (+), subtraction, and scalar multiplication/division.
    • Matrix Algebra: Multiplication (*), adjoint (a' or adjoint(a)), and exponentiation (a ^ n).
    • Outer Products: Multiplying a Ket (u) by a Bra (v') results in an outer product $|u\rangle\langle v|$.
    • Inner Products: Multiplying a Bra (v') by a Ket (u) results in an inner product $\langle v|u\rangle$.

    Note: Multiplying objects with incompatible dims or size will throw an error.

    a = destroy(4)
    
    a' * a      # Inner product/Expectation value style
    a'          # Adjoint
    a + 5       # Scalar addition
    a ^ 3       # Exponentiation
    
    # Outer product
    u = Qobj([1, 2, 3])
    v = Qobj([4, 5, 6])
    u * v'     # Results in an operator
    v' * u      # Results in a scalar (inner product)
  6. Understand the TimeEvolutionSol data structure

    main

    QuantumToolbox uses DifferentialEquation.jl for simulations. The resulting solution object (returned by solvers like sesolve) is a TimeEvolutionSol structure that contains all data required for analysis and plotting.

    Key fields include:

    • sol.times: Time points for expectation value calculations.
    • sol.times_states: Time points for stored states.
    • sol.states: Result states corresponding to sol.times_states.
    • sol.expect: Expectation values corresponding to sol.times.
    • sol.alg: The algorithm used.
    • sol.abstol / sol.reltol: Absolute and relative tolerances.
    • sol.retcode (or sol.converged): Solver status.
  7. How to implement type-stable functions using `Val`

    main

    To implement a function that behaves differently based on a parameter without losing type stability, use Val to trigger multiple dispatch. You can use a helper function like getVal(::Val{N}) where N = N to extract the value from the Val wrapper inside the function body.

    This pattern is used internally by the fock function in QuantumToolbox.jl and is highly recommended for performance-critical user code.

    getVal(::Val{N}) where N = N
    
    function my_fock_good(N::Int, j::Int = 0; sparse::Val = Val(false))
        if getVal(sparse)
            # Logic for one type (e.g., dense)
            array = zeros(ComplexF64, N)
            array[j+1] = 1
        else
            # Logic for another type (e.g., sparse)
            array = sparsevec([j + 1], [1.0 + 0im], N)
        end
        return QuantumObject(array; type = Ket())
    end
    
    # Call with Val(true) or Val(false)
    my_fock_good(2, 1; sparse = Val(true))
  8. Visualize qubit dynamics using multiple points

    main

    When plotting multiple points to visualize dynamics (e.g., a trajectory), Bloch treats them as a single data point plotted at different times by default, meaning they share the same color.

    To vary the color of each point in a trajectory, use the keyword argument meth=:m in add_points!. This tells the sphere to cycle through the colors defined in b.point_color.

    # Plotting a trajectory with varying colors
    add_points!(b, pnts, meth=:m)
    
    # Plotting a trajectory with a single color
    add_points!(b, pnts)
  9. Work with two-level systems (Qubits)

    main

    Qubits are represented using the basis(2, n) function. In QuantumToolbox, the spin operators follow the standard $Z$-basis representation:

    • sigmax(), sigmay(), sigmaz(): Pauli matrices.
    • sigmap(): Raising operator $\hat{\sigma}_+$.
    • sigmam(): Lowering operator $\hat{\sigma}_-$.

    Convention Note: The sigmaz() operator maps the state basis(2, 0) to $+1$ (the $|\uparrow\rangle$ or excited state) and basis(2, 1) to $-1$ (the $|\downarrow\rangle$ or ground state). This aligns with quantum information conventions where $|0\rangle$ is the excited state and $|1\rangle$ is the ground state. Consequently, applying sigmap() to basis(2, 0) results in a zero vector because it attempts to raise the state out of the two-level Hilbert space.

    using QuantumToolbox
    
    # Create qubit states
    spin_up = basis(2, 0)   # Corresponds to |\uparrow\rangle
    spin_dn = basis(2, 1)   # Corresponds to |\downarrow\rangle
    
    # Pauli Z operations
    expect(sigmaz(), spin_up)   # Returns 1.0
    expect(sigmaz(), spin_dn)   # Returns -1.0
    
    # Raising/Lowering
    sigmap() * spin_dn         # Returns |\uparrow\rangle
    sigmap() * spin_up         # Returns zero vector
    
    # For higher spin systems, use jmat()
  10. Work with Quantum objects (Qobj)

    main

    The core data structure in QuantumToolbox is the QuantumObject (or Qobj). It represents various quantum entities:

    • Ket and Bra: State vectors.
    • Operator: Linear operators acting on states.
    • SuperOperator: Operators acting on density matrices (Liouville space).
    • QuantumObjectEvolution: Objects representing time-evolving quantum states.

    You can check the type of a Qobj using boolean functions like isbra, isket, isoper, or issuper.