n2p2 - A neural network potential package
CoreFunction.h
Go to the documentation of this file.
1// n2p2 - A neural network potential package
2// Copyright (C) 2018 Andreas Singraber (University of Vienna)
3// Copyright (C) 2020 Martin P. Bircher
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU 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// This program 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 General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <https://www.gnu.org/licenses/>.
17
18#ifndef COREFUNCTION_H
19#define COREFUNCTION_H
20
21#include <cmath>
22#include <string>
23#include <vector>
24
25namespace nnp
26{
27
29{
30public:
32 enum class Type
33 {
36 COS,
39 POLY1,
42 POLY2,
45 POLY3,
48 POLY4,
51 EXP
52 };
53
61 void setType(Type const type);
66 void setType(std::string const typeString);
71 Type getType() const;
72#ifndef N2P2_NO_ASYM_POLY
77 void setAsymmetric(bool asymmetric);
82 bool getAsymmetric() const;
83#endif
89 double f(double x) const;
95 double df(double x) const;
102 void fdf(double x, double& fx, double& dfx) const;
107 std::vector<std::string> info() const;
108
109private:
110 static double const PI;
111 static double const PI_2;
112 static double const E;
115#ifndef N2P2_NO_ASYM_POLY
118#endif
120 double (CoreFunction::*fPtr)(double x) const;
122 double (CoreFunction::*dfPtr)(double x) const;
124 void (CoreFunction::*fdfPtr)(double x,
125 double& fx,
126 double& dfx) const;
127
128 // Individual functions.
129 double fCOS(double x) const;
130 double dfCOS(double x) const;
131 void fdfCOS(double x, double& fx, double& dfx) const;
132
133 double fPOLY1(double x) const;
134 double dfPOLY1(double x) const;
135 void fdfPOLY1(double x, double& fx, double& dfx) const;
136
137 double fPOLY2(double x) const;
138 double dfPOLY2(double x) const;
139 void fdfPOLY2(double x, double& fx, double& dfx) const;
140
141 double fPOLY3(double x) const;
142 double dfPOLY3(double x) const;
143 void fdfPOLY3(double x, double& fx, double& dfx) const;
144
145 double fPOLY4(double x) const;
146 double dfPOLY4(double x) const;
147 void fdfPOLY4(double x, double& fx, double& dfx) const;
148
149 double fEXP(double x) const;
150 double dfEXP(double x) const;
151 void fdfEXP(double x, double& fx, double& dfx) const;
152};
153
155// Inlined function definitions //
157
159
160#ifndef N2P2_NO_ASYM_POLY
161inline void CoreFunction::setAsymmetric(bool asymmetric)
162{
163 this->asymmetric = asymmetric;
164
165 return;
166}
167
168inline bool CoreFunction::getAsymmetric() const { return asymmetric; }
169#endif
170
171inline double CoreFunction::f(double x) const
172{
173#ifndef N2P2_NO_ASYM_POLY
174 if (asymmetric) x = (2.0 - x) * x;
175#endif
176 return (this->*fPtr)(x);
177}
178
179inline double CoreFunction::df(double x) const
180{
181#ifndef N2P2_NO_ASYM_POLY
182 if (asymmetric) return (2.0 - 2.0 * x) * (this->*dfPtr)((2.0 - x) * x);
183 else return (this->*dfPtr)(x);
184#else
185 return (this->*dfPtr)(x);
186#endif
187}
188
189inline void CoreFunction::fdf(double x, double& fx, double& dfx) const
190{
191#ifndef N2P2_NO_ASYM_POLY
192 if (asymmetric)
193 {
194 (this->*fdfPtr)((2.0 - x) * x, fx, dfx);
195 dfx *= 2.0 - 2.0 * x;
196 }
197 else (this->*fdfPtr)(x, fx, dfx);
198#else
199 (this->*fdfPtr)(x, fx, dfx);
200#endif
201 return;
202}
203
204inline double CoreFunction::fCOS(double x) const
205{
206 return 0.5 * (cos(PI * x) + 1.0);
207}
208
209inline double CoreFunction::dfCOS(double x) const
210{
211 return -PI_2 * sin(PI * x);
212}
213
214inline void CoreFunction::fdfCOS(double x, double& fx, double& dfx) const
215{
216 double const temp = cos(PI * x);
217 fx = 0.5 * (temp + 1.0);
218 dfx = -0.5 * PI * sqrt(1.0 - temp * temp);
219 return;
220}
221
222inline double CoreFunction::fPOLY1(double x) const
223{
224 return (2.0 * x - 3.0) * x * x + 1.0;
225}
226
227inline double CoreFunction::dfPOLY1(double x) const
228{
229 return x * (6.0 * x - 6.0);
230}
231
232inline void CoreFunction::fdfPOLY1(double x, double& fx, double& dfx) const
233{
234 fx = (2.0 * x - 3.0) * x * x + 1.0;
235 dfx = x * (6.0 * x - 6.0);
236 return;
237}
238
239inline double CoreFunction::fPOLY2(double x) const
240{
241 return ((15.0 - 6.0 * x) * x - 10.0) * x * x * x + 1.0;
242}
243
244inline double CoreFunction::dfPOLY2(double x) const
245{
246 return x * x * ((60.0 - 30.0 * x) * x - 30.0);
247}
248
249inline void CoreFunction::fdfPOLY2(double x, double& fx, double& dfx) const
250{
251 double const x2 = x * x;
252 fx = ((15.0 - 6.0 * x) * x - 10.0) * x * x2 + 1.0;
253 dfx = x2 * ((60.0 - 30.0 * x) * x - 30.0);
254 return;
255}
256
257inline double CoreFunction::fPOLY3(double x) const
258{
259 double const x2 = x * x;
260 return (x * (x * (20.0 * x - 70.0) + 84.0) - 35.0) * x2 * x2 + 1.0;
261}
262
263inline double CoreFunction::dfPOLY3(double x) const
264{
265 return x * x * x * (x * (x * (140.0 * x - 420.0) + 420.0) - 140.0);
266}
267
268inline void CoreFunction::fdfPOLY3(double x, double& fx, double& dfx) const
269{
270 double const x2 = x * x;
271 fx = (x * (x * (20.0 * x - 70.0) + 84.0) - 35.0) * x2 * x2 + 1.0;
272 dfx = x2 * x * (x * (x * (140.0 * x - 420.0) + 420.0) - 140.0);
273 return;
274}
275
276inline double CoreFunction::fPOLY4(double x) const
277{
278 double const x2 = x * x;
279 return (x * (x * ((315.0 - 70.0 * x) * x - 540.0) + 420.0) - 126.0) *
280 x2 * x2 * x + 1.0;
281}
282
283inline double CoreFunction::dfPOLY4(double x) const
284{
285 double const x2 = x * x;
286 return x2 * x2 *
287 (x * (x * ((2520.0 - 630.0 * x) * x - 3780.0) + 2520.0) - 630.0);
288}
289
290inline void CoreFunction::fdfPOLY4(double x, double& fx, double& dfx) const
291{
292 double x4 = x * x;
293 x4 *= x4;
294 fx = (x * (x * ((315.0 - 70.0 * x) * x - 540.0) + 420.0) - 126.0) *
295 x * x4 + 1.0;
296 dfx = x4 *
297 (x * (x * ((2520.0 - 630.0 * x) * x - 3780.0) + 2520.0) - 630.0);
298 return;
299}
300
301inline double CoreFunction::fEXP(double x) const
302{
303 return E * exp(1.0 / (x * x - 1.0));
304}
305
306inline double CoreFunction::dfEXP(double x) const
307{
308 double const temp = 1.0 / (x * x - 1.0);
309 return -2.0 * E * x * temp * temp * exp(temp);
310}
311
312inline void CoreFunction::fdfEXP(double x, double& fc, double& dfc) const
313{
314 double const temp = 1.0 / (x * x - 1.0);
315 double const temp2 = exp(temp);
316 fc = E * temp2;
317 dfc = -2.0 * E * x * temp * temp * temp2;
318 return;
319}
320
321}
322
323#endif
double fPOLY4(double x) const
Definition: CoreFunction.h:276
double dfPOLY2(double x) const
Definition: CoreFunction.h:244
double fCOS(double x) const
Definition: CoreFunction.h:204
void fdfEXP(double x, double &fx, double &dfx) const
Definition: CoreFunction.h:312
void setAsymmetric(bool asymmetric)
Set asymmetric property.
Definition: CoreFunction.h:161
std::vector< std::string > info() const
Get string with formula of compact function.
double fPOLY1(double x) const
Definition: CoreFunction.h:222
Type type
Core function type.
Definition: CoreFunction.h:114
static double const PI
Definition: CoreFunction.h:110
void fdfPOLY3(double x, double &fx, double &dfx) const
Definition: CoreFunction.h:268
double dfPOLY4(double x) const
Definition: CoreFunction.h:283
void fdf(double x, double &fx, double &dfx) const
Calculate function and derivative at once.
Definition: CoreFunction.h:189
void(CoreFunction::* fdfPtr)(double x, double &fx, double &dfx) const
Function pointer to fdf.
Definition: CoreFunction.h:124
double dfEXP(double x) const
Definition: CoreFunction.h:306
double(CoreFunction::* dfPtr)(double x) const
Function pointer to df.
Definition: CoreFunction.h:122
double dfPOLY3(double x) const
Definition: CoreFunction.h:263
double fEXP(double x) const
Definition: CoreFunction.h:301
double df(double x) const
Calculate derivative of function at argument .
Definition: CoreFunction.h:179
void fdfPOLY4(double x, double &fx, double &dfx) const
Definition: CoreFunction.h:290
double dfCOS(double x) const
Definition: CoreFunction.h:209
bool asymmetric
Enables asymmetry modification (use with polynomials).
Definition: CoreFunction.h:117
void fdfPOLY1(double x, double &fx, double &dfx) const
Definition: CoreFunction.h:232
void setType(Type const type)
Set function type.
Type getType() const
Getter for type.
Definition: CoreFunction.h:158
void fdfCOS(double x, double &fx, double &dfx) const
Definition: CoreFunction.h:214
double fPOLY2(double x) const
Definition: CoreFunction.h:239
void fdfPOLY2(double x, double &fx, double &dfx) const
Definition: CoreFunction.h:249
double dfPOLY1(double x) const
Definition: CoreFunction.h:227
double f(double x) const
Calculate function value .
Definition: CoreFunction.h:171
Type
List of available function types.
Definition: CoreFunction.h:33
CoreFunction()
Constructor, initializes to #Type::POLY2.
static double const E
Definition: CoreFunction.h:112
double fPOLY3(double x) const
Definition: CoreFunction.h:257
bool getAsymmetric() const
Getter for asymmetric.
Definition: CoreFunction.h:168
static double const PI_2
Definition: CoreFunction.h:111
double(CoreFunction::* fPtr)(double x) const
Function pointer to f.
Definition: CoreFunction.h:120
Definition: Atom.h:29
CutoffFunction fc
Definition: nnp-cutoff.cpp:27