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.
- 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
IsDenseis set to eithertrueorfalsethen return a densely or sparsely represented quantum space respectively. If no value is set forIsDensethen 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 \(2^n\), where \(n\) is the number of qubits of \(H\).
- IsDenselyRepresented(H): HilbSpc -> RngIntElt#
Return
trueif the quantum Hilbert space \(H\) uses a dense representation.
- H1 eq H2: HilbSpc, HilbSpc -> BoolElt#
Return
trueif the Hilbert spaces are equal.
- H1 ne H2: HilbSpc, HilbSpc -> BoolElt#
Return
trueif the Hilbert spaces are not equal.
- Example: Hilbert Space Create (ex-a2ce0e)#
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 \(| 1010 \rangle\). If set totruethen basis kets will be printed using integer values to represent the binary sequences, the previous example becoming \(| 5 \rangle\).
- Example: Quantum State Create (ex-1f7466)#
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: Quantum State Create Coerce (ex-9b3454)#
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
SetPrintKetsIntegerbasis 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 \(e_1\) and \(e_2\).
- 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
trueif and only if the quantum states \(e_1\) and \(e_2\) are equal. States are still considered equal if they have different normalizations.
- e1 ne e2: HilbSpcElt, HilbSpcElt -> BoolElt#
Return
trueif and only if the quantum states \(e_1\) and \(e_2\) are not equal. States are still considered equal if they have different normalizations.
- Example: Quantum State Normalisation (ex-d9a8c5)#
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 \(e_1\) and \(e_2\).
- 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: Infinity() 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
Maxis set to a positive integer, then it will denote the maximum number of basis states to be printed.If the variable argument
MinProbabilityis 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: Quantum State Probabilities (ex-c0f168)#
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: Quantum State Sorted Probabilities (ex-10594e)#
It is usually only those basis states with large probabilities that are of interest. With the function
PrintSortedProbabilitydistributionthese 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: Quantum State Unitary (ex-360d11)#
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>