Skip to main content
Docs

Search guides and API endpoints, for example “Idempotency-Key” or “submit job”.

    Tools · Quantum Chemistry

    Qiskit SQD

    Estimate the ground-state energy of a molecular active space by sample-based quantum diagonalization on the Qiskit Aer simulator, with the exact CASCI energy alongside.

    Updated October 8, 2026

    On this page

    Prices, workflows, and method papersOpen in the app

    Qiskit SQD estimates the ground-state energy of a molecule's active space by sample-based quantum diagonalization (SQD). A quantum circuit is sampled for electronic configurations; configurations with the wrong number of electrons are repaired, and the Hamiltonian is diagonalized in the subspace the remaining configurations span. The circuit runs on the Qiskit Aer simulator, a classical simulation: no quantum hardware is involved.

    How a run works

    1. PySCF builds the Hartree–Fock reference: restricted for singlets, restricted open-shell for higher multiplicities.
    2. An active space is chosen from those orbitals and its one- and two-electron integrals are built. Everything below the window stays doubly occupied.
    3. The exact CASCI energy of that active space is computed as a reference.
    4. Bitstrings are sampled, either from a LUCJ circuit or uniformly at random.
    5. Configuration recovery and subspace diagonalization run for the requested batches and iterations; the lowest batch energy is the SQD energy.

    Choosing an active space

    • Electrons and orbitals: a window of Hartree–Fock orbitals around the frontier, given as active electrons and active orbitals. The electron count has to fit the multiplicity, and the electrons left outside the window must pair up in core orbitals.
    • AVAS: projects the orbitals onto atomic-orbital labels such as C 2p, N 2p or Fe 3d and keeps those above a threshold. The selection depends on the molecule, so a label set that picks too many orbitals fails with the count it found; raise the threshold or drop a label.

    The active space is capped at a small number of orbitals (the field limits are listed below). At that size the exact answer is cheap, which is why every run reports it.

    Samplers

    • LUCJ: a local unitary cluster Jastrow circuit initialized from active-space CCSD amplitudes, with nearest-neighbor same-spin and on-site opposite-spin interactions. Open-shell molecules use the spin-unbalanced form.
    • Uniform: random bitstrings with no circuit, a baseline that leans entirely on configuration recovery.

    Reading the energies

    All energies are in Hartree and include the core and nuclear repulsion energy.

    • e_hf_hartree: the Hartree–Fock reference.
    • e_casci_hartree: the exact energy of the same active space, the value SQD is approximating.
    • e_sqd_hartree and e_sqd_minus_casci_hartree: the SQD estimate and its error against CASCI.
    • e_ccsd_hartree: active-space CCSD, when requested.
    • subspace_dim and sector_yield: how many determinants the final subspace held, and the fraction of shots that already had the right electron counts.

    A small subspace is the usual reason e_sqd_hartree sits above e_casci_hartree: an unoptimized LUCJ circuit can concentrate its samples on a few configurations. More LUCJ layers, more samples per batch, or the uniform sampler widen the subspace.

    Inputs

    One 3D structure with explicit hydrogens, as SDF, MOL, or a mol block. Radicals need an M RAD line so no hydrogens are implied. Charge and multiplicity must agree with the molecule's electron count; mismatches fail before any calculation starts.

    Outputs

    • energies.csv: one row with the energies, active-space size and sampling settings.
    • summary.json: the same values plus the energy after each recovery iteration and the package versions used.
    • active_space.fcidump: the active-space Hamiltonian in FCIDUMP format.
    • samples/counts.json: every sampled bitstring and its count.

    Not covered

    Quantum hardware backends, solvation models, geometry optimization, and multiconfigurational methods such as CASSCF are not part of this tool. The energies are the lowest state with the requested spin projection.

    Use PySCF Electronic Structure for DFT energies and geometry optimization before choosing an active space. In a workflow, the energies table can feed later steps; a multi-molecule upstream runs one SQD job per molecule.

    Run it from the API

    Submit with Submit a job and the job_type below. Price it first with Estimate job reservation cost: submitting reserves that amount from your wallet, and the charge settles at the actual runtime.

    Qiskit SQD qiskit-sqd

    Job type
    qiskit-sqd
    Hardware
    cpu (default)
    Typical runtime
    30 min on CPU

    Payload

    Payload fields
    FieldTypeDescription
    moderequiredstring

    One of: "sqd"

    input_data[]required(string | object)[]

    Limits: min items 1, max items 1

    input_formatrequiredstring

    One of: "sdf", "mol", "molblock"

    chargeinteger

    Default: 0Limits: ≥ -4, ≤ 4

    multiplicityinteger

    Default: 1Limits: ≥ 1, ≤ 5

    basisstring

    Default: "sto-3g"One of: "sto-3g", "6-31g", "cc-pvdz"

    active_spacerequiredobject
    samplerstring

    Default: "lucj"One of: "lucj", "uniform"

    lucj_n_repsinteger

    Default: 1Limits: ≥ 1, ≤ 3

    shotsinteger

    Default: 10000Limits: ≥ 100, ≤ 100000

    num_batchesinteger

    Default: 3Limits: ≥ 1, ≤ 10

    samples_per_batchinteger

    Default: 300Limits: ≥ 10, ≤ 2000

    max_iterationsinteger

    Default: 5Limits: ≥ 1, ≤ 10

    seedinteger

    Default: 0Limits: ≥ 0, ≤ 2147483647

    include_ccsd_referenceboolean

    Default: false

    Example

    from cognichem_client import CogniChem
    
    client = CogniChem.from_env()  # reads COGNICHEM_API_KEY
    payload = {
        "mode": "sqd",
        "input_data": [
            "H2\n     RDKit          3D\n\n  2  1  0  0  0  0  0  0  0  0999… (227 characters)",
        ],
        "input_format": "molblock",
        "charge": 0,
        "multiplicity": 1,
        "basis": "sto-3g",
        "active_space": {"method": "manual", "nelec": 2, "norb": 2},
        "sampler": "lucj",
        "lucj_n_reps": 1,
        "shots": 1000,
        "num_batches": 1,
        "samples_per_batch": 10,
        "max_iterations": 2,
        "seed": 0,
        "include_ccsd_reference": True,
    }
    
    estimate = client.jobs.estimate(job_type="qiskit-sqd", payload=payload, resource="cpu")
    print(f"Reserves ${estimate.cost:.2f}")
    
    job = client.jobs.submit(
        job_name="my-qiskit-sqd-run",
        job_type="qiskit-sqd",
        payload=payload,
        resource="cpu",
    )
    status = client.jobs.wait(job.process_id)
    if status.status == "completed":
        client.jobs.result(job.process_id, save_path=".")

    Sample data from the job catalog; long values are shortened here. Each job_name must be unique among your jobs.

    Workflow inputs

    • MoleculesSDF, MOL, MOLBLOCK

    Workflow outputs

    • ArchiveZIP
    • TableCSV