The Quantum Exact Simulation Toolkit v4.2.0
Loading...
Searching...
No Matches

Functions for calculating reduced density matrices, creating a new output Qureg. More...

Functions

Qureg calcPartialTrace (Qureg qureg, int *traceOutQubits, int numTraceQubits)
 
Qureg calcReducedDensityMatrix (Qureg qureg, int *retainQubits, int numRetainQubits)
 

Detailed Description

Functions for calculating reduced density matrices, creating a new output Qureg.

Function Documentation

◆ calcPartialTrace()

Qureg calcPartialTrace ( Qureg qureg,
int * traceOutQubits,
int numTraceQubits )

Creates and populates a new Qureg which is a reduced density matrix resulting from tracing out the specified qubits of qureg. This should be later freed by the user like all Qureg.

Note that the deployments of the output Qureg (i.e. whether multithreaded, GPU-accelerated and distributed) will match those of qureg. It is ergo intended that this function is used to trace out few qubits, and may show worsening performance when tracing many qubits.

The ordering of traceOutQubits has no effect, and the ordering of the remaining qubits in the output Qureg match their original relative ordering in qureg.

Formulae

Let \(\dmrho_{\text{in}} = \) qureg and let \(\vec{t} = \) traceOutQubits which is a list of length \(n = \) numTraceQubits.

This function returns a new Qureg \(\dmrho_{\text{out}}\) which satisfies

\[ \dmrho_{\text{out}} = \text{Tr}_{\vec{t}} \left( \dmrho_{\text{in}} \right) = \sum\limits_i^{2^n} (\hat{\id} \otimes \bra{i}_{\vec{t}} ) \, \dmrho_{\text{in}} \, (\hat{\id} \otimes \ket{i}_{\vec{t}} ) \]

where \(\ket{i}_{\vec{t}}\) notates the \(i\)-th basis state (in any orthonormal basis) of the targeted qubits, and \((\hat{\id} \otimes \ket{i}_{\vec{t}})\) notates interleaved identity operators upon the non-targeted qubits.

Given an \(N\)-qubit Qureg \(\dmrho_{\text{in}}\), the output \(\dmrho_{\text{out}}\) contains \(N-n\) qubits.

Constraints
Equivalences
Example
reportQureg(state);
int qubits[] = {0,2,4};
Qureg reduced = calcPartialTrace(state, qubits, 3);
reportQureg(reduced);
// state's qubits {1,3} have become reduced's qubits {0,1}
void initRandomMixedState(Qureg qureg, qindex numPureStates)
void reportQureg(Qureg qureg)
Definition qureg.cpp:375
Parameters
[in]qurega density matrix which is not modified.
[in]traceOutQubitsa list of qubits to trace out and ergo from the output Qureg.
[in]numTraceQubitsthe length of traceOutQubits.
Returns
A new, smaller Qureg initialised to the reduced density matrix of qureg.
Exceptions
error
  • if qureg is uninitialised.
  • if numTraceQubits is less than one.
  • if numTraceQubits is equal or greater than the number of qubits in qureg.
  • if qureg is distributed and numTraceQubits exceeds qureg.numQubits - qureg.logNumNodes.
  • if the system contains insufficient RAM (or VRAM) to store the new Qureg in any deployment.
  • if any memory allocation of the output Qureg unexpectedly fails.
seg-fault
  • if traceOutQubits is not a list of length numTraceQubits.
Attention
This function's input validation has not yet been unit tested, so erroneous usage may produce unexpected output. Please use with caution!
See also
Author
Tyson Jones

Definition at line 373 of file calculations.cpp.

373 {
374 validate_quregFields(qureg, __func__);
375 validate_quregIsDensityMatrix(qureg, __func__);
376 validate_targets(qureg, traceOutQubits, numTraceQubits, __func__);
377 validate_quregCanBeReduced(qureg, numTraceQubits, __func__);
378
379 // attempt to create reduced Qureg with same deployments as input Qureg
380 Qureg out = validateAndCreateCustomQureg(
381 qureg.numQubits - numTraceQubits,
382 qureg.isDensityMatrix, qureg.isDistributed,
383 qureg.isGpuAccelerated, qureg.isMultithreaded, __func__);
384
385 // set it to reduced density matrix
386 auto targets = util_getVector(traceOutQubits, numTraceQubits);
387 localiser_densmatr_partialTrace(qureg, out, targets);
388
389 return out;
390}

Referenced by calcPartialTrace(), calcReducedDensityMatrix(), and TEST_CASE().

◆ calcReducedDensityMatrix()

Qureg calcReducedDensityMatrix ( Qureg qureg,
int * retainQubits,
int numRetainQubits )

Creates and populates a new Qureg which is a reduced density matrix of qureg, retaining only the specified qubits and tracing out all others.

Note that the deployments of the output Qureg (i.e. whether multithreaded, GPU-accelerated and distributed) will match those of qureg. It is ergo intended that this function is used to preserve most qubits of qureg, and may show worsening performance when retaining only few.

Attention
The ordering of retainQubits has no effect on the output state. The ordering of the retained qubits will match their original, relative ordering in qureg.
Formulae

This function is entirely equivalent to calcPartialTrace() except that here the retained qubits are specified, whereas calcPartialTrace() accepts those to be traced out.

Let \(\dmrho_{\text{in}} = \) qureg, \(\vec{r} = \) retainQubits, and let \(\vec{q}\) be a list containing all qubits of qureg. This function partially traces out all qubits in list \(\vec{t} = \vec{q} \setminus \vec{r}\), and returns a new Qureg \(\dmrho_{\text{out}}\) which satisfies

\[ \dmrho_{\text{out}} = \text{Tr}_{\vec{t}} \left( \dmrho_{\text{in}} \right) = \sum\limits_i^{2^n} (\hat{\id} \otimes \bra{i}_{\vec{t}} ) \, \dmrho_{\text{in}} \, (\hat{\id} \otimes \ket{i}_{\vec{t}} ) \]

where \(\ket{i}_{\vec{t}}\) notates the \(i\)-th basis state (in any orthonormal basis) of the qubits in \(\vec{t}\), and \((\hat{\id} \otimes \ket{i}_{\vec{t}})\) notates interleaved identity operators upon the qubits in \(\vec{r}\).

Constraints
  • The given qureg must be a density matrix. It is however straightforward to prepare a density matrix from a statevector.
    // let qureg be the intended initial statevector
    Qureg temp = createDensityQureg(qureg.numQubits);
    initPureState(temp, qureg);
    Qureg reduced = calcReducedDensityMatrix(temp, retainQubits, numRetainQubits);
    Qureg calcReducedDensityMatrix(Qureg qureg, int *retainQubits, int numRetainQubits)
  • When qureg is distributed, the returned Qureg will also be distributed, which imposes a minimum on the number of qubits contained within; \(\log_2(W)\) where \(W\) is the number of distributed nodes (or "world size"). This imposes bounds upon numRetainQubits of
    qureg.logNumNodes <= numRetainQubits <= qureg.numQubits - 1
Equivalences
Example
reportQureg(state);
int qubits[] = {1,3};
Qureg reduced = calcReducedDensityMatrix(state, qubits, 2);
reportQureg(reduced);
// state's qubits {1,3} have become reduced's qubits {0,1}
Parameters
[in]qurega density matrix.
[in]retainQubitsa list of qubits to retain in the reduced density matrix (at shifted, contiguous indices).
[in]numRetainQubitsthe length of retainQubits.
Returns
A new Qureg containing numRetainQubits qubits, initialised to the reduced density matrix of qureg.
Exceptions
error
  • if qureg is uninitialised.
  • if numRetainQubits is less than one.
  • if numRetainQubits is equal or greater than the number of qubits in qureg.
  • if qureg is distributed and numRetainQubits is less than qureg.logNumNodes.
  • if the system contains insufficient RAM (or VRAM) to store the new Qureg in any deployment.
  • if any memory allocation of the output Qureg unexpectedly fails.
seg-fault
  • if retainQubits is not a list of length numRetainQubits.
Attention
This function's input validation has not yet been unit tested, so erroneous usage may produce unexpected output. Please use with caution!
See also
Author
Tyson Jones

Definition at line 393 of file calculations.cpp.

393 {
394 validate_quregFields(qureg, __func__);
395 validate_quregIsDensityMatrix(qureg, __func__);
396 validate_targets(qureg, retainQubits, numRetainQubits, __func__);
397 validate_quregCanBeReduced(qureg, qureg.numQubits - numRetainQubits, __func__);
398
399 auto traceQubits = util_getNonTargetedQubits(retainQubits, numRetainQubits, qureg.numQubits);
400
401 // harmlessly re-validates
402 return calcPartialTrace(qureg, traceQubits.data(), traceQubits.size());
403}

Referenced by calcReducedDensityMatrix(), and TEST_CASE().