MADNESS  0.10.1
ccpairfunction.h
Go to the documentation of this file.
1 //
2 // Created by Florian Bischoff on 6/27/22.
3 //
4 
5 #ifndef MADNESS_CCPAIRFUNCTION_H
6 #define MADNESS_CCPAIRFUNCTION_H
7 
8 
9 
10 #include <madness/mra/mra.h>
14 #include <algorithm>
15 #include <iomanip>
16 #include <madness/mra/macrotaskq.h>
17 
18 namespace madness {
19 
20 template<typename T, std::size_t NDIM>
21 class CCConvolutionOperator;
22 class ProjectorBase;
23 
24 /// FuncTypes used by the CC_function_6d structure
25 /// Types of Functions used by CC_function class
27 
28 inline std::string name(const FuncType& type, const int ex=-1) {
29  if (type == PARTICLE) return "tau";
30  else if (type == HOLE) return "phi";
31  else if (type == MIXED) return "t";
32  else if (type == RESPONSE) {
33  MADNESS_CHECK_THROW(ex>=0,"ex must be >=0");
34  return std::to_string(ex) + "_" + "x";
35  }
36  else {
37  MADNESS_EXCEPTION("unknown FuncType",1);
38  }
39  return "undefined";
40 }
41 
42 /// structure for a CC Function 3D which holds an index and a type
43 // the type is defined by the enum FuncType (definition at the start of this file)
44 template<typename T=double, std::size_t NDIM=3>
46 public:
48 
50 
51 // CCFunction(const Function<T,NDIM>& f, const size_t& ii) : current_error(99), function(f), i(ii), type(UNDEFINED) {};
52 //
53  CCFunction(const Function<T,NDIM>& f, const size_t& ii, const FuncType& type_) : current_error(99), function(f),
54  i(ii), type(type_) {};
55 
56  CCFunction(const CCFunction& other) : current_error(other.current_error), function(other.function), i(other.i),
57  type(other.type) {};
58 
59  /// deep copy
60  friend CCFunction copy(const CCFunction& other) {
61  CCFunction tmp;
62  tmp.current_error=other.current_error;
63  tmp.function=madness::copy(other.function);
64  tmp.i=other.i;
65  tmp.type=other.type;
66  return tmp;
67  }
68 
69  double current_error;
70  Function<T,NDIM> function;
71 
72  Function<T,NDIM> get() const { return function; }
73 
74  Function<T,NDIM> f() const { return function; }
75 
76  void set(const Function<T,NDIM>& other) { function = other; }
77 
78  size_t i;
80 
81  void info(World& world, const std::string& msg = " ") const {
82  if (world.rank() == 0) {
83  std::cout << "Information about 3D function: " << name() << " " << msg << std::endl;
84  std::cout << std::setw(10) << std::setfill(' ') << std::setw(50) << " |f| : " << function.norm2()
85  << std::endl;
86  std::cout << std::setw(10) << std::setfill(' ') << std::setw(50) << " |error|: " << current_error << std::endl;
87  }
88  };
89 
90  std::string name() const {
91  if (type == HOLE) {
92  return "phi" + stringify(i);
93  } else if (type == PARTICLE) {
94  return "tau" + stringify(i);
95  } else if (type == MIXED) {
96  return "t" + stringify(i);
97  } else if (type == RESPONSE) {
98  return "x" + stringify(i);
99  } else {
100  return "function" + stringify(i);
101  }
102  };
103 
104  double inner(const CCFunction& f) const {
105  return inner(f.function);
106  }
107 
108  double inner(const Function<T,NDIM>& f) const {
109  return function.inner(f);
110  }
111 
112  /// scalar multiplication
113  CCFunction operator*(const double& fac) const {
114  Function<T,NDIM> fnew = fac * function;
115  return CCFunction(fnew, i, type);
116  }
117 
118  // for convenience
119  bool operator==(const CCFunction& other) const {
120  if (i == other.i and type == other.type) return true;
121  else return false;
122  }
123 
124  /// plotting
125  void plot(const std::string& msg = "") const {
126  plot_plane(function.world(), function, msg + name());
127  }
128 
129  template<typename Archive>
130  void serialize(const Archive& ar) {
131  ar & type & i & current_error & function;
132  }
133 };
134 
135 
137 public:
138  virtual void swap_particles_inplace() = 0;
139  virtual bool is_pure() const {return false;}
140  virtual bool is_decomposed() const {return false;}
141  virtual bool has_operator() const = 0;
142 // virtual void set_operator(const std::shared_ptr<CCConvolutionOperator> op) = 0;
143 // virtual const std::shared_ptr<CCConvolutionOperator> get_operator_ptr() const = 0;
144  virtual void print_size(const std::string name="") const = 0;
145  virtual std::string name(const bool transpose=false) const = 0;
146  virtual World& world() const =0;
147  virtual std::shared_ptr<TwoBodyFunctionComponentBase> clone() = 0;
149  virtual hashT hash() const = 0;
150 };
151 
152 /// a two-body, explicitly 6-dimensional function
153 template<typename T, std::size_t NDIM>
155  static constexpr std::size_t LDIM=NDIM/2;
156  static_assert(NDIM%2==0,"NDIM must be even");
157 
158 public:
160 
163  : u(f), op(op) {}
164 
165  /// deep copy
166  std::shared_ptr<TwoBodyFunctionComponentBase> clone() override {
168  return std::make_shared<TwoBodyFunctionPureComponent<T,NDIM>>(result);
169  }
170 
171  template<typename Q>
173  u.scale(fac);
174  return *this;
175  }
176 
177  bool is_pure() const override {return true;}
178 
179  bool has_operator() const override {return op!=nullptr;}
180 
181  World& world() const override {return u.world();};
182 
183  void print_size(const std::string name1="") const override {
184  u.print_size(name1+name(false));
185  }
186 
187  std::string name(const bool transpose) const override {
188  if (transpose) {
189  if (has_operator()) return "< u |"+get_operator_ptr()->name();
190  return "< u |";
191  }
192  if (has_operator()) return get_operator_ptr()->name() + "| u >";
193  return "| u >";
194  }
195 
196 
197 // template<typename Q, std::size_t MDIM>
198 // TwoBodyFunctionPureComponent operator*()(const Function<Q,MDIM>& g, const int particle=0) {}
199 //
200  template<typename Q, std::size_t MDIM>
202 
203  /// return f(2,1)
204  void swap_particles_inplace() override {
205  u=swap_particles(u);
206  }
207 
208  const std::shared_ptr<CCConvolutionOperator<T,LDIM>> get_operator_ptr() const {return op;};
209 
210  void set_operator(const std::shared_ptr<CCConvolutionOperator<T,LDIM>> op1) {op=op1;}
211 
213  return u;
214  }
215 
216  hashT hash() const override {
217  hashT h1=hash_value(u.get_impl());
218  if (op) hash_combine(h1,hash_value(*op));
219  return h1;
220  }
221 
222 private:
223  /// pure 6D function
225  std::shared_ptr<CCConvolutionOperator<T,LDIM>> op;
226 
227 };
228 
229 /// holds two vectors a and b of low-dimensional functions forming a high-dim function by a sum of outer products
230 /// f(1,2) = sum_i |a_i b_i >
231 template<typename T, std::size_t NDIM>
233  static constexpr std::size_t LDIM=NDIM/2;
234  static_assert(NDIM%2==0,"NDIM must be even");
235 
236 public:
238 
240  const std::vector<Function<T,LDIM>>& b) : a(a), b(b), op(nullptr) {};
241 
243  const std::vector<Function<T,LDIM>>& b,
244  const std::shared_ptr<CCConvolutionOperator<T,LDIM>> op) : a(a), b(b), op(op) {};
245 
247 
248  /// deep copy
249  std::shared_ptr<TwoBodyFunctionComponentBase> clone() override {
251  return std::make_shared<TwoBodyFunctionSeparatedComponent<T,NDIM>>(result);
252  }
253 
254  template<typename Q>
256  if (a.size()>0 and a.front().is_initialized()) scale(a.front().world(),a,fac);
257  return *this;
258  }
259 
260  bool is_decomposed() const override {return true;}
261  bool has_operator() const override {return op!=nullptr;}
262 
263  World& world() const override {
264  MADNESS_ASSERT(a.size()>0 and a.front().is_initialized());
265  return a.front().world();
266  };
267 
268  void print_size(const std::string name1="") const override {
269  if (a.size() > 0) {
270  World& world = a.front().world();
271  madness::print_size(world, a, "a from " + name(false));
272  madness::print_size(world, b, "b from " + name(false));
273  }
274  }
275 
276  std::string name(const bool transpose) const override {
277  if (transpose) {
278  if (has_operator()) return "<ab |"+get_operator_ptr()->name();
279  return "<ab |";
280  }
281  if (has_operator()) return get_operator_ptr()->name() + "| ab>";
282  return "| ab>";
283  };
284 
285  void serialize() {}
286 
287  hashT hash() const override {
288  hashT h1=0;
289  for (const auto& aa : a) hash_combine(h1,hash_value(aa.get_impl()));
290  for (const auto& bb : b) hash_combine(h1,hash_value(bb.get_impl()));
291  // print("hashvalue of TwoBodyFunctionSeparatedComponent: ",h1);
292 
293  if (op) hash_combine(h1,hash_value(*op));
294  return h1;
295  }
296 
297 
298  template<typename Q, std::size_t MDIM>
300  MADNESS_EXCEPTION("TwoBodyFunctionPureComponent<T> apply not yet implemented",1);
301  }
302 
303  /// return f(2,1)
304  void swap_particles_inplace() override {
305  std::swap(a,b);
306  }
307 
308  long rank() const {
309  MADNESS_CHECK(a.size()==b.size());
310  return a.size();
311  }
312 
313  std::vector<Function<T,LDIM>> get_a() const {return a;}
314  std::vector<Function<T,LDIM>> get_b() const {return b;}
315  std::vector<Function<T,LDIM>> get_vector(const int i) const {
316  MADNESS_CHECK(i==0 or i==1);
317  if (i==0) return a;
318  else if (i==1) return b;
319  else {
320  MADNESS_EXCEPTION("confused index in TwoBodyFunctionSeparatedComponent",1);
321  }
322  }
323 
324  const std::shared_ptr<CCConvolutionOperator<T,LDIM>> get_operator_ptr() const {return op;};
325 
326  void set_operator(const std::shared_ptr<CCConvolutionOperator<T,LDIM>> op1) {op=op1;}
327 
328 private:
329 
330  std::vector<Function<T,LDIM>> a;
331  std::vector<Function<T,LDIM>> b;
332  std::shared_ptr<CCConvolutionOperator<T,LDIM>> op;
333 
334 };
335 
336 
337 
338 
339 /// Helper structure for the coupling potential of CC Singles and Doubles
340 /// because of the regularization of the CC-Wavefunction (for CC2: |tauij> = |uij> + Qt12*f12*|titj>)
341 /// we have 6D-functions in std format |u> : type==pure_
342 /// we have 6D-functions in separated format: type==decomposed_ (e.g O1*f12*|titj> = |xy> with x=|k> and y=<k|f12|ti>*|tj>)
343 /// we have 6D-function like f12|xy> which are not needed to be represented on the 6D MRA-Grid, type==op_decomposed_
344 
345 
346 /** functionality
347  *
348  * - ctor
349  * - assignment
350  * - add
351  * - scalar multiplication
352  * - inner
353  * - inner_partial
354  * - swap_particles
355  * - apply
356  * - apply_partial (i.e. exchange)
357  * - serialize
358  * - callapse_to_pure (excl g!)
359  * - mul_partial
360  */
361 
362 /// a 6D function, either in full or low rank form, possibly including an 2-particle function
363 
364 /**
365  * the function is stored as
366  * - pure: full rank form, 6D
367  * - op_pure: full rank form, 6D with an 2-particle function f(1,2) |u>
368  * - decomposed: sum of two vectors of 3D functions \sum_i |a_i(1) b_i(2)>
369  * - op_decomposed: as above, with an 2-particle function: f(1,2) \sum_i |a_i b_i>
370  *
371 **/
372 template<typename T=double, std::size_t NDIM=6>
374 public:
375  static constexpr std::size_t LDIM=NDIM/2;
376  static_assert(NDIM%2==0,"NDIM must be even");
377 
379 
380 public:
381 
382  /// empty ctor
383  CCPairFunction() = default;
384 
385  /// takes a shallow copy of the argument function
386  explicit CCPairFunction(const Function<T,NDIM>& ket) {
388  }
389 
390  /// takes a shallow copy of the argument function
391  explicit CCPairFunction(const std::shared_ptr<CCConvolutionOperator<T,LDIM>> op_, const Function<T,NDIM>& ket) {
393  }
394 
395  /// takes a deep copy of the argument functions
396  explicit CCPairFunction(const std::vector<Function<T,LDIM>>& f1, const std::vector<Function<T,LDIM>>& f2) {
397  World& world=f1.front().world();
399  }
400 
401  /// takes a deep copy of the argument functions
403  CCPairFunction(std::vector<Function<T,LDIM>>({f1}),std::vector<Function<T,LDIM>>({f2})) {
404  }
405 
406  /// takes a deep copy of the argument functions
407  explicit CCPairFunction(const std::pair<std::vector<Function<T,LDIM>>, std::vector<Function<T,LDIM>>>& f) :
408  CCPairFunction(f.first,f.second) {
409  }
410 
411  /// takes a deep copy of the argument functions
412  explicit CCPairFunction(const std::shared_ptr<CCConvolutionOperator<T,LDIM>> op_, const CCFunction<T,LDIM>& f1, const CCFunction<T,LDIM>& f2) :
413  CCPairFunction(op_,std::vector<Function<T,LDIM>>({f1.function}),std::vector<Function<T,LDIM>>({f2.function})) {
414  }
415 
416  /// takes a deep copy of the argument functions
417  explicit CCPairFunction(const std::shared_ptr<CCConvolutionOperator<T,LDIM>> op_, const std::vector<Function<T,LDIM>>& f1,
418  const std::vector<Function<T,LDIM>>& f2) {
419  World& world=f1.front().world();
421  }
422 
423  /// takes a deep copy of the argument functions
424  explicit CCPairFunction(const std::shared_ptr<CCConvolutionOperator<T,LDIM>> op_, const Function<T,LDIM>& f1,
425  const Function<T,LDIM>& f2) : CCPairFunction(op_,std::vector<Function<T,LDIM>>({f1}),
426  std::vector<Function<T,LDIM>>({f2})) {
427  };
428 
429  /// shallow assignment operator
431  component=other.component;
432  return *this;
433  }
434 
435  /// copy ctor -- shallow
436  CCPairFunction(const CCPairFunction& other) = default;
437 
438  /// deep copy
439  friend CCPairFunction copy(const CCPairFunction& other) {
440  CCPairFunction result;
441  result.component=other.component->clone();
442  return result;
443  }
444 
445  bool is_assigned() const {
446  return component.get();
447  }
448 
449  friend hashT hash_value(const CCPairFunction& f) {
450  if (not f.is_assigned()) { return hashT(); }
451  return f.component->hash();
452  }
453 
454 private:
455  std::vector<CCPairFunction> consolidate(const std::vector<CCPairFunction>& other,
456  const std::vector<std::string>& options,
457  const std::vector<Vector<double,LDIM>>& centers) const;
458 
459  /// turn decomposed functions with operator into decomposed functions using LowRankFunction
460  static std::vector<CCPairFunction> op_dec_to_dec(const std::vector<CCPairFunction>& other,
461  const std::vector<Vector<double,LDIM>>& centers);
462 
463  /// turn pure functions with operator into pure functions without operators
464  static std::vector<CCPairFunction> op_pure_to_pure(const std::vector<CCPairFunction>& other);
465 
466  /// turn decomposed functions with operator into pure functions without operators
467  static std::vector<CCPairFunction> op_dec_to_pure(const std::vector<CCPairFunction>& other);
468 
469  /// turn decomposed functions without operator into pure functions without operators
470  static std::vector<CCPairFunction> dec_to_pure(const std::vector<CCPairFunction>& other);
471 
472  /// remove linear dependent terms in the low-rank parts
473  static std::vector<CCPairFunction> remove_linearly_dependent_terms(const std::vector<CCPairFunction>& other,
474  double thresh=-1.0);
475 
476  static std::vector<CCPairFunction> collect_same_types(const std::vector<CCPairFunction>& other);
477 
478 public:
479  // check if all types (pure. op_pure, decomposed, op_decomposed, with various ops) occur only once
480  static bool is_collected(const std::vector<CCPairFunction<T,NDIM>>& other);
481 
482  /// collect the terms into a compact format
483 
484  /// @param[in] other: a vector of CCPairFunctions
485  /// @param[in] options: a vector of strings which can be "one_term", "op_pure_to_pure", "svd"
486  /// @param[in] centers: a vector of 3D-vectors which are the centers of the grid for low-rank functions
487  /// TODO: implement a function for removing linearly dependent terms without orthonormalization
488  friend std::vector<CCPairFunction> consolidate(const std::vector<CCPairFunction>& other,
489  const std::vector<std::string> options=std::vector<std::string>(),
490  const std::vector<Vector<double,LDIM>> centers=std::vector<Vector<double,LDIM>>()) {
491 
492  if (other.size()>0) return other.front().consolidate(other,options,centers); // workaround
493  return other;
494  };
495 
496 
497  void info() const { print_size(); }
498 
499  World& world() const {
501  return component->world();
502  }
503 
505  MADNESS_CHECK(component and (component->is_pure()));
506  return pure().get_function();
507  }
508 
510  MADNESS_CHECK(component and (component->is_pure()));
511  return pure().get_function();
512  }
513 
514  /// make a deep copy and invert the sign
515  /// deep copy necessary otherwise: shallow copy errors
517 
518  /// scalar multiplication: f*fac
519  CCPairFunction operator*(const double fac) const {
520  CCPairFunction result=copy(*this);
521  result*=fac;
522  return result;
523  }
524 
525  /// scalar multiplication: fac*f
526  friend CCPairFunction operator*(const double fac, const CCPairFunction& f) {
527  return f*fac;
528  }
529 
530  /// multiplication with a 2-particle function
531  friend CCPairFunction operator*(const std::shared_ptr<CCConvolutionOperator<T,LDIM>> op, const CCPairFunction& f) {
532  CCPairFunction result=copy(f);
533  return result.multiply_with_op_inplace(op);
534  }
535 
536  /// multiplication with a 2-particle function
537  friend std::vector<CCPairFunction> operator*(const std::shared_ptr<CCConvolutionOperator<T,LDIM>> op,
538  const std::vector<CCPairFunction>& f) {
539  std::vector<CCPairFunction> result;
540  for (auto& ff : f) {
541  result.push_back(copy(ff));
542  result.back().multiply_with_op_inplace(op);
543  }
544  return result;
545  }
546 
547  friend std::vector<CCPairFunction> multiply(const std::vector<CCPairFunction>& other, const Function<T,LDIM> f,
548  const std::array<int, LDIM>& v1) {
549  std::vector<CCPairFunction> result;
550  for (auto& o : other) {
551 // double cpu0=cpu_time();
552 // std::cout << "multiply " << o.name();
553  result.push_back(multiply(o,f,v1));
554 // double cpu1=cpu_time();
555 // std::cout << " done after " << cpu1-cpu0 << std::endl;
556  }
557  return result;
558  }
559 
560  /// multiplication with a 2-particle function
562  CCPairFunction result=copy(*this);
563  return result.multiply_with_op_inplace(op);
564  }
565 
567 
568 
569  bool has_operator() const {return component->has_operator();}
570  bool is_pure() const {return component->is_pure();}
571  bool is_op_pure() const {return is_pure() and has_operator();}
572  bool is_pure_no_op() const {return is_pure() and (not has_operator());}
573  bool is_decomposed() const {return component->is_decomposed();}
574  bool is_op_decomposed() const {return component->is_decomposed() and component->has_operator();}
575  bool is_decomposed_no_op() const {return component->is_decomposed() and (not component->has_operator());}
576 
578  if (auto ptr=dynamic_cast<TwoBodyFunctionPureComponent<T,NDIM>*>(component.get())) return *ptr;
579  MADNESS_EXCEPTION("bad cast in TwoBodyFunction",1);
580  }
581 
583  if (auto ptr=dynamic_cast<TwoBodyFunctionSeparatedComponent<T,NDIM>*>(component.get())) return *ptr;
584  MADNESS_EXCEPTION("bad cast in TwoBodyFunction",1);
585  }
586 
587  std::vector<Function<T,LDIM>> get_a() const {
588  MADNESS_CHECK(component->is_decomposed());
589  return decomposed().get_a();
590  }
591 
592  std::vector<Function<T,LDIM>> get_b() const {
593  MADNESS_CHECK(component->is_decomposed());
594  return decomposed().get_b();
595  }
596 
597  std::vector<Function<T,LDIM>> get_vector(const int i) const {
598  MADNESS_CHECK(component->is_decomposed());
599  return decomposed().get_vector(i);
600  }
601 
603  MADNESS_CHECK(component and component->has_operator());
604  if (is_pure()) return *(pure().get_operator_ptr());
605  if (is_decomposed()) return *(decomposed().get_operator_ptr());
606  MADNESS_EXCEPTION("bad cast in TwoBodyFunction",1);
607  return *(decomposed().get_operator_ptr());
608  }
609 
610  const std::shared_ptr<CCConvolutionOperator<T,LDIM>> get_operator_ptr() const {
612  if (is_pure()) return (pure().get_operator_ptr());
613  if (is_decomposed()) return (decomposed().get_operator_ptr());
614  MADNESS_EXCEPTION("bad cast in TwoBodyFunction",1);
615 // return component->get_operator_ptr();
616  }
617 
618  void reset_operator(const std::shared_ptr<CCConvolutionOperator<T,LDIM>> op) {
620  if (is_pure()) pure().set_operator(op);
621  else if (is_decomposed()) decomposed().set_operator(op);
622  else {
623  MADNESS_EXCEPTION("bad cast in TwoBodyFunction",1);
624  }
625  }
626 
627  /// can this be converted to a pure representation (depends on the operator, if present)
628  bool is_convertible_to_pure_no_op() const;
629 
630  /// out-of-place conversion to pure function
632  auto tmp=copy(*this);
633  MADNESS_CHECK(tmp.is_convertible_to_pure_no_op());
634  tmp.convert_to_pure_no_op_inplace();
635  return tmp;
636  }
637 
638  /// convert this into a pure hi-dim function
640 
641  CCPairFunction& operator*=(const double fac) {
642  if (component->is_pure()) pure()*=fac;
643  if (component->is_decomposed()) decomposed()*=fac;
644  return *this;
645  }
646 
647  /// print the size of the functions
648  void print_size(const std::string name1="") const {
649  if (not component) {
650  print("CCPairFunction "+name1+ " not assigned");
651  } else if (component->is_pure()) {
652  component->print_size(name1);
653  } else {
654  print("printing",name1,name());
655  double wall=wall_time();
656  component->print_size();
657  double anorm=madness::norm2(world(),get_a());
658  double bnorm=madness::norm2(world(),get_b());
659  print("anorm, bnorm",anorm,bnorm);
660  double norm=this->norm2();
661  std::size_t fsize=get_a().size();
662  std::size_t bufsize=128;
663  char buf[bufsize];
664  snprintf(buf, bufsize, "%40s at time %.1fs: norm/ #functions: %7.5f %zu \n",
665  ((name1+" "+name()).c_str()), wall, norm, fsize);
666  if (world().rank()==0) print(std::string(buf));
667  }
668 
669  };
670 
671  std::string name(const bool transpose=false) const {
672  if (not component) return "empty";
673  return component->name(transpose);
674  }
675 
676  typename Tensor<T>::scalar_type norm2() const {
677  if (is_pure_no_op()) {
678  return pure().get_function().norm2();
679  } else if (is_op_pure()) {
680  double n2=inner(*this,*this);
681  if (n2<0.0) print("norm of ",name()," is < 0.0");
682  return sqrt(std::max(0.0,n2));
683  } else if (component->is_decomposed()) {
685  auto tmp= inner_internal(*this,R2);
686  typename Tensor<T>::scalar_type result=std::real(tmp);
687  typename Tensor<T>::scalar_type imag=std::imag(tmp);
688  if ((imag>1.e-14) or (result<-1.e-14)) {
689  MADNESS_EXCEPTION("bad norm in TwoBodyFunction",1);
690  }
691  return sqrt(std::abs(result));
692  }
693  MADNESS_EXCEPTION("bad cast in TwoBodyFunction",1);
694  return 0.0;
695  }
696 
697  /// multiply CCPairFunction with a 3D function of one of the two particles
699  const std::array<int, LDIM>& v1) {
700  auto a012=std::array<int,LDIM>();
701  auto a345=std::array<int,LDIM>();
702  for (int i=0; i<LDIM; ++i) {
703  a012[i]=i;
704  a345[i]=i+LDIM;
705  }
706  int particle=-1;
707  if (v1== a012) particle=0;
708  if (v1== a345) particle=1;
709  MADNESS_CHECK(particle==0 or particle==1);
710  World& world=other.world();
711 
712  if (other.is_decomposed()) {
713  if (particle == 0) {
714  return CCPairFunction<T,NDIM>(other.get_operator_ptr(), f * other.get_a(), copy(world, other.get_b()));
715  } else {
716  return CCPairFunction<T,NDIM>(other.get_operator_ptr(), copy(world, other.get_a()), f * other.get_b());
717  }
718  } else if (other.is_pure()) {
719  auto tmp=multiply(other.get_function(),f,particle+1);
720  return CCPairFunction<T,NDIM>(other.get_operator_ptr(),tmp);
721  } else {
722  MADNESS_EXCEPTION("confused CCPairFunction<T,NDIM> in multiply",1);
723  }
724  };
725 
726  /// @param[in] f: a 3D-CC_function
727  /// @param[in] particle: the particle on which the operation acts
728  /// @param[out] <f|u>_particle (projection from 6D to 3D)
729  Function<T,LDIM> project_out(const CCFunction<T,LDIM>& f, const size_t particle) const;
730 
731  /// result is: <x|op12|f>_particle
732 
733  /// @param[in] x: a 3D-CC_function
734  /// @param[in] op: a CC_convoltion_operator which is currently either f12 or g12
735  /// @param[in] particle: the particle on which the operation acts (can be 1 or 2)
736  /// @param[out] the operator is applied and afterwards a convolution with the delta function makes a 3D-function: <x|op|u>_particle
738  dirac_convolution(const CCFunction<T,LDIM>& x, const CCConvolutionOperator<T,LDIM>& op, const size_t particle) const;
739 
740  /// @param[out] particles are interchanged, if the function was u(1,2) the result is u(2,1)
742  CCPairFunction result=copy(*this);
743  result.component->swap_particles_inplace();
744  return result;
745  };
746 
747  double
748  make_xy_u(const CCFunction<T,LDIM>& xx, const CCFunction<T,LDIM>& yy) const;
749 
750  /// compute the inner product of this and other
751  double inner_internal(const CCPairFunction& other, const Function<T,LDIM>& R2) const;
752 
753  friend double inner(const CCPairFunction& a, const CCPairFunction& b, const Function<T,LDIM>& R2) {
754  return a.inner_internal(b,R2);
755  }
756 
757  friend double inner(const CCPairFunction& a, const CCPairFunction& b) {
759  return a.inner_internal(b,R2);
760  }
761 
762  friend double inner(const std::vector<CCPairFunction>& va, const std::vector<CCPairFunction>& vb,
764  double wall0=cpu_time();
765 // Function<T,LDIM> R2;
766  double result=0.0;
767  for (auto& a : va) {
768  for (auto& b : vb) {
769  double tmp=a.inner_internal(b,R2);
770  double wall1=cpu_time();
771  constexpr std::size_t bufsize=256;
772  char buf[bufsize];
773  snprintf(buf,bufsize,"result from inner %10s %10s %12.8f %4.1fs",a.name(true).c_str(),b.name().c_str(),tmp,wall1-wall0);
774  print(std::string(buf));
775  wall0=wall1;
776  result+=tmp;
777  }
778  }
779  return result;
780  }
781 
782 
783  friend std::vector<CCPairFunction> swap_particles(const std::vector<CCPairFunction>& argument) {
784  std::vector<CCPairFunction> result;
785  for (auto& a : argument) result.push_back(a.swap_particles());
786  return result;
787  };
788 
789 public:
790  /// the 3 types of 6D-function that occur in the CC potential which coupled doubles to singles
791  std::shared_ptr<TwoBodyFunctionComponentBase> component;
792 
793  /// @param[in] f: a 3D-CC_function
794  /// @param[in] particle: the particle on which the operation acts
795  /// @param[out] <f|u>_particle (projection from 6D to 3D) for the case that u=|ab> so <f|u>_particle = <f|a>*|b> if particle==1
797 
798  /// @param[in] f: a 3D-CC_function
799  /// @param[in] particle: the particle on which the operation acts
800  /// @param[out] <f|u>_particle (projection from 6D to 3D) for the case that u=op|xy> so <f|u>_particle = <f|op|x>*|y> if particle==1
802 
803  /// @param[in] x: a 3D-CC_function
804  /// @param[in] op: a CC_convoltion_operator which is currently either f12 or g12
805  /// @param[in] particle: the particle on which the operation acts (can be 1 or 2)
806  /// @param[out] the operator is applied and afterwards a convolution with the delta function makes a 3D-function: <x|op|u>_particle
807  /// in this case u=|ab> and the result is <x|op|u>_1 = <x|op|a>*|b> for particle==1
810 
811  /// small helper function that gives back (a,b) or (b,a) depending on the value of particle
812  const std::pair<std::vector<Function<T,LDIM>>, std::vector<Function<T,LDIM>>> assign_particles(const size_t particle) const;
813 
814  static std::vector<CCPairFunction<T,NDIM>> apply(const ProjectorBase& P, const std::vector<CCPairFunction<T,NDIM>>& argument);
815  static std::vector<CCPairFunction<T,NDIM>> apply(const SeparatedConvolution<T,NDIM>& G, const CCPairFunction<T,NDIM>& argument);
816  static std::vector<CCPairFunction<T,NDIM>> apply(const SeparatedConvolution<T,NDIM>& G, const std::vector<CCPairFunction<T,NDIM>>& argument);
817 
818 
820  const std::array<int, LDIM>& v1,
821  const std::array<int, LDIM>& v2) const;
822 
824  const std::array<int, LDIM>& v1,
825  const std::array<int, LDIM>& v2) const;
826 
827 };
828 
829 namespace archive {
830 template <class archiveT, class T, std::size_t NDIM>
833  constexpr std::size_t LDIM=CCPairFunction<T,NDIM>::LDIM;
834  bool exists=false;
835  bool is_pure=false;
836  bool has_operator=false;
837  ar & exists;
838  if (exists) {
839  ar & is_pure & has_operator;
840  if (is_pure) {
842  ar & f;
844  } else {
845  std::size_t sz=0;
846  ar & sz;
847  std::vector<Function<T,LDIM>> a(sz),b(sz);
848  for (auto& aa : a) ar & aa;
849  for (auto& bb : b) ar & bb;
851  }
852 
853  // store construction parameters of the operator, not the operator itself
854  if (has_operator) {
857  ar & param & type;
858  auto op=std::make_shared<CCConvolutionOperator<T,LDIM>>(*ar.get_world(),type,param);
859  p.reset_operator(op);
860  }
861  }
862  }
863 };
864 
865 template <class archiveT, class T, std::size_t NDIM>
867  static inline void store(const ParallelOutputArchive<archiveT>& ar, const CCPairFunction<T,NDIM>& f) {
868  bool exists=f.is_assigned();
869  ar & exists;
870  if (exists) {
871  ar & f.is_pure() & f.has_operator();
872  if (f.is_pure()) ar & f.get_function();
873  if (f.is_decomposed()) {
874  auto avec=f.get_a();
875  auto bvec=f.get_b();
876  ar & avec.size();
877  for (const auto& a : avec) ar & a;
878  for (const auto& b : bvec) ar & b;
879  }
880  // store construction parameters of the operator, not the operator itself
881  if (f.has_operator()) {
882  ar & f.get_operator().parameters & f.get_operator().type();
883  }
884  }
885  }
886 };
887 }
888 
889 /// apply the operator to the argument
890 
891 /// the operator is applied to one particle only, the other one is left untouched
892 /// note the ordering of the particles, cf the corresponding comment in mra.h
893 /// op.particle==1 : op(f(x,y)) = op(x,x') f(x',y) = result(x,y);
894 /// op.particle==2 : op(f(x,y)) = op(y,y') f(x,y') = result(y,x);
895 template<typename T, std::size_t NDIM>
897  bool convert_to_pure=(arg.has_operator() or arg.is_pure());
899  World& world = arg.world();
900 
901  if (convert_to_pure) {
902  auto tmp=arg.to_pure().get_function();
903  tmp=op(tmp);
904 
905  result=(CCPairFunction<T,NDIM>(tmp));
906  // !! confusing ordering of the result variables!!
907  if (op.particle()==2) result=result.swap_particles();
908 
909  } else if (arg.is_decomposed_no_op()) {
910  MADNESS_CHECK(op.particle()==1 or op.particle()==2);
911  if (op.particle()==1) {
912  auto tmp= madness::apply(world,op,arg.get_a());
913  result=(CCPairFunction<T,NDIM>(tmp,arg.get_b()));
914  } else if (op.particle()==2) {
915  auto tmp= madness::apply(world,op,arg.get_b());
916  result=(CCPairFunction<T,NDIM>(tmp,arg.get_a()));
917  }
918 
919  } else {
920  MADNESS_CHECK_THROW(false,"confused type in apply(CCPairFunction<T,NDIM>)");
921  }
922 
923  return result;
924 }
925 
926 /// apply the operator to the argument
927 
928 /// the operator is applied to one particle only, the other one is left untouched
929 /// note the ordering of the particles, cf the corresponding comment in mra.h
930 /// op.particle==1 : op(f(x,y)) = op(x,x') f(x',y) = result(x,y);
931 /// op.particle==2 : op(f(x,y)) = op(y,y') f(x,y') = result(y,x);
932 template<typename T, std::size_t NDIM>
933 std::vector<CCPairFunction<T,NDIM>> apply(const SeparatedConvolution<T,NDIM/2>& op, const std::vector<CCPairFunction<T,NDIM>>& argument) {
934  std::vector<CCPairFunction<T, NDIM>> result;
935  for (const auto& arg : argument) result.push_back(madness::apply(op, arg));
936  return result;
937 }
938 
939 template<typename T, std::size_t NDIM>
941  CCPairFunction result;
942  for (const auto& a : argument) result+=G(a);
943  return result;
944 }
945 
946 /// apply the operator on a CCPairfunction, both with the same dimension
947 
948 /// note there is another function, where the operator works only on some dimensions of the CCPairFunction!
949 /// @return result(x) = \int op(x,x') arg(x') dx': a CCPairfunction with the same dimension as the argument
950 template<typename T, std::size_t NDIM>
952  CCPairFunction result;
953  timer t1(argument.world());
954  if (argument.is_pure()) {
955  result=CCPairFunction(G(argument.get_function()));
956  } else if (argument.is_decomposed_no_op()) {
957  MADNESS_ASSERT(argument.get_a().size() == argument.get_b().size());
958  Function<T,NDIM> result1=G(argument.get_a(), argument.get_b());
959  result=CCPairFunction(result1);
960  } else {
961  MADNESS_EXCEPTION("unknown type in CCPairFunction::apply",1);
962  }
963  t1.end("applying G to " + argument.name());
964  return result;
965 };
966 
967 
968 /// apply the projector on the argument function, potentially yielding a vector of CCPairfunctions as result
969 
970 /// result can be
971 /// Q12 f12 |ij> = (1 - O1) (1 - O2) f12 i(1) j(2)
972 /// = f12 ij - \sum_k k(1) f_ik(2) j(2) - \sum_k k(2) f_ij(1)j(1)
973 /// which is a pure function and a decomposed function
974 template<typename T, std::size_t NDIM>
975 std::vector<CCPairFunction<T,NDIM>> apply(const ProjectorBase& projector, const std::vector<CCPairFunction<T,NDIM>>& argument) {
976  return CCPairFunction<T,NDIM>::apply(projector,argument);
977 }
978 
979 
980 template<typename T, std::size_t NDIM>
982  auto result=madness::apply(projector,std::vector<CCPairFunction<T,NDIM>> (1,argument));
983  MADNESS_CHECK(result.size()==1);
984  return result[0];
985 }
986 
987 template<typename T, std::size_t NDIM>
989  const std::tuple<int,int,int> v1, const std::tuple<int,int,int> v2) {
990  constexpr std::size_t LDIM=CCPairFunction<T,NDIM>::LDIM;
991  auto v11=std::array<int,LDIM>({std::get<0>(v1),std::get<1>(v1),std::get<2>(v1)});
992  auto v22=std::array<int,LDIM>({std::get<0>(v2),std::get<1>(v2),std::get<2>(v2)});
993 
994  return c.partial_inner(f,v11,v22);
995 }
996 
997 template<typename T, std::size_t NDIM>
999  const std::array<int,CCPairFunction<T,NDIM>::LDIM>& v1,
1000  const std::array<int,CCPairFunction<T,NDIM>::LDIM>& v2) {
1001  return c.partial_inner(f,v1,v2);
1002 }
1003 
1004 template<typename T, std::size_t NDIM>
1006  const std::tuple<int,int,int> v1, const std::tuple<int,int,int> v2) {
1007  constexpr std::size_t LDIM=CCPairFunction<T,NDIM>::LDIM;
1008  auto v11=std::array<int,LDIM>({std::get<0>(v1),std::get<1>(v1),std::get<2>(v1)});
1009  auto v22=std::array<int,LDIM>({std::get<0>(v2),std::get<1>(v2),std::get<2>(v2)});
1010 
1011  return c1.partial_inner(c2,v11,v22);
1012 }
1013 
1014 template<typename T, std::size_t NDIM>
1016  const std::array<int,CCPairFunction<T,NDIM>::LDIM>& v1,
1017  const std::array<int,CCPairFunction<T,NDIM>::LDIM>& v2) {
1018  return c1.partial_inner(c2,v1,v2);
1019 }
1020 
1021 template<typename T, std::size_t NDIM>
1022 std::vector<CCPairFunction<T,NDIM>> inner(const std::vector<CCPairFunction<T,NDIM>>& c1,
1023  const std::vector<CCPairFunction<T,NDIM>>& c2,
1024  const std::tuple<int,int,int> v1, const std::tuple<int,int,int> v2) {
1025  constexpr std::size_t LDIM=CCPairFunction<T,NDIM>::LDIM;
1026  auto v11=std::array<int,LDIM>({std::get<0>(v1),std::get<1>(v1),std::get<2>(v1)});
1027  auto v22=std::array<int,LDIM>({std::get<0>(v2),std::get<1>(v2),std::get<2>(v2)});
1028  return inner(c1,c2,v11,v22);
1029 }
1030 
1031 template<typename T, std::size_t NDIM>
1032 std::vector<CCPairFunction<T,NDIM>> inner(const std::vector<CCPairFunction<T,NDIM>>& c1,
1033  const std::vector<CCPairFunction<T,NDIM>>& c2,
1034  const std::array<int,CCPairFunction<T,NDIM>::LDIM>& v1,
1035  const std::array<int,CCPairFunction<T,NDIM>::LDIM>& v2) {
1036  std::vector<CCPairFunction<T,NDIM>> result;
1037  for (const auto& cc1 : c1) {
1038  for (const auto& cc2 : c2) {
1039  print("inner of ",cc1.name(), cc2.name());
1040  result.push_back(inner(cc1,cc2,v1,v2));
1041  }
1042  }
1043  return result;
1044 }
1045 
1046 template <typename T, std::size_t NDIM>
1047 std::vector<CCPairFunction<T,NDIM> > operator+(const std::vector<CCPairFunction<T,NDIM>> c1, const std::vector<CCPairFunction<T,NDIM> >& c2) {
1048  std::vector<CCPairFunction<T,NDIM>> result;
1049  for (const auto& l : c1) result.push_back(l);
1050  for (const auto& l : c2) result.push_back(l);
1051  return result;
1052 }
1053 
1054 template <typename T, std::size_t NDIM>
1055 std::vector<CCPairFunction<T,NDIM> > operator-(const std::vector<CCPairFunction<T,NDIM>> c1, const std::vector<CCPairFunction<T,NDIM> >& c2) {
1056  std::vector<CCPairFunction<T,NDIM>> result;
1057  for (const auto& l : c1) result.push_back(l);
1058  for (const auto& l : c2) result.push_back(-1.0*l);
1059  return result;
1060 }
1061 
1062 template <typename T, std::size_t NDIM>
1063 std::vector<CCPairFunction<T,NDIM> >& operator+=(std::vector<CCPairFunction<T,NDIM> >& lhs,
1064  const CCPairFunction<T,NDIM >& rhs) {
1065  lhs.push_back(rhs);
1066  return lhs;
1067 }
1068 
1069 template <typename T, std::size_t NDIM>
1070 std::vector<CCPairFunction<T,NDIM> >& operator+=(std::vector<CCPairFunction<T,NDIM> >& rhs,
1071  const std::vector<CCPairFunction<T,NDIM> >& lhs) {
1072  for (const auto& l : lhs) rhs.push_back(l);
1073  return rhs;
1074 }
1075 
1076 template <typename T, std::size_t NDIM>
1077 std::vector<CCPairFunction<T,NDIM> >& operator-=(std::vector<CCPairFunction<T,NDIM> >& rhs,
1078  const std::vector<CCPairFunction<T,NDIM> >& lhs) {
1079  for (const auto& l : lhs) rhs.push_back(-1.0*l);
1080  return rhs;
1081 }
1082 
1083 template <typename T, std::size_t NDIM>
1084 std::vector<CCPairFunction<T,NDIM> > operator*(const double fac, const std::vector<CCPairFunction<T,NDIM> >& arg) {
1085  std::vector<CCPairFunction<T,NDIM>> result;
1086  for (const auto& l : arg) result.push_back(fac*l);
1087  return result;
1088 }
1089 
1090 
1091 template<typename T, std::size_t NDIM>
1092 bool is_collected(const std::vector<CCPairFunction<T,NDIM>>& other) {
1094 
1095 }
1096 } // namespace madness
1097 
1098 #endif //MADNESS_CCPAIRFUNCTION_H
Definition: test_derivative.cc:24
Definition: CCStructures.h:743
structure for a CC Function 3D which holds an index and a type
Definition: ccpairfunction.h:45
void set(const Function< T, NDIM > &other)
Definition: ccpairfunction.h:76
FuncType type
Definition: ccpairfunction.h:79
CCFunction()
Definition: ccpairfunction.h:47
void serialize(const Archive &ar)
Definition: ccpairfunction.h:130
std::string name() const
Definition: ccpairfunction.h:90
double current_error
Definition: ccpairfunction.h:69
CCFunction(const Function< T, NDIM > &f)
Definition: ccpairfunction.h:49
bool operator==(const CCFunction &other) const
Definition: ccpairfunction.h:119
Function< T, NDIM > function
Definition: ccpairfunction.h:70
CCFunction operator*(const double &fac) const
scalar multiplication
Definition: ccpairfunction.h:113
double inner(const CCFunction &f) const
Definition: ccpairfunction.h:104
friend CCFunction copy(const CCFunction &other)
deep copy
Definition: ccpairfunction.h:60
Function< T, NDIM > get() const
Definition: ccpairfunction.h:72
CCFunction(const Function< T, NDIM > &f, const size_t &ii, const FuncType &type_)
Definition: ccpairfunction.h:53
CCFunction(const CCFunction &other)
Definition: ccpairfunction.h:56
size_t i
Definition: ccpairfunction.h:78
double inner(const Function< T, NDIM > &f) const
Definition: ccpairfunction.h:108
void plot(const std::string &msg="") const
plotting
Definition: ccpairfunction.h:125
void info(World &world, const std::string &msg=" ") const
Definition: ccpairfunction.h:81
Function< T, NDIM > f() const
Definition: ccpairfunction.h:74
a 6D function, either in full or low rank form, possibly including an 2-particle function
Definition: ccpairfunction.h:373
void info() const
Definition: ccpairfunction.h:497
CCPairFunction(const std::vector< Function< T, LDIM >> &f1, const std::vector< Function< T, LDIM >> &f2)
takes a deep copy of the argument functions
Definition: ccpairfunction.h:396
static std::vector< CCPairFunction > op_pure_to_pure(const std::vector< CCPairFunction > &other)
turn pure functions with operator into pure functions without operators
Definition: ccpairfunction.cc:59
static std::vector< CCPairFunction > dec_to_pure(const std::vector< CCPairFunction > &other)
turn decomposed functions without operator into pure functions without operators
Definition: ccpairfunction.cc:110
const CCConvolutionOperator< T, LDIM > & get_operator() const
Definition: ccpairfunction.h:602
void convert_to_pure_no_op_inplace()
convert this into a pure hi-dim function
Definition: ccpairfunction.cc:33
CCPairFunction(const Function< T, LDIM > &f1, const Function< T, LDIM > &f2)
takes a deep copy of the argument functions
Definition: ccpairfunction.h:402
static constexpr std::size_t LDIM
Definition: ccpairfunction.h:375
std::vector< Function< T, LDIM > > get_vector(const int i) const
Definition: ccpairfunction.h:597
friend std::vector< CCPairFunction > operator*(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op, const std::vector< CCPairFunction > &f)
multiplication with a 2-particle function
Definition: ccpairfunction.h:537
CCPairFunction(const std::pair< std::vector< Function< T, LDIM >>, std::vector< Function< T, LDIM >>> &f)
takes a deep copy of the argument functions
Definition: ccpairfunction.h:407
std::vector< CCPairFunction > consolidate(const std::vector< CCPairFunction > &other, const std::vector< std::string > &options, const std::vector< Vector< double, LDIM >> &centers) const
TwoBodyFunctionSeparatedComponent< T, NDIM > & decomposed() const
Definition: ccpairfunction.h:582
friend CCPairFunction< T, NDIM > multiply(const CCPairFunction< T, NDIM > &other, const Function< T, LDIM > &f, const std::array< int, LDIM > &v1)
multiply CCPairFunction with a 3D function of one of the two particles
Definition: ccpairfunction.h:698
bool is_convertible_to_pure_no_op() const
can this be converted to a pure representation (depends on the operator, if present)
Definition: ccpairfunction.cc:23
static std::vector< CCPairFunction< T, NDIM > > apply(const ProjectorBase &P, const std::vector< CCPairFunction< T, NDIM >> &argument)
Definition: ccpairfunction.cc:626
std::vector< Function< T, LDIM > > get_b() const
Definition: ccpairfunction.h:592
Function< T, LDIM > project_out(const CCFunction< T, LDIM > &f, const size_t particle) const
Definition: ccpairfunction.cc:300
CCPairFunction< T, NDIM > & multiply_with_op_inplace(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op)
multiplication with a 2-particle function
Definition: ccpairfunction.cc:267
CCPairFunction(const CCPairFunction &other)=default
copy ctor – shallow
friend double inner(const std::vector< CCPairFunction > &va, const std::vector< CCPairFunction > &vb, const Function< T, LDIM > R2=Function< T, LDIM >())
Definition: ccpairfunction.h:762
Function< T, NDIM > & get_function()
Definition: ccpairfunction.h:504
friend CCPairFunction operator*(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op, const CCPairFunction &f)
multiplication with a 2-particle function
Definition: ccpairfunction.h:531
CCPairFunction operator*(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op)
multiplication with a 2-particle function
Definition: ccpairfunction.h:561
World & world() const
Definition: ccpairfunction.h:499
double inner_internal(const CCPairFunction &other, const Function< T, LDIM > &R2) const
compute the inner product of this and other
Definition: ccpairfunction.cc:548
void reset_operator(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op)
Definition: ccpairfunction.h:618
CCPairFunction operator*(const double fac) const
scalar multiplication: f*fac
Definition: ccpairfunction.h:519
void print_size(const std::string name1="") const
print the size of the functions
Definition: ccpairfunction.h:648
bool is_pure() const
Definition: ccpairfunction.h:570
Function< T, LDIM > dirac_convolution_decomposed(const CCFunction< T, LDIM > &x, const CCConvolutionOperator< T, LDIM > &op, const size_t particle) const
Definition: ccpairfunction.cc:518
static std::vector< CCPairFunction > op_dec_to_dec(const std::vector< CCPairFunction > &other, const std::vector< Vector< double, LDIM >> &centers)
turn decomposed functions with operator into decomposed functions using LowRankFunction
Definition: ccpairfunction.cc:83
friend double inner(const CCPairFunction &a, const CCPairFunction &b)
Definition: ccpairfunction.h:757
CCPairFunction(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op_, const Function< T, NDIM > &ket)
takes a shallow copy of the argument function
Definition: ccpairfunction.h:391
bool is_decomposed_no_op() const
Definition: ccpairfunction.h:575
CCPairFunction partial_inner(const CCPairFunction &other, const std::array< int, LDIM > &v1, const std::array< int, LDIM > &v2) const
friend std::vector< CCPairFunction > consolidate(const std::vector< CCPairFunction > &other, const std::vector< std::string > options=std::vector< std::string >(), const std::vector< Vector< double, LDIM >> centers=std::vector< Vector< double, LDIM >>())
collect the terms into a compact format
Definition: ccpairfunction.h:488
static bool is_collected(const std::vector< CCPairFunction< T, NDIM >> &other)
Definition: ccpairfunction.cc:217
bool is_assigned() const
Definition: ccpairfunction.h:445
std::vector< Function< T, LDIM > > get_a() const
Definition: ccpairfunction.h:587
static std::vector< CCPairFunction< T, NDIM > > apply(const SeparatedConvolution< T, NDIM > &G, const std::vector< CCPairFunction< T, NDIM >> &argument)
static std::vector< CCPairFunction > collect_same_types(const std::vector< CCPairFunction > &other)
collect all terms with of similiar type: pure, op_pure, decomposed, op_decomposed
Definition: ccpairfunction.cc:166
Function< T, LDIM > project_out_op_decomposed(const CCFunction< T, LDIM > &f, const size_t particle) const
Definition: ccpairfunction.cc:501
Function< T, LDIM > partial_inner(const Function< T, LDIM > &f, const std::array< int, LDIM > &v1, const std::array< int, LDIM > &v2) const
CCPairFunction(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op_, const Function< T, LDIM > &f1, const Function< T, LDIM > &f2)
takes a deep copy of the argument functions
Definition: ccpairfunction.h:424
friend hashT hash_value(const CCPairFunction &f)
Definition: ccpairfunction.h:449
CCPairFunction(const Function< T, NDIM > &ket)
takes a shallow copy of the argument function
Definition: ccpairfunction.h:386
double make_xy_u(const CCFunction< T, LDIM > &xx, const CCFunction< T, LDIM > &yy) const
Definition: ccpairfunction.cc:279
std::string name(const bool transpose=false) const
Definition: ccpairfunction.h:671
static std::vector< CCPairFunction > remove_linearly_dependent_terms(const std::vector< CCPairFunction > &other, double thresh=-1.0)
remove linear dependent terms in the low-rank parts
Definition: ccpairfunction.cc:144
bool has_operator() const
Definition: ccpairfunction.h:569
std::shared_ptr< TwoBodyFunctionComponentBase > component
the 3 types of 6D-function that occur in the CC potential which coupled doubles to singles
Definition: ccpairfunction.h:787
const std::shared_ptr< CCConvolutionOperator< T, LDIM > > get_operator_ptr() const
Definition: ccpairfunction.h:610
CCPairFunction & operator*=(const double fac)
Definition: ccpairfunction.h:641
CCPairFunction(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op_, const std::vector< Function< T, LDIM >> &f1, const std::vector< Function< T, LDIM >> &f2)
takes a deep copy of the argument functions
Definition: ccpairfunction.h:417
bool is_pure_no_op() const
Definition: ccpairfunction.h:572
friend std::vector< CCPairFunction > swap_particles(const std::vector< CCPairFunction > &argument)
Definition: ccpairfunction.h:783
static std::vector< CCPairFunction > op_dec_to_pure(const std::vector< CCPairFunction > &other)
turn decomposed functions with operator into pure functions without operators
Definition: ccpairfunction.cc:127
bool is_decomposed() const
Definition: ccpairfunction.h:573
CCPairFunction to_pure() const
out-of-place conversion to pure function
Definition: ccpairfunction.h:631
bool is_op_pure() const
Definition: ccpairfunction.h:571
TwoBodyFunctionPureComponent< T, NDIM > & pure() const
Definition: ccpairfunction.h:577
CCPairFunction & operator()(const CCPairFunction &other)
shallow assignment operator
Definition: ccpairfunction.h:430
CCPairFunction(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op_, const CCFunction< T, LDIM > &f1, const CCFunction< T, LDIM > &f2)
takes a deep copy of the argument functions
Definition: ccpairfunction.h:412
friend double inner(const CCPairFunction &a, const CCPairFunction &b, const Function< T, LDIM > &R2)
Definition: ccpairfunction.h:753
Tensor< T >::scalar_type norm2() const
Definition: ccpairfunction.h:676
static std::vector< CCPairFunction< T, NDIM > > apply(const SeparatedConvolution< T, NDIM > &G, const CCPairFunction< T, NDIM > &argument)
Function< T, NDIM > & get_function() const
Definition: ccpairfunction.h:509
CCPairFunction invert_sign()
Definition: ccpairfunction.cc:17
const std::pair< std::vector< Function< T, LDIM > >, std::vector< Function< T, LDIM > > > assign_particles(const size_t particle) const
small helper function that gives back (a,b) or (b,a) depending on the value of particle
Definition: ccpairfunction.cc:533
bool is_op_decomposed() const
Definition: ccpairfunction.h:574
friend std::vector< CCPairFunction > multiply(const std::vector< CCPairFunction > &other, const Function< T, LDIM > f, const std::array< int, LDIM > &v1)
Definition: ccpairfunction.h:547
friend CCPairFunction copy(const CCPairFunction &other)
deep copy
Definition: ccpairfunction.h:439
CCPairFunction swap_particles() const
Definition: ccpairfunction.h:741
friend CCPairFunction operator*(const double fac, const CCPairFunction &f)
scalar multiplication: fac*f
Definition: ccpairfunction.h:526
Function< T, LDIM > dirac_convolution(const CCFunction< T, LDIM > &x, const CCConvolutionOperator< T, LDIM > &op, const size_t particle) const
result is: <x|op12|f>_particle
Definition: ccpairfunction.cc:321
Function< T, LDIM > project_out_decomposed(const Function< T, LDIM > &f, const size_t particle) const
Definition: ccpairfunction.cc:490
CCPairFunction()=default
empty ctor
A multiresolution adaptive numerical function.
Definition: mra.h:122
Definition: projector.h:17
Convolutions in separated form (including Gaussian)
Definition: operator.h:136
TensorTypeData< T >::scalar_type scalar_type
C++ typename of the real type associated with a complex type.
Definition: tensor.h:409
Definition: ccpairfunction.h:136
virtual void print_size(const std::string name="") const =0
virtual hashT hash() const =0
virtual std::shared_ptr< TwoBodyFunctionComponentBase > clone()=0
virtual bool has_operator() const =0
virtual bool is_pure() const
Definition: ccpairfunction.h:139
virtual ~TwoBodyFunctionComponentBase()
Definition: ccpairfunction.h:148
virtual World & world() const =0
virtual bool is_decomposed() const
Definition: ccpairfunction.h:140
virtual std::string name(const bool transpose=false) const =0
a two-body, explicitly 6-dimensional function
Definition: ccpairfunction.h:154
bool has_operator() const override
Definition: ccpairfunction.h:179
TwoBodyFunctionPureComponent(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op, const Function< T, NDIM > &f)
Definition: ccpairfunction.h:162
TwoBodyFunctionPureComponent & operator*=(const Q fac)
Definition: ccpairfunction.h:172
std::string name(const bool transpose) const override
Definition: ccpairfunction.h:187
Function< T, NDIM > & get_function()
Definition: ccpairfunction.h:212
const std::shared_ptr< CCConvolutionOperator< T, LDIM > > get_operator_ptr() const
Definition: ccpairfunction.h:208
std::shared_ptr< CCConvolutionOperator< T, LDIM > > op
Definition: ccpairfunction.h:225
World & world() const override
Definition: ccpairfunction.h:181
Function< T, NDIM > u
pure 6D function
Definition: ccpairfunction.h:224
TwoBodyFunctionPureComponent(const Function< T, NDIM > &f)
Definition: ccpairfunction.h:161
void print_size(const std::string name1="") const override
Definition: ccpairfunction.h:183
void swap_particles_inplace() override
return f(2,1)
Definition: ccpairfunction.h:204
hashT hash() const override
Definition: ccpairfunction.h:216
TwoBodyFunctionPureComponent apply(const SeparatedConvolution< Q, MDIM > *op, const int particle=0)
Definition: ccpairfunction.h:201
std::shared_ptr< TwoBodyFunctionComponentBase > clone() override
deep copy
Definition: ccpairfunction.h:166
void set_operator(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op1)
Definition: ccpairfunction.h:210
bool is_pure() const override
Definition: ccpairfunction.h:177
static constexpr std::size_t LDIM
Definition: ccpairfunction.h:155
Definition: ccpairfunction.h:232
World & world() const override
Definition: ccpairfunction.h:263
long rank() const
Definition: ccpairfunction.h:308
void serialize()
Definition: ccpairfunction.h:285
std::shared_ptr< CCConvolutionOperator< T, LDIM > > op
Definition: ccpairfunction.h:332
std::vector< Function< T, LDIM > > get_vector(const int i) const
Definition: ccpairfunction.h:315
std::vector< Function< T, LDIM > > b
Definition: ccpairfunction.h:331
static constexpr std::size_t LDIM
Definition: ccpairfunction.h:233
TwoBodyFunctionSeparatedComponent(const TwoBodyFunctionSeparatedComponent &other)=default
hashT hash() const override
Definition: ccpairfunction.h:287
void set_operator(const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op1)
Definition: ccpairfunction.h:326
const std::shared_ptr< CCConvolutionOperator< T, LDIM > > get_operator_ptr() const
Definition: ccpairfunction.h:324
TwoBodyFunctionSeparatedComponent(const std::vector< Function< T, LDIM >> &a, const std::vector< Function< T, LDIM >> &b)
Definition: ccpairfunction.h:239
void print_size(const std::string name1="") const override
Definition: ccpairfunction.h:268
bool has_operator() const override
Definition: ccpairfunction.h:261
std::string name(const bool transpose) const override
Definition: ccpairfunction.h:276
TwoBodyFunctionSeparatedComponent(const std::vector< Function< T, LDIM >> &a, const std::vector< Function< T, LDIM >> &b, const std::shared_ptr< CCConvolutionOperator< T, LDIM >> op)
Definition: ccpairfunction.h:242
std::vector< Function< T, LDIM > > get_a() const
Definition: ccpairfunction.h:313
TwoBodyFunctionPureComponent< T, NDIM > apply(const SeparatedConvolution< Q, MDIM > *op, const int particle=0)
Definition: ccpairfunction.h:299
void swap_particles_inplace() override
return f(2,1)
Definition: ccpairfunction.h:304
std::vector< Function< T, LDIM > > a
Definition: ccpairfunction.h:330
bool is_decomposed() const override
Definition: ccpairfunction.h:260
std::vector< Function< T, LDIM > > get_b() const
Definition: ccpairfunction.h:314
TwoBodyFunctionSeparatedComponent & operator*=(const Q fac)
Definition: ccpairfunction.h:255
std::shared_ptr< TwoBodyFunctionComponentBase > clone() override
deep copy
Definition: ccpairfunction.h:249
A simple, fixed dimension vector.
Definition: vector.h:64
A parallel world class.
Definition: world.h:132
ProcessID rank() const
Returns the process rank in this World (same as MPI_Comm_rank()).
Definition: world.h:318
World * get_world() const
Returns a pointer to the world.
Definition: parallel_archive.h:130
An archive for storing local or parallel data, wrapping a BinaryFstreamInputArchive.
Definition: parallel_archive.h:366
An archive for storing local or parallel data wrapping a BinaryFstreamOutputArchive.
Definition: parallel_archive.h:321
Objects that implement their own parallel archive interface should derive from this class.
Definition: parallel_archive.h:58
double(* f1)(const coord_3d &)
Definition: derivatives.cc:55
double(* f2)(const coord_3d &)
Definition: derivatives.cc:56
const std::size_t bufsize
Definition: derivatives.cc:16
char * p(char *buf, const char *name, int k, int initial_level, double thresh, int order)
Definition: derivatives.cc:72
auto T(World &world, response_space &f) -> response_space
Definition: global_functions.cc:34
Tensor< typename Tensor< T >::scalar_type > arg(const Tensor< T > &t)
Return a new tensor holding the argument of each element of t (complex types only)
Definition: tensor.h:2502
Tensor< double > op(const Tensor< double > &x)
Definition: kain.cc:508
#define max(a, b)
Definition: lda.h:51
Declares the macrotaskq and MacroTaskBase classes.
#define MADNESS_CHECK(condition)
Check a condition — even in a release build the condition is always evaluated so it can have side eff...
Definition: madness_exception.h:190
#define MADNESS_EXCEPTION(msg, value)
Macro for throwing a MADNESS exception.
Definition: madness_exception.h:119
#define MADNESS_ASSERT(condition)
Assert a condition that should be free of side-effects since in release builds this might be a no-op.
Definition: madness_exception.h:134
#define MADNESS_CHECK_THROW(condition, msg)
Check a condition — even in a release build the condition is always evaluated so it can have side eff...
Definition: madness_exception.h:210
Main include file for MADNESS and defines Function interface.
double norm(const T &t)
Definition: adquad.h:42
File holds all helper structures necessary for the CC_Operator and CC2 class.
Definition: DFParameters.h:10
std::vector< CCPairFunction< T, NDIM > > operator+(const std::vector< CCPairFunction< T, NDIM >> c1, const std::vector< CCPairFunction< T, NDIM > > &c2)
Definition: ccpairfunction.h:1047
static std::string stringify(T arg)
Definition: funcplot.h:1034
static double cpu_time()
Returns the cpu time in seconds relative to an arbitrary origin.
Definition: timers.h:127
std::enable_if_t< NDIM%2==0, Function< T, NDIM > > swap_particles(const Function< T, NDIM > &f)
swap particles 1 and 2
Definition: mra.h:2302
response_space scale(response_space a, double b)
std::vector< CCPairFunction< T, NDIM > > operator-(const std::vector< CCPairFunction< T, NDIM >> c1, const std::vector< CCPairFunction< T, NDIM > > &c2)
Definition: ccpairfunction.h:1055
response_space apply(World &world, std::vector< std::vector< std::shared_ptr< real_convolution_3d >>> &op, response_space &f)
Definition: basic_operators.cc:39
FuncType
Definition: ccpairfunction.h:26
@ RESPONSE
Definition: ccpairfunction.h:26
@ HOLE
Definition: ccpairfunction.h:26
@ UNDEFINED
Definition: ccpairfunction.h:26
@ PARTICLE
Definition: ccpairfunction.h:26
@ MIXED
Definition: ccpairfunction.h:26
Function< T, NDIM > copy(const Function< T, NDIM > &f, const std::shared_ptr< WorldDCPmapInterface< Key< NDIM > > > &pmap, bool fence=true)
Create a new copy of the function with different distribution and optional fence.
Definition: mra.h:2002
response_space transpose(response_space &f)
Definition: basic_operators.cc:10
void hash_combine(hashT &seed, const T &v)
Combine hash values.
Definition: worldhash.h:260
double norm2(World &world, const std::vector< Function< T, NDIM > > &v)
Computes the 2-norm of a vector of functions.
Definition: vmra.h:851
void plot_plane(World &world, const Function< double, NDIM > &function, const std::string name)
Definition: funcplot.h:621
OpType
operator types
Definition: operatorinfo.h:11
@ OT_UNDEFINED
Definition: operatorinfo.h:12
void print(const T &t, const Ts &... ts)
Print items to std::cout (items separated by spaces) and terminate with a new line.
Definition: print.h:225
bool is_collected(const std::vector< CCPairFunction< T, NDIM >> &other)
Definition: ccpairfunction.h:1092
void print_size(World &world, const std::vector< Function< T, NDIM > > &v, const std::string &msg="vectorfunction")
Definition: vmra.h:1622
std::vector< CCPairFunction< T, NDIM > > & operator+=(std::vector< CCPairFunction< T, NDIM > > &lhs, const CCPairFunction< T, NDIM > &rhs)
Definition: ccpairfunction.h:1063
NDIM & f
Definition: mra.h:2416
std::vector< CCPairFunction< T, NDIM > > & operator-=(std::vector< CCPairFunction< T, NDIM > > &rhs, const std::vector< CCPairFunction< T, NDIM > > &lhs)
Definition: ccpairfunction.h:1077
std::vector< CCPairFunction< T, NDIM > > operator*(const double fac, const std::vector< CCPairFunction< T, NDIM > > &arg)
Definition: ccpairfunction.h:1084
std::size_t hashT
The hash value type.
Definition: worldhash.h:145
double wall_time()
Returns the wall time in seconds relative to an arbitrary origin.
Definition: timers.cc:48
double inner(response_space &a, response_space &b)
Definition: response_functions.h:442
double imag(double x)
Definition: complexfun.h:56
std::string type(const PairType &n)
Definition: PNOParameters.h:18
double real(double x)
Definition: complexfun.h:52
std::string name(const FuncType &type, const int ex=-1)
Definition: ccpairfunction.h:28
madness::hashT hash_value(const std::array< T, N > &a)
Hash std::array with madness hash.
Definition: array_addons.h:78
void swap(Vector< T, N > &l, Vector< T, N > &r)
Swap the contents of two Vectors.
Definition: vector.h:497
Definition: mraimpl.h:50
static long abs(long a)
Definition: tensor.h:218
static const double b
Definition: nonlinschro.cc:119
static const double a
Definition: nonlinschro.cc:118
double Q(double a)
Definition: relops.cc:20
static const double c
Definition: relops.cc:10
static const double thresh
Definition: rk.cc:45
parameter class
Definition: CCStructures.h:747
static void load(const ParallelInputArchive< archiveT > &ar, CCPairFunction< T, NDIM > &p)
Definition: ccpairfunction.h:832
Default load of an object via serialize(ar, t).
Definition: archive.h:666
static void store(const ParallelOutputArchive< archiveT > &ar, const CCPairFunction< T, NDIM > &f)
Definition: ccpairfunction.h:867
Default store of an object via serialize(ar, t).
Definition: archive.h:611
Definition: lowrankfunction.h:332
void push_back(const vector_real_function_3d &f)
Definition: response_functions.h:300
Definition: timing_utilities.h:9
double end(const std::string msg)
Definition: timing_utilities.h:56
pcomplex_operatorT G
Definition: tdse1d.cc:167
InputParameters param
Definition: tdse.cc:203
int P
Definition: test_binsorter.cc:9
double aa
Definition: testbsh.cc:68
static const std::size_t NDIM
Definition: testpdiff.cc:42
const double R2
Definition: vnucso.cc:84