Function applyNamedPhaseFunc

Source
pub unsafe extern "C" fn applyNamedPhaseFunc(
    qureg: Qureg,
    qubits: *mut c_int,
    numQubitsPerReg: *mut c_int,
    numRegs: c_int,
    encoding: bitEncoding,
    functionNameCode: phaseFunc,
)
Expand description

Induces a phase change upon each amplitude of \p qureg, determined by a named (and potentially multi-variable) phase function.

This effects a diagonal unitary operator, with a phase function \f$f(\vec{r})\f$ which may not be simply expressible as an exponential polynomial in functions applyPhaseFunc() and applyMultiVarPhaseFunc().

Arguments \p qubits and \p numQubitsPerReg encode sub-registers of \p qureg in the same manner as in applyMultiVarPhaseFunc():

  • Lists \p qubits and \p numQubitsPerReg together describe #numRegs sub-registers of \p qureg, which can each contain a different number of qubits. \n Although \p qubits is a flat list of unique qubit indices, it should be imagined grouped into #numRegs sub-lists, of lengths given by \p numQubitsPerReg. \n\n For example,

       int qubits[] =          {0,1,  3,4,5,  7}
       int numQubitsPerReg[] = {2,    3,      1};
       int numRegs = 3;

    describes three sub-registers, which are bolded below in an eight-qubit zero-state. \f[ |r_3\rangle ; |0\rangle ; |r_2\rangle ; |0\rangle ; |r_1\rangle = |\mathbf{0}\rangle ; |0\rangle ; |\mathbf{000}\rangle ; |0\rangle ; |\mathbf{00}\rangle \f] Note that the qubits need not be ordered increasing, and qubits within each sub-register are assumed ordered least to most significant in that sub-register.\n\n

    List \p qubits should have length equal to the sum of elements in \p numQubitsPerReg.

  • Each sub-register is associated with a variable \f$r_j\f$ in phase function \f$f(\vec{r})\f$. \n For a given computational basis state of \p qureg, the value of each variable is determined by the binary value in the corresponding sub-register, when intepreted with ::bitEncoding \p encoding. \n See ::bitEncoding for more information.\n\n

  • Argument \p functionNameCode determines the phase function \f$f(\vec{r})\f$.\n For example,

    int numRegs = 3;
    enum phaseFunc functionNameCode = NORM;

    describes phase function \f[ f(\vec{r}) = \sqrt{ {r_1}^2 + {r_2}^2 + {r_3} ^2 }. \f] See ::phaseFunc for a list and description of all named phase functions. \n Some phase functions, like \p SCALED_NORM, require passing additional parameters, through the function applyParamNamedPhaseFunc().\n\n

    If the phase function \f$f(\vec{r})\f$ diverges at one or more \f$\vec{r}\f$ values, you should instead use applyNamedPhaseFuncOverrides() and specify explicit phase changes for these coordinates. Otherwise, the corresponding amplitudes of \p qureg will become indeterminate (like NaN). \n

  • The function \f$f(\vec{r})\f$ specifies the phase change to induce upon amplitude \f$\alpha\f$ of computational basis state with the nominated sub-registers encoding values \f$r_1, ; \dots\f$. \f[ \alpha , |r_{\text{numRegs}}, ; \dots, ; r_2, ; r_1 \rangle \rightarrow , \exp(i f(\vec{r},)) ; \alpha , |r_{\text{numRegs}}, ; \dots, ; r_2, ; r_1 \rangle. \f] For example, using the sub-registers in the above example and \p encoding = \p UNSIGNED, the following states receive amplitude factors: \f[ \begin{aligned} |\mathbf{0}\rangle ; |0\rangle ; |\mathbf{000}\rangle ; |0\rangle ; |\mathbf{00}\rangle & \rightarrow , e^{i f(r_3=0,r_2=0,r_1=0)} \ |\mathbf{0}\rangle ; |0\rangle ; |\mathbf{000}\rangle ; |0\rangle ; |\mathbf{01}\rangle & \rightarrow , e^{i f(r_3=0,r_2=0,r_1=1)} \ |\mathbf{0}\rangle ; |0\rangle ; |\mathbf{000}\rangle ; |0\rangle ; |\mathbf{10}\rangle & \rightarrow , e^{i f(r_3=0,r_2=0,r_1=2)} \ |\mathbf{0}\rangle ; |0\rangle ; |\mathbf{000}\rangle ; |0\rangle ; |\mathbf{11}\rangle & \rightarrow , e^{i f(r_3=0,r_2=0,r_1=3)} \ |\mathbf{0}\rangle ; |0\rangle ; |\mathbf{000}\rangle ; |1\rangle ; |\mathbf{00}\rangle & \rightarrow , e^{i f(r_3=0,r_2=0,r_1=0)} \ & ;;;\vdots \ |\mathbf{0}\rangle ; |0\rangle ; |\mathbf{111}\rangle ; |0\rangle ; |\mathbf{01}\rangle & \rightarrow , e^{i f(r_3=0,r_2=7,r_1=1)} \ & ;;;\vdots \ |\mathbf{1}\rangle ; |0\rangle ; |\mathbf{111}\rangle ; |0\rangle ; |\mathbf{11}\rangle & \rightarrow , e^{i f(r_3=1,r_2=7,r_1=3)} \end{aligned} \f]\n

  • If \p qureg is a density matrix, its elements are modified to \f[ \alpha , |j\rangle\langle k| ; \rightarrow ; \exp(i (f(\vec{r}_j) , - , f(\vec{r}_k))) ; \alpha , |j\rangle\langle k| \f] where \f$f(\vec{r}_j)\f$ and \f$f(\vec{r}_k)\f$ are determined as above. This is equivalent to modification \f[ \rho ; \rightarrow ; \hat{D} , \rho , \hat{D}^\dagger \f] where \f$\hat{D}\f$ is the diagonal unitary \f[ \hat{D} = \text{diag}, { ; e^{i f(\vec{r_0})}, ; e^{i f(\vec{r_1})}, ; \dots ; }. \f]\n

  • The interpreted phase function can be previewed in the QASM log, as a comment. \n For example:

    startRecordingQASM(qureg);
    applyNamedPhaseFunc(qureg, ..., INVERSE_DISTANCE, ... );
    printRecordedQASM(qureg);

    may show

    // Here, applyNamedPhaseFunc() multiplied a complex scalar of form
    //     exp(i 1 / sqrt((x-y)^2 + (z-t)^2))

\n

@see

  • applyNamedPhaseFuncOverrides() to additionally specify phase values for specific sub-register indices.
  • applyParamNamedPhaseFunc() to specify named phase functions which require additional parameters.
  • applyPhaseFunc() to specify a general single-variable exponential polynomial phase function.
  • applyMultiVarPhaseFunc() to specify a general multi-variable exponential polynomial phase function.
  • applyDiagonalOp() to apply a non-unitary diagonal operator.

@ingroup operator @param[in,out] qureg the state-vector or density-matrix to be modified @param[in] qubits a list of all the qubit indices contained in each sub-register @param[in] numQubitsPerReg a list of the lengths of each sub-list in \p qubits @param[in] numRegs the number of sub-registers, which is the length of both \p numQubitsPerReg and \p numTermsPerReg @param[in] encoding the ::bitEncoding under which to infer the binary value \f$r_j\f$ from the bits of a sub-register @param[in] functionNameCode the ::phaseFunc \f$f(\vec{r})\f$ @exception invalidQuESTInputError()

  • if any qubit in \p qubits has an invalid index (i.e. does not satisfy 0 <= qubit < qureg.numQubitsRepresented)
  • if the elements of \p qubits are not unique (including if sub-registers overlap)
  • if \p numRegs <= 0 or \p numRegs > 100 (constrained by MAX_NUM_REGS_APPLY_ARBITRARY_PHASE in QuEST_precision.h)
  • if \p encoding is not a valid ::bitEncoding
  • if the size of any sub-register is incompatible with \p encoding (e.g. contains fewer than two qubits in \p encoding = \p TWOS_COMPLEMENT)
  • if \p functionNameCode is not a valid ::phaseFunc
  • if \p functionNameCode requires additional parameters, which must instead be passed with applyParamNamedPhaseFunc() @author Tyson Jones