# qmlkit > A quantum machine learning library built to refuse a plausible wrong number. In > this field a mistake usually does not raise — a collapsed re-uploading model, a > concentrated kernel and a lead inside the fold spread all run and all return > numbers in the right range — so `diagnose`, `baseline`, `plan`, `selfcheck` and > `progress` are the point of the library rather than an add-on. > > Underneath: reusable feature maps, a composable ansatz vocabulary, quantum > kernels, PyTorch layers, and one `grad()` that points at any circuit and > observable. The same circuit runs on the built-in NumPy reference, SpinQit, > Qiskit, Cirq or Torch, and on two mixed-state backends under noise. Install with `pip install qmlkit`. The core depends on NumPy and nothing else; every SDK is an optional extra (`qmlkit[torch]`, `[qiskit]`, `[cirq]`, `[spinqit]`, `[sklearn]`). What is worth knowing before writing any of it: - **Simulator-only for the whole 0.x line.** No hardware. Expectations and gradients are exact unless you pass `shots=N`, and `adjoint` is therefore the default gradient method — parameter-shift costs `2P` circuit evaluations for the same answer, so it is the teaching subject and the test-suite reference, not the performance default. - **Three layers, and nothing at a higher one hides a lower one.** `VQC(...).fit(X, y)` for a ready-made model; `QuantumLayer(...)` as an `nn.Module` inside any `nn.Sequential`; or circuits and `grad()` directly. Drop a level without giving up what the level above was doing. - **Estimators are scikit-learn clonable** and models are `nn.Module`s, so `Pipeline`, `GridSearchCV`, `cross_val_score` and ordinary torch training loops all work. - **Run `qk.diagnose(model)` before trusting a result.** In this field a mistake usually returns a plausible number rather than raising: a re-uploading model whose trainable block commutes with its encoding reaches one Fourier frequency instead of the `L` it was designed for, and it trains and converges anyway. `diagnose` returns findings with a code, what was measured, and the edit that fixes it. - **The names are qmlkit's, not PennyLane's or Qiskit's**, and a wrong one tells you the right one: `qk.AngleEmbedding` reports that it is `qk.AngleFeatureMap` here. Unknown registry names suggest the nearest valid one, so guessing is cheap. - **Every extension point is a registry:** `register_ansatz`, `register_gate`, `register_gradient`, `register_backend`, `register_conv_filter`. Registering makes your thing a first-class citizen everywhere that kind of argument is taken. - **Data re-uploading is a pattern, not a class.** It is `EncodingLayer` composed into the block vocabulary, with `reupload()` as a convenience over it. ## Start here - [Home](https://ziadt160.github.io/qmlkit/): A quantum machine learning library built to refuse a plausible wrong number. - [Install](https://ziadt160.github.io/qmlkit/install/): That is the whole install. qmlkit depends on NumPy and nothing else — the NumPy backend is the reference implementation, and every core feature works with no optional package present. ## Tutorials - [Tutorials](https://ziadt160.github.io/qmlkit/tutorials/): Eight pages, in order. Each one builds on the last, and each is short enough to read in a sitting. - [1. Circuits are data](https://ziadt160.github.io/qmlkit/tutorials/01-first-circuit/): Most quantum SDKs give you a circuit object that belongs to a particular simulator. - [2. Getting data in](https://ziadt160.github.io/qmlkit/tutorials/02-encoding-data/): A quantum model can only learn functions its encoding can express. - [3. Gradients](https://ziadt160.github.io/qmlkit/tutorials/03-gradients/): Six methods, one function. They differ in cost, in whether they are exact, and in whether they could run on real hardware — not in the answer. - [4. Designing an ansatz](https://ziadt160.github.io/qmlkit/tutorials/04-ansatz-design/): Most libraries give you a list of templates and a note saying "or write your own", where writing your own means implementing parameter counting, gradients and resource estimation from scratch. - [5. Training with PyTorch](https://ziadt160.github.io/qmlkit/tutorials/05-training-torch/): A circuit becomes an nn.Module and everything torch already knows how to do — optimisers, schedulers, batching, autograd — applies unchanged. - [6. Quantum kernels](https://ziadt160.github.io/qmlkit/tutorials/06-quantum-kernels/): The other way to use a feature map. No variational parameters, no training loop, no barren plateaus — just an inner product between encoded states, handed to a classical solver that is convex and has a unique optimum. - [7. Re-uploading and Fourier](https://ziadt160.github.io/qmlkit/tutorials/07-reuploading/): Encode the data once and a circuit is a fairly limited function of it. - [8. Trainability](https://ziadt160.github.io/qmlkit/tutorials/08-trainability/): A correct gradient is not the same as a useful one. Variational circuits have a failure mode where the gradient is exactly right and exponentially small — the barren plateau — and no optimiser recovers from it, because there is nothing to follow. ## Case studies - [Case studies](https://ziadt160.github.io/qmlkit/studies/): The tutorials show how each piece works. These show a whole problem worked through, from the raw data to a number you could defend — and in most of them the number is that the quantum model lost. - [1. Imbalanced classification](https://ziadt160.github.io/qmlkit/studies/01-imbalanced-classification/): The full version of this runs on the Kaggle credit-risk table — 32,581 loan applications, 21.8% of which defaulted — in examples/creditrisk.py. - [2. Is a quantum kernel worth it?](https://ziadt160.github.io/qmlkit/studies/02-quantum-kernels/): A quantum kernel is the most appealing thing in this field: no training loop, no barren plateau, a Gram matrix you hand to any kernel method. - [3. Regression](https://ziadt160.github.io/qmlkit/studies/03-regression/): Classification hides a bad model behind accuracy. Regression hides one behind r2, which is scaled by the variance of whatever you happened to sample — so the same model scores differently on a narrow test set and a wide one, and neither number is wrong. - [4. Chemistry - H2 ground state](https://ziadt160.github.io/qmlkit/studies/04-chemistry/): Chemistry is the one place quantum computing has a target it can be scored against exactly: diagonalise the Hamiltonian and compare. - [5. Clustering and generative](https://ziadt160.github.io/qmlkit/studies/05-beyond-classification/): Accuracy needs labels and a decision. Two large parts of machine learning have neither, and they fail in ways a classification metric cannot describe: a clustering that is beautifully separated and answers the wrong question, and a generative model that assigns zero probability to something that actually happens. - [6. Clinical decisions](https://ziadt160.github.io/qmlkit/studies/06-clinical/): Credit risk in study 1 was about a skewed dataset. This one is about something else that no amount of balancing fixes: a false negative and a false positive are not equivalent mistakes, and no single-number metric knows that. - [7. Images and structure](https://ziadt160.github.io/qmlkit/studies/07-images-and-structure/): Every other study on this page flattens its data and hands it to a general-purpose ansatz. - [8. A classifier that declines](https://ziadt160.github.io/qmlkit/studies/08-selective-classification/): Letting a model abstain is an old and good idea: answer where you are confident, refuse where you are not, and hand the rest to a human. ## Guides - [Guides](https://ziadt160.github.io/qmlkit/guides/): The tutorials show you how. These explain why, and are meant to be read out of order when a particular question comes up. - [Coming from PennyLane](https://ziadt160.github.io/qmlkit/guides/from-pennylane/): You do not have to migrate anything to use this library, and the cheapest way to start is not to. - [The parameter-shift rule](https://ziadt160.github.io/qmlkit/guides/parameter-shift/): It is correct — for a gate whose generator has a single frequency, differentiated one occurrence at a time. - [Choosing a gradient method](https://ziadt160.github.io/qmlkit/guides/choosing-a-gradient/): Six methods, and qk.grad(spec, theta, obs) with no method picks a sensible one. - [Backends and conventions](https://ziadt160.github.io/qmlkit/guides/backends/): One circuit, eight backends, one answer. tests/testcrossbackend.py runs the same circuit zoo through every installed backend and asserts agreement with the NumPy reference on statevectors, probabilities, expectations over X/Y/Z and two-body terms, seeded sampling, and parameter-shift gradients. - [Running under noise](https://ziadt160.github.io/qmlkit/guides/noise/): qmlkit is simulator-only, but a simulator does not have to be a perfect one. - [Evaluating a model honestly](https://ziadt160.github.io/qmlkit/guides/evaluation/): Three things go wrong between a trained model and a reported result, and none of them raises an exception. - [Watching a run](https://ziadt160.github.io/qmlkit/guides/watching-a-run/): qk.plan says what a run will cost before it starts. qk.diagnose says what went wrong after it finishes. - [Extending qmlkit](https://ziadt160.github.io/qmlkit/guides/extending/): Almost every extension point is a registry. Register something and it becomes reachable by name everywhere the library takes one — no subclassing, no plugin manifest, no coordination with anything else, and no fork. - [Working with a coding agent](https://ziadt160.github.io/qmlkit/guides/agents/): Most code written against a library now is written by a model, and a model does not read this page before it types. ## Reference - [Reference](https://ziadt160.github.io/qmlkit/reference/): Generated from the docstrings in the source, so it cannot drift from the code. - [Core](https://ziadt160.github.io/qmlkit/reference/core/): The circuit IR, gates, observables, execution and backends. Everything else in the library reads or writes these types. - [Gradients](https://ziadt160.github.io/qmlkit/reference/gradients/): Six estimators behind one grad(), plus the shift-rule machinery they share. - [Encoding](https://ziadt160.github.io/qmlkit/reference/encoding/): Getting classical data into a circuit, and the scaling decisions that come first. - [Ansatz](https://ziadt160.github.io/qmlkit/reference/ansatz/): A block vocabulary, the templates written in it, and re-uploading as a composition. - [Kernels](https://ziadt160.github.io/qmlkit/reference/kernels/): Three overlap estimators, Gram matrices that stay positive semi-definite, and the models on top. - [PyTorch](https://ziadt160.github.io/qmlkit/reference/nn/): Circuits as nn.Modules, with gradients flowing to the inputs as well as the weights. - [Algorithms](https://ziadt160.github.io/qmlkit/reference/algorithms/): Variational algorithms built on the same IR, ansatz vocabulary and gradients as everything else — so an ansatz you registered, a gate you defined, or a backend you wrote works in all of them without any of them knowing about it. - [Analysis](https://ziadt160.github.io/qmlkit/reference/analysis/): Measuring an ansatz rather than asserting things about it: expressibility, entanglement, spectra, geometry. - [Evaluation](https://ziadt160.github.io/qmlkit/reference/evaluation/): Scoring predictions, handling skewed classes, comparing against classical baselines, costing a run before it starts, and recording what produced a number. ## About - [Validation](https://ziadt160.github.io/qmlkit/about/validation/): A library's own test suite can only catch the bugs its author thought of. - [API stability](https://ziadt160.github.io/qmlkit/about/stability/): Research code outlives the version it was written against. A script from last year that no longer runs is not a small inconvenience — it is a result nobody can reproduce, and it is the most common complaint about every library in this field. - [Changelog](https://ziadt160.github.io/qmlkit/about/changelog/) - [Releasing](https://ziadt160.github.io/qmlkit/about/releasing/) ## Full text - [Everything above as one file](https://ziadt160.github.io/qmlkit/llms-full.txt): every tutorial and guide in full, then the whole public API with signatures - and, for classes, the docstring that says what the arguments mean.