Skip to content

Flipping amplitude - #1504

Draft
jevillegasd wants to merge 13 commits into
mainfrom
flipping_amplitude
Draft

Flipping amplitude#1504
jevillegasd wants to merge 13 commits into
mainfrom
flipping_amplitude

Conversation

@jevillegasd

Copy link
Copy Markdown
Contributor

This is a 2D sweep for the flipping routine in which a amplitude detuning is used in one axis.

@jevillegasd
jevillegasd requested review from a team May 18, 2026 09:15
@codecov

codecov Bot commented May 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 41.22137% with 77 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.75%. Comparing base (0afd097) to head (89cae79).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
src/qibocal/protocols/flipping_amplitude.py 39.84% 77 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #1504      +/-   ##
==========================================
- Coverage   94.38%   93.75%   -0.64%     
==========================================
  Files         136      137       +1     
  Lines       10673    10803     +130     
==========================================
+ Hits        10074    10128      +54     
- Misses        599      675      +76     
Flag Coverage Δ
unittests 93.75% <41.22%> (-0.64%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/qibocal/protocols/__init__.py 93.87% <100.00%> (+0.26%) ⬆️
src/qibocal/protocols/flipping.py 92.56% <100.00%> (ø)
src/qibocal/protocols/flipping_amplitude.py 39.84% <39.84%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jevillegasd
jevillegasd marked this pull request as draft May 18, 2026 11:22
@sorewachigauyo

Copy link
Copy Markdown
Contributor

Maybe put some separation between the colorbar and the "Best amp"

image

(Don't mind the data, there's an issue on my end that I'm debugging)

@sorewachigauyo

Copy link
Copy Markdown
Contributor

Thanks for this, the fitting seems to work well

image

flipping_2d.tar.gz

I had to hack an implementation for sweepers because there were too many sequences to run for my hardware
If you'd like, I can do the PR for that

@lballerio lballerio left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my PR for this new interesting protocol

Comment on lines +49 to +55
# sequence.append((qd_channel, qd_detuned))

if rx90:
sequence.append((qd_channel, qd_detuned))
sequence.append((qd_channel, qd_detuned))

sequence |= natives.R(theta=np.pi / 2, phi=0.0 if flips % 2 == 0 else np.pi)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should go back to the previous configuration

Comment on lines +24 to +33
nflips_max: int = 21
"""Maximum number of flips ([RX(pi) - RX(pi)] sequences)."""
nflips_step: int = 1
"""Step size for the number of consecutive flips."""
delta_amplitude_min: float = -0.05
"""Minimum amplitude delta relative to the native pulse amplitude."""
delta_amplitude_max: float = 0.05
"""Maximum amplitude delta relative to the native pulse amplitude."""
delta_amplitude_step: float = 0.001
"""Amplitude delta step."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this coice for the default values?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mhhh. 🥇 This is just 10% of the total range in amplitude (assuming a rabi pulse is ~ 0.3, it gives some good variability) and nflips is just a number.

Comment on lines +38 to +47
if not isinstance(self.nflips_max, int):
raise TypeError(
f"nflips_max must be int, got {type(self.nflips_max).__name__}"
)
if not isinstance(self.nflips_step, int):
raise TypeError(
f"nflips_step must be int, got {type(self.nflips_step).__name__}"
)
if not isinstance(self.rx90, bool):
raise TypeError(f"rx90 must be boolean, got {type(self.rx90).__name__}")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this checks can be takes as granted or this params can be recasted

@jevillegasd jevillegasd May 19, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true, this I just copied from flipping but then I can make these pareameters be a subclass of FlippingParameters so that it inherits these checks.

Comment on lines +81 to +82
resonator_type: str
"""Resonator type."""

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
resonator_type: str
"""Resonator type."""

in this protocol is not used at all, can be deleted everywhere

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true this was just me copying old code.

"""

data = FlippingAmplitudeData(
resonator_type=platform.resonator_type,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
resonator_type=platform.resonator_type,

as said before

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

Comment on lines +194 to +199
best_idx = int(np.argmin(variances))
best_amp = float(amplitudes[best_idx])
native_amp = data.pulse_amplitudes[qubit]

best_amplitudes[qubit] = [best_amp, 0.0]
delta_amplitudes[qubit] = [best_amp - native_amp, 0.0]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

computing both best_amplitudes and delta_amplitudes is redundant, I would only use one variable, so we also delete a useless dictionary

even for the amplitude uncertainty I don't know how we can estimate it.

Comment on lines +202 to +203
amplitude=best_amplitudes,
delta_amplitude=delta_amplitudes,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

deduplicate

Comment on lines +220 to +222
def ev(prob: np.ndarray) -> np.ndarray:
"""Helper function to calculate the expectation value."""
return 2 * prob - 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why computing the expectation value of Z?

also I am pretty sure it should be: 1 - 2*prob, since prob is the probability of the qubit being in state 1 and for 1 <Z>=-1.

Comment on lines +228 to +236
# Build 2D probability matrix: rows = amplitude, cols = flips
z = np.full((len(amplitudes), len(flips_vals)), np.nan)
amp_index = {amp: i for i, amp in enumerate(amplitudes)}
flip_index = {fl: j for j, fl in enumerate(flips_vals)}

for row in qubit_data:
i = amp_index[row["amplitude"]]
j = flip_index[row["flips"]]
z[i, j] = ev(row["prob"])

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think a simple reshape should be enough:

Suggested change
# Build 2D probability matrix: rows = amplitude, cols = flips
z = np.full((len(amplitudes), len(flips_vals)), np.nan)
amp_index = {amp: i for i, amp in enumerate(amplitudes)}
flip_index = {fl: j for j, fl in enumerate(flips_vals)}
for row in qubit_data:
i = amp_index[row["amplitude"]]
j = flip_index[row["flips"]]
z[i, j] = ev(row["prob"])
z = qubit_data["prob"].reshape((len(amplitudes), len(flip_vals)))

target,
["Best amplitude [a.u.]", "Delta amplitude [a.u.]"],
[fit.amplitude[target], fit.delta_amplitude[target]],
display_error=True,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here you are displaying a 0.0 error, maybe if we don't know how to estimate the uncertainty at the moment we can neglect displaying error.

Suggested change
display_error=True,
display_error=False,

@lballerio

Copy link
Copy Markdown
Contributor

PS maybe we should also think about new tests.

@lballerio

Copy link
Copy Markdown
Contributor

I had to hack an implementation for sweepers because there were too many sequences to run for my hardware
If you'd like, I can do the PR for that

@sorewachigauyo you mean in a separate PR?
I would avoid opening another PR for such a small implementation, I think without sweepers there is no sense in merging it, so if you want to work on it please coordinate with @jevillegasd and try to work on the same PR.
Also @jevillegasd have you tested it? On which chip?

@jevillegasd

Copy link
Copy Markdown
Contributor Author

Thanks for this, the fitting seems to work well

image [flipping_2d.tar.gz](https://github.com/user-attachments/files/27983285/flipping_2d.tar.gz)

I had to hack an implementation for sweepers because there were too many sequences to run for my hardware If you'd like, I can do the PR for that

Yes please do the PR pointing to this one and we can combine it

@sorewachigauyo sorewachigauyo mentioned this pull request May 22, 2026
5 tasks
Add sweeper support for `flipping_amplitude`
@lballerio

Copy link
Copy Markdown
Contributor

Hi @jevillegasd, I've just merged the sweeper implementation of the flipping_amplitude experiment.
Now we can do the detailed review and if you want to test it more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants