QNLP  v1.0
oracle.hpp
Go to the documentation of this file.
1 
9  //# Phase oracle acts on n, boolean oracle acts on n+1; https://arxiv.org/pdf/1703.10535.pdf for examples
10 
11 #ifndef QNLP_ORACLE
12 #define QNLP_ORACLE
13 
14 #include <complex>
15 #include <cassert>
16 #include <vector>
17 #include <iostream>
18 
19 namespace QNLP{
25  template <class SimulatorType>
26  class Oracle{
27  private:
28  //Take the 2x2 matrix type from the template SimulatorType
29  using Mat2x2Type = decltype(std::declval<SimulatorType>().getGateX());
30 
31  public:
36  Oracle(){};
37 
42  ~Oracle(){};
43 
54  static void bitStringNCU(SimulatorType& s, std::size_t bitstring, const std::vector<std::size_t>& ctrl_indices, const std::size_t target, const Mat2x2Type& U, std::string gateLabel){
55  std::size_t bitmask = 0b1;
56  std::vector<std::size_t> reverse_pattern;
57  for(std::size_t i = 0; i < ctrl_indices.size() + 1; ++i){
58  //If the bitstring contains a 1 at desired index, will be true;
59  //We wish to apply X to any state that is false, then undo
60  if( ! (bitstring & (bitmask<<i) ) ){
61  reverse_pattern.push_back(i);
62  if( i < ctrl_indices.size())
63  s.applyGateX(ctrl_indices[i]);
64  else
65  s.applyGateX(target);
66  }
67  }
68  s.applyGateNCU(U, ctrl_indices, target, gateLabel);
69  //Undo PauliX ops
70  for(auto& revIdx : reverse_pattern){
71  if( revIdx < ctrl_indices.size()){
72  s.applyGateX(ctrl_indices[revIdx]);
73  }
74  else{
75  s.applyGateX(target);
76  }
77  }
78  }
79 
80 
92  static void bitStringNCU(SimulatorType& s, std::size_t bitstring, const std::vector<std::size_t>& ctrl_indices, const std::vector<std::size_t>& aux_indices, const std::size_t target, const Mat2x2Type& U, std::string gateLabel){
93  std::size_t bitmask = 0b1;
94  std::vector<std::size_t> reverse_pattern;
95  for(std::size_t i = 0; i < ctrl_indices.size() + 1; ++i){
96  //If the bitstring contains a 1 at desired index, will be true;
97  //We wish to apply X to any state that is false, then undo
98  if( ! (bitstring & (bitmask<<i) ) ){
99  reverse_pattern.push_back(i);
100  if( i < ctrl_indices.size())
101  s.applyGateX(ctrl_indices[i]);
102  else
103  s.applyGateX(target);
104  }
105  }
106  s.applyGateNCU(U, ctrl_indices, aux_indices, target, gateLabel);
107  //Undo PauliX ops
108  for(auto& revIdx : reverse_pattern){
109  if( revIdx < ctrl_indices.size()){
110  s.applyGateX(ctrl_indices[revIdx]);
111  }
112  else{
113  s.applyGateX(target);
114  }
115  }
116  }
117 
126  static void bitStringPhaseOracle(SimulatorType& s, std::size_t bitstring, const std::vector<std::size_t>&ctrlIndices, std::size_t target ){
127  std::size_t num_qubits = s.getNumQubits();
128  assert ( (1<<num_qubits) < bitstring );
129  bitStringNCU(s, bitstring, ctrlIndices, target, s.getGateZ(), "Z");
130  }
131  };
132 };
133 #endif
~Oracle()
Destroy the Oracle object.
Definition: oracle.hpp:42
decltype(std::declval< SimulatorType >().getGateX()) Mat2x2Type
Definition: oracle.hpp:29
Class definition for defining and applying an Oracle.
Definition: oracle.hpp:26
static void bitStringPhaseOracle(SimulatorType &s, std::size_t bitstring, const std::vector< std::size_t > &ctrlIndices, std::size_t target)
Takes bitstring as the binary pattern and indices as the qubits to operate upon. Applies the appropri...
Definition: oracle.hpp:126
static void bitStringNCU(SimulatorType &s, std::size_t bitstring, const std::vector< std::size_t > &ctrl_indices, const std::size_t target, const Mat2x2Type &U, std::string gateLabel)
Takes bitstring as the binary pattern and indices as the qubits to operate upon. Applies the appropri...
Definition: oracle.hpp:54
static void bitStringNCU(SimulatorType &s, std::size_t bitstring, const std::vector< std::size_t > &ctrl_indices, const std::vector< std::size_t > &aux_indices, const std::size_t target, const Mat2x2Type &U, std::string gateLabel)
Takes bitstring as the binary pattern and indices as the qubits to operate upon. Applies the appropri...
Definition: oracle.hpp:92
Oracle()
Construct a new Oracle object.
Definition: oracle.hpp:36