The Quantum Exact Simulation Toolkit v4.3.0
Loading...
Searching...
No Matches
trotterisation.h
1/** @file
2 * API signatures for effecting Trotterised operators which
3 * approximate the action of exponentials of PauliStrSum
4 *
5 * @author Tyson Jones
6 *
7 * @defgroup trotterisation Trotterisation
8 * @ingroup api
9 * @brief Functions for Trottersing operations upon Quregs.
10 * @{
11 */
12
13
14#ifndef TROTTERISATION_H
15#define TROTTERISATION_H
16
17#include <stdbool.h>
18
19#include "quest/include/qureg.h"
20#include "quest/include/paulis.h"
21#include "quest/include/matrices.h"
22
23#ifdef __cplusplus
24 #include <vector>
25#endif
26
27
28
29/**
30 * @defgroup trotter_paulistrsum PauliStrSum gadgets
31 * @brief Functions for using Trotterisation to approximate the action of
32 * exponentials of weighted sums of Pauli tensors upon Quregs.
33 * @{
34 */
35
36
37#ifdef __cplusplus
38extern "C" {
39#endif
40
41
42/** @notyettested
43 *
44 * Effects an approximation to the exponential of @p sum, weighted by @p angle times @f$ i @f$, upon @p qureg,
45 * via the symmetrized Trotter-Suzuki decomposition (<a href="https://arxiv.org/abs/math-ph/0506007">arXiv</a>).
46 *
47 * Increasing @p reps (the number of Trotter repetitions) or @p order (an even, positive integer or one)
48 * improves the accuracy of the approximation by reducing the "Trotter error" due to non-commuting
49 * terms of @p sum, though increases the runtime linearly and exponentially respectively.
50 * Using @p permuteTerms the ordering of terms in the sum can also be randomised, which generally
51 * improves the accuracy of the approximation for low order decompositions (<a href="https://arxiv.org/abs/1805.08385">arXiv</a>).
52 *
53 * @formulae
54 *
55 * Let @f$ \hat{H} = @f$ @p sum and @f$ \theta = @f$ @p angle @f$ \in \mathbb{R} @f$. This function approximates
56 * the action of
57 * @f[
58 \exp \left(\iu \, \theta \, \hat{H} \right)
59 * @f]
60 * via a Trotter-Suzuki decomposition of the specified @p order and number of repetitions (@p reps).
61 * Simulation is exact, regardless of @p order or @p reps, only when all terms in @p sum commute.
62 *
63 * @important
64 * Observe that @f$ \theta @f$ lacks the @f$ -\frac{1}{2} @f$ prefactor present in other functions like
65 * applyPauliGadget().
66 *
67 * To be precise, let @f$ r = @f$ @p reps and assume @p sum is composed of
68 * @f$ T @f$-many terms of the form
69 * @f[
70 \hat{H} = \sum\limits_j^T c_j \, \hat{\sigma}_j
71 * @f]
72 * where @f$ c_j @f$ is the coefficient of the @f$ j @f$-th PauliStr @f$ \hat{\sigma}_j @f$.
73 *
74 * - When @p order=1, this function performs first-order Trotterisation, where the terms of @p sum
75 * are effected in a repeated, arbitrary but fixed order.
76 * @f[
77 \exp(\iu \, \theta \, \hat{H} )
78 \approx
79 \prod\limits^{r}
80 \prod\limits_{j=1}^{T}
81 \exp \left( \iu \, \frac{\theta \, c_j}{r} \, \hat\sigma_j \right).
82 * @f]
83 *
84 * - When @p order=2, this function performs the lowest order "symmetrized" Suzuki decomposition, whereby
85 * each repetition effects the terms of @p sum forward then in reverse.
86 * @f[
87 \exp(\iu \, \theta \, \hat{H} )
88 \approx
89 \prod\limits^{r} \left[
90 \prod\limits_{j=1}^{T} \exp \left( \iu \frac{\theta \, c_j}{2 \, r} \hat\sigma_j \right)
91 \prod\limits_{j=T}^{1} \exp \left( \iu \frac{\theta \, c_j}{2 \, r} \hat\sigma_j \right)
92 \right].
93 * @f]
94 *
95 * - Greater, even values of @p order (denoted by symbol @f$ n @f$) invoke higher-order symmetrized decompositions
96 * @f$ S[\theta,n,r] @f$. These see the lower order Trotter circuits repeated twice forward, then reversed, then
97 * twice forward again, recursively. To be precise, letting @f$ p = \left( 4 - 4^{1/(n-1)} \right)^{-1} @f$, these
98 * satisfy
99 * @f{align*}
100 S[\theta, n, 1] &=
101 \left( \prod\limits^2 S[p \, \theta, n-2, 1] \right)
102 S[ (1-4p)\,\theta, n-2, 1]
103 \left( \prod\limits^2 S[p \, \theta, n-2, 1] \right),
104 \\
105 S[\theta, n, r] &=
106 \prod\limits^{r} S\left[\frac{\theta}{r}, n, 1\right].
107 * @f}
108 *
109 * > These formulations are taken from 'Finding Exponential Product Formulas
110 * > of Higher Orders', Naomichi Hatano and Masuo Suzuki (2005) (<a href="https://arxiv.org/abs/math-ph/0506007">arXiv</a>).
111 *
112 * When @p permuteTerms=true, the terms of @p sum are effected in a random order at each repetition.
113 * That is, each repetition of the Trotter-Suzuki decomposition is evaluated with the sum
114 * @f[
115 \hat{H} = \sum\limits_j^T c_{\pi(j)} \, \hat{\sigma}_{\pi(j)}
116 * @f]
117 * where @f$ \pi @f$ is a randomly selected permutation.
118 *
119 * @equivalences
120 *
121 * - By passing @f$ \theta = - \Delta t / \hbar @f$, this function approximates unitary time evolution of a closed
122 * system under the time-independent Hamiltonian @p sum = @f$ \hat{H} @f$ over a duration of @f$ \Delta t @f$, as
123 * described by propagator
124 * @f[
125 \hat{U}(\Delta t) = \exp(- \iu \, \Delta t \,\hat{H} \, / \, \hbar),
126 * @f]
127 * as utilised by the function applyTrotterizedUnitaryTimeEvolution().
128 *
129 * - This function is equivalent to applyTrotterizedNonUnitaryPauliStrSumGadget() when passing
130 * a @p qcomp instance with a zero imaginary component as the @p angle parameter. This latter
131 * function is useful for generalising dynamical simulation to imaginary-time evolution.
132 *
133 * @constraints
134 *
135 * - Unitarity of the prescribed exponential(s) requires that @p sum is Hermitian, ergo containing
136 * only real coefficients. Validation will check that @p sum is approximately Hermitian, permitting
137 * coefficients with imaginary components smaller (in magnitude) than epsilon.
138 * @f[
139 \max\limits_{i} |c_i| \le \valeps
140 * @f]
141 * where the validation epsilon @f$ \valeps @f$ can be adjusted with setQuESTValidationEpsilon().
142 * Otherwise, use applyTrotterizedNonUnitaryPauliStrSumGadget() to permit non-Hermitian @p sum
143 * and ergo effect a non-unitary exponential(s).
144 *
145 * - The @p angle parameter is necessarily real to retain unitarity, but can be relaxed to an arbitrary
146 * complex scalar (i.e. a @p qcomp) using applyTrotterizedNonUnitaryPauliStrSumGadget(). This permits
147 * cancelling the complex unit @f$ i @f$ to effect non-unitary @f$ \exp(\theta \, \hat{H}) @f$ as
148 * is useful for imaginary-time evolution.
149 *
150 * - This function only ever effects @f$ \exp \left(\iu \, \theta \, \hat{H} \right) @f$ exactly
151 * when all PauliStr in @p sum = @f$ \hat{H} @f$ commute, or @p reps @f$ \rightarrow \infty @f$.
152 *
153 * @param[in,out] qureg the state to modify.
154 * @param[in] sum a weighted sum of Pauli strings to approximately exponentiate.
155 * @param[in] angle the prefactor of @p sum times @f$ i @f$ in the exponent.
156 * @param[in] order the order of the Trotter-Suzuki decomposition (e.g. @p 1, @p 2, @p 4, ...).
157 * @param[in] reps the number of Trotter repetitions.
158 * @param[in] permuteTerms whether to randomly reorder Pauli terms at each repetition.
159 *
160 * @throws @validationerror
161 * - if @p qureg or @p sum are uninitialised.
162 * - if @p sum is not approximately Hermitian.
163 * - if @p sum contains non-identities on qubits beyond the size of @p qureg.
164 * - if @p order is not 1 nor a positive, @b even integer.
165 * - if @p reps is not a positive integer.
166 * - if internal allocation needed for term permutation fails.
167 *
168 * @see
169 * - applyPauliGadget()
170 * - applyTrotterizedNonUnitaryPauliStrSumGadget()
171 * - applyTrotterizedUnitaryTimeEvolution()
172 *
173 * @author Tyson Jones
174 * @author Vasco Ferreira (randomisation)
175 */
176void applyTrotterizedPauliStrSumGadget(Qureg qureg, PauliStrSum sum, qreal angle, int order, int reps, bool permuteTerms);
177
178
179/// @notyetdoced
180/// @notyettested
181///
182/// @author Tyson Jones
183/// @author Vasco Ferreira (randomisation)
184///
185/// @see
186/// - applyTrotterizedPauliStrSumGadget()
187/// - applyControlledCompMatr1()
188void applyTrotterizedControlledPauliStrSumGadget(Qureg qureg, int control, PauliStrSum sum, qreal angle, int order, int reps, bool permuteTerms);
189
190
191/// @notyetdoced
192/// @notyettested
193///
194/// @author Tyson Jones
195/// @author Vasco Ferreira (randomisation)
196///
197/// @see
198/// - applyTrotterizedPauliStrSumGadget()
199/// - applyMultiControlledCompMatr1()
200void applyTrotterizedMultiControlledPauliStrSumGadget(Qureg qureg, int* controls, int numControls, PauliStrSum sum, qreal angle, int order, int reps, bool permuteTerms);
201
202
203/// @notyetdoced
204/// @notyettested
205///
206/// @author Tyson Jones
207/// @author Vasco Ferreira (randomisation)
208///
209/// @see
210/// - applyTrotterizedPauliStrSumGadget()
211/// - applyMultiStateControlledCompMatr1()
212void applyTrotterizedMultiStateControlledPauliStrSumGadget(Qureg qureg, int* controls, int* states, int numControls, PauliStrSum sum, qreal angle, int order, int reps, bool permuteTerms);
213
214
215/** @notyettested
216 *
217 * A generalisation of applyTrotterizedPauliStrSumGadget() which accepts a complex @p angle and permits
218 * @p sum to be non-Hermitian, thereby effecting a potentially non-unitary and non-CPTP operation.
219 *
220 * @formulae
221 *
222 * Let @f$ \hat{H} = @f$ @p sum and @f$ \theta = @f$ @p angle @f$ \in \mathbb{C} @f$. This function
223 * approximates the action of
224 * @f[
225 \exp \left(\iu \, \theta \, \hat{H} \right)
226 * @f]
227 * via a Trotter-Suzuki decomposition of the specified @p order and number of repetitions (@p reps).
228 *
229 * > See applyTrotterizedPauliStrSumGadget() for more information about the decomposition, and other
230 * > parameters.
231 *
232 * @equivalences
233 *
234 * - When @p angle is set to @f$ \theta = \iu \, \Delta \tau @f$ and @p sum = @f$ \hat{H} @f$ is Hermitian,
235 * this function (approximately) evolves @p qureg in imaginary-time for duration @f$ \Delta \tau @f$,
236 * effecting non-unitary propagator
237 @f[
238 \exp(- \Delta \tau \hat{H})
239 * @f]
240 * as utilised by applyTrotterizedImaginaryTimeEvolution().
241 *
242 * - When @p angle is real and @p sum is Hermitian (i.e. has approximately real coefficients), the effected
243 * operation is unitary and this function becomes equivalent to applyTrotterizedPauliStrSumGadget().
244 *
245 * @constraints
246 *
247 * - This function only ever effects @f$ \exp \left(\iu \, \theta \, \hat{H} \right) @f$ exactly
248 * when all PauliStr in @p sum = @f$ \hat{H} @f$ commute.
249 *
250 * @param[in,out] qureg the state to modify.
251 * @param[in] sum a weighted sum of Pauli strings to approximately exponentiate.
252 * @param[in] angle an effective prefactor of @p sum in the exponent.
253 * @param[in] order the order of the Trotter-Suzuki decomposition (e.g. @p 1, @p 2, @p 4, ...).
254 * @param[in] reps the number of Trotter repetitions.
255 * @param[in] permuteTerms whether to randomly reorder Pauli terms at each repetition.
256 *
257 * @throws @validationerror
258 * - if @p qureg or @p sum are uninitialised.
259 * - if @p sum contains non-identities on qubits beyond the size of @p qureg.
260 * - if @p order is not 1 nor a positive, @b even integer.
261 * - if @p reps is not a positive integer.
262 * - if internal allocation needed for term permutation fails.
263 *
264 * @author Tyson Jones
265 * @author Vasco Ferreira (randomisation)
266 */
267void applyTrotterizedNonUnitaryPauliStrSumGadget(Qureg qureg, PauliStrSum sum, qcomp angle, int order, int reps, bool permuteTerms);
268
269
270// end de-mangler
271#ifdef __cplusplus
272}
273#endif
274
275#ifdef __cplusplus
276
277
278/// @notyettested
279/// @notyetvalidated
280/// @notyetdoced
281/// @cppvectoroverload
282///
283/// @author Tyson Jones
284/// @author Vasco Ferreira (randomisation)
285///
286/// @see applyTrotterizedMultiControlledPauliStrSumGadget()
287void applyTrotterizedMultiControlledPauliStrSumGadget(Qureg qureg, std::vector<int> controls, PauliStrSum sum, qreal angle, int order, int reps, bool permuteTerms);
288
289
290/// @notyettested
291/// @notyetvalidated
292/// @notyetdoced
293/// @cppvectoroverload
294///
295/// @author Tyson Jones
296/// @author Vasco Ferreira (randomisation)
297///
298/// @see applyTrotterizedMultiStateControlledPauliStrSumGadget()
299void applyTrotterizedMultiStateControlledPauliStrSumGadget(Qureg qureg, std::vector<int> controls, std::vector<int> states, PauliStrSum sum, qreal angle, int order, int reps, bool permuteTerms);
300
301
302#endif // __cplusplus
303
304/** @} */
305
306
307
308/**
309 * @defgroup trotter_timeevol Time evolution
310 * @brief Functions for approximate dynamical simulation.
311 * @{
312 */
313
314
315#ifdef __cplusplus
316extern "C" {
317#endif
318
319
320/** Unitarily time evolves @p qureg for the duration @p time under the time-independent Hamiltonian @p hamil,
321 * as approximated by symmetrized Trotterisation of the specified @p order and number of cycles @p reps.
322 *
323 * @formulae
324 *
325 * Let @f$ \hat{H} = @f$ @p hamil and @f$ t = @f$ @p time @f$ \in \mathbb{R} @f$. This function approximates
326 * the action of the unitary-time evolution operator/propagator
327 * @f[
328 \hat{U}(t) = \exp \left(- \iu \, t \, \hat{H} \right),
329 * @f]
330 * as solves the time-independent Schrödinger equation. When @p qureg is a statevector @f$ \svpsi @f$, the
331 * resulting state approximates
332 * @f[
333 \approx U(t) \svpsi
334 * @f]
335 * while when @p qureg is a density matrix @f$ \dmrho @f$, the result approximates
336 * @f[
337 \approx U(t) \, \dmrho \, U(t)^\dagger.
338 * @f]
339 *
340 * > See applyTrotterizedPauliStrSumGadget() for information about the Trotter method.
341 *
342 * @equivalences
343 *
344 * - This function merely wraps applyTrotterizedPauliStrSumGadget() which effects @f$ \exp(\iu \theta \hat{H}) @f$,
345 * passing @f$ \theta = - t @f$.
346 *
347 * @constraints
348 *
349 * - Unitarity requires that @p hamil is Hermitian and ergo contains only real coefficients. Validation will check that
350 * @p hamil is approximately Hermitian, permitting coefficients with imaginary components smaller (in magnitude) than
351 * epsilon.
352 * @f[
353 \max\limits_{i} |c_i| \le \valeps
354 * @f]
355 * where the validation epsilon @f$ \valeps @f$ can be adjusted with setQuESTValidationEpsilon(). The imaginary components
356 * of the Hamiltonian _are_ considered during simulation.
357 *
358 * - The @p time parameter is necessarily real to retain unitarity. It can be substituted for a strictly imaginary
359 * scalar to perform imaginary-time evolution (as per Wick rotation @f$ t \rightarrow - \iu \tau @f$) via
360 * applyTrotterizedImaginaryTimeEvolution(), or generalised to an arbitrary complex number through direct use of
361 * applyTrotterizedNonUnitaryPauliStrSumGadget().
362 *
363 * - The simulated system is _closed_ with dynamics described fully by the Hamiltonian @p hamil. Open or otherwise noisy
364 * system dynamics can be simulated with applyTrotterizedNoisyTimeEvolution().
365 *
366 * - Simulation is exact such that the effected operation is precisely @f$ \exp(-\iu t \hat{H}) @f$ only when
367 * @p reps @f$ \rightarrow \infty @f$ or all terms in @p hamil commute with one another. Conveniently, Trotter error
368 * does _not_ break normalisation of the state since the approximating circuit remains unitary.
369 *
370 * @myexample
371 *
372 * ```
373 Qureg qureg = createDensityQureg(10);
374 PauliStrSum hamil = createInlinePauliStrSum(R"(
375 1 ZZI
376 2 IZZ
377 3 ZIZ
378 1.5 XII
379 2.5 IXI
380 3.5 IIX
381 )");
382
383 qreal time = 0.8 * hbar;
384 int order = 4;
385 int reps = 20;
386 applyTrotterizedUnitaryTimeEvolution(qureg, hamil, time, order, reps);
387 * ```
388 *
389 * @see
390 * - applyTrotterizedImaginaryTimeEvolution()
391 * - applyTrotterizedNoisyTimeEvolution()
392 * - applyTrotterizedNonUnitaryPauliStrSumGadget()
393 *
394 * @param[in,out] qureg the state to modify.
395 * @param[in] hamil the Hamiltonian as a a weighted sum of Pauli strings.
396 * @param[in] time the duration over which to simulate evolution.
397 * @param[in] order the order of the Trotter-Suzuki decomposition (e.g. @p 1, @p 2, @p 4, ...).
398 * @param[in] reps the number of Trotter repetitions.
399 * @param[in] permuteTerms whether to randomly reorder Pauli terms at each repetition.
400 *
401 * @throws @validationerror
402 * - if @p qureg or @p hamil are uninitialised.
403 * - if @p hamil contains non-identities on qubits beyond the size of @p qureg.
404 * - if @p hamil is not approximately Hermitian.
405 * - if @p order is not 1 nor a positive, @b even integer.
406 * - if @p reps is not a positive integer.
407 * - if internal allocation needed for term permutation fails.
408 *
409 * @author Tyson Jones
410 * @author Vasco Ferreira (randomisation)
411 */
412void applyTrotterizedUnitaryTimeEvolution(Qureg qureg, PauliStrSum hamil, qreal time, int order, int reps, bool permuteTerms);
413
414
415/** Simulates imaginary-time evolution of @p qureg for the duration @p tau under the time-independent
416 * Hamiltonian @p hamil, as approximated by symmetrized Trotterisation of the specified @p order and
417 * number of cycles @p reps.
418 *
419 * > [!IMPORTANT]
420 * > This is a non-physical operation and breaks the normalisation of state which can be restored
421 * > via setQuregToRenormalized().
422 *
423 * @formulae
424 *
425 * Let @f$ \hat{H} = @f$ @p hamil and @f$ \tau = @f$ @p tau @f$ \in \mathbb{R} @f$. This function
426 * approximates the action of the non-unitary imaginary-time propagator
427 * @f[
428 \hat{V}(\tau) = \exp \left(- \tau \, \hat{H} \right),
429 * @f]
430 * as prescribed by Wick rotating (substituting time @f$ t @f$ for @f$ t \rightarrow -\iu \tau @f$)
431 * the time-independent Schrödinger equation. When @p qureg is a statevector @f$ \svpsi @f$, the
432 * resulting state approximates
433 * @f[
434 \approx V(\tau) \svpsi
435 * @f]
436 * while when @p qureg is a density matrix @f$ \dmrho @f$, the result approximates
437 * @f[
438 \approx V(\tau) \, \dmrho \, V(\tau)^\dagger.
439 * @f]
440 *
441 * > See applyTrotterizedPauliStrSumGadget() for information about the Trotter method.
442 *
443 * @par Utility
444 *
445 * Imaginary-time evolution drives the system toward the (unnormalised) groundstate of the Hamiltonian.
446 * Let @f$ \{ \ket{\phi_i} \} @f$ and @f$ \{ \ket{\lambda_i} \} @f$ be the eigenstates and respective
447 * eigenvalues of @f$ \hat{H} @f$, which are real due to Hermiticity.
448 * @f[
449 \hat{H} = \sum \limits_i \lambda_i \ket{\phi_i}\bra{\phi_i},
450 \;\;\;\;\; \lambda_i \in \mathbb{R}.
451 * @f]
452 *
453 * - When @p qureg is a statevector @f$ \svpsi @f$ and can ergo be expressed in the basis of
454 * @f$ \{ \ket{\phi_i} \} @f$ as @f$ \svpsi = \sum_i \alpha_i \ket{\phi_i} @f$,
455 * this function approximates
456 * @f[
457 \svpsi \, \rightarrow \, \hat{V}(\tau) \svpsi =
458 \sum\limits_i \alpha_i \exp(- \tau \, \lambda_i) \ket{\phi_i}.
459 * @f]
460 * - When @p qureg is a density matrix and is ergo expressible as
461 * @f$ \dmrho = \sum\limits_{ij} \alpha_{ij} \ket{\phi_i}\bra{\phi_j} @f$, this function effects
462 * @f[
463 \dmrho \, \rightarrow \, \hat{V}(\tau) \dmrho \hat{V}(\tau)^\dagger =
464 \sum\limits_{ij} \alpha_{ij} \exp(-\tau (\lambda_i + \lambda_j)) \ket{\phi_i}\bra{\phi_j}.
465 * @f]
466 *
467 * As @f$ \tau \rightarrow \infty @f$, the resulting unnormalised state approaches statevector
468 * @f$ \svpsi \rightarrow \alpha_0 \exp(-\tau \lambda_0) \ket{\phi_0} @f$ or density matrix
469 * @f$ \dmrho \rightarrow \alpha_{0,0} \exp(-2 \tau \lambda_0) \ket{\phi_0}\bra{\phi_0} @f$,
470 * where @f$ \lambda_0 @f$ is the minimum eigenvalue and @f$ \ket{\phi_0} @f$ is the groundstate.
471 * Assuming the initial overlap @f$ \alpha_0 @f$ is not zero (or exponentially tiny),
472 * subsequent renormalisation via setQuregToRenormalized() produces the pure
473 * ground-state @f$ \ket{\phi_0} @f$ or @f$ \ket{\phi_0}\bra{\phi_0} @f$.
474 *
475 * Note degenerate minimum eigenvalues will yield a pure superposition of the corresponding
476 * eigenstates, with coefficients informed by the initial, relative populations.
477 *
478 * @equivalences
479 *
480 * - This function merely wraps applyTrotterizedNonUnitaryPauliStrSumGadget() which effects @f$ \exp(\iu \theta \hat{H}) @f$,
481 * passing @f$ \theta = \tau \iu @f$.
482 *
483 * @constraints
484 *
485 * - While the process of imaginary-time evolution is non-unitary (and non-physical), Hermiticity of @p hamil is still
486 * assumed, requiring it contains only real coefficients. Validation will check that @p hamil is _approximately_ Hermitian,
487 * permitting coefficients with imaginary components smaller (in magnitude) than epsilon.
488 * @f[
489 \max\limits_{i} |c_i| \le \valeps
490 * @f]
491 * where the validation epsilon @f$ \valeps @f$ can be adjusted with setQuESTValidationEpsilon(). Beware however that
492 * imaginary-time evolution under a non-Hermitian Hamiltonian will _not_ necessarily approach the lowest lying eigenstate
493 * (the eigenvalues may be non-real) so is likely of limited utility.
494 *
495 * - The @p tau parameter is necessarily real such that evolution approaches the groundstate (modulo renormalisation).
496 * It can generalised to an arbitrary complex number through direct use of applyTrotterizedNonUnitaryPauliStrSumGadget().
497 *
498 * - Simulation is exact such that the effected operation is precisely @f$ \exp(-\tau \hat{H}) @f$ only when
499 * @p reps @f$ \rightarrow \infty @f$ or all terms in @p hamil commute with one another.
500 *
501 * @myexample
502 *
503 * ```
504 // pray for a non-zero initial overlap
505 initRandomPureState(qureg); // works even for density matrices
506
507 // minimize then renormalise
508 qreal tau = 10; // impatient infinity
509 int order = 4;
510 int reps = 100;
511 applyTrotterizedImaginaryTimeEvolution(qureg, hamil, tau, order, reps);
512 setQuregToRenormalized(qureg);
513
514 // ground-state (phi_0)
515 reportQureg(qureg);
516
517 // lowest lying eigenvalue (lambda_0)
518 qreal expec = calcExpecPauliStrSum(qureg, hamil);
519 reportScalar("expec", expec);
520 * ```
521 *
522 * @see
523 * - applyTrotterizedUnitaryTimeEvolution()
524 * - applyTrotterizedNonUnitaryPauliStrSumGadget()
525 *
526 * @param[in,out] qureg the state to modify.
527 * @param[in] hamil the Hamiltonian as a a weighted sum of Pauli strings.
528 * @param[in] tau the duration over which to simulate imaginary-time evolution.
529 * @param[in] order the order of the Trotter-Suzuki decomposition (e.g. @p 1, @p 2, @p 4, ...).
530 * @param[in] reps the number of Trotter repetitions.
531 * @param[in] permuteTerms whether to randomly reorder Pauli terms at each repetition.
532 *
533 * @throws @validationerror
534 * - if @p qureg or @p hamil are uninitialised.
535 * - if @p hamil contains non-identities on qubits beyond the size of @p qureg.
536 * - if @p hamil is not approximately Hermitian.
537 * - if @p order is not 1 nor a positive, @b even integer.
538 * - if @p reps is not a positive integer.
539 * - if internal allocation needed for term permutation fails.
540 *
541 * @author Tyson Jones
542 * @author Vasco Ferreira (randomisation)
543 */
544void applyTrotterizedImaginaryTimeEvolution(Qureg qureg, PauliStrSum hamil, qreal tau, int order, int reps, bool permuteTerms);
545
546
547/** @notyettested
548 *
549 * Simulates open dynamics of @p qureg as per the Lindblad master equation, under the time-independent
550 * Hamiltonian @p hamil and jump operators @p jumps with corresponding damping rates @p damps, with
551 * evolution approximated by symmetrized Trotterisation of the specified @p order and number of cycles
552 * @p reps.
553 *
554 * Note the ordering of all passed PauliStrSum (through functions like sortPauliStrSumMagnitude()) will
555 * affect that of the internally created super-propagator and ergo the Trotter accuracy. This is overridden
556 * by passing @p permuteTerms=true, whereby the super-propagator order is randomised every Trotter repetition.
557 *
558 * @formulae
559 *
560 * Let @f$ \rho = @f$ @p qureg, @f$ \hat{H} = @f$ @p hamil, @f$ t = @f$ @p time, and denote the @f$ i @f$-th
561 * element of @p damps and @p jumps as @f$ \gamma_i @f$ and @f$ \hat{J}_i @f$ respectively. The Lindblad
562 * master equation prescribes that @f$ \rho @f$ time-evolves according to
563 * @f[
564 \frac{\mathrm{d}}{\mathrm{d}t} \rho = -\iu [\hat{H}, \rho] + \sum\limits_i \gamma_i \left(
565 \hat{J}_i \rho \hat{J}_i^\dagger - \frac{1}{2} \left\{ \hat{J}_i^\dagger \hat{J}_i, \rho \right\}
566 \right).
567 * @f]
568 * This function works by building a superoperator of the right-hand-side which acts upon the space of
569 * linearised @f$\rho@f$,
570 * @f[
571 \boldsymbol{L} = -\iu \left( \hat{\id} \otimes \hat{H} - \hat{H}^* \otimes \hat{\id} \right) +
572 \sum\limits_i \gamma_i \left(
573 \hat{J}_i^* \otimes \hat{J}_i - \frac{1}{2} \hat{\id} \otimes (\hat{J}^\dagger J_i)
574 - \frac{1}{2} (\hat{J}^\dagger J_i)^* \otimes \hat{\id}
575 \right),
576 * @f]
577 * as a non-Hermitian weighted sum of Pauli strings (a PauliStrSum). The superoperator @f$ \boldsymbol{L} @f$
578 * informs a superpropagator which exactly solves evolution as:
579 * @f[
580 \ket{\rho(t)} = \exp\left( t \boldsymbol{L} \right) \ket{\rho(0)}.
581 * @f]
582 * This function approximates the superpropagator @f$ \exp\left( t \boldsymbol{L} \right) @f$ using a higher-order
583 * symmetrized Suzuki-Trotter decomposition, as informed by parameters @p order and @p reps.
584 *
585 * > See applyTrotterizedPauliStrSumGadget() for information about the Trotter method.
586 *
587 * @par Utility
588 *
589 * This function simulates time evolution of an open system, where the jump operators model interactions with
590 * the environment. This can capture sophisticated decoherence processes of the quantum state which are untenable
591 * to model as discrete operations with functions like mixKrausMap(). This function also proves useful for
592 * preparing realistic, physical input states to quantum metrological circuits, or the general high-performance
593 * simulation of digital time evolution of condensed matter systems.
594 *
595 * @equivalences
596 *
597 * - When `numJumps = 0`, evolution is unitary and the Lindblad master equation simplifes to the Liouville–von Neumann
598 * equation, which is equivalently (and more efficiently) simulated via applyTrotterizedUnitaryTimeEvolution().
599 *
600 * @constraints
601 *
602 * - Each damping rate in @p damps is expected to be a zero or positive number, in order for evolution to be trace
603 * preserving. Validation will assert that each damping rate @f$ \gamma_i @f$ satisfies
604 * @f[
605 \min\limits_{i} \gamma_i \ge - \valeps
606 * @f]
607 * where the validation epsilon @f$ \valeps @f$ can be adjusted with setQuESTValidationEpsilon(). Non-trace-preserving,
608 * negative damping rates can be simulated by disabling numerical validation via `setQuESTValidationEpsilon(0)`.
609 *
610 * - The @p time parameter is necessarily real, and cannot be generalised to imaginary or complex like in other
611 * functions. Generalisation is trivially numerically possible, but has no established physical meaning and so
612 * is not exposed in the API. Please open an issue on Github for advice on complex-time simulation.
613 *
614 * - Simulation is exact only when @p reps @f$ \rightarrow \infty @f$ or all terms in the superoperator
615 * @f$ \boldsymbol{L} @f$ incidentally commute with one another, and otherwise incorporates Trotter error.
616 * Unlike for unitary evolution, Trotter error _does_ break normalisation of the state and so this function
617 * is generally non-trace-preserving. In theory, normalisation can be restored with setQuregToRenormalized()
618 * though noticable norm-breaking indicates evolution was inaccurate, and should instead be repeated with
619 * increased @p order or @p reps parameters.
620 *
621 * - The function instantiates superoperator @f$ \boldsymbol{L} @f$ above as a temporary PauliStrSum, incurring a
622 * memory and time overhead which grows quadratically with the number of terms in @p hamil, plus quadratically
623 * with the number in each jump operator. These overheads may prove prohibitively costly for PauliStrSum
624 * containing very many terms.
625 *
626 * @myexample
627 *
628 * ```
629 // |+><+|
630 Qureg qureg = createDensityQureg(3);
631 initPlusState(qureg);
632
633 PauliStrSum hamil = createInlinePauliStrSum(R"(
634 1 IIX
635 2 IYI
636 3 ZZZ
637 )");
638
639 // |0><0|
640 PauliStrSum jump1 = createInlinePauliStrSum(R"(
641 0.5 I
642 0.5 Z
643 )");
644
645 // |1><0|
646 PauliStrSum jump2 = createInlinePauliStrSum(R"(
647 0.5 X
648 -0.5i Y
649 )");
650
651 // "noisiness"
652 qreal damps[] = {.3, .4};
653 PauliStrSum jumps[] = {jump1, jump2};
654 int numJumps = 2;
655
656 reportScalar("initial energy", calcExpecPauliStrSum(qureg, hamil));
657
658 // time and accuracy
659 qreal time = 0.5;
660 int order = 4;
661 int reps = 100;
662 applyTrotterizedNoisyTimeEvolution(qureg, hamil, damps, jumps, numJumps, time, order, reps);
663
664 reportScalar("final energy", calcExpecPauliStrSum(qureg, hamil));
665 * ```
666 *
667 * @see
668 * - applyTrotterizedUnitaryTimeEvolution()
669 * - applyTrotterizedImaginaryTimeEvolution()
670 *
671 * @param[in,out] qureg the density-matrix state to evolve and modify.
672 * @param[in] hamil the Hamiltonian of the qubit system (excludes any environment).
673 * @param[in] damps the damping rates of each jump operator in @p jumps.
674 * @param[in] jumps the jump operators specified as PauliStrSum.
675 * @param[in] numJumps the length of list @p jumps (and @p damps).
676 * @param[in] time the duration through which to evolve the state.
677 * @param[in] order the order of the Trotter-Suzuki decomposition (e.g. @p 1, @p 2, @p 4, ...).
678 * @param[in] reps the number of Trotter repetitions.
679 * @param[in] permuteTerms whether to randomly reorder Pauli terms at each repetition.
680 *
681 * @throws @validationerror
682 * - if @p qureg, @p hamil or any element of @p jumps are uninitialised.
683 * - if @p qureg is not a density matrix.
684 * - if @p hamil or any element of @p jumps contains non-identities on qubits beyond the size of @p qureg.
685 * - if @p hamil is not approximately Hermitian.
686 * - if @p numJumps is negative.
687 * - if any element of @p damps is not approximately positive.
688 * - if the total number of Lindbladian superoperator terms overflows the `qindex` type.
689 * - if all Lindbladian superoperator terms cannot simultaneously fit into CPU memory.
690 * - if memory allocation of the Lindbladian superoperator terms unexpectedly fails.
691 * - if @p order is not 1 nor a positive, @b even integer.
692 * - if @p reps is not a positive integer.
693 * - if internal allocation needed for term permutation fails.
694 *
695 * @author Tyson Jones
696 * @author Vasco Ferreira (randomisation)
697 */
698void applyTrotterizedNoisyTimeEvolution(Qureg qureg, PauliStrSum hamil, qreal* damps, PauliStrSum* jumps, int numJumps, qreal time, int order, int reps, bool permuteTerms);
699
700
701// end de-mangler
702#ifdef __cplusplus
703}
704#endif
705
706/** @} */
707
708
709
710#endif // TROTTERISATION_H
711
712/** @} */ // (end file-wide doxygen defgroup)
void applyTrotterizedMultiControlledPauliStrSumGadget(Qureg qureg, int *controls, int numControls, PauliStrSum sum, qreal angle, int order, int reps, bool permuteTerms)
void applyTrotterizedPauliStrSumGadget(Qureg qureg, PauliStrSum sum, qreal angle, int order, int reps, bool permuteTerms)
void applyTrotterizedControlledPauliStrSumGadget(Qureg qureg, int control, PauliStrSum sum, qreal angle, int order, int reps, bool permuteTerms)
void applyTrotterizedNonUnitaryPauliStrSumGadget(Qureg qureg, PauliStrSum sum, qcomp angle, int order, int reps, bool permuteTerms)
void applyTrotterizedMultiStateControlledPauliStrSumGadget(Qureg qureg, int *controls, int *states, int numControls, PauliStrSum sum, qreal angle, int order, int reps, bool permuteTerms)
void applyTrotterizedNoisyTimeEvolution(Qureg qureg, PauliStrSum hamil, qreal *damps, PauliStrSum *jumps, int numJumps, qreal time, int order, int reps, bool permuteTerms)
void applyTrotterizedUnitaryTimeEvolution(Qureg qureg, PauliStrSum hamil, qreal time, int order, int reps, bool permuteTerms)
void applyTrotterizedImaginaryTimeEvolution(Qureg qureg, PauliStrSum hamil, qreal tau, int order, int reps, bool permuteTerms)
Definition qureg.h:49