Commit 45c56bb2 authored by Davis King's avatar Davis King

Cleaned up the code more and fully filled out the spec.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402685
parent 0b6dad89
......@@ -624,13 +624,13 @@ namespace dlib
// ------------------------------------------------------------------------------------
template <int control_bit1, int control_bit2, int target_bit>
class taffoli : public gate_exp<taffoli<control_bit1, control_bit2, target_bit> >
class toffoli : public gate_exp<toffoli<control_bit1, control_bit2, target_bit> >
{
public:
COMPILE_TIME_ASSERT(control_bit1 != target_bit && control_bit2 != target_bit && control_bit1 != control_bit2);
COMPILE_TIME_ASSERT((control_bit1 < target_bit && control_bit2 < target_bit) ||(control_bit1 > target_bit && control_bit2 > target_bit) );
taffoli() : gate_exp<taffoli>(*this)
toffoli() : gate_exp<toffoli>(*this)
{
const int min_bit = std::min(std::min(control_bit1, control_bit2), target_bit);
......
......@@ -21,60 +21,145 @@ namespace dlib
/*!
INITIAL VALUE
- num_bits() == 1
- state_vector().nr() == 2
- state_vector().nc() == 1
- state_vector()(0) == 1
- state_vector()(1) == 0
- probability_of_bit(0) == 0
- i.e. This register represents a single quantum bit and it is
completely in the 0 state.
WHAT THIS OBJECT REPRESENTS
This object represents a set of quantum bits.
!*/
public:
quantum_register(
);
/*!
ensures
- this object is properly initialized
!*/
int num_bits (
) const;
/*!
ensures
- returns the number of quantum bits in this register
!*/
void set_num_bits (
int num_bits
int new_num_bits
);
/*!
ensures
- #num_bits() == new_num_bits
- #state_vector().nr() == 2^new_num_bits
(i.e. the size of the state_vector is exponential in the number of bits in a register)
- for all valid i:
- probability_of_bit(i) == 0
!*/
void zero_all_bits(
);
/*!
ensures
- for all valid i:
- probability_of_bit(i) == 0
!*/
void append (
const quantum_register& reg
);
/*!
ensures
- #num_bits() == num_bits() + reg.num_bits()
- #this->state_vector() == tensor_product(this->state_vector(), reg.state_vector())
- The original bits in *this become the high order bits of the resulting
register and all the bits in reg end up as the low order bits in the
resulting register.
!*/
double probability_of_bit (
int bit
) const;
/*!
requires
- 0 <= bit < num_bits()
ensures
- returns the probability of measuring the given bit and it being in the 1 state.
- The returned value is also equal to the sum of norm(state_vector()(i)) for all
i where the bit'th bit in i is set to 1. (note that the lowest order bit is bit 0)
!*/
template <typename rand_type>
bool measure_bit (
int bit,
rand_type& rnd
);
/*!
requires
- 0 <= bit < num_bits()
- rand_type == an implementation of dlib/rand/rand_float_abstract.h
ensures
- measures the given bit in this register. Let R denote the boolean
result of the measurement, where true means the bit was measured to
have value 1 and false means it had a value of 0.
- if (R == true) then
- returns true
- #probability_of_bit(bit) == 1
- else
- returns false
- #probability_of_bit(bit) == 0
!*/
template <typename rand_type>
bool measure_and_remove_bit (
int bit,
rand_type& rnd
);
double probability_of_bit (
int bit
) const;
/*!
requires
- num_bits() > 1
- 0 <= bit < num_bits()
- rand_type == an implementation of dlib/rand/rand_float_abstract.h
ensures
- returns the probability of measuring the given bit and it being true
- measures the given bit in this register. Let R denote the boolean
result of the measurement, where true means the bit was measured to
have value 1 and false means it had a value of 0.
- #num_bits() == num_bits() - 1
- removes the bit that was measured from this register.
- if (R == true) then
- returns true
- else
- returns false
!*/
const matrix<qc_scalar_type,0,1>& state_vector(
) const;
/*!
ensures
- returns a const reference to the state vector that describes the state of
the quantum bits in this register.
!*/
matrix<qc_scalar_type,0,1>& state_vector(
);
/*!
ensures
- returns a non-const reference to the state vector that describes the state of
the quantum bits in this register.
!*/
void swap (
quantum_register& item
);
/*!
ensures
- swaps *this and item
!*/
};
......@@ -82,6 +167,9 @@ namespace dlib
quantum_register& a,
quantum_register& b
) { a.swap(b); }
/*!
provides a global swap function
!*/
// ----------------------------------------------------------------------------------------
......@@ -129,7 +217,7 @@ namespace dlib
ensures
- applies this quantum gate to the given quantum register
- Let M represent the matrix for this quantum gate
- reg().state_vector() = M*reg().state_vector()
- #reg().state_vector() = M*reg().state_vector()
!*/
template <typename exp>
......@@ -164,6 +252,23 @@ namespace dlib
template <typename T, typename U>
class composite_gate : public gate_exp<composite_gate<T,U> >
{
/*!
REQUIREMENTS ON T AND U
Both must be gate expressions that inherit from gate_exp
WHAT THIS OBJECT REPRESENTS
This object represents a quantum gate that is the tensor product of
two quantum gates.
As an example, suppose you have 3 registers, reg_high, reg_low, and reg_all. Also
suppose that reg_all is what you get when you append reg_high and reg_low,
so reg_all.state_vector() == tensor_product(reg_high.state_vector(),reg_low.state_vector()).
Then applying a composite gate to reg_all would give you the same thing as
applying the lhs gate to reg_high and the rhs gate to reg_low and then appending
the two resulting registers.
!*/
public:
composite_gate (
......@@ -237,7 +342,8 @@ namespace dlib
0 < bits <= 30
WHAT THIS OBJECT REPRESENTS
This object represents a quantum gate that operates on bits qubits.
It stores its gate matrix explicitly in a dense in-memory matrix.
!*/
public:
......@@ -278,12 +384,28 @@ namespace dlib
const qc_scalar_type& operator() (
long r,
long c
) const { return data(r,c); }
) const;
/*!
requires
- 0 <= r < dims
- 0 <= c < dims
ensures
- Let M denote the matrix for this gate
- returns a const reference to M(r,c)
!*/
qc_scalar_type& operator() (
long r,
long c
) { return data(r,c); }
);
/*!
requires
- 0 <= r < dims
- 0 <= c < dims
ensures
- Let M denote the matrix for this gate
- returns a non-const reference to M(r,c)
!*/
template <typename exp>
qc_scalar_type compute_state_element (
......@@ -315,6 +437,9 @@ namespace dlib
const gate_exp<U>& rhs
) { return composite_gate<T,U>(lhs,rhs); }
/*!
ensures
- returns a composite_gate that represents the tensor product of the lhs
gate with the rhs gate.
!*/
// ----------------------------------------------------------------------------------------
......@@ -323,70 +448,115 @@ namespace dlib
{
inline const gate<1> hadamard(
)
{
gate<1> h;
h(0,0) = std::sqrt(1/2.0);
h(0,1) = std::sqrt(1/2.0);
h(1,0) = std::sqrt(1/2.0);
h(1,1) = -std::sqrt(1/2.0);
return h;
}
);
/*!
ensures
- returns the Hadamard gate.
(i.e. A gate with a matrix of
|1, 1|
1/sqrt(2) * |1,-1| )
!*/
inline const gate<1> x(
)
{
gate<1> x;
x(0,1) = 1;
x(1,0) = 1;
return x;
}
);
/*!
ensures
- returns the not gate.
(i.e. A gate with a matrix of
|0, 1|
|1, 0| )
!*/
inline const gate<1> y(
)
{
gate<1> x;
qc_scalar_type i(0,1);
x(0,1) = -i;
x(1,0) = i;
return x;
}
);
/*!
ensures
- returns the y gate.
(i.e. A gate with a matrix of
|0,-i|
|i, 0| )
!*/
inline const gate<1> z(
)
{
gate<1> z;
z(0,0) = 1;
z(1,1) = -1;
return z;
}
);
/*!
ensures
- returns the z gate.
(i.e. A gate with a matrix of
|1, 0|
|0,-1| )
!*/
inline const gate<1> noop(
)
{
gate<1> i;
i(0,0) = 1;
i(1,1) = 1;
return i;
}
);
/*!
ensures
- returns the no-op or identity gate.
(i.e. A gate with a matrix of
|1, 0|
|0, 1| )
!*/
template <int control_bit, int target_bit>
template <
int control_bit,
int target_bit
>
class cnot : public gate_exp<cnot<control_bit, target_bit> >
{
public:
COMPILE_TIME_ASSERT(control_bit != target_bit);
};
/*!
REQUIREMENTS ON control_bit AND target_bit
- control_bit != target_bit
WHAT THIS OBJECT REPRESENTS
This object represents the controlled-not quantum gate. It is a gate that
operates on abs(control_bit-target_bit)+1 qubits.
In terms of the computational basis vectors, this gate maps input
vectors to output vectors in the following way:
- if (the input vector corresponds to a state where the control_bit
qubit is 1) then
- this gate outputs the computational basis vector that
corresponds to the state where the target_bit has been flipped
with respect to the input vector
- else
- this gate outputs the input vector unmodified
!*/
};
template <int control_bit1, int control_bit2, int target_bit>
class taffoli : public gate_exp<taffoli<control_bit1, control_bit2, target_bit> >
template <
int control_bit1,
int control_bit2,
int target_bit
>
class toffoli : public gate_exp<toffoli<control_bit1, control_bit2, target_bit> >
{
public:
COMPILE_TIME_ASSERT(control_bit1 != target_bit && control_bit2 != target_bit && control_bit1 != control_bit2);
COMPILE_TIME_ASSERT((control_bit1 < target_bit && control_bit2 < target_bit) ||(control_bit1 > target_bit && control_bit2 > target_bit) );
/*!
REQUIREMENTS ON control_bit1, control_bit2, AND target_bit
- all the arguments denote different bits, i.e.:
- control_bit1 != target_bit
- control_bit2 != target_bit
- control_bit1 != control_bit2
- The target bit can't be in-between the control bits, i.e.:
- (control_bit1 < target_bit && control_bit2 < target_bit) ||
(control_bit1 > target_bit && control_bit2 > target_bit)
WHAT THIS OBJECT REPRESENTS
This object represents the toffoli variant of a controlled-not quantum gate.
It is a gate that operates on max(abs(control_bit2-target_bit),abs(control_bit1-target_bit))+1
qubits.
In terms of the computational basis vectors, this gate maps input
vectors to output vectors in the following way:
- if (the input vector corresponds to a state where the control_bit1 and
control_bit2 qubits are 1) then
- this gate outputs the computational basis vector that
corresponds to the state where the target_bit has been flipped
with respect to the input vector
- else
- this gate outputs the input vector unmodified
!*/
};
// ------------------------------------------------------------------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment