Skip to content

Fix sudden_net_zero amp_B and integral (#310, QAE-808)

Issue

The pre-existing test_sudden_net_zero passes obviously. This is it for reference:

image

where the waveform is

image

However, it has two flaws that emerge whenever t_pulse/t_phi/t_integral_correction are not integer multiples of the sample rate.

Inexact 0 integral

This will make the test fail: times = np.arange(0, 40e-9, 0.9e-9). The problem can be traced to these lines in sudden_net_zero:

sampling_rate = t[1] - t[0]

num_corr_samples = t_integral_correction / sampling_rate

corr_amp = -np.sum(waveform_amps) / num_corr_samples

The intention there is to spread the non-zero integral on an integer number of points in an exact manner. However, num_corr_samples is not an integer in general.

Silent amp_B

In this case the test does not fail but amp_B won't be used without raising any flag. For example, setting t_pulse=20.1e-9 gives the waveform

image

but also times = np.arange(0, 40e-9, 0.9e-9) leads to this behaviour before making the test fail for the other reason:

image

Even only the second amp_B can be made to be silent using t_phi=2.1e-9:

image

The problem is related to the use of np.heaviside(t0, amp_at_t0). Amp_B is used only if a point in the time array matches exactly t0, but in general this doesn't happen (in particular, in a realistic scenario t_pulse will be a real number and not a multiple of the sample rate).

Asymmetry of pulse

Additionally, I've noticed that the second half may contain one sample less or more than the first depending on the ratios of sample rate and t_pulse/t_phi. This is physically not acceptable since it leads to a significant asymmetry of the beamsplitters and will cause leakage.

Pulse may be chopped without flags

Currently if for example times = np.arange(0, 40e-9, 1e-9) and t_pulse+t_phi+t_correction=50e-9, the last 10e-9 get chopped off and the user won't notice in general.

Explanation of changes

I have performed a severe rewriting of the waveform. Now everything is based on the sample rate. The various pieces of the waveform are constructed one after the other as exact number of samples and then concatenated. If max(t) is too little compared to the total pulse duration, I've added an assert that will let the user know that.

Furthermore, I have put non-simple numbers in the test and I've added two assert clauses to check that amp_B is used in both sides of the pulse

Motivation of changes

The severe rewriting is due to the fact that the use of np.heaviside in the previous construction did not allow for ensuring the use of amp_B nor the simmetry and I did not see a simple workaround.

Closes #310 (closed)


Merge checklist

See also merge request guidelines

  • Merge request has been reviewed (in-depth by a knowledgeable contributor), and is approved by a project maintainer.
  • New code is covered by unit tests (or N/A).
  • New code is documented and docstrings use numpydoc format (or N/A).
  • New functionality: considered making private instead of extending public API (or N/A).
  • Public API changed: added @deprecated (or N/A).
  • Tested on hardware (or N/A).
  • CHANGELOG.md and AUTHORS.md have been updated (or N/A).
  • Windows tests in CI pipeline pass (manually triggered by maintainers before merging).

For reference, the issues workflow is described in the contribution guidelines.

Edited by Edgar Reehuis

Merge request reports