18#include "quest/include/quest.h"
36static std::mt19937 RNG;
43 std::random_device cspnrg;
44 unsigned seed = cspnrg();
64 DEMAND( min < maxExcl );
67 std::uniform_real_distribution<qreal> dist(min,maxExcl);
68 qreal out = dist(RNG);
74 out = std::nextafter(maxExcl, min);
77 DEMAND( out < maxExcl );
82qreal getRandomPhase() {
85 qreal pi = 3.14159265358979323846;
91 DEMAND( maxExcl >= min );
99 int out =
static_cast<int>(r);
101 DEMAND( out >= min );
102 DEMAND( out < maxExcl );
110 return qcomp(re, im);
114qcomp getRandomUnitComplex() {
115 return std::exp(1_i * getRandomPhase());
125vector<int> getRandomInts(
int min,
int maxExcl,
int len) {
127 DEMAND( min < maxExcl );
129 vector<int> out(len);
138vector<int> getRandomOutcomes(
int len) {
142 return getRandomInts(min, max+1, len);
146vector<int> getRandomSubRange(
int start,
int endExcl,
int numElems) {
147 DEMAND( endExcl >= start );
148 DEMAND( numElems >= 1 );
149 DEMAND( numElems <= endExcl - start );
152 vector<int> range = getRange(start, endExcl);
153 std::shuffle(range.begin(), range.end(), RNG);
156 return vector<int>(range.begin(), range.begin() + numElems);
162 vector<qreal> probs(numProbs, 0);
165 for (
auto& p : probs)
170 for (
auto& p : probs)
173 for (
auto& p : probs)
180listpair getRandomFixedNumCtrlsTargs(
int numQubits,
int numCtrls,
int numTargs) {
182 vector<int> targsCtrls = getRandomSubRange(0, numQubits, numTargs + numCtrls);
183 vector<int> targs = getSublist(targsCtrls, 0, numTargs);
184 vector<int> ctrls = getSublist(targsCtrls, numTargs, numCtrls);
186 return tuple{ctrls,targs};
190listtrio getRandomVariNumCtrlsStatesTargs(
int numQubits,
int minNumTargs,
int maxNumTargsIncl) {
191 DEMAND( minNumTargs <= maxNumTargsIncl );
192 DEMAND( maxNumTargsIncl <= numQubits );
194 int numTargs =
getRandomInt(minNumTargs, maxNumTargsIncl+1);
198 int maxNumCtrls = numQubits - numTargs;
199 int numCtrls =
getRandomInt(minNumCtrls, maxNumCtrls+1);
202 auto [ctrls,targs] = getRandomFixedNumCtrlsTargs(numQubits, numCtrls, numTargs);
203 vector<int> states = getRandomInts(0, 2, numCtrls);
205 return tuple{ctrls,states,targs};
215qvector getRandomVector(
size_t dim) {
217 qvector vec = getZeroVector(dim);
219 for (
auto& elem : vec)
226vector<qvector> getRandomOrthonormalVectors(
size_t dim,
int numVecs) {
228 DEMAND( numVecs >= 1);
230 vector<qvector> vecs(numVecs);
233 for (
int n=0; n<numVecs; n++) {
236 vecs[n] = getRandomVector(dim);
239 for (
int m=0; m<n; m++)
240 vecs[n] -= vecs[m] * getInnerProduct(vecs[m], vecs[n]);
243 vecs[n] = getNormalised(vecs[n]);
256qmatrix getRandomNonSquareMatrix(
size_t numRows,
size_t numCols) {
263 qmatrix out = qmatrix(numRows, qvector(numCols));
265 for (
auto& row : out)
266 for (
auto& elem : row)
273qmatrix getRandomMatrix(
size_t dim) {
275 return getRandomNonSquareMatrix(dim, dim);
279qmatrix getRandomDiagonalMatrix(
size_t dim) {
283 for (
size_t i=0; i<dim; i++)
298 return getNormalised(getRandomVector(getPow2(numQb)));
302vector<qvector> getRandomOrthonormalStateVectors(
int numQb,
int numStates) {
304 return getRandomOrthonormalVectors(getPow2(numQb), numStates);
312 int dim = getPow2(numQb);
317 for (
int i=0; i<dim; i++) {
319 dens += probs[i] * getOuterProduct(pure, pure);
329 qmatrix mat = getOuterProduct(vec, vec);
334void setToRandomState(qvector& state) {
337void setToRandomState(qmatrix& state) {
349 DEMAND( numQb >= 1 );
352 size_t dim = getPow2(numQb);
353 qmatrix matrZ = getRandomMatrix(dim);
354 qmatrix matrZT = getTranspose(matrZ);
357 qmatrix matrQT = getOrthonormalisedRows(matrZ);
358 qmatrix matrQ = getTranspose(matrQT);
362 for (
size_t r=0; r<dim; r++)
363 for (
size_t c=r; c<dim; c++)
364 matrR[r][c] = getInnerProduct(matrQT[r], matrZT[c]);
368 for (
size_t i=0; i<dim; i++)
369 matrD[i][i] = matrR[i][i] / std::abs(matrR[i][i]);
372 qmatrix matrU = matrQ * matrD;
374 DEMAND( isApproxUnitary(matrU) );
379qmatrix getRandomDiagonalUnitary(
int numQb) {
380 DEMAND( numQb >= 1 );
385 for (
size_t i=0; i<matr.size(); i++)
386 matr[i][i] = getRandomUnitComplex();
392qmatrix getRandomDiagonalHermitian(
int numQb) {
393 DEMAND( numQb >= 1 );
398 for (
size_t i=0; i<out.size(); i++)
406 DEMAND( numOps >= 1 );
409 vector<qmatrix> ops(numOps);
414 vector<qreal> weights(numOps);
415 for (
auto& w : weights)
420 for (
auto& w : weights)
422 for (
auto& w : weights)
423 w = std::sqrt(w/sum);
426 for (
int i=0; i<numOps; i++)
427 ops[i] *= weights[i];
429 DEMAND( isApproxCPTP(ops) );
440PauliStr getRandomPauliStr(
int numQubits) {
442 std::string paulis =
"";
443 for (
int i=0; i<numQubits; i++)
450PauliStr getRandomPauliStr(vector<int> targs) {
452 std::string paulis =
"";
453 for (
size_t i=0; i<targs.size(); i++)
460PauliStr getRandomDiagPauliStr(
int numQubits) {
462 std::string paulis =
"";
463 for (
int i=0; i<numQubits; i++)
470PauliStrSum createRandomNonHermitianPauliStrSum(
int numQubits,
int numTerms) {
472 vector<PauliStr> strings(numTerms);
473 for (
auto& str : strings)
474 str = getRandomPauliStr(numQubits);
476 vector<qcomp> coeffs(numTerms);
477 for (
auto& c : coeffs)
484PauliStrSum createRandomPauliStrSum(
int numQubits,
int numTerms) {
486 PauliStrSum out = createRandomNonHermitianPauliStrSum(numQubits, numTerms);
488 for (qindex i=0; i<numTerms; i++)
489 out.coeffs[i] = std::real(out.coeffs[i]);
std::vector< unsigned > getSeeds()
void setSeeds(unsigned *seeds, int numSeeds)
PauliStrSum createPauliStrSum(PauliStr *strings, qcomp *coeffs, qindex numTerms)
PauliStr getPauliStr(const char *paulis, int *indices, int numPaulis)
qmatrix getZeroMatrix(size_t dim)
qvector getRandomStateVector(int numQb)
qmatrix getRandomPureDensityMatrix(int numQb)
qmatrix getRandomUnitary(int numQb)
void setRandomTestStateSeeds()
qreal getRandomReal(qreal min, qreal maxExcl)
qmatrix getRandomDensityMatrix(int numQb)
vector< qreal > getRandomProbabilities(int numProbs)
vector< qmatrix > getRandomKrausMap(int numQb, int numOps)
int getRandomInt(int min, int maxExcl)