quchip.inverse_design.fit

Fit bare chip parameters to a numerical dressed specification.

Devices and couplings declare how their input numbers map to dressed targets. The fitter reads the desired chip structurally rather than diagonalizing it, and a bounded nonlinear least-squares solve evaluates the candidate chips.

References

Dispersive regime (cross-Kerr and dressed frequencies):

  • Koch et al., Phys. Rev. A 76, 042319 (2007), “Charge-insensitive qubit design derived from the Cooper pair box” — the DuffingTransmon approximation and its dispersive shifts.

  • Gambetta et al., Phys. Rev. A 74, 042318 (2006), “Qubit-photon interactions in a cavity” — dispersive frequency shifts. Coupling seeding here uses a numerical signed cross-Kerr root, requiring a bracket across seed_strength_bounds without assuming monotonicity.

JAX traceability

Every bare parameter here (device.freq, device.anharmonicity, the coupling_strength of a coupling) is a sweepable, differentiable quantity. A chip that uses a JAX-native backend supplies a traced dressed-observable residual and an exact Jacobian. SciPy uses their concrete values only at the bounded trust-region boundary. The optimizer itself is not JAX-traceable, but the output Chip stays fully traceable for every downstream operation.

Functions

fit_a_dress(chip, *[, constraints, vary, ...])

Find bare parameters for a numerically specified dressed chip.

quchip.inverse_design.fit.fit_a_dress(chip, *, constraints=None, vary=None, start=None, evaluator='full', max_hilbert_dim=10000, seed_strength_bounds=(1e-06, 0.25), max_nfev=1000)[source]

Find bare parameters for a numerically specified dressed chip.

fit_a_dress(desired) reads component-owned target declarations without evaluating desired. Common spectral devices interpret their declared frequencies and anharmonicities as dressed targets. A Capacitive edge between two non-computational modes targets the dressed exchange_rate. Other Capacitive edges and CrossKerr couplings target the full cross_kerr = E11 - E10 - E01 + E00. The returned chip is a fitted clone, and desired is never mutated.

constraints adds or replaces numerical observables. vary replaces the component-owned selection of free parameters. start replaces the selected starting values.

Parameters:
  • chip (Chip) – Desired dressed-chip specification. Component declarations supply numerical targets, and no dressed analysis runs on this object. A chip declared for simulation is not a specification. Its bare coupling strengths become cross_kerr or exchange_rate targets, and a frequency-only vary cannot meet them. State such targets explicitly with constraints, and read the unmet-target line of summary().

  • constraints (Mapping | None) – Additional {component_or_pair: {observable: value_or_none}} constraints. The supported canonical observables are "freq", "anharmonicity", "cross_kerr", "exchange_rate", and "coupling_strength". The function also accepts the aliases "zz"/"static_zz", "exchange", and "g". An explicit value replaces the same component default. None removes it. Device pairs do not have to be direct coupling edges.

  • vary (Mapping | None) – Complete desired-chip allowlist of the bare parameters that can move: {component_or_label: name_collection}. If omitted, each component’s conservative inverse-design policy applies. Components that are absent from an explicit mapping are frozen.

  • start (Mapping | None) – Optional {"<component>.<parameter>": value} replacements for the optimizer’s selected starting values. A key that vary does not select raises an error rather than being silently ignored.

  • evaluator (Literal['full', 'local']) – "full" evaluates each target on the complete model. "local" explicitly selects one-hop neighborhoods and omits effects of devices outside them. A neighborhood keeps the ports whose targets it holds. Target reports record the selected evaluator. Unsupported local model contributions raise, e.g. a feedline that links a kept port to a discarded one. A PortNetwork with matrix-form scattering also raises when a neighborhood keeps only some of its planes. With the mapping form {(output, input): amplitude}, each neighborhood keeps the entries of its own planes. A chip with an active ExcitationCutoff raises, because a neighborhood would spend the same budget on fewer devices.

  • max_hilbert_dim (int) – Maximum dimension of each matrix that a target evaluation diagonalizes. A chip whose static model conserves the total excitation number diagonalizes only the excitation sectors that its targets read. Under an excitation cutoff, each target diagonalizes the cutoff classes that its labels occupy, and every candidate keeps the same cutoff. Other chips diagonalize the full product space. A larger matrix raises before seeding or optimization. Each rebound or traced target checks the limit again if its conservation proof changes. No different approximation is selected. Increase the value to permit a larger model.

  • seed_strength_bounds (tuple[float, float]) – (lo, hi) magnitude bounds for the seed root solve of the bare coupling strength (_estimate_bare_g()). This solve serves cross_kerr coupling targets. The values at both endpoints must bracket the target observable, or seeding raises ValueError rather than silently returning a saturated endpoint.

  • max_nfev (int) – Maximum number of residual evaluations for the SciPy Trust-Region Reflective solver.

Returns:

Fitted chip clone, loss, residual history, per-target ObservableReport tuples, packed parameters, and solver metadata.

Return type:

FitADressResult

Raises:

ValueError – Raised when seed_strength_bounds does not bracket a cross-Kerr seed, an automatic plan is underdetermined, vary contains unknown, duplicate or invalid parameter selections, or a resource ceiling is exceeded.

Warns:

UserWarning – An explicit vary plan is underdetermined by the target count or by the final scaled-Jacobian rank. A nonconverged automatic fit also returns its candidate with a warning when the final Jacobian does not have full rank. Converged rank-deficient automatic fits raise an error.

Notes

The fitter normalizes residuals by max(|target|, 1e-9), so every anchor contributes on an equal relative-error basis. A coupling’s scalar-strength bounds are symmetric around zero, because the sign of a capacitive-type coupling is physical and the fitter must not constrain it. The solver’s convergence tolerances (ftol/xtol/gtol = 1e-11) are fixed fitter policy, not options. So is the x_scale floor (1e-3, applied per parameter as max(abs(x0), 1e-3)).

Identifiability. The count of free parameters against residuals is necessary but not sufficient. The fitter therefore computes the final SVD rank and condition number from normalized residuals, in the same scaled parameter coordinates that the solver uses. A custom DeviceModel with a discovered tunable_param_names (the derived default, not an explicit declaration) is not automatically fit-ready. An unbounded parameter still needs a tunable_param_bounds() rule before the optimizer can search it.

JAX traceability. When the chip uses a JAX-native backend, the complete map from parameters to residuals and its exact Jacobian are JAX-traceable. SciPy receives their concrete values for bounded trust-region control. The optimizer itself is not differentiated. Other backends keep SciPy’s numerical Jacobian. In both cases, the returned chip stays fully traceable and differentiable.