Loading...
Searching...
No Matches
function.C
Go to the documentation of this file.
1/*
2 * This file is part of the SPLINTER library.
3 * Copyright (C) 2012 Bjarne Grimstad (bjarne.grimstad@gmail.com).
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8*/
9
10#include <function.h>
11#include "utilities.h"
12
13namespace SPLINTER
14{
15
16double Function::eval(const std::vector<double>& x) const
17{
18 auto denseX = vectorToDenseVector(x);
19 return eval(denseX);
20}
21
22std::vector<double> Function::evalJacobian(const std::vector<double>& x) const
23{
24 auto denseX = vectorToDenseVector(x);
25 return denseVectorToVector(evalJacobian(denseX));
26}
27
28std::vector<std::vector<double>> Function::evalHessian(const std::vector<double>
29 & x) const
30{
31 auto denseX = vectorToDenseVector(x);
32 return denseMatrixToVectorVector(secondOrderCentralDifference(denseX));
33}
34
35std::vector<double> Function::centralDifference(const std::vector<double>& x)
36const
37{
38 auto denseX = vectorToDenseVector(x);
39 auto dx = centralDifference(denseX);
40 return denseVectorToVector(dx);
41}
42
43std::vector<std::vector<double>> Function::secondOrderCentralDifference(
44 const std::vector<double>& x) const
45{
46 auto denseX = vectorToDenseVector(x);
47 DenseMatrix ddx = secondOrderCentralDifference(denseX);
48 return denseMatrixToVectorVector(ddx);
49}
50
51DenseMatrix Function::evalJacobian(DenseVector x) const
52{
53 return centralDifference(x);
54}
55
56DenseMatrix Function::evalHessian(DenseVector x) const
57{
58 auto vec = denseVectorToVector(x);
59 auto hessian = evalHessian(vec);
60 return vectorVectorToDenseMatrix(hessian);
61}
62
63DenseMatrix Function::centralDifference(DenseVector x) const
64{
65 DenseMatrix dx(1, x.size());
66 double h = 1e-6; // perturbation step size
67 double hForward = 0.5 * h;
68 double hBackward = 0.5 * h;
69
70 for (unsigned int i = 0; i < getNumVariables(); ++i)
71 {
72 DenseVector xForward(x);
73 xForward(i) = xForward(i) + hForward;
74 DenseVector xBackward(x);
75 xBackward(i) = xBackward(i) - hBackward;
76 double yForward = eval(xForward);
77 double yBackward = eval(xBackward);
78 dx(i) = (yForward - yBackward) / (hBackward + hForward);
79 }
80
81 return dx;
82}
83
84DenseMatrix Function::secondOrderCentralDifference(DenseVector x) const
85{
86 DenseMatrix ddx(getNumVariables(), getNumVariables());
87 double h = 1e-6; // perturbation step size
88 double hForward = 0.5 * h;
89 double hBackward = 0.5 * h;
90
91 for (size_t i = 0; i < getNumVariables(); ++i)
92 {
93 for (size_t j = 0; j < getNumVariables(); ++j)
94 {
95 DenseVector x0(x);
96 DenseVector x1(x);
97 DenseVector x2(x);
98 DenseVector x3(x);
99 x0(i) = x0(i) + hForward;
100 x0(j) = x0(j) + hForward;
101 x1(i) = x1(i) - hBackward;
102 x1(j) = x1(j) + hForward;
103 x2(i) = x2(i) + hForward;
104 x2(j) = x2(j) - hBackward;
105 x3(i) = x3(i) - hBackward;
106 x3(j) = x3(j) - hBackward;
107 ddx(i, j) = (eval(x0) - eval(x1) - eval(x2) + eval(x3)) / (h * h);
108 }
109 }
110
111 return ddx;
112}
113
114} // namespace SPLINTER
DenseMatrix vectorVectorToDenseMatrix(const std::vector< std::vector< double > > &vec)
Definition utilities.C:55
DenseVector vectorToDenseVector(const std::vector< double > &vec)
Definition utilities.C:27
std::vector< std::vector< double > > denseMatrixToVectorVector(const DenseMatrix &mat)
Definition utilities.C:39
std::vector< double > denseVectorToVector(const DenseVector &denseVec)
Definition utilities.C:15
label i
Definition pEqn.H:46