Quantum Information · Channel analysis
Quantum channel analysis
From Kraus operators: Choi matrix, CPTP check, Pauli transfer matrix, gate fidelities, unitarity and diamond distance in one report.
Reconstruct a known pure state of up to 4 qubits from sampled Pauli measurements by linear inversion, with physicality and fidelity.
Officially provided by KetQat — method by Vogel and Risken (1989), James et al. (2001) and others. KetQat prepares, verifies and maintains this product; it does not claim to have invented the method. Read the origin statement.
Simulates state tomography on your machine. A known pure target state -- a point on the Bloch sphere, |0>, |1>, |+>, |->, |+i>, a Bell state, a GHZ state or a seeded random state -- is measured in every Pauli basis: for each of the 4^n Pauli strings the +1/-1 outcome counts are sampled from the exact Born probabilities with the shots you choose, or taken exactly when exact=true. The density matrix is reconstructed by linear inversion, rho = sum <P> P / 2^n, and reported with its eigenvalues, purity, trace, the fidelity with the target and the largest error in any estimated expectation value.
Physicality is reported, never repaired. From finite statistics linear inversion routinely returns a matrix with a negative eigenvalue -- most often near a pure state, where shot noise pushes the Bloch vector past the unit sphere -- and the product returns that matrix unprojected, with the eigenvalue, so you can see how far outside the state space the data landed. The exact (infinite-shot) reconstruction is reported beside it as the reference.
Installs the KetQat SDK from commit 2cedabbd814f, the exact version whose product definition this page shows. The SDK is not on PyPI yet, so pip install ketqat alone will not work.
pip install "ketqat[qinfo] @ git+https://github.com/ketqat/ketqat-sdk@2cedabbd814fd199b1989c8ceb1e9efa1744c2c0#subdirectory=python"Save it as example.py and run python example.py. Or use the CLI: ketqat catalog run [email protected].
import json
from ketqat_runner import catalog
record = catalog.run("[email protected]", seed=7, preset="bell", exact=True)
result = record.result
print(json.dumps({
"status": record.status,
"qubits": result["qubits"],
"pauli_settings": result["pauli_settings"],
"fidelity_with_target": round(result["fidelity_with_target"], 9),
"purity": round(result["purity"], 9),
"physical": result["physical"],
"reconstruction_error": round(result["reconstruction_error"], 9),
}))
{
"purity": 1,
"qubits": 2,
"status": "succeeded",
"physical": true,
"pauli_settings": 16,
"fidelity_with_target": 1,
"reconstruction_error": 0
}Verified with
ketqat report RUN_ID sends an opt-in usage report: product, version, succeeded/failed, time and SDK version only. It shows you the exact payload first and needs an API token from Settings. Nothing is sent unless you run it.
| Name | Type | Default | Allowed values | Description |
|---|---|---|---|---|
| preset | string | bloch | enum: bloch, zero, one, plus, minus, i-plus, bell, ghz, random | Target state: bloch (cos(theta/2)|0> + e^{i phi} sin(theta/2)|1>), zero, one, plus, minus, i-plus (one qubit); bell (|Phi+>); ghz or random (qubits sets the size). |
| theta | number | 1 | maximum: 3.141592653589793; minimum: 0 | Polar angle for preset=bloch, in [0, pi]. Ignored by the other presets. |
| phi | number | 0.5 | maximum: 6.283185307179586; minimum: 0 | Azimuthal angle for preset=bloch, in [0, 2 pi]. Ignored by the other presets. |
| qubits | integer | null | maximum: 4; minimum: 1 | Register size for preset=ghz (null means 3) and preset=random (null means 2); at most 4 (256 Pauli settings). Not accepted with the one- and two-qubit presets. |
| shots | integer | 1000 | maximum: 1000000; minimum: 1 | Measurements per Pauli setting. Ignored when exact=true. |
| exact | boolean | false | — | true uses the exact expectation values (the infinite-shot limit) instead of sampling. |
| Name | Type | Description |
|---|---|---|
| expectations | object[] | For each Pauli string: the estimate, its binomial standard error and the exact value. |
| bloch_vector | object | One qubit only: x, y, z with standard errors, beside target_bloch_vector and the Bloch length. |
| density_matrix_real | object[] | Real part of the reconstructed density matrix (density_matrix_imaginary holds the imaginary part), with eigenvalues, purity and trace. |
| physical | boolean | Whether every eigenvalue is non-negative (within 1e-9); physicality_note says why not and that nothing was projected. |
| fidelity_with_target | number | <psi|rho|psi> for the pure target (for one qubit, (1 + r . t)/2). |
| max_expectation_error | number | Largest |estimate - exact| over all Pauli strings; reconstruction_error is the largest matrix-entry error. |
One qubit at theta = 1, phi = 0.5 with 1000 shots per Pauli setting: Bloch estimate (0.732, 0.428, 0.582) against the target (0.738, 0.403, 0.540), standard errors about 0.02-0.03. The estimate has length 1.028, so the reconstruction has a negative eigenvalue (-0.0142) and is reported as unphysical and unprojected; the linear-inversion fidelity formula then gives 1.014, above 1 for the same reason.
Generated with
{"phi":0.5,"exact":false,"shots":1000,"theta":1,"preset":"bloch","qubits":null}{
"trace": 1,
"purity": 1.028866,
"qubits": 1,
"target": {
"phi": 0.5,
"theta": 1,
"preset": "bloch",
"qubits": 1,
"description": "cos(theta/2)|0> + exp(i phi) sin(theta/2)|1>"
},
"physical": false,
"estimator": "linear inversion: rho = sum_P <P> P / 2^n",
"execution": "exact Born probabilities from the target state vector; seeded binomial sampling; dense linear algebra",
"eigenvalues": [
-0.014230493067,
1.014230493067
],
"measurement": "each Pauli string measured as a +1/-1 observable; outcome counts sampled from the exact Born probabilities",
"bloch_length": 1.028460986134,
"bloch_vector": {
"x": 0.732,
"y": 0.428,
"z": 0.582,
"x_standard_error": 0.021544744139,
"y_standard_error": 0.028579993002,
"z_standard_error": 0.025715287282
},
"expectations": [
{
"exact": 1,
"pauli": "I",
"estimate": 1,
"standard_error": 0
},
{
"exact": 0.738460262604,
"pauli": "X",
"estimate": 0.732,
"standard_error": 0.021544744139
},
{
"exact": 0.403422680111,
"pauli": "Y",
"estimate": 0.428,
"standard_error": 0.028579993002
},
{
"exact": 0.540302305868,
"pauli": "Z",
"estimate": 0.582,
"standard_error": 0.025715287282
}
],
"pauli_settings": 4,
"physicality_note": "The reconstructed Bloch vector has length 1.028461, which exceeds 1, so the smaller eigenvalue is -0.014230 and the matrix is not a density matrix. Linear inversion does this routinely near a pure state, where shot noise pushes the estimate past the state space. It is a statement about the estimator and the shot count, not about the device -- take more shots, or use a maximum-likelihood estimator that is constrained to physical states. The raw estimate is returned unchanged rather than projected, so the size of the excursion stays visible.",
"shots_per_setting": 1000,
"density_matrix_real": [
[
0.791,
0.366
],
[
0.366,
0.209
]
],
"target_bloch_vector": [
0.738460262604,
0.403422680111,
0.540302305868
],
"exact_reconstruction": {
"note": "linear inversion from exact expectation values (multi_qubit_state_tomography)",
"purity": 1,
"physical": true,
"reconstruction_error": 0
},
"fidelity_with_target": 1.013836880665,
"reconstruction_error": 0.020848847066,
"max_expectation_error": 0.041697694132,
"density_matrix_imaginary": [
[
0,
-0.214
],
[
0.214,
0
]
]
}exact recovery
From exact expectation values (exact=true) every preset is recovered: the one-qubit Bloch vector equals (sin theta cos phi, sin theta sin phi, cos theta) to 1e-12, the Bell and GHZ density matrices equal |psi><psi| entry by entry to 1e-12, and fidelity, purity and trace are 1.
statistical consistency
With sampled shots every estimated expectation lies within five binomial standard deviations sqrt((1 - <P>^2)/shots) of its exact value, the reported standard errors equal that formula at the estimate, and the largest expectation error shrinks from 100 to 100000 shots.
unphysical reported
A seed is found for which the few-shot reconstruction of a pure state has a negative eigenvalue; the product reports physical=false with the eigenvalue and returns the raw matrix (trace 1, Bloch length above 1) rather than a projected one, and single-qubit fidelity equals (1 + r . t)/2.
example execution
The example code is executed verbatim in a clean virtual environment with only the qinfo extra installed.
1.0.01 Nov 2026currentShown on this page
Needs SDK 0.3.0 or later with extras: qinfo.
KetQat implementation of published methods
Quantum state tomography originates with Vogel and Risken (1989); the linear-inversion reconstruction from Pauli expectation values used here is the textbook treatment of Nielsen and Chuang, and the qubit measurement analysis follows James, Kwiat, Munro and White (2001), with the unphysicality of linear inversion discussed by Smolin, Gambetta and Smith (2012). KetQat wrote this NumPy implementation (tomography.py, process_tomography.py and this product's sampling), the validation tests and this catalog entry. KetQat did not invent the method.
Apache-2.0 — see Licensing.
People credited for this product. KetQat publishes and maintains it; contributors are credited for their work and are not sellers.
No usage reports yet
Distinct signed-in accounts that chose to send at least one usage report (ketqat report) for this product in the last 90 days. KetQat staff, test and bot accounts are excluded. Reports are opt-in, so this is not a count of all users.
Computed 10 Nov 2026, 17:34 UTC.
Not yet rated
Be the first to rate this product after you run it.
Mean of visible reviews. Hidden reviews and reviews by KetQat staff, test and bot accounts are excluded. Pro status gives no extra weight.
Sign in to review this product. One review per person; you can edit it later.
No reviews yet.