8
8
MixedStatePreparation,
9
9
MixedStatePreparationRequirements,
10
10
PurifiedMixedState,
11
- ObliviousAmplitudeAmplificationFromStatePreparation,
12
- ObliviousAmplitudeAmplificationFromPartialReflections,
13
- ApplyObliviousAmplitudeAmplification,
14
11
PurifiedMixedStateRequirements,
15
12
BlockEncodingByLCU,
16
13
QuantumWalkByQubitization,
@@ -27,6 +24,7 @@ import Std.Math.*;
27
24
import Std.Convert.IntAsDouble;
28
25
import Std.Arithmetic.ApplyIfGreaterLE;
29
26
import Std.StatePreparation.PreparePureStateD;
27
+ import Std.StatePreparation.PrepareUniformSuperposition;
30
28
import Std.Diagnostics.Fact;
31
29
import Utils.GeneratorIndex;
32
30
import Utils.GeneratorSystem;
@@ -628,207 +626,6 @@ operation PrepareQuantumROMState(
628
626
}
629
627
}
630
628
631
- /// # Summary
632
- /// Creates a uniform superposition over states that encode 0 through `nIndices - 1`.
633
- ///
634
- /// # Description
635
- ///
636
- /// This operation can be described by a unitary matrix $U$ that creates
637
- /// a uniform superposition over all number states
638
- /// $0$ to $M-1$, given an input state $\ket{0\cdots 0}$. In other words,
639
- /// $$
640
- /// \begin{align}
641
- /// U \ket{0} = \frac{1}{\sqrt{M}} \sum_{j=0}^{M - 1} \ket{j}.
642
- /// \end{align}
643
- /// $$.
644
- ///
645
- /// # Input
646
- /// ## nIndices
647
- /// The desired number of states $M$ in the uniform superposition.
648
- /// ## indexRegister
649
- /// The qubit register that stores the number states in `LittleEndian` format.
650
- /// This register must be able to store the number $M-1$, and is assumed to be
651
- /// initialized in the state $\ket{0\cdots 0}$.
652
- ///
653
- /// # Remarks
654
- /// The operation is adjointable, but requires that `indexRegister` is in a uniform
655
- /// superposition over the first `nIndices` basis states in that case.
656
- ///
657
- /// # Example
658
- /// The following example prepares the state $\frac{1}{\sqrt{6}}\sum_{j=0}^{5}\ket{j}$
659
- /// on $3$ qubits.
660
- /// ``` Q#
661
- /// let nIndices = 6;
662
- /// using(indexRegister = Qubit[3]) {
663
- /// PrepareUniformSuperposition(nIndices, LittleEndian(indexRegister));
664
- /// // ...
665
- /// }
666
- /// ```
667
- operation PrepareUniformSuperposition(nIndices : Int , indexRegister : Qubit []) : Unit is Adj + Ctl {
668
- if nIndices == 0 {
669
- fail "Cannot prepare uniform superposition over 0 basis states." ;
670
- } elif nIndices == 1 {
671
- // Superposition over one state, so do nothing.
672
- } elif nIndices == 2 {
673
- H(indexRegister[0]);
674
- } else {
675
- let nQubits = BitSizeI(nIndices - 1);
676
- if nQubits > Length(indexRegister) {
677
- fail $"Cannot prepare uniform superposition over {nIndices} states as it is larger than the qubit register." ;
678
- }
679
-
680
- use flagQubit = Qubit [3];
681
- let targetQubits = indexRegister[0.. nQubits - 1];
682
- let qubits = flagQubit + targetQubits;
683
- let stateOracle = PrepareUniformSuperpositionOracle(nIndices, nQubits, 0, _);
684
-
685
- let phases = ([0.0, PI()], [PI(), 0.0]);
686
-
687
- ObliviousAmplitudeAmplificationFromStatePreparation(
688
- phases,
689
- stateOracle,
690
- (qs0, qs1) => I(qs0[0]),
691
- 0
692
- )(qubits, []);
693
-
694
-
695
- ApplyToEachCA(X, flagQubit);
696
- }
697
- }
698
-
699
- function ObliviousAmplitudeAmplificationFromStatePreparation(
700
- phases : (Double [], Double []),
701
- startStateOracle : Qubit [] => Unit is Adj + Ctl ,
702
- signalOracle : (Qubit [], Qubit []) => Unit is Adj + Ctl ,
703
- idxFlagQubit : Int
704
- ) : (Qubit [], Qubit []) => Unit is Adj + Ctl {
705
- let startStateReflection = (phase, qs) => {
706
- within {
707
- ApplyToEachCA(X, qs);
708
- } apply {
709
- Controlled R1(Rest(qs), (phase, qs[0]));
710
- }
711
- };
712
- let targetStateReflection = (phase, qs) => R1(phase, qs[idxFlagQubit]);
713
- let obliviousSignalOracle = (qs0, qs1) => { startStateOracle(qs0); signalOracle(qs0, qs1); };
714
- return ObliviousAmplitudeAmplificationFromPartialReflections(
715
- phases,
716
- startStateReflection,
717
- targetStateReflection,
718
- obliviousSignalOracle
719
- );
720
- }
721
-
722
- function ObliviousAmplitudeAmplificationFromPartialReflections(
723
- phases : (Double [], Double []),
724
- startStateReflection : (Double , Qubit []) => Unit is Adj + Ctl ,
725
- targetStateReflection : (Double , Qubit []) => Unit is Adj + Ctl ,
726
- signalOracle : (Qubit [], Qubit []) => Unit is Adj + Ctl
727
- ) : (Qubit [], Qubit []) => Unit is Adj + Ctl {
728
- return ApplyObliviousAmplitudeAmplification(
729
- phases,
730
- startStateReflection,
731
- targetStateReflection,
732
- signalOracle,
733
- _,
734
- _
735
- );
736
- }
737
-
738
- /// # Summary
739
- /// Oblivious amplitude amplification by specifying partial reflections.
740
- ///
741
- /// # Input
742
- /// ## phases
743
- /// Phases of partial reflections
744
- /// ## startStateReflection
745
- /// Reflection operator about start state of auxiliary register
746
- /// ## targetStateReflection
747
- /// Reflection operator about target state of auxiliary register
748
- /// ## signalOracle
749
- /// Unitary oracle $O$ of type `ObliviousOracle` that acts jointly on the
750
- /// auxiliary and system registers.
751
- /// ## auxiliaryRegister
752
- /// Auxiliary register
753
- /// ## systemRegister
754
- /// System register
755
- ///
756
- /// # Remarks
757
- /// Given a particular auxiliary start state $\ket{\text{start}}\_a$, a
758
- /// particular auxiliary target state $\ket{\text{target}}\_a$, and any
759
- /// system state $\ket{\psi}\_s$, suppose that
760
- /// \begin{align}
761
- /// O\ket{\text{start}}\_a\ket{\psi}\_s= \lambda\ket{\text{target}}\_a U \ket{\psi}\_s + \sqrt{1-|\lambda|^2}\ket{\text{target}^\perp}\_a\cdots
762
- /// \end{align}
763
- /// for some unitary $U$.
764
- /// By a sequence of reflections about the start and target states on the
765
- /// auxiliary register interleaved by applications of `signalOracle` and its
766
- /// adjoint, the success probability of applying $U$ may be altered.
767
- ///
768
- /// In most cases, `auxiliaryRegister` is initialized in the state $\ket{\text{start}}\_a$.
769
- ///
770
- /// # References
771
- /// - See [*D.W. Berry, A.M. Childs, R. Cleve, R. Kothari, R.D. Somma*](https://arxiv.org/abs/1312.1414)
772
- /// for the standard version.
773
- /// - See [*G.H. Low, I.L. Chuang*](https://arxiv.org/abs/1610.06546)
774
- /// for a generalization to partial reflections.
775
- operation ApplyObliviousAmplitudeAmplification(
776
- phases : (Double [], Double []),
777
- startStateReflection : (Double , Qubit []) => Unit is Adj + Ctl ,
778
- targetStateReflection : (Double , Qubit []) => Unit is Adj + Ctl ,
779
- signalOracle : (Qubit [], Qubit []) => Unit is Adj + Ctl ,
780
- auxiliaryRegister : Qubit [],
781
- systemRegister : Qubit []
782
- ) : Unit is Adj + Ctl {
783
- let (aboutStart, aboutTarget) = phases;
784
- Fact(Length(aboutStart) == Length(aboutTarget), "number of phases about start and target state must be equal" );
785
- let numPhases = Length(aboutStart);
786
-
787
- for idx in 0.. numPhases- 1 {
788
- if aboutStart[idx] != 0.0 {
789
- startStateReflection(aboutStart[idx], auxiliaryRegister);
790
- }
791
-
792
- if aboutTarget[idx] != 0.0 {
793
- // In the last iteration we do not need to apply `Adjoint signalOracle`
794
- if idx == numPhases - 1 {
795
- signalOracle(auxiliaryRegister, systemRegister);
796
- targetStateReflection(aboutTarget[idx], auxiliaryRegister);
797
- } else {
798
- within {
799
- signalOracle(auxiliaryRegister, systemRegister);
800
- } apply {
801
- targetStateReflection(aboutTarget[idx], auxiliaryRegister);
802
- }
803
- }
804
- }
805
- }
806
-
807
- // We do need one more `signalOracle` call, if the last phase about the target state was 0.0
808
- if numPhases == 0 or aboutTarget[numPhases - 1] == 0.0 {
809
- signalOracle(auxiliaryRegister, systemRegister);
810
- }
811
- }
812
-
813
- operation PrepareUniformSuperpositionOracle(nIndices : Int , nQubits : Int , idxFlag : Int , qubits : Qubit []) : Unit is Adj + Ctl {
814
- let targetQubits = qubits[3... ];
815
- let flagQubit = qubits[0];
816
- let auxillaryQubits = qubits[1.. 2];
817
- let theta = ArcSin(Sqrt(IntAsDouble(2^ nQubits) / IntAsDouble(nIndices)) * Sin(PI() / 6.0));
818
-
819
- ApplyToEachCA(H, targetQubits);
820
- use compareQubits = Qubit [nQubits] {
821
- within {
822
- ApplyXorInPlace(nIndices - 1, compareQubits);
823
- } apply {
824
- ApplyIfGreaterLE(X, targetQubits, compareQubits, auxillaryQubits[0]);
825
- X(auxillaryQubits[0]);
826
- }
827
- }
828
- Ry(2.0 * theta, auxillaryQubits[1]);
829
- (Controlled X)(auxillaryQubits, flagQubit);
830
- }
831
-
832
629
// Classical processing
833
630
// This discretizes the coefficients such that
834
631
// |coefficient[i] * oneNorm - discretizedCoefficient[i] * discretizedOneNorm| * nCoeffs <= 2^{1-bitsPrecision}.
0 commit comments