microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
minestarks/circuit-disable-tracing

Branches

Tags

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

Clone

HTTPS

Download ZIP

samples/algorithms/Ising/Simple2dIsingOrder2.qs

117lines · modecode

1/// # Sample
2/// Simulation of a simple Ising model evolution
3/// on a 2D grid with second-order Trotterization.
4///
5/// # Description
6/// This sample demonstrates simulation of an Ising model Hamiltonian
7/// on N1xN2 2D grid using a second-order Trotter-Suzuki approximation.
8/// This sample can be easily simulated classically with 3x3 grid and
9/// about 1000 shots. This sample is suitable for Base Profile.
10/// For the purpose of simplicity this sample intentionally doesn't
11/// post-process results or perform eigenvalue estimation.
12operation Main() : Result[] {
13 // Dimensions of a 2D grid is N1 x N2
14 let N1 : Int = 3;
15 let N2 : Int = 3;
16
17 // Total evolution time
18 let evolutionTime : Double = 4.0;
19 // Number of steps
20 let numberOfSteps : Int = 5;
21
22 // Coefficient for 2-qubit interactions between neighboring qubits
23 let J : Double = 1.0;
24 // Coefficient for external field interaction for individual qubits
25 let g : Double = 1.4;
26
27 // Also try simulating with different strength of external field:
28 // let g = 0.2;
29 // let g = 1.0;
30 // let g = 1.4;
31 // let g = 2.0;
32
33 // Model evolution
34 IsingModel2DEvolution(N1, N2, J, g, evolutionTime, numberOfSteps)
35}
36
37/// # Summary
38/// Simulate simple Ising model evolution
39///
40/// # Description
41/// Simulates state |𝜓⟩ evolution to find |𝜓(t)⟩=U(t)|𝜓(0)⟩.
42/// |𝜓(0)⟩ is taken to be |0...0⟩.
43/// U(t)=e⁻ⁱᴴᵗ, where H is an Ising model Hamiltonian H = -J·Σ'ᵢⱼZᵢZⱼ + g·ΣᵢXᵢ
44/// Here Σ' is taken over all pairs of neighboring qubits <i,j>.
45/// Simulation is done by performing K steps assuming U(t)≈(U(t/K))ᴷ.
46operation IsingModel2DEvolution(
47 N1 : Int,
48 N2 : Int,
49 J : Double,
50 g : Double,
51 evolutionTime : Double,
52 numberOfSteps : Int
53) : Result[] {
54
55 // Allocate qubit grid and structure it as a 2D array.
56 use qubits = Qubit[N1 * N2];
57 let qubitsAs2D = Std.Arrays.Chunks(N2, qubits);
58
59 // Compute the time step
60 let dt : Double = evolutionTime / Std.Convert.IntAsDouble(numberOfSteps);
61
62 let theta_x = - g * dt;
63 let theta_zz = J * dt;
64
65 // Perform K steps
66 for i in 1..numberOfSteps {
67
68 // Single-qubit interaction with external field. Half-step.
69 for q in qubits {
70 Rx(theta_x, q);
71 }
72
73 // All Rzz gates applied in the following two loops commute so they can be
74 // applied in any order. To reduce the depth of the algorithm, Rzz gates
75 // between horizontal "even" pairs of qubits are applied first - pairs
76 // that start at even indices. Then Rzz gates between "odd" pairs are
77 // applied. That way all Rzz between horizontal "even" pairs can potentially
78 // be done in parallel. Same is true about horizontal "odd" pairs,
79 // vertical "even" pairs and vertical "odd" pairs.
80
81 // Horizontal two-qubit interactions.
82 for row in 0..N1-1 {
83 // Horizontal interactions between "even" pairs
84 for col in 0..2..N2-2 {
85 Rzz(2.0 * theta_zz, qubitsAs2D[row][col], qubitsAs2D[row][col + 1]);
86 }
87
88 // Horizontal interactions between "odd" pairs
89 for col in 1..2..N2-2 {
90 Rzz(2.0 * theta_zz, qubitsAs2D[row][col], qubitsAs2D[row][col + 1]);
91 }
92 }
93
94 // Vertical two-qubit interactions
95 for col in 0..N2-1 {
96
97 // Vertical interactions between "even" pairs
98 for row in 0..2..N1-2 {
99 Rzz(2.0 * theta_zz, qubitsAs2D[row][col], qubitsAs2D[row + 1][col]);
100 }
101
102 // Vertical interactions between "odd" pairs
103 for row in 1..2..N1-2 {
104 Rzz(2.0 * theta_zz, qubitsAs2D[row][col], qubitsAs2D[row + 1][col]);
105 }
106
107 }
108
109 // Single-qubit interaction with external field. Half-step.
110 for q in qubits {
111 Rx(theta_x, q);
112 }
113
114 }
115
116 MResetEachZ(qubits)
117}