Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions library/src/tests/resources/src/state_preparation.qs
Original file line number Diff line number Diff line change
Expand Up @@ -124,4 +124,14 @@ namespace Test {
}
}

operation TestControlledPreparation() : Unit {
use qs = Qubit[2];
let coeffs = [0.5, 0.5, 0.5, 0.5];
use c = Qubit();
H(c);
Controlled Std.StatePreparation.PreparePureStateD([c], (coeffs, qs));
Std.Diagnostics.DumpMachine();
ResetAll(qs + [c]);
}

}
19 changes: 19 additions & 0 deletions library/src/tests/state_preparation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,3 +307,22 @@ fn check_uniform_superposition_invalid_state_count() {

expect!["program failed: Number of basis states must be positive."].assert_eq(&out);
}

#[test]
fn check_controlled_state_preparation() {
let out = test_expression_with_lib(
"Test.TestControlledPreparation()",
STATE_PREPARATION_TEST_LIB,
&Value::Tuple(vec![].into(), None),
);

expect![[r#"
STATE:
|000⟩: 0.7071+0.0000𝑖
|001⟩: 0.3536+0.0000𝑖
|011⟩: 0.3536+0.0000𝑖
|101⟩: 0.3536+0.0000𝑖
|111⟩: 0.3536+0.0000𝑖
"#]]
.assert_eq(&out);
}
4 changes: 3 additions & 1 deletion library/std/src/Std/StatePreparation.qs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import
Std.Arithmetic.ApplyIfGreaterLE,
Std.Arithmetic.ApplyIfGreaterL,
Std.Arithmetic.ReflectAboutInteger,
Std.ArithmeticUtils.ApplyAsSinglyControlled,
Std.Convert.IntAsBigInt,
Std.Math.*,
Std.Arrays.*;
Expand Down Expand Up @@ -351,7 +352,8 @@ operation ApproximatelyMultiplexZ(
ApproximatelyMultiplexZ(tolerance, coefficients0, control, target);
if AnyOutsideToleranceD(tolerance, coefficients1) {
within {
Controlled X(controlRegister, target);
// Reduce circuit complexity by using aux qubits.
Controlled ApplyAsSinglyControlled(controlRegister, (X, target));
Copy link
Member

Choose a reason for hiding this comment

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

One can still save a factor of 2x by only doing the forward direction of the multi-controlled X gate (chain of computing ANDs) and then the backward direction (chain of uncomputing ANDs) afterwards. However, this will require to allocate the helper qubits in this operation.

For a 3-qubit controlRegister the trace would be as follows:

use helper = Qubit[1];

And(controlRegister[0], controlRegister[1], helper[0]);
And(controlRegister[1], helper[0], target);

ApproximatelyMultiplexZ(tolerance, coefficients1, control, target);

Adjoint And(controlRegister[1], helper[0], target);
Adjoint And(controlRegister[0], controlRegister[1], helper[0]);

} apply {
ApproximatelyMultiplexZ(tolerance, coefficients1, control, target);
}
Expand Down
Loading