Hilbert Spaces

In this first release, Magma offers a basic package for creating and computing with quantum Hilbert spaces. A Hilbert space in Magma can either be densely or sparsely represented, depending on how many qubits are required and how dense the desired quantum states will be. While a dense representation has a speed advantage in computations, the sparse representation uses less memory. Currently there are capabilities for doing basic unitary transformations and manipulations of quantum states.

In future versions, functionality will be added for more complex unitary transformations and measurements, allowing for a more general simulation of quantum computations. There will also be machinery for encoding quantum states using quantum error correcting codes, and testing their effectiveness by simulating a noisy quantum channel and decoding the results.

Contents

HilbertSpace(F, n) : FldCom, RngIntElt -> HilbSpc
    IsDense: BoolElt                    Default: 
Given a complex field F and a positive integer n, return then quantum Hilbert Space on n qubits over F.

If the variable argument IsDense is set to either true or false then return a densely or sparsely represented quantum space respectively. If no value is set for IsDense then Magma will decide automatically.

Field(H) : HilbSpc -> FldCom
Given a Hilbert space H, return the complex field over which the coefficients of states of H are defined.
NumberOfQubits(H) : HilbSpc -> RngIntElt
Nqubits(H) : HilbSpc -> RngIntElt
Given a Hilbert space H, return the number of qubits which comprises the space.
Dimension(H) : HilbSpc -> RngIntElt
Given a Hilbert space H, return its dimension. This is 2n, where n is the number of qubits of H.
IsDenselyRepresented(H) : HilbSpc -> RngIntElt
Return true if the quantum Hilbert space H uses a dense representation.
H1 eq H2 : HilbSpc, HilbSpc -> BoolElt
Return true if the Hilbert spaces are equal.
H1 ne H2 : HilbSpc, HilbSpc -> BoolElt
Return true if the Hilbert spaces are not equal.

Example QECC_HilbertSpaceCreate (H167E29)

A Hilbert space over 5 qubits will by default be a densely represented quantum space. It can however be manually chosen to use a sparse representation, it can be seen that these two space are not considered equal.
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 5);
> H;
A densely represented Hilbert Space on 5 qubits to precision 4
> Dimension(H);
32
> IsDenselyRepresented(H);
true
>
> H1 := HilbertSpace(F, 5 : IsDense := false);
> H1;
A sparely represented Hilbert Space on 5 qubits to precision 4
> IsDenselyRepresented(H1);
false
> H eq H1;
false

Creation of Quantum States

QuantumState(H, v) : HilbSpc, ModTupFldElt -> HilbSpcElt
QuantumState(H, v) : HilbSpc, MtrxSprs -> HilbSpcElt
Given a Hilbert space H and coefficients v (which can be either a dense or a sparse vector), of length equal to the dimension of H, then return the quantum state in H defined by v.
H ! i : HilbSpc, RngIntElt -> HilbSpcElt
Return the i-th quantum basis state of the Hilbert space H. This corresponds to the basis state whose qubits giving a binary representation of i.
H ! s : HilbSpc, [RngIntElt] -> HilbSpcElt
Given a sequence s of binary values, whose length is equal to the number of qubits of the Hilbert space H, return the quantum basis state corresponding to s.
SetPrintKetsInteger(b) : BoolElt ->
Input is a boolean value b, which controls a global variable determining the way quantum states are printed. If set to false (which is the default) then values in basis kets will be printed as binary sequences such as ket(1010). If set to true then basis kets will be printed using integer values to represent the binary sequences, the previous example becoming ket(5).

Example QECC_QuantumStateCreate (H167E30)

One way to create a quantum state is to specify each coefficient of the state with a vector of length equal to the dimension of the Hilbert space.
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 4);
> KS := KSpace(F, Dimension(H));
> v := KS! [F| i,    1,    0, -i,
>              2,    0,    0, 1+i,
>              -i-1, -3*i, 7, 0.5,
>              2.5*i, 0,   0, 1.2];
> v;
(1.000*i 1.000 0.0000 -1.000*i 2.000 0.0000 0.0000 1.000 + 1.000*i
    -1.000 - 1.000*i -3.000*i 7.000 0.5000 2.500*i 0.0000 0.0000
    1.200)
> e := QuantumState(H, v);
> e;
1.000*i|0000> + |1000> - 1.000*i|1100> + 2.000|0010> + (1.000 +
1.000*i)|1110> - (1.000 + 1.000*i)|0001> - 3.000*i|1001> + 7.000|0101>
+ 0.5000|1101> + 2.500*i|0011> + 1.200|1111>

Example QECC_QuantumStateCreateCoerce (H167E31)

Quantum states can be created by combining basis states, input as either integer values or binary sequences.
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 12);
> Dimension(H);
4096
> e1 := H!1 + (1+i)*(H!76) - H!3000;
> e1;
|100000000000> + (1.000 + 1.000*i)|001100100000> - |000111011101>
> e2 := H![1,0,1,1,1,0,0,0,1,1,0,0] - H![1,1,0,1,0,0,0,0,1,1,0,1];
> e2;
|101110001100> - |110100001101>
By using the function SetPrintKetsInteger basis states can also be printed as either integer values of binary sequences.
> SetPrintKetsInteger(true);
> e1;
|1> + (1.000 + 1.000*i)|76> - |3000>
> e2;
|797> - |2827>

Manipulation of Quantum States

a * e : FldComElt , HilbSpcElt -> HilbSpcElt
Given a complex scalar value a, multiply the coefficients of the quantum state e by a.
- e : HilbSpcElt -> HilbSpcElt
Negate all coefficients of the quantum state e.
e1 + e2 : HilbSpcElt, HilbSpcElt -> HilbSpcElt
e1 - e2 : HilbSpcElt, HilbSpcElt -> HilbSpcElt
Addition and subtraction of the quantum states e1 and e2.
Normalisation(e) : HilbSpcElt -> HilbSpcElt
Normalisation(~e) : HilbSpcElt ->
Normalization(e) : HilbSpcElt -> HilbSpcElt
Normalization(~e) : HilbSpcElt ->
Normalize the coefficients of the quantum state e, giving an equivalent state whose normalization coefficient is equal to one. Available either as a procedure or a function.
NormalisationCoefficient(e) : HilbSpc -> FldComElt
NormalizationCoefficient(e) : HilbSpc -> FldComElt
Return the normalisation coefficient of the quantum state e
e1 eq e2 : HilbSpcElt, HilbSpcElt -> BoolElt
Return true if and only if the quantum states e1 and e2 are equal. States are still considered equal if they have different normalizations.
e1 ne e2 : HilbSpcElt, HilbSpcElt -> BoolElt
Return true if and only if the quantum states e1 and e2 are not equal. States are still considered equal if they have different normalizations.

Example QECC_QuantumStateNormalisation (H167E32)

Although a quantum state can be expressed with any normalisation, in reality a quantum state occupies a ray in a Hilbert space. So two quantum states are still considered equal if they lie on the same ray.
> F<i> := ComplexField(8);
> H := HilbertSpace(F, 1);
> e := H!0 + H!1;
> e;
|0> + |1>
> NormalisationCoefficient(e);
2.0000000
> e1 := Normalisation(e);
> e1;
0.70710678|0> + 0.70710678|1>
> NormalisationCoefficient(e1);
0.99999999
> e eq e1;
true

Inner Product and Probabilities of Quantum States

InnerProduct(e1, e2) : HilbSpcElt, HilbSpcElt -> HilbSpcElt
Return the inner product of the quantum states e1 and e2.
ProbabilityDistribution(e) : HilbSpcElt -> Mtrx
Return the probability distribution of the quantum state as a vector over the reals.
Probability(e, i) : HilbSpcElt, RngIntElt -> FldReElt
Return the probability of basis state i being returned as the result of a measurement on the quantum state e.
Probability(e, v) : HilbSpcElt, RngIntElt -> FldReElt
Given a binary vector v of length equal to the number of qubits in the quantum state e, return the probability of basis state corresponding to v being returned as the result of a measurement on e.
PrintProbabilityDistribution(e) : HilbSpcElt ->
Print the probability distribution of the quantum state.
PrintSortedProbabilityDistribution(e) : HilbSpcElt ->
    Max: RngIntElt                      Default: ∞
    MinProbability: RngIntElt           Default: 0
Print the probability distribution of the quantum state in sorted order, with the most probable states printed first.

If the variable argument Max is set to a positive integer, then it will denote the maximum number of basis states to be printed.

If the variable argument MinProbability is set to some integer between 1 and 100, then it will denote the minimum probability of any basis state to be printed. This is useful for investigating those basis states which will are the likely results of any measurement.

Example QECC_QuantumStateProbabilities (H167E33)

From a quantum state it is possible to either access the full probability distribution, or the probabilities of individual basis states.
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 3);
> e := -0.5*H!0 + 6*i*H!3 + 7*H!4 - (1+i)*H!7;
> ProbabilityDistribution(e);
(0.002865 0.0000 0.0000 0.4126 0.5616 0.0000 0.0000 0.02292)
> Probability(e, 0);
0.002865
> Probability(e, 1);
0.0000
It is also possible to print out the full probability distribution.
> PrintProbabilityDistribution(e);
Non-zero probabilities:
|000>:  0.2865
|110>:  41.26
|001>:  56.16
|111>:  2.292

Example QECC_QuantumStateSortedProbabilities (H167E34)

It is usually only those basis states with large probabilities that are of interest. With the function PrintSortedProbabilitydistribution these basis states can be identified.
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 4);
> KS := KSpace(F, 2^4);
> v := KS! [F| i,   11,   0, -3*i,
>              2,   0,    0, 6+i,
>             -i-1, -3*i, 7, -0.5,
>             2.5*i, 0,   0, 9.2];
> e := QuantumState(H, v);
> e;
1.000*i|0000> + 11.00|1000> - 3.000*i|1100> + 2.000|0010> + (6.000 +
1.000*i)|1110> - (1.000 + 1.000*i)|0001> - 3.000*i|1001> + 7.000|0101>
- 0.5000|1101> + 2.500*i|0011> + 9.200|1111>
> PrintSortedProbabilityDistribution(e);
Non-zero probabilities:
|1000>:         37.45
|1111>:         26.19
|0101>:         15.16
|1110>:         11.45
|1100>:         2.785
|1001>:         2.785
|0011>:         1.934
|0010>:         1.238
|0001>:         0.6190
|0000>:         0.3095
|1101>:         0.07737
A useful way to isolate the important basis states is to provide a minimum cutoff probability.
> PrintSortedProbabilityDistribution(e: MinProbability := 15);
Non-zero probabilities:
|1000>:         37.45
|1111>:         26.19
|0101>:         15.16
Reached Minimum Percentage
Another way is to supply the maximum number basis states that should be printed. A combination of these methods can also be used
> PrintSortedProbabilityDistribution(e: Max := 6);
Non-zero probabilities:
|1000>:         37.45
|1111>:         26.19
|0101>:         15.16
|1110>:         11.45
|1100>:         2.785
|1001>:         2.785
Reached Maximum count

Unitary Transformations on Quantum States

In this first release Magma offers a small selection of unitary transformations on quantum states. In future versions this list will be expanded to include more complex operations.

BitFlip(e, k) : HilbSpcElt,RngIntElt -> HilbSpcElt
BitFlip(~e, k) : HilbSpcElt,RngIntElt ->
Flip the value of the k-th qubit of the quantum state e.
BitFlip(e, B) : HilbSpcElt, RngIntElt -> HilbSpcElt
BitFlip(~e, B) : HilbSpcElt,RngIntElt ->
Given a set of positive integers B, flip the value of the qubits of the quantum state e indexed by the entries in B.
PhaseFlip(e, k) : HilbSpcElt,RngIntElt -> HilbSpcElt
PhaseFlip(~e, k) : HilbSpcElt,RngIntElt ->
Flip the phase on the k-th qubit of the quantum state e.
PhaseFlip(e, B) : HilbSpcElt, RngIntElt -> HilbSpcElt
PhaseFlip(~e, B) : HilbSpcElt,RngIntElt ->
Given a set of positive integers B, flip the phase on the qubits of the quantum state e indexed by the entries in B.
ControlledNot(e, B, k) : HilbSpcElt, RngIntElt, RngIntElt -> HilbSpcElt
ControlledNot(~e, B, k) : HilbSpcElt, RngIntElt, RngIntElt ->
Flip the k-th bit of the quantum state e if all bits contained in B are set to 1.
HadamardTrasformation(e) : HilbSpcElt -> HilbSpcElt
HadamardTrasformation(~e) : HilbSpcElt ->
Perform a Hadamard transformation on the quantum state e, which must be densely represented.

Example QECC_QuantumStateUnitary (H167E35)

The behaviours of several of the available unitary transformations are displayed on a quantum state.
> F<i> := ComplexField(4);
> H := HilbertSpace(F, 4);
> e := H!0 + H!3 + H!6 + H!15;
> PhaseFlip(~e, 4); e;
|0000> + |1100> + |0110> - |1111>
> ControlledNot(~e, {1,2}, 4); e;
|0000> + |0110> - |1110> + |1101>
> BitFlip(~e, 2); e;
|0100> + |0010> - |1010> + |1001>
> ControlledNot(~e, {2}, 3); e;
|0010> - |1010> + |0110> + |1001>
V2.28, 13 July 2023