Skip to content

Commit

Permalink
Updates to documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Benn Bollay committed Mar 28, 2018
1 parent 8e732bd commit 6e9fdf2
Show file tree
Hide file tree
Showing 7 changed files with 162 additions and 32 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.pyc
_build
13 changes: 11 additions & 2 deletions docs/api/coherent_unit.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
.. Copyright (c) 2018
Qrack::CoherentUnit
================
===================

Defined in `qregister.hpp <https://github.com/vm6502q/qrack/blob/master/qregister.hpp>`_.

Expand All @@ -30,7 +30,12 @@ Constructors

.. doxygenfunction:: CoherentUnit(const CoherentUnit&)

Utility and Configuration Methods
Members
-------

.. doxygenvariable:: stateVec

Configuration Methods
---------------------------------

.. doxygenfunction:: SetRandomSeed
Expand Down Expand Up @@ -127,4 +132,8 @@ Quantum Gates

.. doxygenfunction:: CRZDyad(int, int, bitLenInt, bitLenInt, bitLenInt)

Internal Utility Methods
------------------------

.. doxygenfunction:: Apply2x2

71 changes: 71 additions & 0 deletions docs/examples.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
Examples
--------

The `quantum enabled cc65 <https://github.com/vm6502q/cc65>`_ compiler provides a mechanism to both compile the `examples <https://github.com/vm6502q/examples>`_ as well as develop new programs to execute on the *vm6502q* virtual machine. These changes live on the *6502q* branch.

Start by compiling the *cc65* repository and the *vm6502q* virtual machine:

.. code-block:: bash
cc65/ $ git checkout 6502q
cc65/ $ make
...
vm6502q/ $ make
Then, make the various examples:

.. code-block:: bash
examples/ $ cd hello_c && make
# OR if to directly execute within the emulator
examples/ $ cd hello_c && make run
...
.. code-block:: text
hello world
^C
Interrupted at e002
Emulation performance stats is OFF.
*-------------*-----------------------*----------*----------*
| PC: $e002 | Acc: $0e (00001110) | X: $55 | Y: $0c |
*-------------*-----------------------*----------*----------*
| NVQBDIZC | :
| 00000100 | :
*-------------*
Stack: $f7
[03 04 03 04 e2 00 fe 01 ]
I/O status: enabled, at: $e000, local echo: OFF.
Graphics status: disabled, at: $e002
ROM: disabled. Range: $d000 - $dfff.
Op-code execute history: disabled.
------------------------------------+----------------------------------------
C - continue, S - step | A - set address for next step
G - go/cont. from new address | N - go number of steps, P - IRQ
I - toggle char I/O emulation | X - execute from new address
T - show I/O console | B - blank (clear) screen
E - toggle I/O local echo | F - toggle registers animation
J - set animation delay | M - dump memory, W - write memory
K - toggle ROM emulation | R - show registers, Y - snapshot
L - load memory image | O - display op-code exec. history
D - disassemble code in memory | Q - quit, 0 - reset, H - help
V - toggle graphics emulation | U - enable/disable exec. history
Z - enable/disable debug traces | 1 - enable/disable perf. stats
2 - display debug traces | ? - show this menu
------------------------------------+----------------------------------------
> q
Thank you for using VM65.
Use *Ctrl-C* to bring up the in-VM menu, and *q* to exit.

Creating a new example
======================

* Copy the ``prototype/`` directory to your example name, renaming the ``.cfg`` file to match the source file.
* Change ``prototype`` in ``Makefile`` to be the basename of your cfg and source file.
* Adjust the ``project.cfg`` file as necessary for memory sizing.

4 changes: 2 additions & 2 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,17 +55,17 @@ Qrack is a C++ quantum bit simulator, with the ability to support arbitrary numb

As a demonstration of the :cpp:class:`Qrack::CoherentUnit` implementation, a MOS-6502 microprocessor [MOS-6502]_ virtual machine has been modified with a set of new opcodes supporting quantum operations. The `vm6502q <https://github.com/vm6502q/vm6502q>`_ virtual machine exposes new integrated quantum opcodes such as a Grover Search [Grover]_ across a page of memory. These programs are demonstrated in the `examples <https://github.com/vm6502q/examples>`_ repository.

Finally, a `6502 toolchain <https://github.com/vm6502q/cc65>`_, based on the CC65 toolchain [CC65]_, has been modified and enhanced to support both the new opcodes - for the assembler - as well as :ref:`c-syntax-enhancements-ref`. This is performed primarily as sandbox/exploratory work to help clarify what quantum computational software engineering might look like as the hardware reaches commoditization.
Finally, a `6502 toolchain <https://github.com/vm6502q/cc65>`_ - based on CC65 `CC65 <http://cc65.github.io/doc/>`_ - has been modified and enhanced to support both the new opcodes - for the assembler - as well as :ref:`c-syntax-enhancements-ref`. This is performed primarily as sandbox/exploratory work to help clarify what quantum computational software engineering might look like as the hardware reaches commoditization.

.. toctree::
:maxdepth: 2
:hidden:

Introduction <self>
start
examples
theory
implementation
citations

.. toctree::
:hidden:
Expand Down
56 changes: 28 additions & 28 deletions docs/legacy.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,22 @@ Primarily, this documentation teaches enough practical quantum computation and e
Quantum Bit Permutation Basis Overview
--------------------------------------

Like classical bits, a set of qubits has a maximal representation as the permutation of bits. (An 8 bit byte has 256 permutations, commonly numbered 0 to 255, as does an 8 bit qubyte.) Additionally, the state of a qubyte is fully specified in terms of probability and phase of each permutation of qubits. This is the ":math:`|0\rangle/|1\rangle`" or "permutation basis." There are other fully descriptive bases, such as the ":math:`|+\rangle/|-\rangle`" permutation basis, which is characteristic of Hadamard gates. The notation ":math:`|x\rangle`" represents a "ket" of the "x" state in the quantum "bra-ket" notation of Dirac. It is a quantum state vector as described by Schrödinger's equation. When we say :math:`|01\rangle`, we mean the qubit equivalent of the classical binary bit permutation "01."
Like classical bits, a set of qubits has a maximal representation as the permutation of bits. (An 8 bit byte has 256 permutations, commonly numbered 0 to 255, as does an 8 bit qubyte.) Additionally, the state of a qubyte is fully specified in terms of probability and phase of each permutation of qubits. This is the ":math:`\rvert0\rangle/\rvert1\rangle`" or "permutation basis." There are other fully descriptive bases, such as the ":math:`\rvert+\rangle/\rvert-\rangle`" permutation basis, which is characteristic of Hadamard gates. The notation ":math:`\rvertx\rangle`" represents a "ket" of the "x" state in the quantum "bra-ket" notation of Dirac. It is a quantum state vector as described by Schrödinger's equation. When we say :math:`\rvert01\rangle`, we mean the qubit equivalent of the classical binary bit permutation "01."

The state of a two bit permutation can be described as follows: where one in the set of variables ":math:`x_0, x_1, x_2,` and :math:`x_3`" is equal to 1 and the rest are equal to zero, the state of the bit permutation can always be described by:

.. math:: |\psi\rangle = x_0 |00\rangle + x_1 |01\rangle + x_2 |10\rangle + x_3 |11\rangle
.. math:: \rvert\psi\rangle = x_0 \rvert00\rangle + x_1 \rvert01\rangle + x_2 \rvert10\rangle + x_3 \rvert11\rangle
:label: psi_prob

.. Syntax Highlight fixing comment: `|
.. Syntax Highlight fixing comment: `\rvert
One of the leading variables is always 1 and the rest are always 0. That is, the state of the classical bit combination is always exactly one of :math:`|00\rangle, |01\rangle, |10\rangle,` or :math:`|11\rangle,` and is not probabilistic in it's value.
One of the leading variables is always 1 and the rest are always 0. That is, the state of the classical bit combination is always exactly one of :math:`\rvert00\rangle, \rvert01\rangle, \rvert10\rangle,` or :math:`\rvert11\rangle,` and is not probabilistic in it's value.

However, quantum bit's can be represented probabilistically, in which the sum of probabilities of states should be 100% or 1. For example, this suggests splitting x_0 and x_1 into 1/2 and 1/2 to represent a potential :math:`|\psi\rangle`, but Schrödinger's equation actually requires us to split into :math:`1/\sqrt{2}` and :math:`1/\sqrt{2}` to get 100% probability, like so,
However, quantum bit's can be represented probabilistically, in which the sum of probabilities of states should be 100% or 1. For example, this suggests splitting x_0 and x_1 into 1/2 and 1/2 to represent a potential :math:`\rvert\psi\rangle`, but Schrödinger's equation actually requires us to split into :math:`1/\sqrt{2}` and :math:`1/\sqrt{2}` to get 100% probability, like so,

.. math:: |\psi\rangle = \frac{1}{\sqrt{2}} |00\rangle + \frac{1}{\sqrt{2}} |10\rangle,
.. math:: \rvert\psi\rangle = \frac{1}{\sqrt{2}} \rvert00\rangle + \frac{1}{\sqrt{2}} \rvert10\rangle,

.. Syntax Highlight fixing comment: `|
.. Syntax Highlight fixing comment: `\rvert
where the leading coefficients are ultimately squared - more accurately: multiplied by their complex conjugate. This is a valid description of a 2 qubit permutation.

Expand All @@ -30,45 +30,45 @@ Complex Number States

The equation :eq:`psi_prob` given above encompasses all possible states of a 2 qubit combination, when :math:`x_n` are constrained so that the total probability of all states adds up to one. However, the domain of the :math:`x_n` variables must also be the complex numbers. This is also a valid state, for example:

.. math:: |\psi\rangle = \frac{1+i}{2 \sqrt{2}} |00\rangle + \frac{1-i}{2 \sqrt{2}} |10\rangle
.. math:: \rvert\psi\rangle = \frac{1+i}{2 \sqrt{2}} \rvert00\rangle + \frac{1-i}{2 \sqrt{2}} \rvert10\rangle

.. Syntax Highlight fixing comment: `|
.. Syntax Highlight fixing comment: `\rvert
where "i" is defined as the :math:`\sqrt(-1)`. This imparts "phase" to each permutation state vector component like :math:`|00\rangle` or :math:`|10\rangle` - which are "eigenstates". Phase and probability of permutation state fully (but not uniquely) specify the state of a coherent set of qubits.
where "i" is defined as the :math:`\sqrt(-1)`. This imparts "phase" to each permutation state vector component like :math:`\rvert00\rangle` or :math:`\rvert10\rangle` - which are "eigenstates". Phase and probability of permutation state fully (but not uniquely) specify the state of a coherent set of qubits.

:cpp:class:`Qrack::CoherentUnit` Qubit Simulation
-------------------------------------------------

For N bits, there are :math:`2^N` permutation basis "eigenstates" that with probability normalization and phase fully describe every possible quantum state of the N qubits. A :cpp:class:`Qrack::CoherentUnit` tracks the :math:`2^N` dimensional state vector of eigenstate components, each permutation carrying probability and phase. It optimizes certain register-like methods by operating in parallel over the "entanglements" of these permutation basis states. For example, the state

.. math:: |\psi\rangle = \frac{1}{\sqrt{2}} |00\rangle + \frac{1}{\sqrt{2}} |11\rangle
.. math:: \rvert\psi\rangle = \frac{1}{\sqrt{2}} \rvert00\rangle + \frac{1}{\sqrt{2}} \rvert11\rangle

.. Syntax Highlight fixing comment: `|
.. Syntax Highlight fixing comment: `\rvert
has a probability of both bits being 1 or else both bits being 0, but it has no independent probability for the bits being different, when measured. If this state is acted on by an ``X`` or ``NOT`` gate on the left qubit we need only act on the states entangled into the original state.

For example, when acted on by an ``X`` gate on the left bit:

.. math:: |\psi_0\rangle = \frac{1}{\sqrt{2}} |00\rangle + \frac{1}{\sqrt{2}} |11\rangle \Rightarrow \frac{1}{\sqrt{2}} |10\rangle + \frac{1}{\sqrt{2}} |01\rangle
.. math:: \rvert\psi_0\rangle = \frac{1}{\sqrt{2}} \rvert00\rangle + \frac{1}{\sqrt{2}} \rvert11\rangle \Rightarrow \frac{1}{\sqrt{2}} \rvert10\rangle + \frac{1}{\sqrt{2}} \rvert01\rangle

.. Syntax Highlight fixing comment: `|
.. Syntax Highlight fixing comment: `\rvert
In the permutation basis, "entanglement" is as simple as the ability to restrain bit combinations in specifying an arbitrary :math:`|\psi\rangle` state.
In the permutation basis, "entanglement" is as simple as the ability to restrain bit combinations in specifying an arbitrary :math:`\rvert\psi\rangle` state.

.. TODO: This section is a bit ambiguous. What is meant by paired? How is
this actually implemented mathematically and programmatically?
In Qrack, simple gates are represented by small complex number matrices, generally with :math:`2\times2` components, that act on pairings of state vector components with the target qubit being 0 or 1 and all other qubits being held fixed in a loop iteration. For example, in an 8 qubit system, acting on a single bit gate on the leftmost qubit, these two states become paired:

.. math::
&|00101111\rangle \Rightarrow \\
&|10101111\rangle
&\rvert00101111\rangle \Rightarrow \\
&\rvert10101111\rangle
Similarly, these states also become paired:

.. math::
&|00101100\rangle \Rightarrow \\
&|10101100\rangle
&\rvert00101100\rangle \Rightarrow \\
&\rvert10101100\rangle
And so on for all states in which the seven uninvolved bits are kept the same, but 0 and 1 states are paired for the bit acted on by the gate.

Expand Down Expand Up @@ -125,15 +125,15 @@ The action of a gate is a matrix multiplication:
For 2 qubits, we can form 4x4 matrices to act on 4 permutation eigenstates. For 3 qubits, we can form 8x8 matrices to act on 8 permutation eigenstates, and so on. However, for gates acting on single bits in states with large numbers of qubits, it is actually not necessary to carry out any matrix multiplication larger than a :math:`2\times2` matrix acting on a sub-state vector of 2 components. We pair all permutation state vector components where all qubits are the same same, except for the one bit being acted on, for which we pair 0 and 1. For example, acting on the leftmost qubit,

:math:`|00100011\rangle` is paired with :math:`|10100011\rangle`,
:math:`\rvert00100011\rangle` is paired with :math:`\rvert10100011\rangle`,

and

:math:`|00101011\rangle` is paired with :math:`|10101011\rangle`,
:math:`\rvert00101011\rangle` is paired with :math:`\rvert10101011\rangle`,

and

:math:`|01101011\rangle` is paired with :math:`|11101011\rangle`,
:math:`\rvert01101011\rangle` is paired with :math:`\rvert11101011\rangle`,

and we can carry out the gate in terms of only :math:`2\times2` complex number matrix multiplications, which is a massive optimization and "embarrassingly parallel."

Expand All @@ -149,9 +149,9 @@ For register-like operations, we can optimize beyond this level for single bit g
For a bitwise ``NOT`` or ``X`` operation on one register, we can take an initial entangled state and sieve out initial register states to be mapped to final register states. For example, say we start with an entangled state:

.. math:: |\psi\rangle = \frac{1}{\sqrt{2}} |(01010101)\ (11111110)\rangle - \frac{1}{\sqrt{2}} |(10101010)\ (00000000)\rangle
.. math:: \rvert\psi\rangle = \frac{1}{\sqrt{2}} \rvert(01010101)\ (11111110)\rangle - \frac{1}{\sqrt{2}} \rvert(10101010)\ (00000000)\rangle

.. Syntax Highlight fixing comment: `|
.. Syntax Highlight fixing comment: `\rvert
.. TODO: Clarify: normalization
Expand All @@ -161,15 +161,15 @@ In general, measuring a single bit might only partially collapse the entanglemen

Say we want to apply a bitwise ``NOT`` or ``X`` operation on the right-hand register of 8 bits. We simply apply the ``NOT`` operation simultaneously on all of the right-hand bits in all entangled input states:

.. math:: |\psi_0\rangle = \frac{1}{\sqrt{2}} |(01010101)\ (11111110)\rangle - \frac{1}{\sqrt{2}} |(10101010)\ (00000000)\rangle
.. math:: \rvert\psi_0\rangle = \frac{1}{\sqrt{2}} \rvert(01010101)\ (11111110)\rangle - \frac{1}{\sqrt{2}} \rvert(10101010)\ (00000000)\rangle

.. TODO: Replace the line of text below with the actual line of code that'd be used.
(acted on by a bitwise NOT or X on the right-hand 8 bit register becomes)

.. math:: |\psi_1\rangle = \frac{1}{\sqrt{2}} |(01010101)\ (00000001)\rangle - \frac{1}{\sqrt{2}} |(10101010)\ (11111111)\rangle
.. math:: \rvert\psi_1\rangle = \frac{1}{\sqrt{2}} \rvert(01010101)\ (00000001)\rangle - \frac{1}{\sqrt{2}} \rvert(10101010)\ (11111111)\rangle

.. Syntax Highlight fixing comment: `|
.. Syntax Highlight fixing comment: `\rvert
:cpp:class:`Qrack::CoherentUnit` Gate Implementations
-----------------------------------------------------
Expand All @@ -178,7 +178,7 @@ This is again "embarrassingly parallel." Some bits are completely uninvolved and

.. TODO: I think you're saying here that the various x_i change but not the nature of the overall equation. While true, this doesn't lead naturally to how the implementation actually handles those various x_i values.
And, in fact, bits are not rearranged in the state vector at all; it is the ":math:`x_n`" complex number coefficients which are rearranged according to this bitmask transformation and mapping of the input state to the output state. (The coefficient ":math:`x_i`" of state :math:`|(01010101)\ (11111110)\rangle` is switched for the coefficient ":math:`x_j`" of state :math:`|(01010101)\ (00000001)\rangle`, and only the coefficients are rearranged, with a mapping that's determined via bitmask transformations.) This is almost the entire principle behind the algorithms for optimized register-like methods in Qrack. Also, as a point of algorithmic optimization, if N bits are known to have a fixed value like 0, we can often also completely skip permutations where their value would be 1, dividing the number of permutation states we need to iterate over in total by a factor of :math:`2^N`. This optimization is again handled in terms of bitmasks and bitshifts. See also the register-wise :cpp:func:`Qrack::CoherentUnit::X()` gate implementation for inline documentation on this general algorithm.
And, in fact, bits are not rearranged in the state vector at all; it is the ":math:`x_n`" complex number coefficients which are rearranged according to this bitmask transformation and mapping of the input state to the output state. (The coefficient ":math:`x_i`" of state :math:`\rvert(01010101)\ (11111110)\rangle` is switched for the coefficient ":math:`x_j`" of state :math:`\rvert(01010101)\ (00000001)\rangle`, and only the coefficients are rearranged, with a mapping that's determined via bitmask transformations.) This is almost the entire principle behind the algorithms for optimized register-like methods in Qrack. Also, as a point of algorithmic optimization, if N bits are known to have a fixed value like 0, we can often also completely skip permutations where their value would be 1, dividing the number of permutation states we need to iterate over in total by a factor of :math:`2^N`. This optimization is again handled in terms of bitmasks and bitshifts. See also the register-wise :cpp:func:`Qrack::CoherentUnit::X()` gate implementation for inline documentation on this general algorithm.
Quantum gates are represented by "unitary" matrices. Unitary matrices preserve the norm (length) of state vectors. Quantum physically observable quantities are associated with "Hermitian" unitary matrices, which are equal to their own conjugate transpose. Not all gates are Hermitian or associated with quantum observables, like general rotation operators. (Three dimensions of spin can be physically measured; the act of rotating spin along these axes is not associated with independent measurable quantities.)

Expand Down

0 comments on commit 6e9fdf2

Please sign in to comment.