state_dm.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_dm.h>
7 #include <csim/stat_ops_dm.h>
8 #include <csim/update_ops_dm.h>
9 }
10 #else
11 #include <csim/memory_ops_dm.h>
12 #include <csim/stat_ops_dm.h>
13 #include <csim/update_ops_dm.h>
14 #endif
15 
16 #include "state.hpp"
17 
19 private:
20  CPPCTYPE* _density_matrix;
21  Random random;
22 public:
28  DensityMatrixCpu(UINT qubit_count_) : QuantumStateBase(qubit_count_, false){
29  this->_density_matrix = reinterpret_cast<CPPCTYPE*>(dm_allocate_quantum_state(this->_dim));
30  dm_initialize_quantum_state(this->data_c(), _dim);
31  }
35  virtual ~DensityMatrixCpu(){
36  dm_release_quantum_state(this->data_c());
37  }
41  virtual void set_zero_state() override{
42  dm_initialize_quantum_state(this->data_c(), _dim);
43  }
49  virtual void set_computational_basis(ITYPE comp_basis) override {
50  if (comp_basis >= (ITYPE)(1ULL << this->qubit_count)) {
51  std::cerr << "Error: DensityMatrixCpu::set_computational_basis(ITYPE): index of computational basis must be smaller than 2^qubit_count" << std::endl;
52  return;
53  }
55  _density_matrix[0] = 0.;
56  _density_matrix[comp_basis*dim+comp_basis] = 1.;
57  }
61  virtual void set_Haar_random_state() override{
62  this->set_Haar_random_state(random.int32());
63  }
67  virtual void set_Haar_random_state(UINT seed) override {
68  QuantumStateCpu* pure_state = new QuantumStateCpu(qubit_count);
69  pure_state->set_Haar_random_state(seed);
70  dm_initialize_with_pure_state(this->data_c(), pure_state->data_c(), _dim);
71  delete pure_state;
72  }
80  virtual double get_zero_probability(UINT target_qubit_index) const override {
81  if (target_qubit_index >= this->qubit_count) {
82  std::cerr << "Error: DensityMatrixCpu::get_zero_probability(UINT): index of target qubit must be smaller than qubit_count" << std::endl;
83  return 0.;
84  }
85  return dm_M0_prob(target_qubit_index, this->data_c(), _dim);
86  }
93  virtual double get_marginal_probability(std::vector<UINT> measured_values) const override {
94  if (measured_values.size() != this->qubit_count) {
95  std::cerr << "Error: DensityMatrixCpu::get_marginal_probability(vector<UINT>): the length of measured_values must be equal to qubit_count" << std::endl;
96  return 0.;
97  }
98 
99  std::vector<UINT> target_index;
100  std::vector<UINT> target_value;
101  for (UINT i = 0; i < measured_values.size(); ++i) {
102  UINT measured_value = measured_values[i];
103  if (measured_value== 0 || measured_value == 1) {
104  target_index.push_back(i);
105  target_value.push_back(measured_value);
106  }
107  }
108  return dm_marginal_prob(target_index.data(), target_value.data(), (UINT)target_index.size(), this->data_c(), _dim);
109  }
115  virtual double get_entropy() const override{
116  return dm_measurement_distribution_entropy(this->data_c(), _dim);
117  }
118 
125  virtual double get_norm() const override {
126  return dm_state_norm(this->data_c(),_dim);
127  }
128 
134  virtual void normalize(double norm) override{
135  dm_normalize(norm, this->data_c(), _dim);
136  }
137 
138 
144  virtual QuantumStateBase* allocate_buffer() const override {
145  DensityMatrixCpu* new_state = new DensityMatrixCpu(this->_qubit_count);
146  return new_state;
147  }
153  virtual QuantumStateBase* copy() const override {
154  DensityMatrixCpu* new_state = new DensityMatrixCpu(this->_qubit_count);
155  memcpy(new_state->data_cpp(), _density_matrix, (size_t)(sizeof(CPPCTYPE)*_dim*_dim));
156  for(UINT i=0;i<_classical_register.size();++i) new_state->set_classical_value(i,_classical_register[i]);
157  return new_state;
158  }
162  virtual void load(const QuantumStateBase* _state) {
163  if (_state->qubit_count != this->qubit_count) {
164  std::cerr << "Error: DensityMatrixCpu::load(const QuantumStateBase*): invalid qubit count" << std::endl;
165  return;
166  }
167  if (_state->is_state_vector()) {
168  dm_initialize_with_pure_state(this->data_c(), _state->data_c(), dim);
169  }else {
170  memcpy(this->data_cpp(), _state->data_cpp(), (size_t)(sizeof(CPPCTYPE)*_dim*_dim));
171  }
172  this->_classical_register = _state->classical_register;
173  }
177  virtual void load(const std::vector<CPPCTYPE>& _state) {
178  if (_state.size() != _dim && _state.size() != _dim*_dim) {
179  std::cerr << "Error: DensityMatrixCpu::load(vector<Complex>&): invalid length of state" << std::endl;
180  return;
181  }
182  if (_state.size() == _dim) {
183  dm_initialize_with_pure_state(this->data_c(), (const CTYPE*)_state.data(), dim);
184  }
185  else {
186  memcpy(this->data_cpp(), _state.data(), (size_t)(sizeof(CPPCTYPE)*_dim*_dim));
187  }
188  }
189 
190  virtual void load(const Eigen::VectorXcd& _state) {
191  if (_state.size() != _dim && _state.size() != _dim * _dim) {
192  std::cerr << "Error: DensityMatrixCpu::load(vector<Complex>&): invalid length of state" << std::endl;
193  return;
194  }
195  if (_state.size() == _dim) {
196  dm_initialize_with_pure_state(this->data_c(), (const CTYPE*)_state.data(), dim);
197  }
198  else {
199  memcpy(this->data_cpp(), _state.data(), (size_t)(sizeof(CPPCTYPE)*_dim*_dim));
200  }
201  }
202 
203  virtual void load(const ComplexMatrix& _state) {
204  if (_state.cols() != _dim && _state.rows() != _dim * _dim) {
205  std::cerr << "Error: DensityMatrixCpu::load(ComplexMatrix&): invalid length of state" << std::endl;
206  return;
207  }
208  memcpy(this->data_cpp(), _state.data(), (size_t)(sizeof(CPPCTYPE)*_dim*_dim));
209  }
210 
214  virtual void load(const CPPCTYPE* _state) {
215  memcpy(this->data_cpp(), _state, (size_t)(sizeof(CPPCTYPE)*_dim*_dim));
216  }
217 
221  virtual const std::string get_device_name() const override {return "cpu";}
222 
226  virtual void* data() const override {
227  return reinterpret_cast<void*>(this->_density_matrix);
228  }
234  virtual CPPCTYPE* data_cpp() const override { return this->_density_matrix; }
240  virtual CTYPE* data_c() const override {
241  return reinterpret_cast<CTYPE*>(this->_density_matrix);
242  }
243 
244 
245 
249  virtual void add_state(const QuantumStateBase* state) override {
250  dm_state_add(state->data_c(), this->data_c(), this->dim);
251  }
255  virtual void multiply_coef(CPPCTYPE coef) override {
256 #ifdef _MSC_VER
257  dm_state_multiply(coef, this->data_c(), this->dim);
258 #else
259  CTYPE c_coef = { coef.real(), coef.imag() };
260  dm_state_multiply(c_coef, this->data_c(), this->dim);
261 #endif
262  }
263 
264 
271  virtual std::vector<ITYPE> sampling(UINT sampling_count) override{
272  std::vector<double> stacked_prob;
273  std::vector<ITYPE> result;
274  double sum = 0.;
275  auto ptr = this->data_cpp();
276  stacked_prob.push_back(0.);
277  for (UINT i = 0; i < this->dim; ++i) {
278  sum += norm(ptr[i*dim+i]);
279  stacked_prob.push_back(sum);
280  }
281 
282  for (UINT count = 0; count < sampling_count; ++count) {
283  double r = random.uniform();
284  auto ite = std::lower_bound(stacked_prob.begin(), stacked_prob.end(), r);
285  auto index = std::distance(stacked_prob.begin(), ite) - 1;
286  result.push_back(index);
287  }
288  return result;
289  }
290 
291  virtual std::string to_string() const {
292  std::stringstream os;
293  ComplexMatrix eigen_state(this->dim, this->dim);
294  auto data = this->data_cpp();
295  for (UINT i = 0; i < this->dim; ++i) {
296  for (UINT j = 0; j < this->dim; ++j) {
297  eigen_state(i,j) = data[i*dim+j];
298  }
299  }
300  os << " *** Density Matrix ***" << std::endl;
301  os << " * Qubit Count : " << this->qubit_count << std::endl;
302  os << " * Dimension : " << this->dim << std::endl;
303  os << " * Density matrix : \n" << eigen_state << std::endl;
304  return os.str();
305  }
306 };
307 
Eigen::Matrix< CPPCTYPE, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor > ComplexMatrix
Definition: type.hpp:18
Definition: state_dm.hpp:18
virtual void load(const Eigen::VectorXcd &_state)
Definition: state_dm.hpp:190
virtual void normalize(double norm) override
Definition: state_dm.hpp:134
std::vector< UINT > _classical_register
Definition: state.hpp:29
virtual void set_classical_value(UINT index, UINT val)
Definition: state.hpp:199
virtual void load(const ComplexMatrix &_state)
Definition: state_dm.hpp:203
virtual double get_marginal_probability(std::vector< UINT > measured_values) const override
Definition: state_dm.hpp:93
virtual bool is_state_vector() const
Definition: state.hpp:55
virtual void add_state(const QuantumStateBase *state) override
Definition: state_dm.hpp:249
virtual CTYPE * data_c() const =0
Definition: utility.hpp:51
virtual CTYPE * data_c() const override
Definition: state.hpp:452
virtual QuantumStateBase * allocate_buffer() const override
Definition: state_dm.hpp:144
virtual QuantumStateBase * copy() const override
Definition: state_dm.hpp:153
virtual void set_Haar_random_state() override
Definition: state.hpp:305
virtual const std::string get_device_name() const override
Definition: state_dm.hpp:221
virtual void multiply_coef(CPPCTYPE coef) override
Definition: state_dm.hpp:255
virtual double get_zero_probability(UINT target_qubit_index) const override
Definition: state_dm.hpp:80
virtual std::vector< ITYPE > sampling(UINT sampling_count) override
Definition: state_dm.hpp:271
virtual void load(const std::vector< CPPCTYPE > &_state)
Definition: state_dm.hpp:177
DensityMatrixCpu DensityMatrix
Definition: state_dm.hpp:308
std::complex< double > CPPCTYPE
Definition: type.hpp:14
virtual CTYPE * data_c() const override
Definition: state_dm.hpp:240
DensityMatrixCpu(UINT qubit_count_)
Definition: state_dm.hpp:28
virtual void set_Haar_random_state() override
Definition: state_dm.hpp:61
Definition: state.hpp:24
virtual CPPCTYPE * data_cpp() const =0
virtual void set_computational_basis(ITYPE comp_basis) override
Definition: state_dm.hpp:49
virtual double get_entropy() const override
Definition: state_dm.hpp:115
virtual void load(const CPPCTYPE *_state)
Definition: state_dm.hpp:214
const std::vector< UINT > & classical_register
Definition: state.hpp:33
virtual void set_Haar_random_state(UINT seed) override
Definition: state_dm.hpp:67
const ITYPE & dim
Definition: state.hpp:32
virtual void load(const QuantumStateBase *_state)
Definition: state_dm.hpp:162
virtual double get_norm() const override
Definition: state_dm.hpp:125
virtual void * data() const override
Definition: state_dm.hpp:226
virtual void set_zero_state() override
Definition: state_dm.hpp:41
Definition: state.cpp:15
virtual CPPCTYPE * data_cpp() const override
Definition: state_dm.hpp:234
const UINT & qubit_count
Definition: state.hpp:31
Definition: state.hpp:262
UINT _qubit_count
Definition: state.hpp:27
unsigned long int32()
Definition: utility.hpp:99
virtual std::string to_string() const
Definition: state_dm.hpp:291
double uniform()
Definition: utility.hpp:78
virtual ~DensityMatrixCpu()
Definition: state_dm.hpp:35
ITYPE _dim
Definition: state.hpp:26