Quantum Dimensions

Quantum Dimensions is an adaptation of Dimensions, where the program operates on qubits instead of numbers. Quantum Dimensions was invented in 2014 by Tom Price-Nicholson. There are several differences between Dimensions and Quantum Dimensions, including the removal of pointer velocity and the introduction of a def function that allows you to define your own quantum transformations. It is theoretically possible to implement Shor's algorithm in Quantum Dimensions, but it (probably) won't run in polynomial time. Quantum teleportation is possible, and a program is included below.

Setup
Quantum Dimensions has a 52-dimensional array of cells. Each dimension in the array in Quantum Dimensions is infinite. The first 26 dimensions are referred to as a-z and the second 26 are A-Z. Each cell can be empty, or can contain a qubit. At the start, all cells are empty. The pointer is initially at the origin. As each cell can only provide one binary digit, Quantum Dimensions has a binary list. This is a reserved piece of memory consisting of a 1D array of cells. When a qubit is measured, the value is printed to the first available space in the binary list. As this continues, a binary number is built up in the list, which can be ouputed. The binary list is initially empty.

Qubits
A qubit is defined as a|0> + b|1>, where |a|^2 + |b|^2 = 1. When defining a qubit in Quantum Dimensions, two items are needed: the angle of probability q, which is the angle in a bloch sphere between the |0> axis and the qubit; and the angle of phase p. Both angles are measured in radians. From these, a and b are defined: a = cos(q/2); b = sin(q/2)*(e^ip). Furthermore, if you know the probability of either 1 or 0, represented by P(1) and P(0), you can calculate q: 2 arccos(P(0)^0.5) = q = 2 arcsin(P(1)^0.5).

Syntax
You can choose which dimension or dimensions the current instruction acts in (if the instruction is dimension specific, such as moving the pointer) by typing in the letters of the dimensions that you want, e.g. AbCdXQzbF. You can also choose a range of dimensions, e.g. A-Q chooses every dimension from A to Q inclusive. Each instruction is enclosed in a pair of brackets to make it clear where one instruction ends and another begins. For example, (XCdfG>b<)(+) is a pair of instructions. A, B, C, D, E and F are used as example dimensions in the following explanations.

Moving the pointer
(ABC>DEF<) moves the pointer. The pointer moves one space forward in the dimensions followed by > and one space backwards in the dimensions followed by <. Both > and < must be included in the instruction, even if only one of them is used, so (A><) and (>B<) are valid but (C>) and (D<) are not.

Storing qubits in cells
(q#p) stores a qubit with probability angle q radians and phase p radians in the current cell. 0 ≤ q ≤ π must be obeyed.

Moving qubits between cells
(¬D<) moves the qubit in the current cell to the cell one space along in the specified direction, provided that the destination cell is empty. If the qubit is entangled with another, the entangled state is preserved.

Quantum entanglement
({E} A>) entangles the current qubit with the qubit one space along in the given direction, so that qubit 1 = NOT qubit 2, even after transformations are applied to either of the qubits (so if one qubit is transformed, the other is transformed as well so that qubit 1 = NOT qubit 2 still holds). The first qubit is unaffected and the second qubit is transformed to NOT qubit 1. If one of the qubits is measured to be a zero, the other is set to |1>, and if one is measured to be a one, the other is set to |0>, so they are still qubits, but you know what state they are in. ({D}) disentangles the current qubit with whatever qubit it was entangled with. Only two qubits can be entangled. If you try to entangle an entangled qubit with a third qubit, all three qubits in the system are destroyed (cells set to empty).

1 qubit transformations
These transformations are performed on one qubit. Each qubit is replaced by its transformed self, as are any qubits that they are entangled with.

Hadamard
({H}) performs the Hadamard transformation on the current qubit.

Pauli X
({X}) performs the Pauli X (NOT) transformation on the current qubit.

Pauli Y
({Y}) performs the Pauli Y transformation on the current qubit.

Pauli Z
({Z}) performs the Pauli Z transformation on the current qubit.

Phase shift
({P} p) performs the phase shift transformation on the current qubit, by p radians.

2 qubit transformations
These transformations are performed on two qubits. Each qubit is replaced by its transformed self, as are any qubits that they are entangled with.

CNOT
(A> {C}) performs the CNOT transformation on the current qubit, using the qubit one space along in the specified direction (A>; b<; etc.) as the control qubit.

SWAP
({S} B<) performs the SWAP transformation on the current qubit and the qubit one space along in the specified direction.

3 qubit transformations
These transformations are performed on three qubits. Each qubit is replaced with its transformed self, as are any qubits that they are entangled with.

Fredkin
(C> {F} D>) performs the Fredkin transformation on the current qubit and the qubit one space along in the direction specified after {F} (D> in this example), with the qubit one space along in the direction specified before {F} acting as the control qubit.

Toffoli
(E>F> {T}) performs the Toffoli transformation on the current qubit, with the qubits one space along in the specified directions acting as the control qubits.

def function
The def function allows you to define your own transformations.

( def {name}[number of qubits]  [first line of transformation matrix]   [second line of transformation matrix]   [etc.]   [number of control qubits {name} number of transformed qubits, including current qubit] )

and then the next definition (if there is one) or the main code goes underneath. For example:

( def {I}[3]  [10000000]   [01000000]   [00100000]   [00010000]   [00001000]   [00000100]   [00000010]   [00000001]   [2 {I} 1] ) (1#0)(A><)(1#1)(B>A<)(1#2)(>B<)(A>B>{I}) The name of the function cannot be C, D, E, F, H, P, S, T, X, Y, or Z, as these are already in use.

Input
(%) clears the current cell, then asks for q. Once q is given, it asks for p, the inputs the qubit (q#p) into the cell.

Output
(&) measures the current qubit, prints the result to the first available space in the binary list, then clears the cell.

(€) prints the current qubit on screen, in the form a|0> + b|1>, without destroying the qubit state.

(!) outputs the value of the binary list as a decimal number, then resets the binary list to empty.

(?) outputs the ASCII character that corresponds to the value of the binary list, then resets the binary list to empty.

Clearing cells
(/) clears the current cell.

(\) clears the binary list.

Loops
([) if the cell under the pointer is empty, skip to the instruction immediately after the next (]) instruction. Otherwise, continue as normal.

(]) jump back to the most recent (]) instruction.

Example programs
If anybody comes up with any example programs, feel free to post them in this section.

Hello World!
This program will print Hello World! on the screen. However, due to the quantum nature of the program, this will only occur ≈99% of the time.

(0.02046#0)(&)(3.12113#0)(&)(0.02046#0)(&)(0.02046#0)(&)(3.12113#0)(&)(0.02046#0)(&)(0.02046#0)(&)(0.02046#0)(&)(?)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(0.02046#0)(&)(0.02046#0)(&)(3.12113#0)(&)(0.02046#0)(&)(3.12113#0)(&)(?)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(0.02046#0)(&)(0.02046#0)(&)(?)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(0.02046#0)(&)(0.02046#0)(&)(?)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(3.12113#0)(&)(3.12113#0)(&)(?)(0.02046#0)(&)(0.02046#0)(&)(3.12113#0)(&)(0.02046#0)(&)(0.02046#0)(&)(0.02046#0)(&)(0.02046#0)(&)(0.02046#0)(&)(?)(0.02046#0)(&)(3.12113#0)(&)(0.02046#0)(&)(3.12113#0)(&)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(3.12113#0)(&)(?)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(3.12113#0)(&)(3.12113#0)(&)(?)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(3.12113#0)(&)(0.02046#0)(&)(0.02046#0)(&)(3.12113#0)(&)(0.02046#0)(&)(?)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(0.02046#0)(&)(0.02046#0)(&)(?)(0.02046#0)(&)(3.12113#0)(&)(3.12113#0)(&)(0.02046#0)(&)(0.02046#0)(&)(3.12113#0)(&)(0.02046#0)(&)(0.02046#0)(&)(?)(0.02046#0)(&)(0.02046#0)(&)(3.12113#0)(&)(0.02046#0)(&)(0.02046#0)(&)(0.02046#0)(&)(0.02046#0)(&)(3.12113#0)(&)(?)

Teleportation
This program will teleport a qubit from one cell to another.

(1#0)(a><)(2#0)({E}a<)(¬a>)(%)(€)({X})({S}a<)({D})(>a<)(/)(a><)(/)(a><)(€)

The program inputs two qubits, moves on one space to the right, asks for a qubit, inputs it in the space between the two existing qubits, then teleports the inputted qubit one space to the right.

True random number generator
This program is a true random number generator, as opposed to a pseudorandom number generator. Such a program is possible due to the quantum nature of the program. The random number is between 0 and 255 inclusive.

(1.57080#0)(&)(1.57080#0)(&)(1.57080#0)(&)(1.57080#0)(&)(1.57080#0)(&)(1.57080#0)(&)(1.57080#0)(&)(1.57080#0)(&)(!)

Disclaimer
Quantum Dimensions may seem needlessly complicated, but I never said that it was going to be easy. Check out Malbolge to see how hard esolangs can get.