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