MADNESS 0.10.1
vector.h
Go to the documentation of this file.
1/*
2 This file is part of MADNESS.
3
4 Copyright (C) 2007,2010 Oak Ridge National Laboratory
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20 For more information please contact:
21
22 Robert J. Harrison
23 Oak Ridge National Laboratory
24 One Bethel Valley Road
25 P.O. Box 2008, MS-6367
26
27 email: harrisonrj@ornl.gov
28 tel: 865-241-3937
29 fax: 865-572-0680
30*/
31
32#ifndef MADNESS_WORLD_VECTOR_H__INCLUDED
33#define MADNESS_WORLD_VECTOR_H__INCLUDED
34
35/**
36 \file vector.h
37 \brief Implement the \c madness:Vector class, an extension of \c std::array
38 that supports some mathematical operations.
39 \ingroup containers
40*/
41
47#include <vector>
48#include <algorithm>
49#include <iostream>
50#include <math.h>
51
52namespace madness {
53
54 /// A simple, fixed dimension vector.
55
56 /// This class eliminates memory allocation cost, is just POD (it can be
57 /// copied easily and allocated on the stack), and the known
58 /// dimension permits aggressive compiler optimizations.
59 ///
60 /// Provides additional mathematical and I/O operations.
61 /// \tparam T The type of data stored in the vector.
62 /// \tparam N The size of the vector.
63 template <typename T, std::size_t N>
64 class Vector {
65 public:
66 using arrayT = std::array<T,N>; ///< The underlying array type.
67
68 template <typename Q,std::size_t M>
69 friend class Vector;
70
71 private:
72 arrayT data_; ///< The underlying array.
73
74 public:
75 // type defs... these are just wrappers to the underlying array types
76 using value_type = typename arrayT::value_type; ///< The data value type.
77 using iterator = typename arrayT::iterator; ///< Iterator type.
78 using const_iterator = typename arrayT::const_iterator; ///< Const iterator type.
79 using reverse_iterator = typename arrayT::reverse_iterator; ///< Reverse iterator type.
80 using const_reverse_iterator = typename arrayT::const_reverse_iterator; ///< Const reverse iterator type.
81 using reference = typename arrayT::reference; ///< Reference type.
82 using const_reference = typename arrayT::const_reference; ///< Const reference type.
83 using size_type = typename arrayT::size_type; ///< Size type.
84 using difference_type = typename arrayT::difference_type; ///< Difference type.
85
86 /// The size of the \c Vector.
87 static inline constexpr size_type static_size = N;
88
89 /// Default constructor; does not initialize vector contents.
90 constexpr Vector() = default;
91
92 /// Initialize all elements to value \c t.
93
94 /// \tparam Q The type of \c t.
95 /// \param[in] t The value used to initialized the \c Vector.
96 template <typename Q>
97 constexpr explicit Vector(Q t) : data_{} {
98 fill(t);
99 }
100
101 /// Construct from a C-style array of the same dimension.
102
103 /// \tparam Q The type of data in \c t.
104 /// \param[in] t The C-style array.
105 template <typename Q>
106 constexpr explicit Vector(const Q (&t)[N]) {
107#if __cplusplus >= 202002L
108 std::copy(t, t+N, data_.begin());
109#else
110 for(std::size_t i=0; i!=N; ++i) data_[i] = t[i];
111#endif
112 }
113
114 /// Construct from an STL vector of equal or greater length.
115
116 /// \tparam Q Type of data stored in the \c std::vector.
117 /// \tparam A Allocator type for the \c std::vector.
118 /// \param[in] t The \c std::vector.
119 template <typename Q, typename A>
120 constexpr explicit Vector(const std::vector<Q, A>& t) {
121 operator=(t);
122 }
123
124 /// Construct from a \c std::array of equal length.
125
126 /// \tparam Q Type of data stored in the original \c std::array.
127 /// \param[in] t The \c std::array.
128 template <typename Q>
129 constexpr explicit Vector(const std::array<Q, N>& t) {
130 data_ = t;
131 }
132
133 /// Copy constructor is deep (because \c Vector is POD).
134
135 /// \param[in] other The \c Vector to copy.
136 constexpr Vector(const Vector<T,N>& other) {
138MADNESS_PRAGMA_GCC(diagnostic ignored "-Wuninitialized")
139MADNESS_PRAGMA_GCC(diagnostic ignored "-Wmaybe-uninitialized")
140 data_ = other.data_;
142 }
143
144 /// Copy constructor is deep (because \c Vector is POD).
145
146 /// \tparam Q Type of the \c Vector to copy.
147 /// \param[in] other The \c Vector to copy.
148 template <typename Q>
149 constexpr Vector(const Vector<Q,N>& other) {
150 std::copy(other.data_.begin(), other.data_.end(), data_.begin());
151 }
152
153 /// List initialization constructor (deep copy because \c Vector is POD).
154
155 /// This constructor allows initialization using, e.g.,
156 /// \code
157 /// Vector<double, 3> v{ 1.5, 2.4, -1.9 };
158 /// \endcode
159 /// \throw MadnessException if the list does not contain exactly \c N
160 /// elements.
161 /// \param[in] list The initializer list; elements are copied to the
162 /// \c Vector.
163 constexpr Vector(std::initializer_list<T> list) :
164 data_()
165 {
166 MADNESS_ASSERT(list.size() == N);
167#if __cplusplus >= 202002L
168 std::copy(list.begin(), list.end(), data_.begin());
169#else
170 for(std::size_t i=0; i!=N; ++i) data_[i] = *(list.begin()+i);
171#endif
172 }
173
174 /// Assignment is deep (because a \c Vector is POD).
175
176 /// \param[in] other The \c Vector to copy.
177 /// \return This \c Vector.
178 constexpr Vector<T,N>& operator=(const Vector<T,N>& other) {
179 data_ = other.data_;
180 return *this;
181 }
182
183 /// Assignment is deep (because \c Vector is POD).
184
185 /// \tparam Q The type of the \c Vector to copy.
186 /// \param[in] other The \c Vector to copy.
187 /// \return This \c Vector.
188 template <typename Q>
189 constexpr Vector<T,N>& operator=(const Vector<Q,N>& other) {
190 std::copy(other.data_.begin(), other.data_.end(), data_.begin());
191 return *this;
192 }
193
194 /// Assignment is deep (because \c Vector is POD).
195
196 /// Make sure the size of \c other is at least \c N.
197 /// \tparam Q The type of data in the \c std::vector.
198 /// \tparam A The allocator type for the \c std::vector.
199 /// \param[in] other The \c std::vector to copy.
200 /// \return This \c Vector.
201 template <typename Q, typename A>
202 constexpr Vector<T,N>& operator=(const std::vector<Q, A>& other) {
203 MADNESS_ASSERT(other.size() >= N);
204#if __cplusplus >= 202002L
205 std::copy(other.begin(), other.begin() + N, data_.begin());
206#else
207 for(std::size_t i=0; i!=N; ++i) data_[i] = other[i];
208#endif
209 return *this;
210 }
211
212 /// List initialization assignment (deep copy because \c Vector is POD).
213
214 /// This assignment operator allows initialization using, e.g.,
215 /// \code
216 /// v = { 1.5, 2.4, -1.9 };
217 /// \endcode
218 /// \throw MadnessException if the list does not contain exactly \c N
219 /// elements.
220 /// \param[in] list The initializer list; elements are copied to the
221 /// \c Vector.
222 constexpr Vector<T,N>& operator=(std::initializer_list<T> list) {
223 MADNESS_ASSERT(list.size() == N);
224#if __cplusplus >= 202002L
225 std::copy(list.begin(), list.end(), data_.begin());
226#else
227 for(std::size_t i=0; i!=N; ++i) data_[i] = *(list.begin() + i);
228#endif
229 return *this;
230 }
231
232 /// Fill from a scalar value.
233
234 /// \param[in] t The scalar to use for filling.
235 /// \return This \c Vector.
236 constexpr Vector<T,N>& operator=(const T& t) {
237 fill(t);
238 return *this;
239 }
240
241 /// Type conversion to a \c std::array.
242
243 /// \return The underlying \c std::array.
244 constexpr operator std::array<T,N> () { return data_; }
245
246 // iterator support
247 /// Iterator starting at the first element.
248
249 /// \return Iterator to the starting element.
250 constexpr iterator begin() { return data_.begin(); }
251
252 /// Const iterator starting at the first element.
253
254 /// \return Const iterator to the starting element.
255 constexpr const_iterator begin() const { return data_.begin(); }
256
257 /// Iterator to the end (past the last element).
258
259 /// \return Iterator to the end.
260 constexpr iterator end() { return data_.end(); }
261
262 /// Const iterator to the end (past the last element).
263
264 /// \return Const iterator to the end.
265 constexpr const_iterator end() const { return data_.end(); }
266
267 // reverse iterator support
268 /// Reverse iterator starting at the last element.
269
270 /// \return Reverse iterator to the last element.
271 constexpr reverse_iterator rbegin() { return data_.rbegin(); }
272
273 /// Const reverse iterator starting at the last element.
274
275 /// \return Const reverse iterator to the last element.
276 constexpr const_reverse_iterator rbegin() const { return data_.rbegin(); }
277
278 /// Reverse iterator to the beginning (before the first element).
279
280 /// \return Reverse iterator to the beginning.
281 constexpr reverse_iterator rend() { return data_.rend(); }
282
283 /// Const reverse iterator to the beginning (before the first element).
284
285 /// \return Const reverse iterator to the beginning.
286 constexpr const_reverse_iterator rend() const { return data_.rend(); }
287
288 // capacity
289 /// Accessor for the number of elements in the \c Vector.
290
291 /// \return The number of elements.
292 constexpr size_type size() const { return data_.size(); }
293
294 /// Check if the \c Vector is empty.
295
296 /// \return True if the \c Vector is empty; false otherwise. This
297 /// should be false unless `N == 0`.
298 constexpr bool empty() const { return data_.empty(); }
299
300 /// Get the maximum size of the \c Vector.
301
302 /// \return The maximum size, \c N.
303 constexpr size_type max_size() const { return data_.max_size(); }
304
305 // element access
306 /// Access element \c i of the \c Vector.
307
308 /// Bounds checking is not performed.
309 /// \param[in] i The index.
310 /// \return A reference to element \c i.
311 constexpr reference operator[](size_type i) { return data_[i]; }
312
313 /// Access element \c i of the \c Vector.
314
315 /// Bounds checking is not performed.
316 /// \param[in] i The index.
317 /// \return A const reference to element \c i.
318 constexpr const_reference operator[](size_type i) const { return data_[i]; }
319
320 /// Access element \c i of the \c Vector with bounds checking.
321
322 /// \param[in] i The index.
323 /// \return A reference to element \c i.
324 constexpr reference at(size_type i) { return data_.at(i); }
325
326 /// Access element \c i of the \c Vector with bounds checking.
327
328 /// \param[in] i The index.
329 /// \return A const reference to element \c i.
330 constexpr const_reference at(size_type i) const { return data_.at(i); }
331
332 /// Access the first element.
333
334 /// \return A reference to the first element.
335 constexpr reference front() { return data_.front(); }
336
337 /// Access the first element.
338
339 /// \return A const reference to the first element.
340 constexpr const_reference front() const { return data_.front(); }
341
342 /// Access the last element.
343
344 /// \return A reference to the last element.
345 constexpr reference back() { return data_.back(); }
346
347 /// Access the last element.
348
349 /// \return A const reference to the last element.
350 constexpr const_reference back() const { return data_.back(); }
351
352 /// Direct access to the underlying array.
353
354 /// \return Pointer to the underlying array.
355 constexpr T* data() { return data_.data(); }
356
357 /// Direct access to the underlying array.
358
359 /// \return Const pointer to the underlying array.
360 constexpr const T* data() const { return data_.data(); }
361
362 // modifiers
363 /// Swap the contents with another \c Vector.
364
365 /// \param[in] other The other vector.
366 constexpr void swap(Vector<T, N>& other) { data_.swap(other.data_); }
367
368 /// Fill the \c Vector with the specified value.
369
370 /// \param[in] t The value used to fill the \c Vector.
371 constexpr void fill(const T& t) {
372#if __cplusplus >= 202002L
373 data_.fill(t);
374#else
375 for (std::size_t i = 0; i < N; i++)
376 data_[i] = t;
377#endif
378 }
379
380 /// In-place, element-wise multiplcation by a scalar.
381
382 /// \tparam Q Type of the scalar.
383 /// \param[in] q The scalar.
384 /// \return A reference to this for chaining operations.
385 /// \todo Do we want a similar division operation?
386 template <typename Q>
387 constexpr Vector<T,N>& operator*=(Q q) {
388 for(size_type i = 0; i < N; ++i)
389 data_[i] *= q;
390 return *this;
391 }
392
393 /// In-place, element-wise addition of another \c Vector.
394
395 /// \tparam Q Type stored in the other \c Vector.
396 /// \param[in] q The other \c Vector.
397 /// \return A reference to this for chaining operations.
398 template <typename Q>
399 constexpr Vector<T,N>& operator+=(const Vector<Q,N>& q) {
400 for(size_type i = 0; i < N; ++i)
401 data_[i] += q[i];
402 return *this;
403 }
404
405 /// In-place, element-wise subtraction of another \c Vector.
406
407 /// \tparam Q Type stored in the other \c Vector.
408 /// \param[in] q The other \c Vector.
409 /// \returns A reference to this for chaining operations.
410 template <typename Q>
411 constexpr Vector<T,N>& operator-=(const Vector<Q,N>& q) {
412 for(size_type i = 0; i < N; ++i)
413 data_[i] -= q[i];
414 return *this;
415 }
416
417 /// Calculate the 2-norm of the vector elements.
418
419 /// \return The 2-norm.
420 /// \todo Is there a reason this is "normf" and not "norm2"?
421 constexpr T normf() const {
422 T d = 0.;
423 for(std::size_t i=0; i<N; ++i)
424 d += (data_[i])*(data_[i]);
425 return sqrt(d);
426 }
427
428 /// Support for MADNESS serialization.
429
430 /// \tparam Archive The archive type.
431 /// \param[in,out] ar The archive.
432 template <typename Archive>
433 constexpr void serialize(Archive& ar) {
434 ar & data_;
435 }
436
437 /// Support for MADNESS hashing.
438
439 /// \return The hash.
440 constexpr hashT hash() const {
441 return hash_value(data_);
442 }
443
444 // comparisons
445 /// Check if each element is equal to its partner in the other \c Vector.
446
447 /// \param[in] l One \c Vector.
448 /// \param[in] r The other \c Vector.
449 /// \return True if each element is equal to its partner; false otherwise.
450 friend constexpr bool operator==(const Vector<T, N>& l, const Vector<T, N>& r) {
451 return l.data_ == r.data_;
452 }
453
454 /// Check if any element is not equal to its partner in the other \c Vector.
455
456 /// \param[in] l One \c Vector.
457 /// \param[in] r The other \c Vector.
458 /// \return True if any element is not equal to its partner; false otherwise.
459 friend constexpr bool operator!=(const Vector<T, N>& l, const Vector<T, N>& r) {
460 return l.data_ != r.data_;
461 }
462
463 /// Compare \c l and \c r lexicographically.
464
465 /// \param[in] l One \c Vector.
466 /// \param[in] r The other \c Vector.
467 /// \return True if the contents of \c l are lexicographically less than the contents of \c r; false otherwise.
468 friend constexpr bool operator<(const Vector<T, N>& l, const Vector<T, N>& r) {
469 return l.data_ < r.data_;
470 }
471
472 /// Compare \c l and \c r lexicographically.
473
474 /// \param[in] l One \c Vector.
475 /// \param[in] r The other \c Vector.
476 /// \return True if the contents of \c l are lexicographically greater than the contents of \c r; false otherwise.
477 friend constexpr bool operator>(const Vector<T, N>& l, const Vector<T, N>& r) {
478 return l.data_ > r.data_;
479 }
480
481 /// Compare \c l and \c r lexicographically.
482
483 /// \param[in] l One \c Vector.
484 /// \param[in] r The other \c Vector.
485 /// \return True if the contents of \c l are lexicographically less than or equal to the contents of \c r; false otherwise.
486 friend constexpr bool operator<=(const Vector<T, N>& l, const Vector<T, N>& r) {
487 return l.data_ <= r.data_;
488 }
489
490 /// Compare \c l and \c r lexicographically.
491
492 /// \param[in] l One \c Vector.
493 /// \param[in] r The other \c Vector.
494 /// \return True if the contents of \c l are lexicographically greater than or equal to the contents of \c r; false otherwise.
495 friend constexpr bool operator>=(const Vector<T, N>& l, const Vector<T, N>& r) {
496 return l.data_ >= r.data_;
497 }
498
499 /// Output a \c Vector to stream.
500
501 /// \param[in] s The output stream.
502 /// \param[in] v The \c Vector to output.
503 /// \return The output stream.
504 friend std::ostream& operator<<(std::ostream& s, const Vector<T,N>& v) {
505 using madness::operators::operator<<;
506 s << v.data_;
507 return s;
508 }
509 }; // class Vector
510
511 /// Swap the contents of two `Vector`s.
512
513 /// \tparam T The type of data stored in the `Vector`s.
514 /// \tparam N The size of the `Vector`s.
515 /// \param[in,out] l One \c Vector.
516 /// \param[in,out] r The other \c Vector.
517 template <typename T, std::size_t N>
518 constexpr void swap(Vector<T,N>& l, Vector<T,N>& r) {
519 l.swap(r);
520 }
521
522
523 // Arithmetic operators
524
525 /// Scale a \c Vector.
526
527 /// Multiply each \c Vector element by the scalar value \c r.
528 /// \tparam T The left-hand \c Vector element type.
529 /// \tparam N The \c Vector size.
530 /// \tparam U The right-hand scalar type.
531 /// \param[in] l The left-hand \c Vector.
532 /// \param[in] r The right-hand scalar value to be multiplied by
533 /// the \c Vector elements.
534 /// \return A new \c Vector, \c c, where `c[i]==(l[i]*r)`.
535 template <typename T, std::size_t N, typename U>
537 // coordinate passed by value to allow compiler optimization
538 for (std::size_t i = 0; i < N; ++i)
539 l[i] *= r;
540 return l;
541 }
542
543
544 /// Scale a \c Vector.
545
546 /// Multiply the scalar value \c l by each \c Vector element.
547 /// \tparam T The left-hand scalar type.
548 /// \tparam U The right-hand \c Vector element type.
549 /// \tparam N The \c Vector size.
550 /// \param[in] l The left-hand scalar value to be multiplied by
551 /// the \c Vector elements.
552 /// \param[in] r The right-hand \c Vector.
553 /// \return A new \c Vector, \c c, where `c[i]==(l*r[i])`.
554 template <typename T, typename U, std::size_t N>
556 // coordinate passed by value to allow compiler optimization
557 for (std::size_t i = 0; i < N; ++i)
558 r[i] *= l;
559 return r;
560 }
561
562 /// Multiply (element-wise) two `Vector`s.
563
564 /// Do an element-wise multiplication of \c l and \c r and return the
565 /// result in a new \c Vector.
566 /// \tparam T The left-hand \c Vector element type.
567 /// \tparam N The \c Vector size.
568 /// \tparam U The right-hand \c Vector element type.
569 /// \param[in] l The left-hand \c Vector.
570 /// \param[in] r The right-hand \c Vector.
571 /// \return A new \c Vector, \c c, where `c[i]==(l[i]*r[i])`.
572 template <typename T, std::size_t N, typename U>
574 // coordinate r passed by value to allow compiler optimization
575 for (std::size_t i = 0; i < N; ++i)
576 l[i] *= r[i];
577 return l;
578 }
579
580 /// Divide (element-wise) two `Vector`s.
581
582 /// Do an element-wise division of \c l by \c r and return the
583 /// result in a new \c Vector.
584 /// \tparam T The left-hand \c Vector element type.
585 /// \tparam N The \c Vector size.
586 /// \tparam U The right-hand \c Vector element type.
587 /// \param[in] l The left-hand \c Vector.
588 /// \param[in] r The right-hand \c Vector.
589 /// \return A new \c Vector, \c c, where `c[i]==(l[i]/r[i])`.
590 template <typename T, std::size_t N, typename U>
592 for (std::size_t i = 0; i < N; ++i)
593 l[i] /= r[i];
594 return l;
595 }
596
597 /// Add a scalar to a \c Vector.
598
599 /// Add the scalar value \c r to each \c Vector element.
600 /// \tparam T The left-hand \c Vector element type.
601 /// \tparam N The \c Vector size.
602 /// \tparam U The right-hand scalar type.
603 /// \param[in] l The left-hand \c Vector.
604 /// \param[in] r The right-hand scalar value to be added to the \c Vector.
605 /// \return A new \c Vector, \c c, where `c[i]==(l[i]+r)`.
606 template <typename T, std::size_t N, typename U>
608 // coordinate passed by value to allow compiler optimization
609 for (std::size_t i = 0; i < N; ++i)
610 l[i] += r;
611 return l;
612 }
613
614 /// Add (element-wise) two `Vector`s.
615
616 /// Do an element-wise addition of \c l and \c r and return the
617 /// result in a new \c Vector.
618 /// \tparam T The left-hand \c Vector element type.
619 /// \tparam N The \c Vector size.
620 /// \tparam U The right-hand \c Vector element type.
621 /// \param[in] l The left-hand \c Vector.
622 /// \param[in] r The right-hand \c Vector.
623 /// \return A new \c Vector, \c c, where `c[i]==(l[i]+r[i])`.
624 template <typename T, std::size_t N, typename U>
626 // l passed by value to allow compiler optimization
627 for (std::size_t i = 0; i < N; ++i)
628 l[i] += r[i];
629 return l;
630 }
631
632 /// Subtract a scalar from a \c Vector.
633
634 /// Subtract the scalar value \c r from the \c Vector elements `l[i]`.
635 /// \tparam T The left-hand \c Vector element type.
636 /// \tparam N The \c Vector size.
637 /// \tparam U The right-hand scalar type.
638 /// \param[in] l The left-hand \c Vector.
639 /// \param[in] r The right-hand scalar value to be added to the \c Vector.
640 /// \return A new \c Vector, \c c, where `c[i]==(l[i]-r)`.
641 template <typename T, std::size_t N, typename U>
643 // l passed by value to allow compiler optimization
644 for (std::size_t i = 0; i < N; ++i)
645 l[i] -= r;
646 return l;
647 }
648
649 /// Subtract (element-wise) two `Vector`s.
650
651 /// Do an element-wise subtraction of \c l and \c r and return the
652 /// result in a new \c Vector.
653 /// \tparam T The left-hand \c Vector element type.
654 /// \tparam N The \c Vector size.
655 /// \tparam U The right-hand \c Vector element type.
656 /// \param[in] l The left-hand \c Vector.
657 /// \param[in] r The right-hand \c Vector.
658 /// \return A new \c Vector, \c c, where `c[i]==(l[i]-r[i])`.
659 template <typename T, std::size_t N, typename U>
661 // l passed by value to allow compiler optimization
662 for (std::size_t i = 0; i < N; ++i)
663 l[i] -= r[i];
664 return l;
665 }
666
667
668 /// compute the inner product two `Vector`s.
669
670 /// Do an inner product of \c l and \c r and return the
671 /// result in a new \c Vector.
672 /// \tparam T The \c Vector element type.
673 /// \tparam N The \c Vector size.
674 /// \param[in] l The left-hand \c Vector.
675 /// \param[in] r The right-hand \c Vector.
676 /// \return the inner product, where `result==\sum_i(l[i]*r[i])`.
677 template <typename T, std::size_t N>
678 constexpr T inner(const Vector<T,N>& l, const Vector<T,N>& r) {
679 static_assert(std::is_arithmetic_v<T>); // for complex need to conjugate l
680 T result=0.0;
681 for (std::size_t i = 0; i < N; ++i)
682 result+=l[i]*r[i];
683 return result;
684 }
685
686 /// compute the cross product two `Vector`s of dimension 3
687
688 /// Do a cross product of \c l and \c r and return the result in a new \c Vector.
689 /// \tparam T The \c Vector element type.
690 /// \tparam N The \c Vector size.
691 /// \param[in] l The left-hand \c Vector.
692 /// \param[in] r The right-hand \c Vector.
693 /// \return the cross product
694 template <typename T, std::size_t N>
695 constexpr typename std::enable_if<N==3, Vector<T,N> >::type
696 cross(const Vector<T,N>& l, const Vector<T,N>& r) {
697 Vector<T,N> result;
698 result[0]=l[1]*r[2] - r[1]*l[2];
699 result[1]=l[2]*r[0] - r[2]*l[0];
700 result[2]=l[0]*r[1] - r[0]*l[1];
701 return result;
702 }
703
704
705 /// Factory function for creating a \c madness::Vector.
706
707 /// Variadic templates are used to create factories that mimic
708 /// \code
709 /// inline madness::Vector<T, N> vec(T t1, ..., T tN) {
710 /// std::Vector<T, N> ret;
711 /// ret[0] = t1;
712 /// ...
713 /// ret[N-1] = tN;
714 /// return ret;
715 /// }
716 /// \endcode
717 ///
718 /// This function counts the number of arguments passed in through the
719 /// argument pack, creates a \c std::array of the appropriate size,
720 /// forwards the arguments to the `std::array`'s constructor, and passes
721 /// the \c std::array to \c madness::Vector.
722 ///
723 /// \deprecated This function has been replaced by the list-initialization
724 /// constructor and assignment operator. Rather than
725 /// \code
726 /// Vector<double, 3> v = vec(1.4, 2.5, 4.0);
727 /// \endcode
728 /// use
729 /// \code
730 /// Vector<double, 3> v{ 1.4, 2.5, 4.0 };
731 /// \endcode
732 /// or
733 /// \code
734 /// Vector<double, 3> v = { 1.4, 2.5, 4.0 };
735 /// \endcode
736 ///
737 /// \note The first argument is separated from the pack to prevent 0-size
738 /// arrays and also so that the caller doesn't have to explicitly
739 /// specify \c T. It is assumed that all arguments are of type \c T or
740 /// are convertible to type \c T.
741 ///
742 /// \tparam T The data type for the array.
743 /// \tparam Ts The argument pack; that is, the list of arguments. The
744 /// size of the resulting \c Vector is directly determined from the
745 /// size of the argument pack.
746 /// \param[in] t The first argument.
747 /// \param[in] ts The rest of the arguments.
748 /// \return The \c Vector with the arguments put into it.
749 template<typename T, typename... Ts>
750 constexpr inline Vector<T, sizeof...(Ts) + 1> vec(T t, Ts... ts) {
751 return Vector<T, sizeof...(Ts) + 1> {
752 std::array<T, sizeof...(Ts) + 1>
753 {{ t, static_cast<T>(ts)... }}
754 };
755 }
756
757
758 /// Construct a unit-`Vector` that has the same direction as \c r.
759
760 /// \tparam T The type of data stored in the \c Vector.
761 /// \tparam N The size of the \c Vector.
762 /// \param[in] r The \c Vector.
763 /// \param[in] eps A precision. If the norm of \c r is less than \c eps,
764 /// the zero vector is returned.
765 /// \return The desired unit-`Vector` (unless \c r is numerically the zero
766 /// \c Vector).
767 template<typename T, std::size_t N>
768 constexpr Vector<T,N> unitvec(const Vector<T,N>& r, const double eps=1.e-6) {
769 const double norm=r.normf();
770 if(norm < eps)
771 return Vector<T,N>(0.0);
772 return r * (1.0/norm);
773 }
774
775} // namespace madness
776
777#endif // MADNESS_WORLD_VECTOR_H__INCLUDED
double q(double t)
Definition DKops.h:18
Interface templates for the archives (serialization).
Supplements to the std::array class, such as I/O operations, for convenience.
A simple, fixed dimension vector.
Definition vector.h:64
constexpr const_iterator end() const
Const iterator to the end (past the last element).
Definition vector.h:265
constexpr Vector(const Vector< T, N > &other)
Copy constructor is deep (because Vector is POD).
Definition vector.h:136
friend constexpr bool operator>(const Vector< T, N > &l, const Vector< T, N > &r)
Compare l and r lexicographically.
Definition vector.h:477
typename arrayT::reverse_iterator reverse_iterator
Reverse iterator type.
Definition vector.h:79
typename arrayT::iterator iterator
Iterator type.
Definition vector.h:77
typename arrayT::const_reference const_reference
Const reference type.
Definition vector.h:82
constexpr const_reference back() const
Access the last element.
Definition vector.h:350
friend constexpr bool operator!=(const Vector< T, N > &l, const Vector< T, N > &r)
Check if any element is not equal to its partner in the other Vector.
Definition vector.h:459
constexpr Vector()=default
Default constructor; does not initialize vector contents.
friend constexpr bool operator<(const Vector< T, N > &l, const Vector< T, N > &r)
Compare l and r lexicographically.
Definition vector.h:468
typename arrayT::value_type value_type
The data value type.
Definition vector.h:76
constexpr const_reverse_iterator rend() const
Const reverse iterator to the beginning (before the first element).
Definition vector.h:286
constexpr Vector(std::initializer_list< T > list)
List initialization constructor (deep copy because Vector is POD).
Definition vector.h:163
constexpr size_type max_size() const
Get the maximum size of the Vector.
Definition vector.h:303
constexpr iterator begin()
Iterator starting at the first element.
Definition vector.h:250
constexpr Vector< T, N > & operator=(const Vector< T, N > &other)
Assignment is deep (because a Vector is POD).
Definition vector.h:178
constexpr Vector(const std::vector< Q, A > &t)
Construct from an STL vector of equal or greater length.
Definition vector.h:120
friend constexpr bool operator>=(const Vector< T, N > &l, const Vector< T, N > &r)
Compare l and r lexicographically.
Definition vector.h:495
constexpr reverse_iterator rbegin()
Reverse iterator starting at the last element.
Definition vector.h:271
constexpr const_reference front() const
Access the first element.
Definition vector.h:340
constexpr Vector< T, N > & operator-=(const Vector< Q, N > &q)
In-place, element-wise subtraction of another Vector.
Definition vector.h:411
constexpr T normf() const
Calculate the 2-norm of the vector elements.
Definition vector.h:421
constexpr Vector(const Q(&t)[N])
Construct from a C-style array of the same dimension.
Definition vector.h:106
constexpr reference front()
Access the first element.
Definition vector.h:335
constexpr Vector< T, N > & operator=(std::initializer_list< T > list)
List initialization assignment (deep copy because Vector is POD).
Definition vector.h:222
constexpr const_reference operator[](size_type i) const
Access element i of the Vector.
Definition vector.h:318
constexpr size_type size() const
Accessor for the number of elements in the Vector.
Definition vector.h:292
constexpr iterator end()
Iterator to the end (past the last element).
Definition vector.h:260
typename arrayT::const_reverse_iterator const_reverse_iterator
Const reverse iterator type.
Definition vector.h:80
constexpr T * data()
Direct access to the underlying array.
Definition vector.h:355
constexpr Vector(const Vector< Q, N > &other)
Copy constructor is deep (because Vector is POD).
Definition vector.h:149
constexpr Vector(const std::array< Q, N > &t)
Construct from a std::array of equal length.
Definition vector.h:129
constexpr void swap(Vector< T, N > &other)
Swap the contents with another Vector.
Definition vector.h:366
constexpr reference operator[](size_type i)
Access element i of the Vector.
Definition vector.h:311
constexpr bool empty() const
Check if the Vector is empty.
Definition vector.h:298
static constexpr size_type static_size
The size of the Vector.
Definition vector.h:87
constexpr const_iterator begin() const
Const iterator starting at the first element.
Definition vector.h:255
typename arrayT::const_iterator const_iterator
Const iterator type.
Definition vector.h:78
constexpr reverse_iterator rend()
Reverse iterator to the beginning (before the first element).
Definition vector.h:281
constexpr Vector< T, N > & operator+=(const Vector< Q, N > &q)
In-place, element-wise addition of another Vector.
Definition vector.h:399
constexpr reference back()
Access the last element.
Definition vector.h:345
constexpr Vector(Q t)
Initialize all elements to value t.
Definition vector.h:97
constexpr Vector< T, N > & operator=(const T &t)
Fill from a scalar value.
Definition vector.h:236
typename arrayT::difference_type difference_type
Difference type.
Definition vector.h:84
friend constexpr bool operator<=(const Vector< T, N > &l, const Vector< T, N > &r)
Compare l and r lexicographically.
Definition vector.h:486
typename arrayT::reference reference
Reference type.
Definition vector.h:81
constexpr const T * data() const
Direct access to the underlying array.
Definition vector.h:360
constexpr reference at(size_type i)
Access element i of the Vector with bounds checking.
Definition vector.h:324
friend std::ostream & operator<<(std::ostream &s, const Vector< T, N > &v)
Output a Vector to stream.
Definition vector.h:504
constexpr const_reference at(size_type i) const
Access element i of the Vector with bounds checking.
Definition vector.h:330
constexpr void fill(const T &t)
Fill the Vector with the specified value.
Definition vector.h:371
constexpr Vector< T, N > & operator=(const Vector< Q, N > &other)
Assignment is deep (because Vector is POD).
Definition vector.h:189
arrayT data_
The underlying array.
Definition vector.h:72
constexpr hashT hash() const
Support for MADNESS hashing.
Definition vector.h:440
constexpr Vector< T, N > & operator=(const std::vector< Q, A > &other)
Assignment is deep (because Vector is POD).
Definition vector.h:202
constexpr const_reverse_iterator rbegin() const
Const reverse iterator starting at the last element.
Definition vector.h:276
std::array< T, N > arrayT
The underlying array type.
Definition vector.h:66
constexpr void serialize(Archive &ar)
Support for MADNESS serialization.
Definition vector.h:433
friend constexpr bool operator==(const Vector< T, N > &l, const Vector< T, N > &r)
Check if each element is equal to its partner in the other Vector.
Definition vector.h:450
constexpr Vector< T, N > & operator*=(Q q)
In-place, element-wise multiplcation by a scalar.
Definition vector.h:387
typename arrayT::size_type size_type
Size type.
Definition vector.h:83
auto T(World &world, response_space &f) -> response_space
Definition global_functions.cc:34
static const double v
Definition hatom_sf_dirac.cc:20
Macros and tools pertaining to the configuration of MADNESS.
#define MADNESS_PRAGMA_GCC(x)
Definition madness_config.h:205
Defines madness::MadnessException for exception handling.
#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
Namespace for all elements and tools of MADNESS.
Definition DFParameters.h:10
constexpr void swap(Vector< T, N > &l, Vector< T, N > &r)
Swap the contents of two Vectors.
Definition vector.h:518
std::vector< Function< TENSOR_RESULT_TYPE(T, R), NDIM > > cross(const std::vector< Function< T, NDIM > > &f, const std::vector< Function< R, NDIM > > &g, bool do_refine=false, bool fence=true)
shorthand cross operator
Definition vmra.h:2098
std::vector< CCPairFunction< T, NDIM > > operator*(const double fac, const std::vector< CCPairFunction< T, NDIM > > &arg)
Definition ccpairfunction.h:1089
constexpr Vector< T, N > unitvec(const Vector< T, N > &r, const double eps=1.e-6)
Construct a unit-Vector that has the same direction as r.
Definition vector.h:768
std::vector< CCPairFunction< T, NDIM > > operator-(const std::vector< CCPairFunction< T, NDIM > > c1, const std::vector< CCPairFunction< T, NDIM > > &c2)
Definition ccpairfunction.h:1060
constexpr Vector< T, N > operator/(Vector< T, N > l, const Vector< U, N > &r)
Divide (element-wise) two Vectors.
Definition vector.h:591
static double pop(std::vector< double > &v)
Definition SCF.cc:113
std::size_t hashT
The hash value type.
Definition worldhash.h:145
double inner(response_space &a, response_space &b)
Definition response_functions.h:442
std::string type(const PairType &n)
Definition PNOParameters.h:18
std::vector< CCPairFunction< T, NDIM > > operator+(const std::vector< CCPairFunction< T, NDIM > > c1, const std::vector< CCPairFunction< T, NDIM > > &c2)
Definition ccpairfunction.h:1052
constexpr Vector< T, sizeof...(Ts)+1 > vec(T t, Ts... ts)
Factory function for creating a madness::Vector.
Definition vector.h:750
static XNonlinearSolver< std::vector< Function< T, NDIM > >, T, vector_function_allocator< T, NDIM > > nonlinear_vector_solver(World &world, const long nvec)
Definition nonlinsol.h:284
madness::hashT hash_value(const std::array< T, N > &a)
Hash std::array with madness hash.
Definition array_addons.h:78
static const double d
Definition nonlinschro.cc:121
double Q(double a)
Definition relops.cc:20
double norm(const T i1)
Definition test_cloud.cc:72
#define N
Definition testconv.cc:37
Defines hash functions for use in distributed containers.