@@ -7,21 +7,39 @@ namespace Microsoft.Quantum.SparseSimulatorTests {
77 open Microsoft .Quantum .Intrinsic ;
88 open Microsoft .Quantum .Diagnostics ;
99 open Microsoft .Quantum .Convert ;
10- open Microsoft .Quantum .Arithmetic ;
1110 open Microsoft .Quantum .Arrays ;
12- open Microsoft .Quantum .Preparation ;
1311 open Microsoft .Quantum .Math ;
1412
15- operation DumpIdRotation () : Unit {
16- use qubits = Qubit [2 ] {
17- H (qubits [0 ]);
18- H (qubits [1 ]);
19- (Controlled Exp )([qubits [0 ]], ([PauliI ], 0.5 , [qubits [1 ]]));
20- DumpMachine ();
21- ResetAll (qubits );
13+ internal operation ApplyToEachCA < 'T > (singleElementOperation : ('T => Unit is Adj + Ctl ), register : 'T [])
14+ : Unit is Adj + Ctl {
15+ for idxQubit in IndexRange (register ) {
16+ singleElementOperation (register [idxQubit ]);
2217 }
2318 }
2419
20+ internal operation ApplyToFirstTwoQubitsCA (op : ((Qubit , Qubit ) => Unit is Adj + Ctl ), register : Qubit [])
21+ : Unit is Adj + Ctl {
22+ if (Length (register ) < 2 )
23+ {
24+ fail $"Must have at least two qubits to act on." ;
25+ }
26+
27+ op (register [0 ], register [1 ]);
28+ }
29+
30+ internal function Zipped < 'T , 'U > (left : 'T [], right : 'U []) : ('T , 'U )[] {
31+ let nElements = Length (left ) < Length (right )
32+ ? Length (left )
33+ | Length (right );
34+ mutable output = new ('T , 'U )[nElements ];
35+
36+ for idxElement in 0 .. nElements - 1 {
37+ set output w/= idxElement <- (left [idxElement ], right [idxElement ]);
38+ }
39+
40+ return output ;
41+ }
42+
2543 operation _R (pauli : Pauli , theta : Double , qubits : Qubit []) : Unit is Adj + Ctl {
2644 R (pauli , theta , qubits [0 ]);
2745 }
@@ -50,24 +68,12 @@ namespace Microsoft.Quantum.SparseSimulatorTests {
5068 }
5169 }
5270
53- operation DumpMultiplexZ () : Unit {
54- use qubits = Qubit [12 ] {
55- ApplyToEach (H , qubits [0 .. 5 ]);
56- ApplyToEach (CNOT , Zipped (qubits [0 .. 5 ], qubits [6 .. 11 ]));
57- ApproximatelyMultiplexZ (0 .001 , [0 .12 , 0 .34 , - 0 .26 , 0.5 , 1.8 ], LittleEndian (qubits [6 .. 10 ]), qubits [11 ]);
58- DumpMachine ();
59- ResetAll (qubits );
60- }
61- }
62-
63-
64-
65- internal operation ControlledRz (angle : Double , (control : Qubit , target : Qubit )) : Unit is Adj {
71+ internal operation ControlledRz (angle : Double , (control : Qubit , target : Qubit )) : Unit is Adj + Ctl {
6672 Controlled Rz ([control ], (angle , target ));
6773 DumpMachine ();
6874 }
6975
70- internal operation ControlledRzAsR1 (angle : Double , (control : Qubit , target : Qubit )) : Unit is Adj {
76+ internal operation ControlledRzAsR1 (angle : Double , (control : Qubit , target : Qubit )) : Unit is Adj + Ctl {
7177 Controlled R1 ([control ], (angle , target ));
7278 R1 (- angle / 2.0 , control );
7379 DumpMachine ();
@@ -76,7 +82,7 @@ namespace Microsoft.Quantum.SparseSimulatorTests {
7682 operation TestEqualityOfControlledRz () : Unit {
7783 for _ in 1 .. 10 {
7884 let angle = Microsoft .Quantum .Random .DrawRandomDouble (0.0 , 2.0 * PI ());
79- AssertOperationsEqualReferenced (2 , ApplyToFirstTwoQubits (ControlledRzAsR1 (angle , _ ), _ ), ApplyToFirstTwoQubitsA (ControlledRz (angle , _ ), _ ));
85+ AssertOperationsEqualReferenced (2 , ApplyToFirstTwoQubitsCA (ControlledRzAsR1 (angle , _ ), _ ), ApplyToFirstTwoQubitsCA (ControlledRz (angle , _ ), _ ));
8086 }
8187 }
8288
@@ -90,8 +96,6 @@ namespace Microsoft.Quantum.SparseSimulatorTests {
9096 LargeStateTestWrapper (CNOTTest , nqubits );
9197 LargeStateTestWrapper (ResetTest , nqubits );
9298 LargeStateTestWrapper (AssertTest , nqubits );
93- LargeStateTestWrapper (AndChainTest , nqubits );
94- LargeStateTestWrapper (CZTest , nqubits );
9599 LargeStateTestWrapper (AllocationTest , nqubits );
96100 LargeStateTestWrapper (Rotation1CompareTest , nqubits );
97101 LargeStateTestWrapper (RotationFracCompareTest , nqubits );
@@ -128,7 +132,7 @@ namespace Microsoft.Quantum.SparseSimulatorTests {
128132 @Test("Microsoft.Quantum.SparseSimulation.SparseSimulator" )
129133 operation PartialDumpTest () : Unit {
130134 use qubits = Qubit [4 ] {
131- ApplyToEach (H , qubits );
135+ ApplyToEachCA (H , qubits );
132136 CNOT (qubits [2 ], qubits [3 ]);
133137 DumpRegister ("Test_file_1" , qubits [0 .. 1 ]);
134138 DumpRegister ("Test_file_2" , qubits [2 .. 3 ]);
@@ -218,99 +222,6 @@ namespace Microsoft.Quantum.SparseSimulatorTests {
218222 }
219223 }
220224
221- // Taken from the PurifiedMixedState documentation
222- @Test("Microsoft.Quantum.SparseSimulation.SparseSimulator" )
223- operation QROMPrepareTest () : Unit {
224- let coefficients = [1.0 , 2.0 , 3.0 , 4.0 , 5.0 ];
225- let targetError = 1e - 3 ;
226- let purifiedState = PurifiedMixedState (targetError , coefficients );
227- use indexRegister = Qubit [purifiedState ::Requirements ::NIndexQubits ] {
228- use garbageRegister = Qubit [purifiedState ::Requirements ::NGarbageQubits ] {
229- purifiedState ::Prepare (LittleEndian (indexRegister ), new Qubit [0 ], garbageRegister );
230- ResetAll (garbageRegister );
231- }
232- ResetAll (indexRegister );
233- }
234- }
235-
236-
237- @Test("Microsoft.Quantum.SparseSimulation.SparseSimulator" )
238- operation CZTest () : Unit {
239- let num_qubits = 5 ;
240- use qubits = Qubit [num_qubits ]{
241- H (qubits [0 ]);
242- for idx in 0 .. (2 ^ (num_qubits - 1 ) - 1 ) {
243- let result = (idx == 2 ^ (num_qubits - 1 ) - 1 );
244- within {
245- ApplyXorInPlace (idx , LittleEndian (qubits [1 .. num_qubits - 1 ]));
246- (Controlled Z )(qubits [1 .. num_qubits - 1 ], (qubits [0 ]));
247- } apply {
248- if (result ){
249- AssertMeasurement ([PauliX ], qubits [0 .. 0 ], One , "CZ failed to add phase" );
250- } else {
251- AssertMeasurement ([PauliX ], qubits [0 .. 0 ], Zero , "CZ added unexpected phase" );
252- }
253- }
254- }
255- H (qubits [0 ]);
256- }
257- }
258-
259- operation ApplyAndChain (andOp : ((Qubit , Qubit , Qubit )=> Unit is Adj + Ctl ), auxRegister : Qubit [], ctrlRegister : Qubit [], target : Qubit )
260- : Unit is Adj {
261- if (Length (ctrlRegister ) == 0 ) {
262- X (target );
263- } elif (Length (ctrlRegister ) == 1 ) {
264- CNOT (Head (ctrlRegister ), target );
265- } else {
266- EqualityFactI (Length (auxRegister ), Length (ctrlRegister ) - 2 , "Unexpected number of auxiliary qubits" );
267- let controls1 = ctrlRegister [0 .. 0 ] + auxRegister ;
268- let controls2 = Rest (ctrlRegister );
269- let targets = auxRegister + [target ];
270- ApplyToEachA (andOp , Zipped3 (controls1 , controls2 , targets ));
271- }
272- }
273-
274- operation AndChainDump () : Unit {
275- let num_qubits = 5 ;
276- use qubits = Qubit [num_qubits ]{
277- use aux = Qubit [num_qubits - 3 ]{
278- within {
279- for idx in 1 .. num_qubits - 1 {
280- H (qubits [idx ]);
281- if (idx % 3 == 0 ){ Z (qubits [idx ]);}
282- }
283- ApplyAndChain (ApplyAnd , aux , qubits [1 .. num_qubits - 1 ], qubits [0 ]);
284- } apply {
285- DumpMachine ();
286- }
287- }
288- }
289- }
290- @Test("Microsoft.Quantum.SparseSimulation.SparseSimulator" )
291- operation AndChainTest () : Unit {
292- let num_qubits = 5 ;
293- use qubits = Qubit [num_qubits ]{
294- use aux = Qubit [num_qubits - 3 ]{
295- for idx in 0 .. (2 ^ (num_qubits - 1 ) - 1 ) {
296- let result = (idx == 2 ^ (num_qubits - 1 ) - 1 );
297- within {
298- ApplyXorInPlace (idx , LittleEndian (qubits [1 .. num_qubits - 1 ]));
299- ApplyAndChain (ApplyAnd , aux , qubits [1 .. num_qubits - 1 ], qubits [0 ]);
300- } apply {
301- let after = M (qubits [0 ]);
302- if (result ){
303- Fact (after == One , "Did not apply AND" );
304- } else {
305- Fact (after == Zero , "Applied AND unexpectedly" );
306- }
307- }
308- }
309- }
310- }
311- }
312-
313-
314225 operation DumpMCXFrac () : Unit {
315226 use qubits = Qubit [2 ] {
316227 H (qubits [0 ]);
0 commit comments