microsoft/qdk

Public

mirrored from https://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
swernli/eval-optimization

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

library/chemistry/src/JordanWigner/Oracles.qs

134lines · modecode

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4export TrotterStepOracle;
5export QubitizationOracle;
6export OptimizedQubitizationOracle;
7
8import Std.Convert.IntAsDouble;
9import Std.Math.Ceiling;
10import Std.Math.Lg;
11
12import JordanWigner.BlockEncoding.JWBlockEncodingGeneratorSystem;
13import JordanWigner.EvolutionSet.JWFermionEvolutionSet;
14import JordanWigner.EvolutionSet.JWGeneratorSystem;
15import JordanWigner.OptimizedBlockEncoding.JWOptimizedBlockEncoding;
16import JordanWigner.OptimizedBlockEncoding.PauliBlockEncoding;
17import JordanWigner.OptimizedBlockEncoding.QuantumWalkByQubitization;
18import JordanWigner.Data.JWEncodingData;
19import Trotterization.TrotterSimulationAlgorithm;
20import Generators.EvolutionGenerator;
21
22// Convenience functions for performing simulation.
23
24/// # Summary
25/// Returns Trotter step operation and the parameters necessary to run it.
26///
27/// # Input
28/// ## jwHamiltonian
29/// Hamiltonian described by `JWEncodingData` format.
30/// ## trotterStepSize
31/// Step size of Trotter integrator.
32/// ## trotterOrder
33/// Order of Trotter integrator.
34///
35/// # Output
36/// A tuple where: `Int` is the number of qubits allocated,
37/// `Double` is `1.0/trotterStepSize`, and the operation
38/// is the Trotter step.
39function TrotterStepOracle(
40 jwHamiltonian : JWEncodingData,
41 trotterStepSize : Double,
42 trotterOrder : Int
43) : (Int, (Double, (Qubit[] => Unit is Adj + Ctl))) {
44 let generatorSystem = JWGeneratorSystem(jwHamiltonian.Terms);
45 let evolutionGenerator = new EvolutionGenerator { EvolutionSet = JWFermionEvolutionSet(), System = generatorSystem };
46 let simulationAlgorithm = TrotterSimulationAlgorithm(trotterStepSize, trotterOrder);
47 let oracle = simulationAlgorithm(trotterStepSize, evolutionGenerator, _);
48 let nTargetRegisterQubits = jwHamiltonian.NumQubits;
49 let rescaleFactor = 1.0 / trotterStepSize;
50 return (nTargetRegisterQubits, (rescaleFactor, oracle));
51}
52
53function QubitizationOracleSeperatedRegisters(
54 jwHamiltonian : JWEncodingData
55) : ((Int, Int), (Double, ((Qubit[], Qubit[]) => Unit is Adj + Ctl))) {
56 let generatorSystem = JWBlockEncodingGeneratorSystem(jwHamiltonian.Terms);
57 let (oneNorm, blockEncodingReflection) = PauliBlockEncoding(generatorSystem);
58 let nTargetRegisterQubits = jwHamiltonian.NumQubits;
59 let nCtrlRegisterQubits = Ceiling(Lg(IntAsDouble(generatorSystem.NumEntries)));
60 return (
61 (nCtrlRegisterQubits, nTargetRegisterQubits),
62 (oneNorm, QuantumWalkByQubitization(blockEncodingReflection))
63 );
64}
65
66/// # Summary
67/// Returns Qubitization operation and the parameters necessary to run it.
68///
69/// # Input
70/// ## jwHamiltonian
71/// Hamiltonian described by `JWEncodingData` format.
72///
73/// # Output
74/// A tuple where: `Int` is the number of qubits allocated,
75/// `Double` is the one-norm of Hamiltonian coefficients, and the operation
76/// is the Quantum walk created by Qubitization.
77function QubitizationOracle(
78 jwHamiltonian : JWEncodingData
79) : (Int, (Double, (Qubit[] => Unit is Adj + Ctl))) {
80 let (
81 (nCtrlRegisterQubits, nTargetRegisterQubits),
82 (oneNorm, oracle)
83 ) = QubitizationOracleSeperatedRegisters(jwHamiltonian);
84 let nQubits = nCtrlRegisterQubits + nTargetRegisterQubits;
85 return (nQubits, (oneNorm, ApplyOracleOnRegisterParts(oracle, nTargetRegisterQubits, _)));
86}
87
88function OptimizedQubitizationOracleSeperatedRegisters(
89 jwHamiltonian : JWEncodingData,
90 targetError : Double
91) : ((Int, Int), (Double, ((Qubit[], Qubit[]) => Unit is Adj + Ctl))) {
92 let (
93 (nCtrlRegisterQubits, nTargetRegisterQubits),
94 (oneNorm, blockEncodingReflection)
95 ) = JWOptimizedBlockEncoding(targetError, jwHamiltonian.Terms, jwHamiltonian.NumQubits);
96 return (
97 (nCtrlRegisterQubits, nTargetRegisterQubits),
98 (oneNorm, QuantumWalkByQubitization(blockEncodingReflection))
99 );
100}
101
102/// # Summary
103/// Returns T-count optimized Qubitization operation
104/// and the parameters necessary to run it.
105///
106/// # Input
107/// ## jwHamiltonian
108/// Hamiltonian described by `JWEncodingData` format.
109/// ## targetError
110/// Error of auxillary state preparation step.
111///
112/// # Output
113/// A tuple where: `Int` is the number of qubits allocated,
114/// `Double` is the one-norm of Hamiltonian coefficients, and the operation
115/// is the Quantum walk created by Qubitization.
116function OptimizedQubitizationOracle(
117 jwHamiltonian : JWEncodingData,
118 targetError : Double
119) : (Int, (Double, (Qubit[] => Unit is Adj + Ctl))) {
120 let (
121 (nCtrlRegisterQubits, nTargetRegisterQubits),
122 (oneNorm, oracle)
123 ) = OptimizedQubitizationOracleSeperatedRegisters(jwHamiltonian, targetError);
124 let nQubits = nCtrlRegisterQubits + nTargetRegisterQubits;
125 return (nQubits, (oneNorm, ApplyOracleOnRegisterParts(oracle, nTargetRegisterQubits, _)));
126}
127
128operation ApplyOracleOnRegisterParts(
129 oracle : ((Qubit[], Qubit[]) => Unit is Adj + Ctl),
130 nSystemQubits : Int,
131 allQubits : Qubit[]
132) : Unit is Adj + Ctl {
133 oracle(allQubits[nSystemQubits..Length(allQubits) - 1], allQubits[0..nSystemQubits - 1]);
134}
135