Source code for qdesignoptimizer.utils.optimization_targets

"""Definitions of common optimization targets for qubit/resonator/coupler systems.

This module provides standard optimization target definitions used to specify how
different physical parameters (frequency, coupling strength, anharmonicity, etc.)
respond to changes in design variables during the optimization process. Each function returns an
OptTarget instance that describes how a specific physical parameter depends on one or more design
variables and other parameters. The module implements common optimization strategies for:

- Qubit frequency via Josephson inductance
- Qubit anharmonicity via capacitance width
- Resonator frequency via length
- Resonator linewidth (kappa) via coupling length
- Qubit-resonator dispersive shift (chi) via coupling length
- Combined qubit-resonator system optimization

Each optimization target specifies a proportionality relationship between
physical parameters and design variables, along with valid ranges for the
design variables.
"""

from typing import Callable, List

import numpy as np

import qdesignoptimizer.utils.names_design_variables as n
from qdesignoptimizer.design_analysis_types import OptTarget
from qdesignoptimizer.utils.names_parameters import (
    FREQ,
    KAPPA,
    NONLIN,
    Mode,
    param,
    param_nonlin,
)


[docs] def get_opt_target_qubit_freq_via_lj( qubit: Mode, design_var_qubit_lj: Callable = n.design_var_lj, design_var_qubit_width: Callable = n.design_var_width, ) -> OptTarget: """ Create an optimization target for qubit frequency via Josephson inductance. This function creates an optimization target that models how a qubit's frequency depends on its Josephson inductance (Lj) and width. The relationship follows the standard LC oscillator model, where frequency is inversely proportional to the square root of inductance times capacitance (which scales with width). Args: qubit (Mode): The qubit mode identifier. design_var_qubit_lj (Callable, optional): Function to generate the design variable name for qubit Josephson inductance. Defaults to n.design_var_lj. design_var_qubit_width (Callable, optional): Function to generate the design variable name for qubit width. Defaults to n.design_var_width. Notes: - The target uses the relationship f ∝ 1/√(L·C), where C scales with width. - Valid inductance range is constrained between 0.1nH and 400nH. - This is marked as a dependent target since frequency depends on multiple design variables and physical parameters. """ return OptTarget( target_param_type=FREQ, involved_modes=[qubit], design_var=design_var_qubit_lj(qubit), design_var_constraint={"larger_than": "0.1nH", "smaller_than": "400nH"}, prop_to=lambda p, v: 1 / np.sqrt(v[design_var_qubit_lj(qubit)] * v[design_var_qubit_width(qubit)]), independent_target=False, )
[docs] def get_opt_target_qubit_anharmonicity_via_capacitance_width( qubit: Mode, design_var_qubit_width: Callable = n.design_var_width, ) -> OptTarget: """ Create an optimization target for qubit anharmonicity via capacitive pad width. This function creates an optimization target that models how a qubit's anharmonicity (self-Kerr nonlinearity) depends on its capacitive pad width. Larger capacitance (wider pad) leads to smaller anharmonicity, following the relation where anharmonicity is inversely proportional to capacitance. Args: qubit (Mode): The qubit mode identifier. design_var_qubit_width (Callable, optional): Function to generate the design variable name for qubit width. Defaults to n.design_var_width. Notes: - The target uses the relationship α ∝ 1/C, where C scales with width. - Valid width range is constrained between 5µm and 1000µm. - This is marked as an independent target since anharmonicity depends only on the capacitance width. """ return OptTarget( target_param_type=NONLIN, involved_modes=[qubit, qubit], design_var=design_var_qubit_width(qubit), design_var_constraint={"larger_than": "5um", "smaller_than": "1000um"}, prop_to=lambda p, v: 1 / v[design_var_qubit_width(qubit)], independent_target=True, )
[docs] def get_opt_target_res_freq_via_length( resonator: Mode, design_var_res_length: Callable = n.design_var_length, ) -> OptTarget: """ Create an optimization target for resonator frequency via length. This function creates an optimization target that models how a resonator's frequency depends on its physical length. Longer resonators have lower frequencies, following the relation where frequency is inversely proportional to length. Args: resonator (Mode): The resonator mode identifier. design_var_res_length (Callable, optional): Function to generate the design variable name for resonator length. Defaults to n.design_var_length. Notes: - The target uses the relationship f ∝ 1/L, where L is the resonator length. - Valid length range is constrained between 500µm and 15000µm. - This is marked as an independent target since frequency depends only on the resonator's length. """ return OptTarget( target_param_type=FREQ, involved_modes=[resonator], design_var=design_var_res_length(resonator), design_var_constraint={"larger_than": "500um", "smaller_than": "15000um"}, prop_to=lambda p, v: 1 / v[design_var_res_length(resonator)], independent_target=True, )
[docs] def get_opt_target_res_kappa_via_coupl_length( resonator: Mode, resonator_coupled_identifier: str, design_var_res_coupl_length: Callable = n.design_var_coupl_length, ) -> OptTarget: """ Create an optimization target for resonator linewidth via coupling length. This function creates an optimization target that models how a resonator's linewidth (kappa) depends on its coupling length to a feedline or other component. Longer coupling sections lead to stronger coupling and thus higher linewidth, following the relation where kappa is proportional to the square of coupling length. Args: resonator (Mode): The resonator mode identifier. resonator_coupled_identifier (str): Identifier for the element to which the resonator is coupled (e.g., a feedline or transmission line). design_var_res_coupl_length (Callable, optional): Function to generate the design variable name for coupling length. Defaults to n.design_var_coupl_length. Notes: - The target uses the relationship κ ∝ L², where L is the coupling length. - Valid coupling length range is constrained between 20µm and 1000µm. - This is marked as an independent target since kappa depends only on the coupling length. """ return OptTarget( target_param_type=KAPPA, involved_modes=[resonator], design_var=design_var_res_coupl_length(resonator, resonator_coupled_identifier), design_var_constraint={"larger_than": "20um", "smaller_than": "1000um"}, prop_to=lambda p, v: v[ design_var_res_coupl_length(resonator, resonator_coupled_identifier) ] ** 2, independent_target=True, )
[docs] def get_opt_target_res_qub_chi_via_coupl_length( qubit: Mode, resonator: Mode, design_var_res_qb_coupl_length: Callable = n.design_var_coupl_length, design_var_qubit_width: Callable = n.design_var_width, ) -> OptTarget: """ Create an optimization target for qubit-resonator dispersive shift. This function creates an optimization target that models how the dispersive shift (chi) between a qubit and resonator depends on their coupling length and the qubit's width. The dispersive shift follows from circuit QED theory, where chi depends on the coupling strength, qubit anharmonicity, and detuning between the qubit and resonator. Args: qubit (Mode): The qubit mode identifier. resonator (Mode): The resonator mode identifier. design_var_res_qb_coupl_length (Callable, optional): Function to generate the design variable name for qubit-resonator coupling length. Defaults to n.design_var_coupl_length. design_var_qubit_width (Callable, optional): Function to generate the design variable name for qubit width. Defaults to n.design_var_width. Notes: - The target uses the relationship χ ∝ g²α/(Δ·(Δ-α)), where: - g is the coupling strength (proportional to coupling length / qubit width) - α is the qubit anharmonicity - Δ is the detuning between qubit and resonator frequencies - Valid coupling length range is constrained between 5µm and 1000µm. - This is marked as a dependent target since chi depends on multiple design variables and physical parameters. """ return OptTarget( target_param_type=NONLIN, involved_modes=[qubit, resonator], design_var=design_var_res_qb_coupl_length(resonator, qubit), design_var_constraint={"larger_than": "5um", "smaller_than": "1000um"}, prop_to=lambda p, v: np.abs( v[design_var_res_qb_coupl_length(resonator, qubit)] / v[design_var_qubit_width(qubit)] * p[param_nonlin(qubit, qubit)] / ( p[param(qubit, FREQ)] - p[param(resonator, FREQ)] - p[param_nonlin(qubit, qubit)] ) ), independent_target=False, )
[docs] def get_opt_target_res_qub_chi_via_coupl_length_simple( qubit: Mode, resonator: Mode, design_var_res_qb_coupl_length: Callable = n.design_var_coupl_length, design_var_qubit_width: Callable = n.design_var_width, ) -> OptTarget: """ Create a simplified optimization target for qubit-resonator dispersive shift. This function creates an optimization target that uses a simplified model for the dispersive shift (chi) between a qubit and resonator. In this model, chi is considered to be directly proportional to the coupling length between the qubit and resonator, ignoring other dependencies to provide a more straightforward optimization approach. Args: qubit (Mode): The qubit mode identifier. resonator (Mode): The resonator mode identifier. design_var_res_qb_coupl_length (Callable, optional): Function to generate the design variable name for qubit-resonator coupling length. Defaults to n.design_var_coupl_length. design_var_qubit_width (Callable, optional): Function to generate the design variable name for qubit width. Not used in this simplified model, but included for API compatibility. Notes: - This simplified model uses the relationship χ ∝ coupling_length, making the dispersive shift directly proportional to the coupling length. - Valid coupling length range is constrained between 5µm and 1000µm. - This is marked as a dependent target to maintain consistency with the full model, although it has a simpler relationship. - Use this simplified model when a coarse approximation is sufficient or when the full parameter dependencies are not critical. """ return OptTarget( target_param_type=NONLIN, involved_modes=[qubit, resonator], design_var=design_var_res_qb_coupl_length(resonator, qubit), design_var_constraint={"larger_than": "5um", "smaller_than": "1000um"}, prop_to=lambda p, v: np.abs( v[design_var_res_qb_coupl_length(resonator, qubit)] ), independent_target=False, )
[docs] def get_opt_targets_qb_res_transmission( qubit: Mode, resonator: Mode, resonator_coupled_identifier: str, opt_target_qubit_freq=False, opt_target_qubit_anharm=False, opt_target_resonator_freq=False, opt_target_resonator_kappa=False, opt_target_resonator_qubit_chi=False, use_simple_resonator_qubit_chi_relation=False, design_var_qubit_lj: Callable[[str], str] = n.design_var_lj, design_var_qubit_width: Callable[[str], str] = n.design_var_width, design_var_res_length: Callable[[str], str] = n.design_var_length, design_var_res_coupl_length: Callable[[str, str], str] = n.design_var_coupl_length, ) -> List[OptTarget]: """ Create a comprehensive set of optimization targets for a qubit-resonator system. This function combines multiple optimization targets to create a complete optimization strategy for a coupled qubit-resonator system. It allows for selectively including or excluding specific targets based on the design requirements. Args: qubit (Mode): The qubit mode identifier. resonator (Mode): The resonator mode identifier. resonator_coupled_identifier (str): Identifier for the element to which the resonator is coupled (e.g., a feedline or transmission line). opt_target_qubit_freq (bool, optional): Whether to include qubit frequency optimization. Defaults to True. opt_target_qubit_anharm (bool, optional): Whether to include qubit anharmonicity optimization. Defaults to True. opt_target_resonator_freq (bool, optional): Whether to include resonator frequency optimization. Defaults to True. opt_target_resonator_kappa (bool, optional): Whether to include resonator linewidth optimization. Defaults to True. opt_target_resonator_qubit_chi (bool, optional): Whether to include qubit-resonator dispersive shift optimization. Defaults to True. design_var_qubit_lj (Callable, optional): Function to generate the design variable name for qubit Josephson inductance. Defaults to n.design_var_lj. design_var_qubit_width (Callable, optional): Function to generate the design variable name for qubit width. Defaults to n.design_var_width. design_var_res_length (Callable, optional): Function to generate the design variable name for resonator length. Defaults to n.design_var_length. design_var_res_coupl_length (Callable, optional): Function to generate the design variable name for coupling length. Defaults to n.design_var_coupl_length. Returns: List[OptTarget]: A list of optimization targets for the qubit-resonator system. Example: >>> targets = get_opt_targets_qb_res_transmission( ... qubit="qubit_1", ... resonator="resonator_1", ... resonator_coupled_identifier="feedline", ... opt_target_qubit_freq=True, ... opt_target_qubit_anharm=True, ... opt_target_resonator_freq=True, ... opt_target_resonator_kappa=True, ... opt_target_resonator_qubit_chi=True, ... ) >>> len(targets) # Returns 5 if all targets are enabled 5 """ opt_targets = [] if opt_target_qubit_freq: opt_targets.append( get_opt_target_qubit_freq_via_lj( qubit, design_var_qubit_lj=design_var_qubit_lj, design_var_qubit_width=design_var_qubit_width, ) ) if opt_target_qubit_anharm: opt_targets.append( get_opt_target_qubit_anharmonicity_via_capacitance_width( qubit, design_var_qubit_width=design_var_qubit_width ) ) if opt_target_resonator_freq: opt_targets.append( get_opt_target_res_freq_via_length( resonator, design_var_res_length=design_var_res_length, ) ) if opt_target_resonator_kappa: opt_targets.append( get_opt_target_res_kappa_via_coupl_length( resonator, resonator_coupled_identifier, design_var_res_coupl_length=design_var_res_coupl_length, ) ) if opt_target_resonator_qubit_chi: if use_simple_resonator_qubit_chi_relation is True: opt_targets.append( get_opt_target_res_qub_chi_via_coupl_length_simple( qubit, resonator, design_var_res_qb_coupl_length=design_var_res_coupl_length, design_var_qubit_width=design_var_qubit_width, ) ) else: opt_targets.append( get_opt_target_res_qub_chi_via_coupl_length( qubit, resonator, design_var_res_qb_coupl_length=design_var_res_coupl_length, design_var_qubit_width=design_var_qubit_width, ) ) return opt_targets