Skip to content

Commit

Permalink
removing Monte Carlo sampling
Browse files Browse the repository at this point in the history
pending further testing. This removes functions GetCircuitsFromChannel, GetRandomCircuitFromChannel, and SampleExpecPauliString
  • Loading branch information
TysonRayJones committed Nov 7, 2022
1 parent a2a5979 commit d133373
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 5 deletions.
20 changes: 18 additions & 2 deletions Link/QuESTlink.m
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,8 @@ CheckCircuitSchedule returns False if the (possibly symbolic) times cannot possi
(https://arxiv.org/pdf/1801.01053.pdf)"
GetKnownCircuit::error = "`1`"

(* BELOW ARE TEMPORARILY MADE PRIVATE DUE TO INSUFFICIENT TESTING BEFORE v012 RELEASE *)
(*
GetCircuitsFromChannel::usage = "GetCircuitsFromChannel[channel] returns a list of all pure, analytic circuits which are admitted as possible errors of the input channel (a circuit including decoherence). Coherent noise channels become unitaries weighted by a non-unitary Fac[] operator, while incoherent noise channels become non-trace-preserving Matr[] operators. The sum of the expected values of the (potentially unnormalised) state-vectors output by the returned circuits is equivalent to the expected value of the input channel.
See GetRandomCircuitFromChannel[] to randomly select one of these circuits, weighted by its probability.
See SampleExpecPauliString[] to sample such circuits in order to efficiently approximate the effect of decoherence on an expectation value."
Expand All @@ -280,6 +282,7 @@ CheckCircuitSchedule returns False if the (possibly symbolic) times cannot possi
SampleExpecPauliString[initQureg, channel, pauliString, numSamples, {workQureg1, workQureg2}] uses the given persistent working registers to avoid their internal creation and destruction.
Use option ShowProgress to monitor the progress of sampling."
SampleExpecPauliString::error = "`1`"
*)

SampleClassicalShadow::usage = "SampleClassicalShadow[qureg, numSamples] returns a sequence of pseudorandom measurement bases (X, Y and Z) and their outcomes (as bits) when performed on all qubits of the given input state.
\[Bullet] The output has structure { {bases, outcomes}, ...} where bases is a list of Pauli bases (encoded as 1=X, 2=Y, 3=Z) specified per-qubit, and outcomes are the corresponding classical qubit outcomes (0 or 1)."
Expand Down Expand Up @@ -714,6 +717,9 @@ The probability of the forced measurement outcome (if hypothetically not forced)
With[
{codes = codifyCircuit[circuit]},
Which[
MemberQ[codes[[1]], -1],
Message[ApplyCircuit::error, "Circuit contained an unrecognised gate: " <> ToString@StandardForm@
circuit[[ Position[codes[[1]], -1][[1,1]] ]]]; $Failed,
Not @ AllTrue[codes[[4]], Internal`RealValuedNumericQ, 2],
Message[ApplyCircuit::error, "Circuit contains non-numerical or non-real parameters!"]; $Failed,
Not @ Or[OptionValue[WithBackup] === True, OptionValue[WithBackup] === False],
Expand Down Expand Up @@ -786,6 +792,11 @@ The probability of the forced measurement outcome (if hypothetically not forced)
(* encode the circuit for the backend *)
encodedCirc = codifyCircuit[(circuit /. varVals)];

(* validate that all gates were recognised *)
If[MemberQ[encodedCirc[[1]], -1],
Throw["Circuit contained an unrecognised gate: " <> ToString@StandardForm@
circuit[[ Position[encodedCirc[[1]], -1][[1,1]] ]]]];

(* validate the circuit contains no unspecified variables *)
If[Not @ AllTrue[encodedCirc[[4]], Internal`RealValuedNumericQ, 2],
Throw @ "The circuit contained variables which were not assigned real values."];
Expand Down Expand Up @@ -1112,15 +1123,17 @@ The probability of the forced measurement outcome (if hypothetically not forced)
convertOpToPureCircs[g_] :=
{{g}} (* non-decoherence ops have no alternatives *)

GetCircuitsFromChannel[circ_?isCircuitFormat ] := With[
GetCircuitsFromChannel[circ_List /; isCircuitFormat[circ] ] := With[
{choices = convertOpToPureCircs /@ circ},
{numCircs = Times @@ Length /@ choices},
If[Ceiling @ Log2[numCircs] > $SystemWordLength,
Message[GetCircuitsFromChannel::error, "The number of unique circuit decompositions exceeds 2^$SystemWordLength and cannot be enumerated."]; $Failed,
Flatten /@ Tuples[choices]]]
GetCircuitsFromChannel[gate_?isCircuitFormat] :=
GetCircuitsFromChannel @ {gate}
GetCircuitsFromChannel[___] := invalidArgError[GetCircuitsFromChannel]

GetRandomCircuitFromChannel[ channel_?isCircuitFormat ] := With[
GetRandomCircuitFromChannel[ channel_List /; isCircuitFormat[channel] ] := With[

(* get circuit decompositions of each operator *)
{circs = convertOpToPureCircs /@ channel},
Expand Down Expand Up @@ -1149,6 +1162,8 @@ The probability of the forced measurement outcome (if hypothetically not forced)
choice /. Fac[_]->Nothing]] &,
{probs, circs}]
]
GetRandomCircuitFromChannel[operator_?isCircuitFormat] :=
GetRandomCircuitFromChannel @ {operator}
GetRandomCircuitFromChannel[___] := invalidArgError[GetRandomCircuitFromChannel]

Options[SampleExpecPauliString] = {
Expand Down Expand Up @@ -2254,6 +2269,7 @@ The probability of the forced measurement outcome (if hypothetically not forced)
getAnalGateMatrix[R[a_, pauli_]] := MatrixExp[-I a/2 getAnalGateMatrix @ pauli];
getAnalGateMatrix[R[a_, paulis_Times]] := MatrixExp[-I a/2 * KroneckerProduct @@ (getAnalGateMatrix /@ List @@ paulis)]
getAnalGateMatrix[Subscript[C, __][g_]] := getAnalGateMatrix[g]
getAnalGateMatrix[Subscript[Id, t__]] = IdentityMatrix[2^Length[{t}]]

(* extract ctrls from gate symbols *)
getAnalGateControls[Subscript[C, c_List][___]] := c
Expand Down
10 changes: 7 additions & 3 deletions Link/circuits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,12 @@ pauliOpType* local_preparePauliCache(pauliOpType pauli, int numPaulis) {
pauliOpType* local_preparePauliCache(qreal* paulis, int numPaulis) {

static pauliOpType pauliCache[MAX_NUM_TARGS_CTRLS];
for (int p=0; p < numPaulis; p++)
pauliCache[p] = (pauliOpType) ((int) paulis[p]);
for (int p=0; p < numPaulis; p++) {
if ((int) paulis[p] == OPCODE_Id)
pauliCache[p] = PAULI_I;
else
pauliCache[p] = (pauliOpType) ((int) paulis[p]);
}
return pauliCache;
}

Expand Down Expand Up @@ -236,7 +240,7 @@ std::string Gate::getSyntax() {
form = opStr + "[" + std::to_string(params[0]) + ", ";
for (int t=0; t<numTargs; t++) {
std::string paulis[] = {"Id", "X", "Y", "Z"};
std::string pauliStr = paulis[(int) params[t+1]];
std::string pauliStr = paulis[((int) params[t+1])%OPCODE_Id];
form += "Subscript[" + pauliStr + ", " + std::to_string(targs[t]) + "]";
}
form += "]";
Expand Down

0 comments on commit d133373

Please sign in to comment.