Skip to content

Commit

Permalink
feat: Fixed qubit crosstalk
Browse files Browse the repository at this point in the history
  • Loading branch information
andrea-pasquale committed May 16, 2024
1 parent 5f06538 commit c10e513
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,8 @@ class QubitCrosstalkParameters(QubitFluxParameters):
class QubitCrosstalkData(QubitFluxData):
"""Crosstalk acquisition outputs when ``flux_qubits`` are given."""

sweetspot: dict[QubitId, float] = field(default_factory=dict)
offset: dict[QubitId, float] = field(default_factory=dict)
"""Sweetspot for each qubit."""
d: dict[QubitId, float] = field(default_factory=dict)
"""Asymmetry for each qubit."""
voltage: dict[QubitId, float] = field(default_factory=dict)
"""Voltage applied to each flux line."""
matrix_element: dict[QubitId, float] = field(default_factory=dict)
"""Diagonal crosstalk matrix element."""
qubit_frequency: dict[QubitId, float] = field(default_factory=dict)
Expand All @@ -72,6 +68,7 @@ def register_qubit(self, qubit, flux_qubit, freq, bias, signal, phase):
def diagonal(self) -> Optional[QubitFluxData]:
instance = QubitFluxData(
resonator_type=self.resonator_type,
charging_energy=self.charging_energy,
qubit_frequency=self.qubit_frequency,
)
for qubit in self.qubits:
Expand All @@ -86,7 +83,7 @@ def diagonal(self) -> Optional[QubitFluxData]:
return instance
return QubitFluxData(
resonator_type=self.resonator_type,
qubit_frequency=self.qubit_frequency,
charging_energy=self.charging_energy,
)


Expand Down Expand Up @@ -117,20 +114,21 @@ def _acquisition(
sequence = PulseSequence()
ro_pulses = {}
qd_pulses = {}
sweetspots = {}
d = {}
voltage = {}
offset = {}
charging_energy = {}
matrix_element = {}
qubit_frequency = {}
for qubit in targets:
qubit_frequency[qubit] = platform.qubits[qubit].drive_frequency

charging_energy[qubit] = -platform.qubits[qubit].anharmonicity
qd_pulses[qubit] = platform.create_qubit_drive_pulse(
qubit, start=0, duration=params.drive_duration
)
try:
d[qubit] = platform.qubits[qubit].asymmetry
qubit_frequency[qubit] = platform.qubits[qubit].drive_frequency
matrix_element[qubit] = platform.qubits[qubit].crosstalk_matrix[qubit]
sweetspots[qubit] = voltage[qubit] = platform.qubits[qubit].sweetspot
offset[qubit] = -platform.qubits[qubit].sweetspot * matrix_element[qubit]

except KeyError:
log.warning(f"Missing flux parameters for qubit {qubit}.")

Expand Down Expand Up @@ -181,11 +179,10 @@ def _acquisition(

data = QubitCrosstalkData(
resonator_type=platform.resonator_type,
sweetspot=sweetspots,
voltage=voltage,
offset=offset,
matrix_element=matrix_element,
d=d,
qubit_frequency=qubit_frequency,
charging_energy=charging_energy,
)

options = ExecutionParameters(
Expand Down Expand Up @@ -220,8 +217,7 @@ def _fit(data: QubitCrosstalkData) -> QubitCrosstalkResults:
crosstalk_matrix = {qubit: {} for qubit in data.qubit_frequency}
fitted_parameters = {}

voltage = {}
asymmetry = {}
# voltage = {}
sweetspot = {}
matrix_element = {}
qubit_frequency = {}
Expand All @@ -230,8 +226,6 @@ def _fit(data: QubitCrosstalkData) -> QubitCrosstalkResults:

for qubit in data.qubits:
condition = qubit in diagonal
voltage[qubit] = diagonal.sweetspot[qubit] if condition else data.voltage[qubit]
asymmetry[qubit] = diagonal.asymmetry[qubit] if condition else data.d[qubit]
sweetspot[qubit] = (
diagonal.sweetspot[qubit] if condition else data.sweetspot[qubit]
)
Expand All @@ -257,12 +251,13 @@ def _fit(data: QubitCrosstalkData) -> QubitCrosstalkResults:
# at runtime
def fit_function(x, crosstalk_element):
return utils.transmon_frequency(
xi=voltage[target_qubit],
xi=sweetspot[target_qubit],
xj=x,
d=0,
w_max=qubit_frequency[target_qubit] * HZ_TO_GHZ,
d=asymmetry[target_qubit],
sweetspot=sweetspot[target_qubit],
matrix_element=matrix_element[target_qubit],
offset=-sweetspot[target_qubit] * matrix_element[target_qubit],
scaling=matrix_element[target_qubit],
charging_energy=data.charging_energy[target_qubit] * HZ_TO_GHZ,
crosstalk_element=crosstalk_element,
)

Expand All @@ -273,13 +268,14 @@ def fit_function(x, crosstalk_element):
frequencies * HZ_TO_GHZ,
bounds=(-np.inf, np.inf),
)

print(popt)
fitted_parameters[target_qubit, flux_qubit] = dict(
xi=voltage[target_qubit],
w_max=qubit_frequency[target_qubit],
d=asymmetry[target_qubit],
sweetspot=sweetspot[target_qubit],
matrix_element=matrix_element[target_qubit],
xi=sweetspot[target_qubit],
d=0,
w_max=qubit_frequency[target_qubit] * HZ_TO_GHZ,
offset=-sweetspot[target_qubit] * matrix_element[target_qubit],
scaling=matrix_element[target_qubit],
charging_energy=data.charging_energy[target_qubit] * HZ_TO_GHZ,
crosstalk_element=float(popt),
)
crosstalk_matrix[target_qubit][flux_qubit] = float(popt)
Expand All @@ -297,7 +293,6 @@ def fit_function(x, crosstalk_element):
return QubitCrosstalkResults(
frequency=qubit_frequency,
sweetspot=sweetspot,
asymmetry=asymmetry,
matrix_element=matrix_element,
crosstalk_matrix=crosstalk_matrix,
fitted_parameters=fitted_parameters,
Expand All @@ -310,11 +305,10 @@ def _plot(data: QubitCrosstalkData, fit: QubitCrosstalkResults, target: QubitId)
data, target, fit, fit_function=utils.transmon_frequency
)
if fit is not None:
labels = ["Sweetspot [V]", "Qubit Frequency at Sweetspot [Hz]", "Asymmetry d"]
labels = ["Sweetspot [V]", "Qubit Frequency at Sweetspot [Hz]"]
values = [
np.round(fit.sweetspot[target], 4),
np.round(fit.frequency[target], 4),
np.round(fit.asymmetry[target], 4),
]
for flux_qubit in fit.crosstalk_matrix[target]:
if flux_qubit != target:
Expand All @@ -336,7 +330,6 @@ def _update(results: QubitCrosstalkResults, platform: Platform, qubit: QubitId):
"""Update crosstalk matrix."""
update.drive_frequency(results.frequency[qubit], platform, qubit)
update.sweetspot(results.sweetspot[qubit], platform, qubit)
update.asymmetry(results.asymmetry[qubit], platform, qubit)
for flux_qubit, element in results.crosstalk_matrix[qubit].items():
update.crosstalk_matrix(element, platform, qubit, flux_qubit)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,10 @@ class QubitFluxData(Data):
resonator_type: str
"""Resonator type."""

qubit_frequency: dict[QubitId, float] = field(default_factory=dict)
"""Qubit frequencies."""

offset: dict[QubitId, float] = field(default_factory=dict)
"""Qubit bias offset."""

charging_energy: dict[QubitId, float] = field(default_factory=dict)
"""Qubit charging energy."""

qubit_frequency: dict[QubitId, float] = field(default_factory=dict)
"""Qubit charging energy."""
data: dict[QubitId, npt.NDArray[QubitFluxType]] = field(default_factory=dict)
"""Raw data acquired."""

Expand All @@ -98,7 +93,6 @@ def _acquisition(
ro_pulses = {}
qd_pulses = {}
qubit_frequency = {}
offset = {}
for qubit in targets:
qd_pulses[qubit] = platform.create_qubit_drive_pulse(
qubit, start=0, duration=params.drive_duration
Expand Down Expand Up @@ -149,7 +143,7 @@ def _acquisition(
charging_energy={
qubit: -platform.qubits[qubit].anharmonicity for qubit in targets
},
offset=offset,
qubit_frequency=qubit_frequency,
)
options = ExecutionParameters(
nshots=params.nshots,
Expand Down Expand Up @@ -217,6 +211,7 @@ def fit_function(x, w_max, scaling, offset):
),
maxfev=100000,
)[0]
print(popt[1])
fitted_parameters[qubit] = {
"w_max": popt[0],
"xj": 0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ def flux_crosstalk_plot(data, qubit, fit, fit_function):
go.Scatter(
x=fit_function(
xj=qubit_data.bias, **fit.fitted_parameters[flux_qubit]
)
* HZ_TO_GHZ,
),
y=qubit_data.bias,
showlegend=not any(
isinstance(trace, go.Scatter) for trace in fig.data
Expand All @@ -157,9 +156,9 @@ def flux_crosstalk_plot(data, qubit, fit, fit_function):
diagonal_params = fit.fitted_parameters[qubit, qubit]
fig.add_trace(
go.Scatter(
x=globals().get(fit_function.__name__ + "_diagonal")(
x=fit_function(
qubit_data.bias,
*diagonal_params,
**diagonal_params,
),
y=qubit_data.bias,
showlegend=not any(
Expand Down

0 comments on commit c10e513

Please sign in to comment.