Source code for quchip.chip.transformations.eliminate_coupling

"""Remove a selected edge through a captured change of coordinates.

Both endpoint devices survive with their authored parameters. The kept matrix
includes the selected interaction's level-dependent shifts and its
transformation of every other interaction in the chip.
"""

from __future__ import annotations

from typing import TYPE_CHECKING, Any

import jax.numpy as jnp
from jax.scipy.linalg import expm

from quchip.chip.sw import bare_hamiltonian, degeneracy_error, interaction_generator
from quchip.chip.transformations.coordinate_change import (
    embed_on_labels, isolated_hamiltonian, labeled_eigenvectors, product_energies, retain_coordinate_change,
)
from quchip.chip.transformations.dispatch import EliminationTarget, register_elimination_target
from quchip.chip.transformations.plumbing import StrandedLine, plan_stranded_lines, reattach_equipment
from quchip.chip.transformations.result import EliminationResult
from quchip.utils.labeling import LabelKeyedDict, resolve_label

if TYPE_CHECKING:
    from quchip.chip.chip import Chip

[docs] def reduce_coupling(chip: "Chip", target: Any, method: str) -> EliminationResult: """Diagonalize an edge exactly or remove its exchange to second order. The pair rotation uses only its isolated devices and selected edge. Its action on the full chip, including parallel and spectator interactions, is kept. ``method='sw'`` truncates the Hamiltonian at second order in interactions. ``method='exact'`` applies a full unitary transformation. The coordinate map keeps the full Hilbert space. Exact derivatives require a locally stable dressed assignment and nondegenerate eigenpairs. Channels follow the captured operator projection, and surviving components continue to own their rates. SW channels use the exponentiated first-order coordinate map. The Hamiltonian keeps its second-order truncation. Surviving control operators are not transformed yet. """ if method not in {"sw", "exact"}: raise NotImplementedError(f"Coupling-target reduction does not implement method {method!r}.") coupling_label = resolve_label(target) coupling = chip.coupling_map[coupling_label] if coupling._time_terms(): raise NotImplementedError( f"Coupling {coupling_label!r} has intrinsic time-dependent terms. " "Their retained coordinate transformation is not implemented; keep this edge." ) pair_labels = (coupling.device_a_label, coupling.device_b_label) result_kind = "coupling" equipment = chip.control_equipment def classify(line: Any) -> StrandedLine | None: from quchip.control.drive import CouplingDrive if not isinstance(line, CouplingDrive) or line.target_label != coupling_label: return None return StrandedLine( rule_target=coupling, missing_rule_message=( f"Control line '{line.label}' ({type(line).__name__}) pumps the eliminated " f"coupling '{coupling_label}'. No retarget rule converts it " f"(register_retarget_rule({type(line).__name__}, {type(coupling).__name__}, " f"'{result_kind}', ...)); unwire the line first (chip.unwire('{line.label}')), " "or keep the coupling." ), ) survivor_lines, retarget_plan = plan_stranded_lines(equipment, classify, result_kind) approximation = chip.approximation source = chip.resolve(frame="lab", approximation=approximation) h, labels, dims = bare_hamiltonian(chip, approximation=approximation) cloned = chip.clone() pair_devices = [cloned[label] for label in pair_labels] pair_h, pair_e, pair_dims = isolated_hamiltonian(chip, pair_devices, approximation, couplings=[cloned.coupling_map[coupling_label]]) if method == "exact": pair_rotation = labeled_eigenvectors(pair_h, pair_dims) rotation = embed_on_labels(chip.backend, labels, dims, pair_rotation, pair_labels) pair_after = pair_rotation.conj().T @ pair_h @ pair_rotation retained_h = rotation.conj().T @ h @ rotation else: pair_s = interaction_generator(pair_e, pair_h, error=degeneracy_error(pair_labels, pair_dims)) s = embed_on_labels(chip.backend, labels, dims, pair_s, pair_labels) rotation = expm(-s) energies = product_energies(source.bases, labels) def second_order(matrix: Any, energies: Any, generator: Any) -> Any: h0 = jnp.diag(energies) first = generator @ h0 - h0 @ generator interaction = matrix - h0 return (matrix + first + generator @ interaction - interaction @ generator + .5 * (generator @ first - first @ generator)) retained_h = second_order(h, energies, s) pair_after = second_order(pair_h, pair_e, pair_s) notes = [f"Removed '{coupling_label}' and retained its complete {method} Hamiltonian correction; " "device parameters and remaining edges stay authored.", "The full-space coordinate map includes the effect on parallel and spectator interactions.", "Surviving channel operators follow the captured map; control operators are not transformed yet."] final, mapping = retain_coordinate_change( chip, source=source, labels=labels, dims=dims, rotation=rotation, retained_h=retained_h, approximation=approximation, devices=cloned.devices, couplings=[c for c in cloned.couplings if c.label != coupling_label], label=f"retained_{coupling_label}", notes=tuple(notes), removed_owners=(coupling,), ) # These diagnostics describe the isolated selected pair, not a refolding # of all the remaining chip interactions into two frequencies. diagonal = jnp.real(jnp.diagonal(pair_after)) indices = (pair_dims[1], 1) chi = diagonal[pair_dims[1] + 1] - diagonal[indices[0]] - diagonal[indices[1]] + diagonal[0] effective_params: dict[str, Any] = LabelKeyedDict({ label: {"lamb_shift": diagonal[index] - diagonal[0] - (pair_e[index] - pair_e[0]), "freq_after": diagonal[index] - diagonal[0], "chi": chi} for label, index in zip(pair_labels, indices) }) delta = pair_e[indices[0]] - pair_e[indices[1]] # The resolved exchange element, not the authored strength: a charge # operator's 0-1 element can be complex or differ from one. ratio = jnp.abs(pair_h[indices[0], indices[1]] / delta) validity: dict[str, Any] = LabelKeyedDict({coupling_label: {"g_over_delta": ratio, "is_valid": ratio < .1}}) reattach_equipment(chip, final, equipment, survivor_lines, retarget_plan, mode_label=coupling_label, result_kind=result_kind, edges={}, notes=notes) return EliminationResult(chip=final, effective_params=effective_params, validity=validity, notes=notes, mapping=mapping)
register_elimination_target(EliminationTarget( kind="coupling", claims=lambda chip, target: resolve_label(target) in chip.coupling_map, reduce=reduce_coupling, ))