Paclet Resource

Wolfram

QuantumFramework

Perform analytic and numeric computation in Quantum Information Theory

Contributed By: Wolfram Research, Quantum Computation Framework team

Quantum Computing is an emerging technology that could revolutionize how computations are performed in the future. It operates based on the law of quantum mechanics - a radically different law of physics from the one our current computers are based on. A quantum computer may be able to solve problems that are difficult to solve using current computers such as breaking encryption, simulating a quantum system, or enhancing machine learning algorithms.

The Wolfram Language Quantum Computation Framework performs high-level analytic and numeric computations in Quantum Information Theory, allowing simulation of quantum circuits and quantum algorithms. Starting from discrete quantum mechanics, this framework can work with quantum states and quantum operators, implements measurements, performs basis manipulation, computes measure entanglement, and more. The semantics is very intuitive and it is equipped with various named states and operators such as Bell states, Pauli operators, universal quantum gates, and others. Thus, making it easy for people to simulate a quantum computer using the Wolfram Language.

Details

This paclet works with V12.3 and more of Woflram Language Mathematica.

Examples

Quantum Basis and State (19) 

In our Quantum Framework, a quantum state is defined with respect to a QuantumBasis. For pure states, the given input can be a list of amplitudes, or an association with keys corresponds to basis elements and values as amplitudes.


Define a 2D quantum basis (computational):

In[1]:=
PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumBasis"][2]
Out[1]=

Given the basis dimension n, the basis elements will be indexed by ket with i=0,1,...,n-1

In[2]:=
%["ElementAssociation"]
Out[2]=

Use a sequence as QuantumBasis[n,m], for n qudits of m-dimensional (overall dimension will be nm). For example, let us define a 2×2×2 dimensional quantum basis (three qubits):

In[3]:=
PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumBasis"][2, 3]
Out[3]=
In[4]:=
%["Dimensions"]
Out[4]=

Use a list as QuantumBasis[{n1,n2,...,nm}] for n1×n2×n2×...×nm dimensional Hilbert space of m qudits. For example, define a 3×5 dimensional quantum basis (two qudits):

In[5]:=
PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumBasis"][{3, 5}]
Out[5]=
In[6]:=
%["Dimensions"]
Out[6]=

A basis can also be defined by an association with the basis element names as keys, and corresponding vectors as values.

In[7]:=
PacletSymbol[
 "https://wolfr.am/ZcQr0uIt", "QuantumBasis"][<|a -> {1, I}, b -> {2, -I}|>]
Out[7]=

There are many named-basis built in the quantum framework, {"Computational", "PauliX", "PauliY", "PauliZ","Fourier", "Identity","Schwinger", "Pauli", "Dirac", "Wigner"}:

In[8]:=
Out[8]=

After a basis object has been defined, it is straightforward to use it to construct quantum states and operators. A quantum state is represented by QuantumState object and a quantum operator is represented by QuantumOperator.

For pure quantum states, a vector with elements as amplitudes, and the corresponding basis should be given in this format: QuantumState[amp_List,QuantumBasis[args]]. With no basis specified, the default basis will be the computational basis whose dimension depends on the amplitude vector.


Define a pure 2-dimensional quantum state (qubit) in the Pauli-X basis:

In[9]:=
PacletSymbol[
 "https://wolfr.am/ZcQr0uIt", "QuantumState"][{1, -1 + I}, PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumBasis"]["PauliX"]]
Out[9]=
In[10]:=
%["Formula"]
Out[10]=

If the basis is not specified, the default is the computational basis of 2n dimension (n qubits):

In[11]:=
PacletSymbol[
 "https://wolfr.am/ZcQr0uIt", "QuantumState"][{3, 2 I, 1, -5}]
%["Amplitudes"]
Out[11]=
Out[12]=

If the vector has more than 2 elements, it is interpreted as a n-qubit state (by right-padding of zeros), unless the dimension is specified.

In[13]:=
state = PacletSymbol[
  "https://wolfr.am/ZcQr0uIt", "QuantumState"][{2, 0, I}]
Out[13]=
In[14]:=
state["Amplitudes"]
Out[14]=

Same amplitude vector, but this time the dimension is specified:

In[15]:=
state = PacletSymbol[
   "https://wolfr.am/ZcQr0uIt", "QuantumState"][{2, 0, I}, 3];
state["Amplitudes"]
Out[16]=

Many named states are available for easy access:

In[17]:=
{PacletSymbol[
  "https://wolfr.am/ZcQr0uIt", "QuantumState"][{"UniformSuperposition", 4}], PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumState"][
  "PsiPlus"], PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumState"]["GHZ"]}
Out[17]=

Using associations, one can create a superposition of states, with keys as a list of corresponding indexes, and values as amplitudes. For example, let us create a superposition of 3 qubits (i.e., QuantumBasis[2,3]) as :

In[18]:=
\[Psi] = PacletSymbol[
  "https://wolfr.am/ZcQr0uIt", "QuantumState"][<|{0, 0, 0} -> 1/Sqrt[2], {1, 1, 1} -> 1/Sqrt[2]|>,
   2, 3]
Out[18]=
In[19]:=
\[Psi]["Formula"]
Out[19]=
In[20]:=
\[Psi]["Dimensions"]
Out[20]=

A different way of creating superposition is simple adding two quantum state objects. For example, the previous state can be constructed as follows, too:

In[21]:=
\[Psi]2 = (PacletSymbol[
      "https://wolfr.am/ZcQr0uIt", "QuantumState"][{"BasisState", {0, 0, 0}}] + PacletSymbol[
      "https://wolfr.am/ZcQr0uIt", "QuantumState"][{"BasisState", {1, 1, 1}}])/Sqrt[2];
\[Psi] == \[Psi]2
Out[19]=

Once a built-in basis is specified, amplitudes correspond to the basis elements. For example, let's use Bell basis:

In[22]:=
Normal /@ PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumBasis"]["Bell"][
  "ElementAssociation"]
Out[22]=
In[23]:=
\[Psi] = PacletSymbol[
  "https://wolfr.am/ZcQr0uIt", "QuantumState"][{2, -I, 1, 3}, PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumBasis"]["Bell"]]
Out[23]=
In[24]:=
\[Psi]["Amplitudes"]
Out[24]=

We can also define a state by inputting a density matrix:

In[25]:=
PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumState"][
 1/2 (IdentityMatrix[2] + PauliMatrix[2])]
Out[25]=

For pure states, one can get the corresponding normalized state vector:

In[26]:=
%["Formula"]
Out[26]=

Define a generic Bloch vector:

In[27]:=
mat[r_] /; VectorQ[r] := 1/2 (IdentityMatrix[2] + r . Table[PauliMatrix[i], {i, 3}])
In[28]:=
r = {.1, .1, 0};
state = PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumState"][
  mat[r]]
Out[20]=

Test if it is a mixed state:

In[29]:=
state["MixedStateQ"]
Out[29]=

Calculate Von Neumann Entropy:

In[30]:=
state["VonNeumannEntropy"]
Out[30]=

Purity:

In[31]:=
state["Purity"]
Out[31]=

A pure state (by normalizing the vector r):

In[32]:=
state = PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumState"][
  mat[Normalize@r]]
Out[32]=

Purity:

In[33]:=
state["PureStateQ"]
Out[33]=

Calculate Bloch Spherical Coordinates

In[34]:=
state["BlochSphericalCoordinates"]
Out[34]=

A matrix that is not positive semi-definite (cannot be a density matrix in standard QM, but in ZX-formalism we can have situations like this):

In[35]:=
mat[{1, 2, 0}] // PositiveSemidefiniteMatrixQ
Out[35]=

A non positive-semidefinite matrix as state:

In[36]:=
PacletSymbol["https://wolfr.am/ZcQr0uIt", "QuantumState"][
 mat[{1, 2, 0}]]
Out[36]=