void shor_decode (
quantum_register& reg
)
/*!
requires
- reg.num_bits() == 9
ensures
- #reg.num_bits() == 1
- #reg == the decoded qubit that was in the given input register
!*/
{
DLIB_CASSERT(reg.num_bits() == 9,"");
using namespace dlib::quantum_gates;
const gate<1> h = hadamard();
const gate<1> i = noop();
// Now apply the gates that constitute Shor's decoding to the input register
(cnot<2,0>(),cnot<2,0>(),cnot<2,0>()).apply_gate_to(reg);
(cnot<1,0>(),i,cnot<1,0>(),i,cnot<1,0>(),i).apply_gate_to(reg);
(toffoli<0,1,2>(),toffoli<0,1,2>(),toffoli<0,1,2>()).apply_gate_to(reg);
(h,i,i,h,i,i,h,i,i).apply_gate_to(reg);
(cnot<6,0>(),i,i).apply_gate_to(reg);
(cnot<3,0>(),i,i,i,i,i).apply_gate_to(reg);
(toffoli<0,3,6>(),i,i).apply_gate_to(reg);
// Now that we have decoded the value we don't need the extra 8 bits any more so
// remove them from the register.
for (int i = 0; i < 8; ++i)
reg.measure_and_remove_bit(0,rnd);
}
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
// This is the function we will use in Grover's search algorithm. In this
// case the value we are searching for is 257.
bool is_key (unsignedlong n)
{
return n == 257;
}
// ----------------------------------------------------------------------------------------
template <int bits>
class uf_gate;
namespace dlib {
template <int bits>
struct gate_traits<uf_gate<bits> >
{
static const long num_bits = bits;
static const long dims = dlib::qc_helpers::exp_2_n<num_bits>::value;
};}
template <int bits>
class uf_gate : public gate_exp<uf_gate<bits> >
{
/*!
This gate represents the black box function in Grover's search algorithm.
That is, it is the gate defined as follows:
Uf|x>|y> = |x>|y XOR is_key(x)>
See the documentation for the gate_exp object for the details regarding
the compute_state_element() andoperator() functions defined below.
!*/
public:
uf_gate() : gate_exp<uf_gate>(*this) {}
static const long num_bits = gate_traits<uf_gate>::num_bits;
static const long dims = gate_traits<uf_gate>::dims;
const qc_scalar_type operator() (long r, long c) const{
unsigned long output = c;
// if the input control bit is set
if (is_key(output>>1))
{
output = output^0x1;
}
if ((unsigned long)r == output)
return 1;
else
return 0;
}
template <typename exp>
qc_scalar_type compute_state_element (
const matrix_exp<exp>& reg,
long row_idx
) const{
unsigned long output = row_idx;
// if the input control bit is set
if (is_key(output>>1))
{
output = output^0x1;
}
return reg(output);
}
};
// ----------------------------------------------------------------------------------------
template <int bits>
class w_gate;