Function applyPhaseFunc

Source
pub unsafe extern "C" fn applyPhaseFunc(
    qureg: Qureg,
    qubits: *mut c_int,
    numQubits: c_int,
    encoding: bitEncoding,
    coeffs: *mut f64,
    exponents: *mut f64,
    numTerms: c_int,
)
Expand description

Induces a phase change upon each amplitude of \p qureg, determined by the passed exponential polynomial “phase function”. This effects a diagonal unitary of unit complex scalars, targeting the nominated \p qubits.

  • Arguments \p coeffs and \p exponents together specify a real exponential polynomial \f$f(r)\f$ with \p numTerms terms, of the form \f[ f(r) = \sum\limits_{i}^{\text{numTerms}} \text{coeffs}[i] ; r^{, \text{exponents}[i]},, \f] where both \p coeffs and \p exponents can be negative, positive and fractional. For example,
       qreal coeffs[] = {1, -3.14};
       qreal exponents[] = {2, -5.5};
       int numTerms = 2;
    constitutes the function \f[ f(r) = 1 , r^2 - 3.14 , r^{-5.5}. \f] Note you cannot use fractional exponents with \p encoding = ::TWOS_COMPLEMENT, since the negative indices would generate (illegal) complex phases, and must be overriden with applyPhaseFuncOverrides(). \n

If your function \f$f(r)\f$ diverges at one or more \f$r\f$ values, you must instead use applyPhaseFuncOverrides() and specify explicit phase changes for these values. Otherwise, the corresponding amplitudes of the state-vector will become indeterminate (like NaN). Note that use of any negative exponent will result in divergences at \f$r=0\f$.

  • The function \f$f(r)\f$ specifies the phase change to induce upon amplitude \f$\alpha\f$ of computational basis state with index \f$r\f$, such that \f[ \alpha , |r\rangle \rightarrow , \exp(i f(r)) ; \alpha , |r\rangle. \f] The index \f$r\f$ associated with each computational basis state is determined by the binary value of the specified \p qubits (ordered least to most significant), interpreted under the given ::bitEncoding \p encoding. \n\n For example, under \p encoding = \p UNSIGNED and \p qubits = {0,1}, \f[ \begin{aligned} |0\mathbf{00}\rangle & \rightarrow , e^{i f(0)},|0\mathbf{00}\rangle \ |0\mathbf{01}\rangle & \rightarrow , e^{i f(1)},|0\mathbf{01}\rangle \ |0\mathbf{10}\rangle & \rightarrow , e^{i f(2)},|0\mathbf{10}\rangle \ |0\mathbf{11}\rangle & \rightarrow , e^{i f(3)},|0\mathbf{11}\rangle \ |1\mathbf{00}\rangle & \rightarrow , e^{i f(0)},|1\mathbf{00}\rangle \ |1\mathbf{01}\rangle & \rightarrow , e^{i f(1)},|1\mathbf{01}\rangle \ |1\mathbf{10}\rangle & \rightarrow , e^{i f(2)},|1\mathbf{10}\rangle \ |1\mathbf{11}\rangle & \rightarrow , e^{i f(3)},|1\mathbf{11}\rangle \end{aligned} \f]

  • If \p qureg is a density matrix \f$\rho\f$, this function modifies \p qureg to \f[ \rho \rightarrow \hat{D} , \rho , \hat{D}^\dagger \f] where \f$\hat{D}\f$ is the diagonal unitary operator \f[ \hat{D} = \text{diag} , { ; e^{i f(r_0)}, ; e^{i f(r_1)}, ; \dots ; }. \f] This means element \f$\rho_{jk}\f$ is modified to \f[ \alpha , |j\rangle\langle k| ; \rightarrow ; e^{i (f(r_j) - f(r_k))} ; \alpha , |j\rangle\langle k| \f]\n

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

    startRecordingQASM(qureg);
    applyPhaseFunc(qureg, ...);
    printRecordedQASM(qureg);

    may show

    // Here, applyPhaseFunc() multiplied a complex scalar of the form
    //     exp(i (1 x^3))
    //   upon every substate |x>, informed by qubits (under an unsigned binary encoding)
    //     {4, 1, 2, 0}

This function may become numerically imprecise for quickly growing phase functions which admit very large phases, for example of 10^10.

@see

  • applyPhaseFuncOverrides() to override the phase function for specific states.
  • applyMultiVarPhaseFunc() for multi-variable exponential polynomial phase functions.
  • applyNamedPhaseFunc() for a set of specific phase functions.
  • 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 the indices of the qubits which will inform \f$r\f$ for each amplitude in \p qureg @param[in] numQubits the length of list \p qubits @param[in] encoding the ::bitEncoding under which to infer the binary value \f$r\f$ from the bits of \p qubits in each basis state of \p qureg @param[in] coeffs the coefficients of the exponential polynomial phase function \f$f(r)\f$ @param[in] exponents the exponents of the exponential polynomial phase function \f$f(r)\f$ @param[in] numTerms the length of list \p coeffs, which must be the same as that of \p exponents @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
  • if \p numQubits < 0 or \p numQubits >= qureg.numQubitsRepresented
  • if \p encoding is not a valid ::bitEncoding
  • if \p encoding is not compatible with \p numQubits (e.g. \p TWOS_COMPLEMENT with only 1 qubit)
  • if \p exponents contains a fractional number despite \p encoding = ::TWOS_COMPLEMENT (you must instead use applyPhaseFuncOverrides() and override all negative indices)
  • if \p exponents contains a negative power (you must instead use applyPhaseFuncOverrides() and override the zero index)
  • if \p numTerms <= 0 @author Tyson Jones