MADNESS 0.10.1
x_space.h
Go to the documentation of this file.
1// Copyright 2021 Adrian Hurtado
2#ifndef SRC_APPS_MOLRESPONSE_X_SPACE_H_
3#define SRC_APPS_MOLRESPONSE_X_SPACE_H_
4
5#include <madness/mra/mra.h>
7
8#include <algorithm>
9#include <cstdint>
10#include <memory>
11#include <numeric>
12#include <vector>
13
15
16
17namespace madness {
18
19 typedef std::vector<vector_real_function_3d> response_matrix;
20
21 struct X_space;
22
25 auto create_response_matrix(const size_t &num_state,
26 const size_t &num_orbitals) -> response_matrix;
27 auto to_response_matrix(const X_space &x) -> response_matrix;
28 auto to_conjugate_response_matrix(const X_space &x) -> response_matrix;
29 auto to_flattened_vector(const X_space &x) -> vector_real_function_3d;
30 auto to_X_space(const response_matrix &x) -> X_space;
31 auto to_conjugate_X_space(const response_matrix &x) -> X_space;
32 struct X_space {
33 private:
34 size_t n_states; // Num. of resp. states
35 size_t n_orbitals;// Num. of ground states
36
37 public:
39 std::list<size_t> active;
40
41 public:
42 [[nodiscard]] size_t num_states() const { return n_states; }
43 [[nodiscard]] size_t num_orbitals() const { return n_orbitals; }
44 // default constructor
45 X_space() : n_states(0), n_orbitals(0), x(), y(), active(0) {}
46 // Copy constructor
47 void reset_active() {
48 active.resize(n_states);
49 size_t i{0};
50 for (auto &ai: active) { ai = i++; }
51 }
52 void set_active(const std::list<size_t> &new_active) {
53 active = new_active;
54 x.active = new_active;
55 y.active = new_active;
56 }
60 [[nodiscard]] X_space copy() const {
61 auto &world = x[0][0].world();
62 auto new_x = X_space(*this);// copy
63 for (const auto &i: active) {
64 new_x.x[i] = madness::copy(world, x[i], false);
65 new_x.y[i] = madness::copy(world, y[i], false);
66 }
67 world.gop.fence();
68
69 return new_x;
70 }
71 /// Create a new copy of the function with different distribution and optional
72 /// fence
73
74 /// Works in either basis. Different distributions imply
75 /// asynchronous communication and the optional fence is
76 /// collective.
77 [[nodiscard]] auto
78 copy(const std::shared_ptr<WorldDCPmapInterface<Key<3>>> &p_map,
79 bool fence = false) const -> X_space {
80 auto &world = x[0][0].world();
81 auto new_x = X_space(*this);// copy
82 for (int i = 0; i < new_x.num_states(); i++) {
83 new_x.x[i] = madness::copy(world, x[i], p_map, false);
84 new_x.y[i] = madness::copy(world, y[i], p_map, false);
85 }
86 world.gop.fence();
87 return new_x;
88 }
89 // assignment
90 auto operator=(const X_space &B) -> X_space & {
91 if (this != &B) {// is it the same object?
92
93 this->n_states = B.num_states();
94 this->n_orbitals = B.num_orbitals();
95 this->x = B.x;
96 this->y = B.y;
97 this->active = B.active;
98 }
99 return *this;// NO SHALLOW COPIES
100 }
101 // Zero Constructor
102 X_space(World &world, size_t n_states, size_t n_orbitals)
104 x(world, n_states, n_orbitals), y(world, n_states, n_orbitals),
106 reset_active();
107 }
108 void clear() {
109 x.clear();
110 y.clear();
111 active.clear();
112 }
114 const vector_real_function_3d &vy) {
115 if (n_orbitals > 0) {
118 MADNESS_ASSERT(x.size() == y.size());
119 } else {// g_states == 0 (empty vector)
120 n_orbitals = x.size();
121 }
124 active.push_back(active.back() + 1);
125 n_states++;
126 x.push_back(vx);
127 y.push_back(vy);
128 // Be smart with g_states
129 }
130 void pop_back() {
131 x.pop_back();
132 y.pop_back();
133 active.pop_back();
134 n_states--;
135 if (n_states == 0) { n_orbitals = 0; }
136 }
137
138
139 friend auto inplace_apply(
140 X_space &A,
141 const std::function<void(vector_real_function_3d &)> &func)
142 -> void {
143 auto &world = A.x[0][0].world();
144 for (auto &i: A.active) {
145 func(A.x[i]);
146 func(A.y[i]);
147 }
148 world.gop.fence();
149 }
150
151 /**
152 * @brief Apply a function to the X_space
153 * @param A
154 * @param func
155 * @return
156 */
157 friend auto oop_apply(const X_space &A,
158 const std::function<vector_real_function_3d(
159 const vector_real_function_3d &)> &func)
160 -> X_space {
161 auto &world = A.x[0][0].world();
162 auto result = X_space::zero_functions(world, A.num_states(),
163 A.num_orbitals());
164 // if (world.rank() == 0) { print("oop_apply"); }
165 for (auto &i: result.active) {
166 // if (world.rank() == 0) { print("oop_apply", i); }
167 result.x[i] = func(A.x[i]);
168 result.y[i] = func(A.y[i]);
169 }
170 world.gop.fence();
171 return result;
172 }
173
174 template<typename T>
175 friend auto binary_apply(const X_space &A, const X_space &B, T &func)
176 -> X_space {
178
179 auto &world = A.x[0][0].world();
180 X_space result = X_space::zero_functions(world, A.num_states(),
181 A.num_orbitals());
182
183 for (const auto &i: result.active) {
184 auto ax = A.x[i];
185 auto bx = B.x[i];
186
187 auto ay = A.y[i];
188 auto by = B.y[i];
189
190 result.x[i] = func(ax, bx);
191 result.y[i] = func(ay, by);
192 }
193 world.gop.fence();
194 return result;
195 }
196
197 template<class T>
198 friend auto binary_inplace(X_space &A, const X_space &B,
199 const T &func) {
201 auto &world = A.x[0][0].world();
202 for (const auto &i: A.active) {
203 auto ax = A.x[i];
204 auto ay = A.y[i];
205
206 auto bx = B.x[i];
207 auto by = B.y[i];
208
209 func(ax, bx);
210 func(ay, by);
211 }
212 world.gop.fence();
213
214 return A;
215 }
216
217 static X_space zero_functions(World &world, size_t n_states,
218 size_t n_orbitals) {
219 auto zeros = X_space(world, n_states, n_orbitals);
220 for (int i = 0; i < zeros.num_states(); i++) {
221 zeros.x[i] = ::madness::zero_functions<double, 3>(
222 world, n_orbitals, false);
223 zeros.y[i] = ::madness::zero_functions<double, 3>(
224 world, n_orbitals, false);
225 }
226 world.gop.fence();
227 return zeros;
228 }
229
230 auto operator+=(const X_space &B) -> X_space & {
231 MADNESS_ASSERT(same_size(*this, B));
232 auto &world = this->x[0][0].world();
233 auto add_inplace = [&](auto &a, const auto &b) {
234 gaxpy(world, 1.0, a, 1.0, b, false);
235 };
236 binary_inplace(*this, B, add_inplace);
237 return *this;
238 }
239
240
241 friend auto operator+(const X_space &A, const X_space &B) -> X_space {
243 auto add_ab = [&](const auto &a, const auto &b) {
244 return gaxpy_oop(1.0, a, 1.0, b, false);
245 };
246 return binary_apply(A, B, add_ab);
247 }
248
249
250 friend X_space operator-(const X_space &A, const X_space &B) {
252 auto sub_ab = [&](const auto &a, const auto &b) {
253 return gaxpy_oop(1.0, a, -1.0, b, false);
254 };
255 return binary_apply(A, B, sub_ab);
256 }
257
258 friend X_space operator*(const X_space &A, const double &b) {
259 World &world = A.x[0][0].world();
260 auto result = A.copy();
261 auto scale_a = [&](vector_real_function_3d &vec_ai) {
262 scale(world, vec_ai, b, false);
263 };
264 inplace_apply(result, scale_a);
265 return result;
266 }
267 friend X_space operator*(const double &b, const X_space &A) {
268 World &world = A.x[0][0].world();
269 auto result = A.copy();
270 auto scale_a = [&](vector_real_function_3d &vec_ai) {
271 scale(world, vec_ai, b, false);
272 };
273 inplace_apply(result, scale_a);
274 return result;
275 }
276
277 friend X_space operator*(const X_space &A,
278 const Function<double, 3> &f) {
279 World &world = A.x[0][0].world();
280 auto mul_f = [&](const vector_real_function_3d &vec_ai) {
281 return mul(world, f, vec_ai, false);
282 };
283 return oop_apply(A, mul_f);
284 }
285 friend auto operator*(const Function<double, 3> &f, const X_space &A)
286 -> X_space {
287 World &world = A.x[0][0].world();
288 auto mul_f = [&](const vector_real_function_3d &vec_ai) {
289 return mul(world, f, vec_ai, false);
290 };
291 return oop_apply(A, mul_f);
292 }
293
294 friend auto operator*(const X_space &A, const Tensor<double> &b)
295 -> X_space {
298
299 World &world = A.x[0][0].world();
300 auto transform_ai = [&](auto &ai) {
301 return transform(world, ai, b, false);
302 };
303 return oop_apply(A, transform_ai);
304 }
305 /***
306 *
307 * @param A
308 * @param B
309 * @return
310 */
311 friend auto inner(const X_space &A, const X_space &B) -> Tensor<double>;
312
313 void truncate() {
314 auto rx = to_response_matrix(*this);
315 auto &world = rx[0][0].world();
316 auto truncate_i = [&](auto &fi) {
318 false);
319 };
320 inplace_apply(*this, truncate_i);
321 }
322
323 void truncate(double thresh) {
324 auto rx = to_response_matrix(*this);
325 auto &world = rx[0][0].world();
326 auto truncate_i = [&](auto &fi) {
327 madness::truncate(world, fi, thresh, false);
328 };
329 inplace_apply(*this, truncate_i);
330 }
331
332 auto norm2s() const -> Tensor<double> {
333 World &world = x[0][0].world();
334 Tensor<double> norms(num_states());
335
336 auto x = to_response_matrix(*this);
337 int b = 0;
338 for (const auto &xb: x) { norms[b++] = norm2(world, xb); }
339 world.gop.fence();
340 return norms;
341 }
342
343 [[nodiscard]] auto component_norm2s() const -> Tensor<double> {
344 World &world = x[0][0].world();
345 auto rx = to_flattened_vector(*this);
346 auto norms = norm2s_T(world, rx);
347 return norms.reshape(n_states, 2 * n_orbitals);
348 }
349
350 friend auto size_states(const X_space &x) -> size_t {
351 return x.n_states;
352 }
353 friend auto size_orbitals(const X_space &x) -> size_t {
354 return x.n_orbitals;
355 }
356 friend auto same_size(const X_space &A, const X_space &B) -> bool {
357 return ((size_states(A) == size_states(B) &&
359 }
360 };
361
362 // but the solver needs the functions initialized to zero for which we also need
363 // the world object.
364
365 struct X_vector : public X_space {
366 X_vector(World &world, size_t n_orbtials) {
367 this->X_space::zero_functions(world, size_t(1), n_orbtials);
368 }
369
371 : X_space(A.x[0][0].world(), size_t(1), A.num_orbitals()) {
372 x[0] = A.x[b];
373 y[0] = A.y[b];
374 }
375 friend X_vector operator-(const X_vector &A, const X_vector &B) {
377
378 World &world = A.x[0][0].world();
379 X_vector result(world, size_orbitals(A));// create zero_functions
380 result.x = A.x - B.x;
381 result.y = A.y - B.y;
382 return result;
383 }
384 friend X_vector operator*(const X_vector &A, const double &c) {
385 World &world = A.x[0][0].world();
386 X_vector result(world, size_orbitals(A));// create zero_functions
387 result.x = A.x * c;
388 result.y = A.y * c;
389 return result;
390 }
391 X_vector copy() const {
392 X_vector copyX(x[0][0].world(), x.num_orbitals);
393 copyX.x = x.copy();
394 copyX.y = y.copy();
395 return copyX;
396 }
397 auto operator+=(const X_vector &B) -> X_vector & {
398 MADNESS_ASSERT(same_size(*this, B));
399 this->x += B.x;
400 this->y += B.y;
401 return *this;
402 }
403 inline friend auto inner(X_vector &A, X_vector &B) -> double {
407
408 Tensor<double> G(1, 1);
409 Tensor<double> G1(1, 1);
410 Tensor<double> G2(1, 1);
411
412 World &world = A.x[0][0].world();
413
414 auto ax = madness::copy(world, A.x[0]);
415 auto ay = madness::copy(world, A.y[0]);
416
417 auto bx = madness::copy(world, B.x[0]);
418 auto by = madness::copy(world, B.y[0]);
419
420 for (auto &ayi: ay) { ax.push_back(madness::copy(ayi)); }
421 for (auto &byi: by) { bx.push_back(madness::copy(byi)); };
422
423 double result = inner(ax, bx);
424
425 return result;
426 }
427 };
428 // function object with allocator()()
431 const size_t n_orbtials;
434 // overloading the default constructor () operator
436 //print("allocator called with ", int(n_orbtials), " orbitals");
437 // returning constructor of x_vector
438 return zero_functions<double, 3>(world, n_orbtials);
439 }
440 // Copy constructor
441
446 };
447
451 // overloading the default constructor () operator
459 };
460}// namespace madness
461
462#endif// SRC_APPS_MOLRESPONSE_X_SPACE_H_
Definition test_ar.cc:118
Definition test_ar.cc:141
Definition test_derivative.cc:24
FunctionDefaults holds default paramaters as static class members.
Definition funcdefaults.h:204
A multiresolution adaptive numerical function.
Definition mra.h:122
Key is the index for a node of the 2^NDIM-tree.
Definition key.h:66
A tensor is a multidimension array.
Definition tensor.h:317
Interface to be provided by any process map.
Definition worlddc.h:82
void fence(bool debug=false)
Synchronizes all processes in communicator AND globally ensures no pending AM or tasks.
Definition worldgop.cc:161
A parallel world class.
Definition world.h:132
WorldGopInterface & gop
Global operations.
Definition world.h:205
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:34
#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
Main include file for MADNESS and defines Function interface.
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
Function< TENSOR_RESULT_TYPE(L, R), NDIM > gaxpy_oop(TENSOR_RESULT_TYPE(L, R) alpha, const Function< L, NDIM > &left, TENSOR_RESULT_TYPE(L, R) beta, const Function< R, NDIM > &right, bool fence=true)
Returns new function alpha*left + beta*right optional fence and no automatic compression.
Definition mra.h:1917
response_space scale(response_space a, double b)
Tensor< double > norm2s_T(World &world, const std::vector< Function< T, NDIM > > &v)
Computes the 2-norms of a vector of functions.
Definition vmra.h:839
auto to_X_space(const response_matrix &x) -> X_space
Definition x_space.cc:99
Function< TENSOR_RESULT_TYPE(Q, T), NDIM > mul(const Q alpha, const Function< T, NDIM > &f, bool fence=true)
Returns new function equal to alpha*f(x) with optional fence.
Definition mra.h:1701
std::vector< vector_real_function_3d > response_matrix
Definition response_functions.h:19
void truncate(World &world, response_space &v, double tol, bool fence)
Definition basic_operators.cc:30
std::vector< Function< TENSOR_RESULT_TYPE(T, R), NDIM > > transform(World &world, const std::vector< Function< T, NDIM > > &v, const Tensor< R > &c, bool fence=true)
Transforms a vector of functions according to new[i] = sum[j] old[j]*c[j,i].
Definition vmra.h:689
auto to_conjugate_X_space(const response_matrix &x) -> X_space
response_matrix [x,y] -> Xspace X.x=y X.y=conjugate(x)
Definition x_space.cc:122
double norm2(World &world, const std::vector< Function< T, NDIM > > &v)
Computes the 2-norm of a vector of functions.
Definition vmra.h:851
std::vector< real_function_3d > vector_real_function_3d
Definition functypedefs.h:79
std::shared_ptr< FunctionFunctorInterface< double, 3 > > func(new opT(g))
auto create_response_matrix(const size_t &num_states, const size_t &num_orbitals) -> response_matrix
Create a response matrix object.
Definition x_space.cc:35
FunctionFactory< double, 3 > real_factory_3d
Definition functypedefs.h:93
NDIM & f
Definition mra.h:2416
auto to_response_vector(const vector_real_function_3d &vec) -> vector_real_function_3d
Definition x_space.cc:14
Function< double, 3 > real_function_3d
Definition functypedefs.h:65
auto to_response_matrix(const X_space &x) -> response_matrix
Definition x_space.cc:51
auto to_conjugate_response_matrix(const X_space &x) -> response_matrix
Definition x_space.cc:65
auto to_flattened_vector(const X_space &x) -> vector_real_function_3d
Flattens all response functions into a single vector of functions.
Definition x_space.cc:85
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
Vector< T, sizeof...(Ts)+1 > vec(T t, Ts... ts)
Factory function for creating a madness::Vector.
Definition vector.h:711
void gaxpy(const double a, ScalarResult< T > &left, const double b, const T &right, const bool fence=true)
the result type of a macrotask must implement gaxpy
Definition macrotaskq.h:140
static const double b
Definition nonlinschro.cc:119
static const double a
Definition nonlinschro.cc:118
static const double c
Definition relops.cc:10
static const double thresh
Definition rk.cc:45
Definition test_ar.cc:261
Definition x_space.h:32
auto norm2s() const -> Tensor< double >
Definition x_space.h:332
friend auto oop_apply(const X_space &A, const std::function< vector_real_function_3d(const vector_real_function_3d &)> &func) -> X_space
Apply a function to the X_space.
Definition x_space.h:157
friend auto operator+(const X_space &A, const X_space &B) -> X_space
Definition x_space.h:241
auto operator=(const X_space &B) -> X_space &
Definition x_space.h:90
X_space(const X_space &A)
Definition x_space.h:57
void reset_active()
Definition x_space.h:47
void clear()
Definition x_space.h:108
size_t num_states() const
Definition x_space.h:42
std::list< size_t > active
Definition x_space.h:39
friend auto inner(const X_space &A, const X_space &B) -> Tensor< double >
Computes the matrix elements between two response spaces.
Definition x_space.cc:168
static X_space zero_functions(World &world, size_t n_states, size_t n_orbitals)
Definition x_space.h:217
friend X_space operator*(const X_space &A, const double &b)
Definition x_space.h:258
friend auto operator*(const X_space &A, const Tensor< double > &b) -> X_space
Definition x_space.h:294
X_space copy() const
Definition x_space.h:60
friend auto operator*(const Function< double, 3 > &f, const X_space &A) -> X_space
Definition x_space.h:285
auto operator+=(const X_space &B) -> X_space &
Definition x_space.h:230
auto component_norm2s() const -> Tensor< double >
Definition x_space.h:343
size_t num_orbitals() const
Definition x_space.h:43
friend auto size_orbitals(const X_space &x) -> size_t
Definition x_space.h:353
friend auto inplace_apply(X_space &A, const std::function< void(vector_real_function_3d &)> &func) -> void
Definition x_space.h:139
size_t n_states
Definition x_space.h:34
friend auto binary_inplace(X_space &A, const X_space &B, const T &func)
Definition x_space.h:198
friend X_space operator-(const X_space &A, const X_space &B)
Definition x_space.h:250
X_space(World &world, size_t n_states, size_t n_orbitals)
Definition x_space.h:102
void push_back(const vector_real_function_3d &vx, const vector_real_function_3d &vy)
Definition x_space.h:113
response_space y
Definition x_space.h:38
response_space x
Definition x_space.h:38
friend auto same_size(const X_space &A, const X_space &B) -> bool
Definition x_space.h:356
void truncate()
Definition x_space.h:313
friend X_space operator*(const double &b, const X_space &A)
Definition x_space.h:267
X_space()
Definition x_space.h:45
void set_active(const std::list< size_t > &new_active)
Definition x_space.h:52
size_t n_orbitals
Definition x_space.h:35
friend auto binary_apply(const X_space &A, const X_space &B, T &func) -> X_space
Definition x_space.h:175
auto copy(const std::shared_ptr< WorldDCPmapInterface< Key< 3 > > > &p_map, bool fence=false) const -> X_space
Definition x_space.h:78
void truncate(double thresh)
Definition x_space.h:323
friend X_space operator*(const X_space &A, const Function< double, 3 > &f)
Definition x_space.h:277
void pop_back()
Definition x_space.h:130
friend auto size_states(const X_space &x) -> size_t
Definition x_space.h:350
Definition x_space.h:365
X_vector(World &world, size_t n_orbtials)
Definition x_space.h:366
auto operator+=(const X_vector &B) -> X_vector &
Definition x_space.h:397
X_vector(X_space A, size_t b)
Definition x_space.h:370
friend X_vector operator-(const X_vector &A, const X_vector &B)
Definition x_space.h:375
X_vector copy() const
Definition x_space.h:391
friend X_vector operator*(const X_vector &A, const double &c)
Definition x_space.h:384
friend auto inner(X_vector &A, X_vector &B) -> double
Definition x_space.h:403
Definition x_space.h:448
real_function_3d operator()()
Definition x_space.h:452
World & world
Definition x_space.h:449
response_function_allocator(World &world)
Definition x_space.h:450
response_function_allocator operator=(const response_function_allocator &other)
Definition x_space.h:456
Definition x_space.h:429
World & world
Definition x_space.h:430
vector_real_function_3d operator()()
Definition x_space.h:435
response_matrix_allocator(World &world, size_t n_orbtials)
Definition x_space.h:432
const size_t n_orbtials
Definition x_space.h:431
response_matrix_allocator operator=(const response_matrix_allocator &other)
Definition x_space.h:443
Definition response_functions.h:25
void push_back(const vector_real_function_3d &f)
Definition response_functions.h:300
size_t num_orbitals
Definition response_functions.h:34
void pop_back()
Definition response_functions.h:312
size_t size() const
Definition response_functions.h:337
response_space copy() const
Definition response_functions.h:122
std::list< size_t > active
Definition response_functions.h:36
void clear()
Definition response_functions.h:323
Defines and implements most of Tensor.
int G2
Definition testperiodic.cc:64