state.hpp
Go to the documentation of this file.
1 
2 #pragma once
3 
4 #ifndef _MSC_VER
5 extern "C"{
6 #include <csim/memory_ops.h>
7 #include <csim/stat_ops.h>
8 #include <csim/update_ops.h>
9 }
10 #else
11 #include <csim/memory_ops.h>
12 #include <csim/stat_ops.h>
13 #include <csim/update_ops.h>
14 #endif
15 
16 #include "type.hpp"
17 #include "utility.hpp"
18 #include <vector>
19 
24 protected:
25  ITYPE _dim;
27  std::vector<UINT> _classical_register;
28 public:
29  const UINT& qubit_count = _qubit_count;
30  const ITYPE& dim = _dim;
31  const std::vector<UINT>& classical_register = _classical_register;
38  QuantumStateBase(UINT qubit_count_){
39  this->_qubit_count = qubit_count_;
40  this->_dim = 1ULL << qubit_count_;
41  }
45  virtual ~QuantumStateBase(){}
46 
50  virtual void set_zero_state() = 0;
51 
57  virtual void set_computational_basis(ITYPE comp_basis) = 0;
58 
62  virtual void set_Haar_random_state() = 0;
63 
67  virtual void set_Haar_random_state(UINT seed) = 0;
68 
76  virtual double get_zero_probability(UINT target_qubit_index) const = 0;
77 
84  virtual double get_marginal_probability(std::vector<UINT> measured_values) const = 0;
85 
91  virtual double get_entropy() const = 0;
92 
99  virtual double get_norm() const = 0;
100 
106  virtual void normalize(double norm) = 0;
107 
113  virtual QuantumStateBase* allocate_buffer() const = 0;
114 
120  virtual QuantumStateBase* copy() const = 0;
121 
125  virtual void load(const QuantumStateBase* state) = 0;
126 
130  virtual void load(const std::vector<CPPCTYPE>& state) = 0;
131 
135  virtual void load(const CPPCTYPE* state) = 0;
136 
140  virtual const char* get_device_name() const = 0;
141 
147  virtual CPPCTYPE* data_cpp() const = 0;
148 
154  virtual CTYPE* data_c() const = 0;
155 
162  virtual UINT get_classical_value(UINT index) {
163  if(_classical_register.size() <= index) {
164  _classical_register.resize(index+1,0);
165  }
166  return _classical_register[index];
167  }
168 
176  virtual void set_classical_value(UINT index, UINT val) {
177  if(_classical_register.size() <= index) {
178  _classical_register.resize(index+1,0);
179  }
180  _classical_register[index] = val;
181  }
182 
188  virtual const std::vector<UINT> get_classical_register() const {
189  return _classical_register;
190  }
191 
198  virtual std::vector<ITYPE> sampling(UINT sampling_count) = 0;
199 
200 
206  virtual std::string to_string() const {
207  std::stringstream os;
208  ComplexVector eigen_state(this->dim);
209  auto data = this->data_cpp();
210  for (UINT i = 0; i < this->dim; ++i) eigen_state[i] = data[i];
211  os << " *** Quantum State ***" << std::endl;
212  os << " * Qubit Count : " << this->qubit_count << std::endl;
213  os << " * Dimension : " << this->dim << std::endl;
214  os << " * State vector : \n" << eigen_state << std::endl;
215  return os.str();
216  }
217 
223  friend std::ostream& operator<<(std::ostream& os, const QuantumStateBase& state) {
224  os << state.to_string();
225  return os;
226  }
227 
233  friend std::ostream& operator<<(std::ostream& os, const QuantumStateBase* state) {
234  os << *state;
235  return os;
236  }
237 };
238 
240 private:
241  CPPCTYPE* _state_vector;
242  Random random;
243 public:
249  QuantumStateCpu(UINT qubit_count_) : QuantumStateBase(qubit_count_){
250  this->_state_vector = reinterpret_cast<CPPCTYPE*>(allocate_quantum_state(this->_dim));
251  initialize_quantum_state(this->data_c(), _dim);
252  }
256  virtual ~QuantumStateCpu(){
257  release_quantum_state(this->data_c());
258  }
262  virtual void set_zero_state() override{
263  initialize_quantum_state(this->data_c(), _dim);
264  }
270  virtual void set_computational_basis(ITYPE comp_basis) override {
271  set_zero_state();
272  _state_vector[0] = 0.;
273  _state_vector[comp_basis] = 1.;
274  }
278  virtual void set_Haar_random_state() override{
279  initialize_Haar_random_state_with_seed(this->data_c(), _dim, random.int32());
280  }
284  virtual void set_Haar_random_state(UINT seed) override {
285  initialize_Haar_random_state_with_seed(this->data_c(), _dim,seed);
286  }
294  virtual double get_zero_probability(UINT target_qubit_index) const override {
295  return M0_prob(target_qubit_index, this->data_c(), _dim);
296  }
303  virtual double get_marginal_probability(std::vector<UINT> measured_values) const override {
304  std::vector<UINT> target_index;
305  std::vector<UINT> target_value;
306  for (UINT i = 0; i < measured_values.size(); ++i) {
307  if (i == 0 || i == 1) {
308  target_index.push_back(i);
309  target_value.push_back(measured_values[i]);
310  }
311  }
312  return marginal_prob(target_index.data(), target_value.data(), (UINT)target_index.size(), this->data_c(), _dim);
313  }
319  virtual double get_entropy() const override{
320  return measurement_distribution_entropy(this->data_c(), _dim);
321  }
322 
329  virtual double get_norm() const override {
330  return state_norm(this->data_c(),_dim);
331  }
332 
338  virtual void normalize(double norm) override{
339  ::normalize(norm, this->data_c(), _dim);
340  }
341 
342 
348  virtual QuantumStateBase* allocate_buffer() const override {
349  QuantumStateCpu* new_state = new QuantumStateCpu(this->_qubit_count);
350  return new_state;
351  }
357  virtual QuantumStateBase* copy() const override {
358  QuantumStateCpu* new_state = new QuantumStateCpu(this->_qubit_count);
359  memcpy(new_state->data_cpp(), _state_vector, (size_t)(sizeof(CPPCTYPE)*_dim));
360  for(UINT i=0;i<_classical_register.size();++i) new_state->set_classical_value(i,_classical_register[i]);
361  return new_state;
362  }
366  virtual void load(const QuantumStateBase* _state) {
367  this->_classical_register = _state->classical_register;
368  memcpy(this->data_cpp(), _state->data_cpp(), (size_t)(sizeof(CPPCTYPE)*_dim));
369  }
373  virtual void load(const std::vector<CPPCTYPE>& _state) {
374  assert(_state.size() == _dim);
375  memcpy(this->data_cpp(), _state.data(), (size_t)(sizeof(CPPCTYPE)*_dim));
376  }
377 
381  virtual void load(const CPPCTYPE* _state) {
382  memcpy(this->data_cpp(), _state, (size_t)(sizeof(CPPCTYPE)*_dim));
383  }
384 
388  virtual const char* get_device_name() const override {return "cpu";}
394  virtual CPPCTYPE* data_cpp() const override { return this->_state_vector; }
400  virtual CTYPE* data_c() const override {
401  return reinterpret_cast<CTYPE*>(this->_state_vector);
402  }
403 
410  virtual std::vector<ITYPE> sampling(UINT sampling_count) override{
411  std::vector<double> stacked_prob;
412  std::vector<ITYPE> result;
413  double sum = 0.;
414  auto ptr = this->data_cpp();
415  stacked_prob.push_back(0.);
416  for (UINT i = 0; i < this->dim; ++i) {
417  sum += norm(ptr[i]);
418  stacked_prob.push_back(sum);
419  }
420 
421  for (UINT count = 0; count < sampling_count; ++count) {
422  double r = random.uniform();
423  auto ite = std::lower_bound(stacked_prob.begin(), stacked_prob.end(), r);
424  auto index = std::distance(stacked_prob.begin(), ite) - 1;
425  result.push_back(index);
426  }
427  return result;
428  }
429 
430 };
431 
434 namespace state {
442  CPPCTYPE DllExport inner_product(const QuantumState* state_bra, const QuantumState* state_ket);
443 }
Eigen::VectorXcd ComplexVector
Definition: type.hpp:14
virtual double get_zero_probability(UINT target_qubit_index) const =0
virtual const char * get_device_name() const =0
std::vector< UINT > _classical_register
Definition: state.hpp:27
#define DllExport
Definition: type.hpp:30
virtual double get_norm() const override
Definition: state.hpp:329
CPPCTYPE inner_product(const QuantumState *state1, const QuantumState *state2)
Definition: state.cpp:15
virtual void load(const QuantumStateBase *state)=0
virtual void set_classical_value(UINT index, UINT val)
Definition: state.hpp:176
virtual CTYPE * data_c() const =0
virtual std::string to_string() const
Definition: state.hpp:206
Definition: utility.hpp:49
virtual CTYPE * data_c() const override
Definition: state.hpp:400
virtual void set_Haar_random_state() override
Definition: state.hpp:278
virtual void set_Haar_random_state()=0
virtual void set_Haar_random_state(UINT seed) override
Definition: state.hpp:284
virtual QuantumStateBase * allocate_buffer() const override
Definition: state.hpp:348
virtual ~QuantumStateBase()
Definition: state.hpp:45
virtual QuantumStateBase * copy() const override
Definition: state.hpp:357
virtual CPPCTYPE * data_cpp() const override
Definition: state.hpp:394
virtual double get_entropy() const override
Definition: state.hpp:319
virtual void set_zero_state() override
Definition: state.hpp:262
virtual std::vector< ITYPE > sampling(UINT sampling_count)=0
std::complex< double > CPPCTYPE
Definition: type.hpp:13
Definition: state.hpp:23
virtual void set_computational_basis(ITYPE comp_basis)=0
virtual CPPCTYPE * data_cpp() const =0
virtual UINT get_classical_value(UINT index)
Definition: state.hpp:162
virtual void load(const std::vector< CPPCTYPE > &_state)
Definition: state.hpp:373
virtual void normalize(double norm) override
Definition: state.hpp:338
friend std::ostream & operator<<(std::ostream &os, const QuantumStateBase &state)
Definition: state.hpp:223
virtual double get_norm() const =0
virtual ~QuantumStateCpu()
Definition: state.hpp:256
virtual const char * get_device_name() const override
Definition: state.hpp:388
const std::vector< UINT > & classical_register
Definition: state.hpp:31
QuantumStateCpu(UINT qubit_count_)
Definition: state.hpp:249
const ITYPE & dim
Definition: state.hpp:30
virtual std::vector< ITYPE > sampling(UINT sampling_count) override
Definition: state.hpp:410
virtual void load(const QuantumStateBase *_state)
Definition: state.hpp:366
QuantumStateCpu QuantumState
Definition: state.hpp:432
virtual void set_computational_basis(ITYPE comp_basis) override
Definition: state.hpp:270
QuantumStateBase(UINT qubit_count_)
Definition: state.hpp:38
virtual QuantumStateBase * copy() const =0
Definition: state.cpp:14
virtual double get_zero_probability(UINT target_qubit_index) const override
Definition: state.hpp:294
const UINT & qubit_count
Definition: state.hpp:29
virtual QuantumStateBase * allocate_buffer() const =0
virtual const std::vector< UINT > get_classical_register() const
Definition: state.hpp:188
Definition: state.hpp:239
UINT _qubit_count
Definition: state.hpp:26
friend std::ostream & operator<<(std::ostream &os, const QuantumStateBase *state)
Definition: state.hpp:233
virtual void set_zero_state()=0
unsigned long int32()
Definition: utility.hpp:97
virtual void normalize(double norm)=0
virtual double get_entropy() const =0
double uniform()
Definition: utility.hpp:76
virtual void load(const CPPCTYPE *_state)
Definition: state.hpp:381
virtual double get_marginal_probability(std::vector< UINT > measured_values) const override
Definition: state.hpp:303
ITYPE _dim
Definition: state.hpp:25
virtual double get_marginal_probability(std::vector< UINT > measured_values) const =0