The Quantum Exact Simulation Toolkit v4.0.0
Loading...
Searching...
No Matches
initialisations.cpp
1/** @file
2 * API definitions for initialising Quregs into
3 * particular states. Note when a Qureg is GPU-
4 * accelerated, these functions only update the
5 * state in GPU memory; the CPU amps are unchanged.
6 *
7 * @author Tyson Jones
8 */
9
10#include "quest/include/qureg.h"
11#include "quest/include/calculations.h"
12#include "quest/include/initialisations.h"
13
14#include "quest/src/core/validation.hpp"
15#include "quest/src/core/localiser.hpp"
16#include "quest/src/core/utilities.hpp"
17#include "quest/src/core/bitwise.hpp"
18#include "quest/src/gpu/gpu_config.hpp"
19
20#include <algorithm>
21#include <cmath>
22
23
24// enable invocation by both C and C++ binaries
25extern "C" {
26
27
28
29/*
30 * INIT
31 */
32
33
34void initBlankState(Qureg qureg) {
35 validate_quregFields(qureg, __func__);
36
37 // |null> = {0, 0, 0, ...}
38 qcomp amp = 0;
39 localiser_statevec_initUniformState(qureg, amp);
40}
41
42
43void initZeroState(Qureg qureg) {
44 validate_quregFields(qureg, __func__);
45
46 // |0> = |0><0|
47 qindex ind = 0;
48 localiser_statevec_initClassicalState(qureg, ind);
49}
50
51
52void initPlusState(Qureg qureg) {
53 validate_quregFields(qureg, __func__);
54
55 // |+> = sum_i 1/sqrt(2^N) |i> where 2^N = numAmps
56 // |+><+| = sum_ij 1/2^N |i><j| where 2^N = sqrt(numAmps)
57 qcomp amp = 1.0 / std::sqrt(qureg.numAmps);
58 localiser_statevec_initUniformState(qureg, amp);
59}
60
61
62void initPureState(Qureg qureg, Qureg pure) {
63 validate_quregFields(qureg, __func__);
64 validate_quregFields(pure, __func__);
65 validate_quregCanBeInitialisedToPureState(qureg, pure, __func__);
66
67 // when qureg=statevec, we lazily invoke setQuregToSuperposition which
68 // invokes superfluous floating-point operations which will be happily
69 // occluded by the memory movement costs
70 (qureg.isDensityMatrix)?
71 localiser_densmatr_initPureState(qureg, pure):
72 localiser_statevec_setQuregToSuperposition(0, qureg, 1, pure, 0, pure);
73}
74
75
76void initClassicalState(Qureg qureg, qindex ind) {
77 validate_quregFields(qureg, __func__);
78 validate_basisStateIndex(qureg, ind, __func__);
79
80 // |ind><ind| = ||ind'>>
81 if (qureg.isDensityMatrix)
82 ind = util_getGlobalFlatIndex(qureg, ind, ind);
83
84 localiser_statevec_initClassicalState(qureg, ind);
85}
86
87
88void initDebugState(Qureg qureg) {
89 validate_quregFields(qureg, __func__);
90
91 localiser_statevec_initDebugState(qureg);
92}
93
94
95void initArbitraryPureState(Qureg qureg, qcomp* amps) {
96 validate_quregFields(qureg, __func__);
97
98 // set qureg = |amps> or |amps><amps|
99 (qureg.isDensityMatrix)?
100 localiser_densmatr_initArbitraryPureState(qureg, amps):
101 localiser_statevec_initArbitraryPureState(qureg, amps);
102}
103
104
105void initArbitraryMixedState(Qureg qureg, qcomp** amps) {
106 validate_quregFields(qureg, __func__);
107 validate_quregIsDensityMatrix(qureg, __func__);
108
109 localiser_densmatr_initArbitraryMixedState(qureg, amps);
110}
111
112
114 validate_quregFields(qureg, __func__);
115
116 // these invoked localiser functions may harmlessly
117 // re-call the API and re-perform input validation
118
119 if (qureg.isDensityMatrix)
120 localiser_densmatr_initUniformlyRandomPureStateAmps(qureg);
121 else {
122 localiser_statevec_initUnnormalisedUniformlyRandomPureStateAmps(qureg);
124 }
125}
126
127
128void initRandomMixedState(Qureg qureg, qindex numPureStates) {
129 validate_quregFields(qureg, __func__);
130 validate_quregIsDensityMatrix(qureg, __func__);
131 validate_numInitRandomPureStates(numPureStates, __func__);
132
133 localiser_densmatr_initMixtureOfUniformlyRandomPureStates(qureg, numPureStates);
134}
135
136
137
138/*
139 * SET
140 */
141
142
143void setQuregAmps(Qureg qureg, qindex startInd, qcomp* amps, qindex numAmps) {
144 validate_quregFields(qureg, __func__);
145 validate_quregIsStateVector(qureg, __func__);
146 validate_basisStateIndices(qureg, startInd, numAmps, __func__);
147
148 localiser_statevec_setAmps(amps, qureg, startInd, numAmps);
149}
150
151
152void setDensityQuregAmps(Qureg qureg, qindex startRow, qindex startCol, qcomp** amps, qindex numRows, qindex numCols) {
153 validate_quregFields(qureg, __func__);
154 validate_quregIsDensityMatrix(qureg, __func__);
155 validate_basisStateRowCols(qureg, startRow, startCol, numRows, numCols, __func__);
156
157 localiser_densmatr_setAmps(amps, qureg, startRow, startCol, numRows, numCols);
158}
159
160
161void setDensityQuregFlatAmps(Qureg qureg, qindex startInd, qcomp* amps, qindex numAmps) {
162 validate_quregFields(qureg, __func__);
163 validate_quregIsDensityMatrix(qureg, __func__);
164 validate_basisStateIndices(qureg, startInd, numAmps, __func__); // validation msg correct for density-matrix
165
166 localiser_statevec_setAmps(amps, qureg, startInd, numAmps);
167}
168
169
170void setQuregToClone(Qureg targetQureg, Qureg copyQureg) {
171 validate_quregFields(targetQureg, __func__);
172 validate_quregFields(copyQureg, __func__);
173 validate_quregsCanBeCloned(targetQureg, copyQureg, __func__);
174
175 // we invoke mixing/superposing, which involves superfluous
176 // floating-point operators but is not expected to cause an
177 // appreciable slowdown since simulation is memory-bound
178 (targetQureg.isDensityMatrix)?
179 localiser_densmatr_mixQureg(0, targetQureg, 1, copyQureg):
180 localiser_statevec_setQuregToSuperposition(0, targetQureg, 1, copyQureg, 0, copyQureg);
181}
182
183
184void setQuregToSuperposition(qcomp facOut, Qureg out, qcomp fac1, Qureg qureg1, qcomp fac2, Qureg qureg2) {
185 validate_quregFields(out, __func__);
186 validate_quregFields(qureg1, __func__);
187 validate_quregFields(qureg2, __func__);
188 validate_quregsCanBeSuperposed(out, qureg1, qureg2, __func__); // asserts statevectors
189
190 localiser_statevec_setQuregToSuperposition(facOut, out, fac1, qureg1, fac2, qureg2);
191}
192
193
195 validate_quregFields(qureg, __func__);
196
197 qreal prob = calcTotalProb(qureg); // harmlessly re-validates
198 validate_quregRenormProbIsNotZero(prob, __func__);
199
200 qreal norm = (qureg.isDensityMatrix)? prob : std::sqrt(prob);
201 qreal fac = 1 / norm;
202 localiser_statevec_setQuregToSuperposition(fac, qureg, 0, qureg, 0, qureg);
203
204 return fac;
205}
206
207
209 validate_quregFields(qureg, __func__);
210 validate_quregIsDensityMatrix(qureg, __func__);
211 validate_pauliStrSumFields(sum, __func__);
212 validate_pauliStrSumTargets(sum, qureg, __func__);
213
214 // sum is permitted to be non-Hermitian, since Hermiticity
215 // is insufficient to ensure qureg would be physical/valid
216
217 localiser_densmatr_setAmpsToPauliStrSum(qureg, sum);
218}
219
220
221void setQuregToPartialTrace(Qureg out, Qureg in, int* traceOutQubits, int numTraceQubits) {
222 validate_quregFields(in, __func__);
223 validate_quregFields(out, __func__);
224 validate_quregIsDensityMatrix(in, __func__);
225 validate_quregIsDensityMatrix(out, __func__);
226 validate_targets(in, traceOutQubits, numTraceQubits, __func__);
227 validate_quregCanBeSetToReducedDensMatr(out, in, numTraceQubits, __func__);
228
229 auto targets = util_getVector(traceOutQubits, numTraceQubits);
230 localiser_densmatr_partialTrace(in, out, targets);
231}
232
233
234void setQuregToReducedDensityMatrix(Qureg out, Qureg in, int* retainQubits, int numRetainQubits) {
235 validate_quregFields(in, __func__);
236 validate_quregFields(out, __func__);
237 validate_quregIsDensityMatrix(in, __func__);
238 validate_quregIsDensityMatrix(out, __func__);
239 validate_targets(in, retainQubits, numRetainQubits, __func__);
240 validate_quregCanBeSetToReducedDensMatr(out, in, in.numQubits - numRetainQubits, __func__);
241
242 auto traceQubits = util_getNonTargetedQubits(retainQubits, numRetainQubits, in.numQubits);
243 localiser_densmatr_partialTrace(in, out, traceQubits);
244}
245
246
247
248} // end de-mangler
qreal calcTotalProb(Qureg qureg)
void setDensityQuregFlatAmps(Qureg qureg, qindex startInd, qcomp *amps, qindex numAmps)
void setQuregToReducedDensityMatrix(Qureg out, Qureg in, int *retainQubits, int numRetainQubits)
void setQuregToPauliStrSum(Qureg qureg, PauliStrSum sum)
void setQuregAmps(Qureg qureg, qindex startInd, qcomp *amps, qindex numAmps)
void setQuregToPartialTrace(Qureg out, Qureg in, int *traceOutQubits, int numTraceQubits)
qreal setQuregToRenormalized(Qureg qureg)
void setQuregToClone(Qureg targetQureg, Qureg copyQureg)
void setDensityQuregAmps(Qureg qureg, qindex startRow, qindex startCol, qcomp **amps, qindex numRows, qindex numCols)
void setQuregToSuperposition(qcomp facOut, Qureg out, qcomp fac1, Qureg qureg1, qcomp fac2, Qureg qureg2)
void initArbitraryPureState(Qureg qureg, qcomp *amps)
void initRandomPureState(Qureg qureg)
void initPlusState(Qureg qureg)
void initZeroState(Qureg qureg)
void initPureState(Qureg qureg, Qureg pure)
void initDebugState(Qureg qureg)
void initRandomMixedState(Qureg qureg, qindex numPureStates)
void initClassicalState(Qureg qureg, qindex ind)
void initBlankState(Qureg qureg)
Definition qureg.h:42