GQCP
Loading...
Searching...
No Matches
EvaluableLinearCombination.hpp
Go to the documentation of this file.
1// This file is part of GQCG-GQCP.
2//
3// Copyright (C) 2017-2020 the GQCG developers
4//
5// GQCG-GQCP is free software: you can redistribute it and/or modify
6// it under the terms of the GNU Lesser General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// GQCG-GQCP is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU Lesser General Public License for more details.
14//
15// You should have received a copy of the GNU Lesser General Public License
16// along with GQCG-GQCP. If not, see <http://www.gnu.org/licenses/>.
17
18#pragma once
19
20
23#include "Utilities/aliases.hpp"
24#include "Utilities/complex.hpp"
25
26#include <boost/format.hpp>
27#include <boost/lexical_cast.hpp>
28
29#include <vector>
30
31
32namespace GQCP {
33
34
43template <typename _Coefficient, typename _FunctionType>
45 public Function<sum_t<_Coefficient, typename _FunctionType::OutputType>, typename _FunctionType::InputType>,
46 public VectorSpaceArithmetic<EvaluableLinearCombination<_Coefficient, _FunctionType>, _Coefficient> {
47
48public:
49 // The type of a coefficient.
50 using Coefficient = _Coefficient;
51
52 // The type of the function.
53 using FunctionType = _FunctionType;
54
55 // The return type of the `operator()`.
57
58 // The input type of the `operator()`.
59 using InputType = typename FunctionType::InputType;
60
61 // static_assert(std::is_base_of<Function<OutputType, InputType>, FunctionType>::value, "EvaluableLinearCombination: FunctionType must derive from `Function`.");
62
63 // The type of 'this'.
65
66
67protected:
68 // The coefficients of the linear combination.
69 std::vector<Coefficient> m_coefficients;
70
71 // The functions of the linear combination.
72 std::vector<FunctionType> m_functions;
73
74
75public:
76 /*
77 * MARK: Constructors
78 */
79
84 EvaluableLinearCombination(const std::vector<Coefficient>& coefficients, const std::vector<FunctionType>& functions) :
87
88 if (coefficients.size() != functions.size()) {
89 throw std::invalid_argument("EvaluableLinearCombination(const std::vector<Coefficient>&, const std::vector<FunctionType>&): The number of coefficients and functions do not match.");
90 }
91 }
92
93
98 EvaluableLinearCombination(std::vector<Coefficient> {}, std::vector<FunctionType> {}) {}
99
100
108 EvaluableLinearCombination(std::vector<Coefficient> {coefficient}, std::vector<FunctionType> {function}) {}
109
110
118
119
127
128 if (zero != 0) {
129 throw std::invalid_argument("EvaluableLinearCombination(const int): Can't convert a non-zero integer to a 'zero' instance.");
130 }
131 }
132
133
134 /*
135 * MARK: Vector space arithmetic
136 */
137
141 Self& operator+=(const Self& rhs) override {
142 this->append(rhs.m_coefficients, rhs.m_functions);
143 return *this;
144 }
145
146
150 Self& operator*=(const Coefficient& a) override {
151
152 if (std::abs(a) < 1.0e-16) { // multiplication by zero returns a 'zero vector'
153 this->m_coefficients = std::vector<Coefficient> {};
154 this->m_functions = std::vector<FunctionType> {};
155 return *this;
156 }
157
158 std::transform(this->m_coefficients.begin(), this->m_coefficients.end(),
159 this->m_coefficients.begin(), [a](const Coefficient& C) { return C * a; });
160
161 return *this;
162 }
163
164
165 /*
166 * MARK: General information
167 */
168
172 std::string description() const {
173
174 std::string description = "[";
175 for (size_t i = 0; i < this->length(); i++) {
176
177 // Provide the coefficient and the function's description.
178 description += (boost::format("(%|.3f|) %s") % this->coefficient(i) % this->function(i).description()).str();
179
180 // Add a '+' when we're not at the end.
181 if (i != this->length() - 1) {
182 description += " + ";
183 } else {
184 description += "]";
185 }
186 }
187
188 return description;
189 }
190
194 size_t length() const { return this->m_coefficients.size(); }
195
196
197 /*
198 * MARK: Access
199 */
200
208 const Coefficient& coefficient(const size_t i) const { return this->m_coefficients[i]; }
209
213 const std::vector<Coefficient>& coefficients() const { return this->m_coefficients; }
214
222 const FunctionType& function(const size_t i) const { return this->m_functions[i]; }
223
227 const std::vector<FunctionType>& functions() const { return this->m_functions; }
228
229
230 /*
231 * MARK: Conforming to `Function`
232 */
233
241 OutputType operator()(const InputType& in) const override {
242
243 // Evaluate every function of the linear combination.
244 OutputType out {}; // Default initialization of the `OutputType`.
245 const auto n = this->length();
246 for (size_t i = 0; i < n; i++) {
247 out += this->m_coefficients[i] * this->m_functions[i].operator()(in);
248 }
249
250 return out;
251 }
252
253
254 /*
255 * MARK: Comparison operators
256 */
257
263 bool operator==(const Self& other) const {
264 return (this->m_coefficients == other.m_coefficients) && (this->m_functions == other.m_functions);
265 }
266
267
268 /*
269 * MARK: Appending
270 */
271
279
280 this->m_coefficients.push_back(coefficient);
281 this->m_functions.push_back(function);
282 }
283
284
292 void appendWithThreshold(const Coefficient& coefficient, const FunctionType& function, const double threshold = 1.0e-16) {
293
294 // Only enlarge the linear combination for sufficiently large coefficients.
295 if (std::abs(coefficient) < threshold) {
296 return;
297 } else {
298 this->append(coefficient, function);
299 }
300 }
301
302
309 void append(const std::vector<Coefficient>& coefficients, const std::vector<FunctionType>& functions) {
310
311 if (coefficients.size() != functions.size()) {
312 throw std::invalid_argument("EvaluableLinearCombination::append(const std::vector<Coefficient>&, const std::vector<FunctionType>&): The number of coefficients and functions do not match.");
313 }
314
315 this->m_coefficients.insert(this->m_coefficients.end(), coefficients.begin(), coefficients.end());
316 this->m_functions.insert(this->m_functions.end(), functions.begin(), functions.end());
317 }
318};
319
320
321} // namespace GQCP
322
323
324#include <Eigen/Dense>
325
326/*
327 * Make GQCP::EvaluableLinearCombination<FunctionType> an Eigen scalar type.
328 */
329
330namespace Eigen {
331
332
333template <typename Coefficient, typename FunctionType>
334struct NumTraits<GQCP::EvaluableLinearCombination<Coefficient, FunctionType>>:
335 public NumTraits<double> { // permits to get the epsilon, dummy_precision, lowest, highest functions
336
340
341 enum {
342 IsComplex = 0,
343 IsInteger = 0,
344 IsSigned = 1,
345 RequireInitialization = 1,
346 ReadCost = 1,
347 AddCost = 5,
348 MulCost = 1000 // just put something big
349 };
350};
351
352
353// Enable the scalar product of a EvaluableLinearCombination<Coefficient, FunctionType> with its own Coefficient (both sides).
354
355template <typename Coefficient, typename FunctionType>
356struct ScalarBinaryOpTraits<GQCP::EvaluableLinearCombination<Coefficient, FunctionType>, Coefficient,
357 Eigen::internal::scalar_product_op<GQCP::EvaluableLinearCombination<Coefficient, FunctionType>, Coefficient>> {
358
360};
361
362template <typename Coefficient, typename FunctionType>
363struct ScalarBinaryOpTraits<Coefficient, GQCP::EvaluableLinearCombination<Coefficient, FunctionType>,
364 Eigen::internal::scalar_product_op<Coefficient, GQCP::EvaluableLinearCombination<Coefficient, FunctionType>>> {
365
367};
368
369
370} // namespace Eigen
Definition: EvaluableLinearCombination.hpp:46
EvaluableLinearCombination(const Coefficient coefficient, const FunctionType &function)
Definition: EvaluableLinearCombination.hpp:107
EvaluableLinearCombination(const std::vector< Coefficient > &coefficients, const std::vector< FunctionType > &functions)
Definition: EvaluableLinearCombination.hpp:84
_FunctionType FunctionType
Definition: EvaluableLinearCombination.hpp:53
Self & operator+=(const Self &rhs) override
Definition: EvaluableLinearCombination.hpp:141
std::vector< FunctionType > m_functions
Definition: EvaluableLinearCombination.hpp:72
const std::vector< FunctionType > & functions() const
Definition: EvaluableLinearCombination.hpp:227
EvaluableLinearCombination(const int zero)
Definition: EvaluableLinearCombination.hpp:125
const FunctionType & function(const size_t i) const
Definition: EvaluableLinearCombination.hpp:222
std::string description() const
Definition: EvaluableLinearCombination.hpp:172
Self & operator*=(const Coefficient &a) override
Definition: EvaluableLinearCombination.hpp:150
typename FunctionType::InputType InputType
Definition: EvaluableLinearCombination.hpp:59
OutputType operator()(const InputType &in) const override
Definition: EvaluableLinearCombination.hpp:241
void append(const std::vector< Coefficient > &coefficients, const std::vector< FunctionType > &functions)
Definition: EvaluableLinearCombination.hpp:309
void appendWithThreshold(const Coefficient &coefficient, const FunctionType &function, const double threshold=1.0e-16)
Definition: EvaluableLinearCombination.hpp:292
EvaluableLinearCombination()
Definition: EvaluableLinearCombination.hpp:97
sum_t< Coefficient, typename FunctionType::OutputType > OutputType
Definition: EvaluableLinearCombination.hpp:56
const std::vector< Coefficient > & coefficients() const
Definition: EvaluableLinearCombination.hpp:213
bool operator==(const Self &other) const
Definition: EvaluableLinearCombination.hpp:263
void append(const Coefficient &coefficient, const FunctionType &function)
Definition: EvaluableLinearCombination.hpp:278
EvaluableLinearCombination(const FunctionType &function)
Definition: EvaluableLinearCombination.hpp:116
_Coefficient Coefficient
Definition: EvaluableLinearCombination.hpp:50
std::vector< Coefficient > m_coefficients
Definition: EvaluableLinearCombination.hpp:69
size_t length() const
Definition: EvaluableLinearCombination.hpp:194
const Coefficient & coefficient(const size_t i) const
Definition: EvaluableLinearCombination.hpp:208
Definition: Function.hpp:153
Definition: VectorSpaceArithmetic.hpp:35
Definition: EvaluableLinearCombination.hpp:330
Definition: BaseOneElectronIntegralBuffer.hpp:25
decltype(std::declval< T >()+std::declval< U >()) sum_t
Definition: aliases.hpp:38