Skip to content

Commit b9328d1

Browse files
DmitryVasilevskyDmitry Vasilevsky
and
Dmitry Vasilevsky
authored
Some cleanup of chemistry library (#2158)
Redundant code removed (Especially state preparation and LE comparison), some renames, some cleanup of old syntax. Added test for superposition preparation. --------- Co-authored-by: Dmitry Vasilevsky <[email protected]>
1 parent f4bc094 commit b9328d1

9 files changed

+78
-735
lines changed

library/chemistry/src/JordanWigner/Convenience.qs

+15-20
Original file line numberDiff line numberDiff line change
@@ -12,23 +12,21 @@ import JordanWigner.JordanWignerEvolutionSet.JordanWignerGeneratorSystem;
1212
import JordanWigner.JordanWignerOptimizedBlockEncoding.JordanWignerOptimizedBlockEncoding;
1313
import JordanWigner.JordanWignerOptimizedBlockEncoding.PauliBlockEncoding;
1414
import JordanWigner.JordanWignerOptimizedBlockEncoding.QuantumWalkByQubitization;
15-
import JordanWigner.StatePreparation.PrepareArbitraryStateD;
1615
import JordanWigner.Utils.JordanWignerEncodingData;
1716
import JordanWigner.Utils.MultiplexOperationsFromGenerator;
1817
import JordanWigner.Utils.TrotterSimulationAlgorithm;
1918
import Std.Convert.IntAsDouble;
2019
import Std.Math.Ceiling;
2120
import Std.Math.Lg;
2221
import Utils.EvolutionGenerator;
23-
import Utils.GeneratorSystem;
2422

2523
// Convenience functions for performing simulation.
2624

2725
/// # Summary
2826
/// Returns Trotter step operation and the parameters necessary to run it.
2927
///
3028
/// # Input
31-
/// ## qSharpData
29+
/// ## jwHamiltonian
3230
/// Hamiltonian described by `JordanWignerEncodingData` format.
3331
/// ## trotterStepSize
3432
/// Step size of Trotter integrator.
@@ -39,24 +37,22 @@ import Utils.GeneratorSystem;
3937
/// A tuple where: `Int` is the number of qubits allocated,
4038
/// `Double` is `1.0/trotterStepSize`, and the operation
4139
/// is the Trotter step.
42-
function TrotterStepOracle(qSharpData : JordanWignerEncodingData, trotterStepSize : Double, trotterOrder : Int) : (Int, (Double, (Qubit[] => Unit is Adj + Ctl))) {
43-
let (nSpinOrbitals, data, statePrepData, energyShift) = qSharpData!;
44-
let generatorSystem = JordanWignerGeneratorSystem(data);
40+
function TrotterStepOracle(jwHamiltonian : JordanWignerEncodingData, trotterStepSize : Double, trotterOrder : Int) : (Int, (Double, (Qubit[] => Unit is Adj + Ctl))) {
41+
let generatorSystem = JordanWignerGeneratorSystem(jwHamiltonian.Terms);
4542
let evolutionGenerator = new EvolutionGenerator { EvolutionSet = JordanWignerFermionEvolutionSet(), System = generatorSystem };
4643
let simulationAlgorithm = TrotterSimulationAlgorithm(trotterStepSize, trotterOrder);
4744
let oracle = simulationAlgorithm(trotterStepSize, evolutionGenerator, _);
48-
let nTargetRegisterQubits = nSpinOrbitals;
45+
let nTargetRegisterQubits = jwHamiltonian.NumQubits;
4946
let rescaleFactor = 1.0 / trotterStepSize;
5047
return (nTargetRegisterQubits, (rescaleFactor, oracle));
5148
}
5249

5350

54-
function QubitizationOracleSeperatedRegisters(qSharpData : JordanWignerEncodingData) : ((Int, Int), (Double, ((Qubit[], Qubit[]) => Unit is Adj + Ctl))) {
55-
let (nSpinOrbitals, data, statePrepData, energyShift) = qSharpData!;
56-
let generatorSystem = JordanWignerBlockEncodingGeneratorSystem(data);
51+
function QubitizationOracleSeperatedRegisters(jwHamiltonian : JordanWignerEncodingData) : ((Int, Int), (Double, ((Qubit[], Qubit[]) => Unit is Adj + Ctl))) {
52+
let generatorSystem = JordanWignerBlockEncodingGeneratorSystem(jwHamiltonian.Terms);
5753
let (nTerms, genIdxFunction) = generatorSystem!;
5854
let (oneNorm, blockEncodingReflection) = PauliBlockEncoding(generatorSystem);
59-
let nTargetRegisterQubits = nSpinOrbitals;
55+
let nTargetRegisterQubits = jwHamiltonian.NumQubits;
6056
let nCtrlRegisterQubits = Ceiling(Lg(IntAsDouble(nTerms)));
6157
return ((nCtrlRegisterQubits, nTargetRegisterQubits), (oneNorm, QuantumWalkByQubitization(blockEncodingReflection)));
6258
}
@@ -65,15 +61,15 @@ function QubitizationOracleSeperatedRegisters(qSharpData : JordanWignerEncodingD
6561
/// Returns Qubitization operation and the parameters necessary to run it.
6662
///
6763
/// # Input
68-
/// ## qSharpData
64+
/// ## jwHamiltonian
6965
/// Hamiltonian described by `JordanWignerEncodingData` format.
7066
///
7167
/// # Output
7268
/// A tuple where: `Int` is the number of qubits allocated,
7369
/// `Double` is the one-norm of Hamiltonian coefficients, and the operation
7470
/// is the Quantum walk created by Qubitization.
75-
function QubitizationOracle(qSharpData : JordanWignerEncodingData) : (Int, (Double, (Qubit[] => Unit is Adj + Ctl))) {
76-
let ((nCtrlRegisterQubits, nTargetRegisterQubits), (oneNorm, oracle)) = QubitizationOracleSeperatedRegisters(qSharpData);
71+
function QubitizationOracle(jwHamiltonian : JordanWignerEncodingData) : (Int, (Double, (Qubit[] => Unit is Adj + Ctl))) {
72+
let ((nCtrlRegisterQubits, nTargetRegisterQubits), (oneNorm, oracle)) = QubitizationOracleSeperatedRegisters(jwHamiltonian);
7773
let nQubits = nCtrlRegisterQubits + nTargetRegisterQubits;
7874
return (nQubits, (oneNorm, MergeTwoRegisters(oracle, nTargetRegisterQubits, _)));
7975
}
@@ -84,9 +80,8 @@ operation MergeTwoRegisters(oracle : ((Qubit[], Qubit[]) => Unit is Adj + Ctl),
8480
}
8581

8682

87-
function OptimizedQubitizationOracleSeperatedRegisters(qSharpData : JordanWignerEncodingData, targetError : Double) : ((Int, Int), (Double, ((Qubit[], Qubit[]) => Unit is Adj + Ctl))) {
88-
let (nSpinOrbitals, data, statePrepData, energyShift) = qSharpData!;
89-
let ((nCtrlRegisterQubits, nTargetRegisterQubits), (oneNorm, blockEncodingReflection)) = JordanWignerOptimizedBlockEncoding(targetError, data, nSpinOrbitals);
83+
function OptimizedQubitizationOracleSeperatedRegisters(jwHamiltonian : JordanWignerEncodingData, targetError : Double) : ((Int, Int), (Double, ((Qubit[], Qubit[]) => Unit is Adj + Ctl))) {
84+
let ((nCtrlRegisterQubits, nTargetRegisterQubits), (oneNorm, blockEncodingReflection)) = JordanWignerOptimizedBlockEncoding(targetError, jwHamiltonian.Terms, jwHamiltonian.NumQubits);
9085
return ((nCtrlRegisterQubits, nTargetRegisterQubits), (oneNorm, QuantumWalkByQubitization(blockEncodingReflection)));
9186
}
9287

@@ -96,7 +91,7 @@ function OptimizedQubitizationOracleSeperatedRegisters(qSharpData : JordanWigner
9691
/// and the parameters necessary to run it.
9792
///
9893
/// # Input
99-
/// ## qSharpData
94+
/// ## jwHamiltonian
10095
/// Hamiltonian described by `JordanWignerEncodingData` format.
10196
/// ## targetError
10297
/// Error of auxillary state preparation step.
@@ -105,8 +100,8 @@ function OptimizedQubitizationOracleSeperatedRegisters(qSharpData : JordanWigner
105100
/// A tuple where: `Int` is the number of qubits allocated,
106101
/// `Double` is the one-norm of Hamiltonian coefficients, and the operation
107102
/// is the Quantum walk created by Qubitization.
108-
function OptimizedQubitizationOracle(qSharpData : JordanWignerEncodingData, targetError : Double) : (Int, (Double, (Qubit[] => Unit is Adj + Ctl))) {
109-
let ((nCtrlRegisterQubits, nTargetRegisterQubits), (oneNorm, oracle)) = OptimizedQubitizationOracleSeperatedRegisters(qSharpData, targetError);
103+
function OptimizedQubitizationOracle(jwHamiltonian : JordanWignerEncodingData, targetError : Double) : (Int, (Double, (Qubit[] => Unit is Adj + Ctl))) {
104+
let ((nCtrlRegisterQubits, nTargetRegisterQubits), (oneNorm, oracle)) = OptimizedQubitizationOracleSeperatedRegisters(jwHamiltonian, targetError);
110105
let nQubits = nCtrlRegisterQubits + nTargetRegisterQubits;
111106
return (nQubits, (oneNorm, MergeTwoRegisters(oracle, nTargetRegisterQubits, _)));
112107
}

library/chemistry/src/JordanWigner/ConvenienceVQE.qs

-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import JordanWigner.StatePreparation.PrepareTrialState;
1313
import JordanWigner.Utils.JordanWignerEncodingData;
1414
import JordanWigner.Utils.JordanWignerInputState;
1515
import JordanWigner.Utils.JWOptimizedHTerms;
16-
import Std.Arrays.ForEach;
1716

1817
/// # Summary
1918
/// Estimates the energy of the molecule by summing the energy contributed by the individual Jordan-Wigner terms.

library/chemistry/src/JordanWigner/JordanWignerBlockEncoding.qs

+15-15
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ import Utils.IsNotZero;
3636
/// # Output
3737
/// `GeneratorIndex[]` expressing Z term as Pauli terms.
3838
function ZTermToPauliGenIdx(term : GeneratorIndex) : GeneratorIndex[] {
39-
let ((idxTermType, coeff), idxFermions) = term!;
40-
return [new GeneratorIndex { Term = ([3], coeff), Subsystem = idxFermions }];
39+
let (_, coeff) = term.Term;
40+
return [new GeneratorIndex { Term = ([3], coeff), Subsystem = term.Subsystem }];
4141
}
4242

4343
/// # Summary
@@ -51,8 +51,8 @@ function ZTermToPauliGenIdx(term : GeneratorIndex) : GeneratorIndex[] {
5151
/// # Output
5252
/// `GeneratorIndex[]` expressing ZZ term as Pauli terms.
5353
function ZZTermToPauliGenIdx(term : GeneratorIndex) : GeneratorIndex[] {
54-
let ((idxTermType, coeff), idxFermions) = term!;
55-
return [new GeneratorIndex { Term = ([3, 3], coeff), Subsystem = idxFermions }];
54+
let (_, coeff) = term.Term;
55+
return [new GeneratorIndex { Term = ([3, 3], coeff), Subsystem = term.Subsystem }];
5656
}
5757

5858
/// # Summary
@@ -66,10 +66,10 @@ function ZZTermToPauliGenIdx(term : GeneratorIndex) : GeneratorIndex[] {
6666
/// # Output
6767
/// `GeneratorIndex[]` expressing PQ term as Pauli terms.
6868
function PQTermToPauliGenIdx(term : GeneratorIndex) : GeneratorIndex[] {
69-
let ((idxTermType, coeff), idxFermions) = term!;
69+
let (_, coeff) = term.Term;
7070
let newCoeff = [coeff[0]];
71-
let qubitPidx = idxFermions[0];
72-
let qubitQidx = idxFermions[1];
71+
let qubitPidx = term.Subsystem[0];
72+
let qubitQidx = term.Subsystem[1];
7373
let qubitIndices = RangeAsIntArray(qubitPidx..qubitQidx);
7474
return [
7575
new GeneratorIndex { Term = (([1] + Repeated(3, Length(qubitIndices) - 2)) + [1], newCoeff), Subsystem = qubitIndices },
@@ -88,15 +88,15 @@ function PQTermToPauliGenIdx(term : GeneratorIndex) : GeneratorIndex[] {
8888
/// # Output
8989
/// `GeneratorIndex[]` expressing PQ or PQQR term as Pauli terms.
9090
function PQandPQQRTermToPauliGenIdx(term : GeneratorIndex) : GeneratorIndex[] {
91-
let ((idxTermType, coeff), idxFermions) = term!;
91+
let (_, coeff) = term.Term;
9292
let newCoeff = [coeff[0]];
9393

94-
if Length(idxFermions) == 2 {
94+
if Length(term.Subsystem) == 2 {
9595
return PQTermToPauliGenIdx(term);
9696
} else {
97-
let qubitPidx = idxFermions[0];
98-
let qubitQidx = idxFermions[1];
99-
let qubitRidx = idxFermions[3];
97+
let qubitPidx = term.Subsystem[0];
98+
let qubitQidx = term.Subsystem[1];
99+
let qubitRidx = term.Subsystem[3];
100100

101101
if (qubitPidx < qubitQidx and qubitQidx < qubitRidx) {
102102

@@ -129,9 +129,9 @@ function PQandPQQRTermToPauliGenIdx(term : GeneratorIndex) : GeneratorIndex[] {
129129
/// # Output
130130
/// `GeneratorIndex[]` expressing PQRS term as Pauli terms.
131131
function V0123TermToPauliGenIdx(term : GeneratorIndex) : GeneratorIndex[] {
132-
let ((idxTermType, v0123), idxFermions) = term!;
133-
let qubitsPQ = idxFermions[0..1];
134-
let qubitsRS = idxFermions[2..3];
132+
let (_, v0123) = term.Term;
133+
let qubitsPQ = term.Subsystem[0..1];
134+
let qubitsRS = term.Subsystem[2..3];
135135
let qubitsPQJW = RangeAsIntArray(qubitsPQ[0] + 1..qubitsPQ[1] - 1);
136136
let qubitsRSJW = RangeAsIntArray(qubitsRS[0] + 1..qubitsRS[1] - 1);
137137
let ops = [[1, 1, 1, 1], [1, 1, 2, 2], [1, 2, 1, 2], [2, 1, 1, 2], [2, 2, 2, 2], [2, 2, 1, 1], [2, 1, 2, 1], [1, 2, 2, 1]];

library/chemistry/src/JordanWigner/JordanWignerEvolutionSet.qs

+8-39
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ export
66
JordanWignerFermionEvolutionSet;
77

88
import JordanWigner.Utils.JWOptimizedHTerms;
9-
import Std.Arrays.Fold;
109
import Std.Arrays.IndexRange;
1110
import Std.Arrays.Subarray;
1211
import Utils.GeneratorIndex;
@@ -40,9 +39,9 @@ import Utils.IsNotZero;
4039
/// ## qubits
4140
/// Qubits of Hamiltonian.
4241
operation ApplyJordanWignerZTerm(term : GeneratorIndex, stepSize : Double, qubits : Qubit[]) : Unit is Adj + Ctl {
43-
let ((idxTermType, coeff), idxFermions) = term!;
42+
let (_, coeff) = term.Term;
4443
let angle = (1.0 * coeff[0]) * stepSize;
45-
let qubit = qubits[idxFermions[0]];
44+
let qubit = qubits[term.Subsystem[0]];
4645
Exp([PauliZ], angle, [qubit]);
4746
}
4847

@@ -58,9 +57,9 @@ operation ApplyJordanWignerZTerm(term : GeneratorIndex, stepSize : Double, qubit
5857
/// ## qubits
5958
/// Qubits of Hamiltonian.
6059
operation ApplyJordanWignerZZTerm(term : GeneratorIndex, stepSize : Double, qubits : Qubit[]) : Unit is Adj + Ctl {
61-
let ((idxTermType, coeff), idxFermions) = term!;
60+
let (_, coeff) = term.Term;
6261
let angle = (1.0 * coeff[0]) * stepSize;
63-
let qubitsZZ = Subarray(idxFermions[0..1], qubits);
62+
let qubitsZZ = Subarray(term.Subsystem[0..1], qubits);
6463
Exp([PauliZ, PauliZ], angle, qubitsZZ);
6564
}
6665

@@ -190,48 +189,18 @@ function JordanWignerGeneratorSystem(data : JWOptimizedHTerms) : GeneratorSystem
190189
/// A `GeneratorSystem` representing a system that is the sum of the
191190
/// input generator systems.
192191
function AddGeneratorSystems(generatorSystemA : GeneratorSystem, generatorSystemB : GeneratorSystem) : GeneratorSystem {
193-
let nTermsA = GetGeneratorSystemNTerms(generatorSystemA);
194-
let nTermsB = GetGeneratorSystemNTerms(generatorSystemB);
195-
let generatorIndexFunctionA = GetGeneratorSystemFunction(generatorSystemA);
196-
let generatorIndexFunctionB = GetGeneratorSystemFunction(generatorSystemB);
192+
let nTermsA = generatorSystemA.NumEntries;
193+
let nTermsB = generatorSystemB.NumEntries;
197194
let generatorIndexFunction = idx -> {
198195
if idx < nTermsA {
199-
return generatorIndexFunctionA(idx);
196+
return generatorSystemA.EntryAt(idx);
200197
} else {
201-
return generatorIndexFunctionB(idx - nTermsA);
198+
return generatorSystemB.EntryAt(idx - nTermsA);
202199
}
203200
};
204201
return new GeneratorSystem { NumEntries = nTermsA + nTermsB, EntryAt = generatorIndexFunction };
205202
}
206203

207-
/// # Summary
208-
/// Retrieves the number of terms in a `GeneratorSystem`.
209-
///
210-
/// # Input
211-
/// ## generatorSystem
212-
/// The `GeneratorSystem` of interest.
213-
///
214-
/// # Output
215-
/// The number of terms in a `GeneratorSystem`.
216-
function GetGeneratorSystemNTerms(generatorSystem : GeneratorSystem) : Int {
217-
let (nTerms, generatorIndexFunction) = generatorSystem!;
218-
return nTerms;
219-
}
220-
221-
/// # Summary
222-
/// Retrieves the `GeneratorIndex` function in a `GeneratorSystem`.
223-
///
224-
/// # Input
225-
/// ## generatorSystem
226-
/// The `GeneratorSystem` of interest.
227-
///
228-
/// # Output
229-
/// An function that indexes each `GeneratorIndex` term in a Hamiltonian.
230-
function GetGeneratorSystemFunction(generatorSystem : GeneratorSystem) : (Int -> GeneratorIndex) {
231-
let (nTerms, generatorIndexFunction) = generatorSystem!;
232-
return generatorIndexFunction;
233-
}
234-
235204
/// # Summary
236205
/// Represents a dynamical generator as a set of simulatable gates and an
237206
/// expansion in the JordanWigner basis.

library/chemistry/src/JordanWigner/JordanWignerOptimizedBlockEncoding.qs

+8-64
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,15 @@ export
1919
import JordanWigner.OptimizedBEOperator.JordanWignerSelect;
2020
import JordanWigner.OptimizedBEOperator.JordanWignerSelectQubitCount;
2121
import JordanWigner.OptimizedBEOperator.JordanWignerSelectQubitManager;
22-
import JordanWigner.StatePreparation.PrepareArbitraryStateD;
2322
import JordanWigner.Utils.JWOptimizedHTerms;
2423
import JordanWigner.Utils.MultiplexOperationsFromGenerator;
2524
import JordanWigner.Utils.RangeAsIntArray;
26-
import Std.Arithmetic.MAJ;
27-
import Std.Arrays.Head;
28-
import Std.Arrays.IndexRange;
29-
import Std.Arrays.Mapped;
30-
import Std.Arrays.Most;
31-
import Std.Arrays.Partitioned;
32-
import Std.Arrays.Rest;
33-
import Std.Arrays.Subarray;
34-
import Std.Arrays.Tail;
25+
import Std.Arrays.*;
26+
import Std.Math.*;
3527
import Std.Convert.IntAsDouble;
28+
import Std.Arithmetic.ApplyIfGreaterLE;
29+
import Std.StatePreparation.PreparePureStateD;
3630
import Std.Diagnostics.Fact;
37-
import Std.Math.*;
3831
import Utils.GeneratorIndex;
3932
import Utils.GeneratorSystem;
4033
import Utils.HTermToGenIdx;
@@ -623,7 +616,7 @@ operation PrepareQuantumROMState(
623616
MultiplexOperationsFromGenerator(unitaryGenerator, indexRegister, (keepCoeffRegister, altIndexRegister, dataRegister, altDataRegister));
624617

625618
// Perform comparison
626-
CompareUsingRippleCarry(uniformKeepCoeffRegister, keepCoeffRegister, flagQubit);
619+
ApplyIfGreaterLE(X, uniformKeepCoeffRegister, keepCoeffRegister, flagQubit);
627620

628621
let indexRegisterSize = Length(indexRegister);
629622

@@ -828,63 +821,14 @@ operation PrepareUniformSuperpositionOracle(nIndices : Int, nQubits : Int, idxFl
828821
within {
829822
ApplyXorInPlace(nIndices - 1, compareQubits);
830823
} apply {
831-
CompareUsingRippleCarry(targetQubits, compareQubits, auxillaryQubits[0]);
824+
ApplyIfGreaterLE(X, targetQubits, compareQubits, auxillaryQubits[0]);
832825
X(auxillaryQubits[0]);
833826
}
834827
}
835828
Ry(2.0 * theta, auxillaryQubits[1]);
836829
(Controlled X)(auxillaryQubits, flagQubit);
837830
}
838831

839-
/// # Summary
840-
/// This operation tests if an integer represented by a register of qubits
841-
/// is greater than another integer, applying an XOR of the result onto an
842-
/// output qubit.
843-
///
844-
/// # Description
845-
/// Given two integers `x` and `y` stored in equal-size qubit registers,
846-
/// this operation checks if they satisfy `x > y`. If true, 1 is
847-
/// XORed into an output qubit. Otherwise, 0 is XORed into an output qubit.
848-
/// In other words, this operation can be represented by the unitary
849-
/// $$
850-
/// \begin{align}
851-
/// U\ket{x}\ket{y}\ket{z} = \ket{x}\ket{y}\ket{z\oplus (x>y)}.
852-
/// \end{align}
853-
/// $$
854-
///
855-
/// # Input
856-
/// ## x
857-
/// First number to be compared stored in `LittleEndian` format in a qubit register.
858-
/// ## y
859-
/// Second number to be compared stored in `LittleEndian` format in a qubit register.
860-
/// ## output
861-
/// Qubit that stores the result of the comparison $x>y$.
862-
///
863-
/// # References
864-
/// - [A new quantum ripple-carry addition circuit](https://arxiv.org/abs/quant-ph/0410184)
865-
/// Steven A. Cuccaro, Thomas G. Draper, Samuel A. Kutin, David Petrie Moulton
866-
operation CompareUsingRippleCarry(x : Qubit[], y : Qubit[], output : Qubit) : Unit is Adj + Ctl {
867-
if (Length(x) != Length(y)) {
868-
fail "Size of integer registers must be equal.";
869-
}
870-
871-
use auxiliary = Qubit();
872-
within {
873-
let nQubitsX = Length(x);
874-
875-
// Take 2's complement
876-
ApplyToEachCA(X, x + [auxiliary]);
877-
878-
MAJ(y[0], auxiliary, x[0]);
879-
for i in IndexRange(Most(x)) {
880-
MAJ(Most(x)[i], Rest(y)[i], Rest(x)[i])
881-
}
882-
} apply {
883-
X(output);
884-
CNOT(Tail(x), output);
885-
}
886-
}
887-
888832
// Classical processing
889833
// This discretizes the coefficients such that
890834
// |coefficient[i] * oneNorm - discretizedCoefficient[i] * discretizedOneNorm| * nCoeffs <= 2^{1-bitsPrecision}.
@@ -893,7 +837,7 @@ function QuantumROMDiscretization(bitsPrecision : Int, coefficients : Double[])
893837
let nCoefficients = Length(coefficients);
894838
Fact(bitsPrecision <= 31, $"Bits of precision {bitsPrecision} unsupported. Max is 31.");
895839
Fact(nCoefficients > 1, "Cannot prepare state with less than 2 coefficients.");
896-
Fact(oneNorm != 0.0, "State must have at least one coefficient > 0");
840+
Fact(oneNorm >= 0.0, "State must have at least one coefficient > 0");
897841

898842
let barHeight = 2^bitsPrecision - 1;
899843

@@ -1103,7 +1047,7 @@ operation WriteQuantumROMBitString(idx : Int, keepCoeff : Int[], altIndex : Int[
11031047
/// and constructing a multiply-controlled unitary `PrepareArbitraryStateD` and `MultiplexOperationsFromGenerator`.
11041048
function PauliBlockEncoding(generatorSystem : GeneratorSystem) : (Double, (Qubit[], Qubit[]) => Unit is Adj + Ctl) {
11051049
let multiplexer = unitaryGenerator -> MultiplexOperationsFromGenerator(unitaryGenerator, _, _);
1106-
return PauliBlockEncodingInner(generatorSystem, coeff -> (qs => PrepareArbitraryStateD(coeff, qs)), multiplexer);
1050+
return PauliBlockEncodingInner(generatorSystem, coeff -> (qs => PreparePureStateD(coeff, Reversed(qs))), multiplexer);
11071051
}
11081052

11091053
/// # Summary

library/chemistry/src/JordanWigner/JordanWignerVQE.qs

+1-1
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ operation EstimateFrequency(preparation : (Qubit[] => Unit), measurement : (Qubi
9292

9393
// NB: We absolutely must reset here, since preparation()
9494
// and measurement() can each use randomness internally.
95-
ApplyToEach(Reset, register);
95+
ResetAll(register);
9696
}
9797

9898
return IntAsDouble(nUp) / IntAsDouble(nMeasurements);

0 commit comments

Comments
 (0)