Loading...
Searching...
No Matches
function.C
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(
29 const std::vector<double>
30 & x) const
31{
32 auto denseX = vectorToDenseVector(x);
33 return denseMatrixToVectorVector(secondOrderCentralDifference(denseX));
34}
35
36std::vector<double> Function::centralDifference(const std::vector<double>& x)
37const
38{
39 auto denseX = vectorToDenseVector(x);
40 auto dx = centralDifference(denseX);
41 return denseVectorToVector(dx);
42}
43
44std::vector<std::vector<double >> Function::secondOrderCentralDifference(
45 const std::vector<double>& x) const
46{
47 auto denseX = vectorToDenseVector(x);
48 DenseMatrix ddx = secondOrderCentralDifference(denseX);
49 return denseMatrixToVectorVector(ddx);
50}
51
52DenseMatrix Function::evalJacobian(DenseVector x) const
53{
54 return centralDifference(x);
55}
56
57DenseMatrix Function::evalHessian(DenseVector x) const
58{
59 auto vec = denseVectorToVector(x);
60 auto hessian = evalHessian(vec);
61 return vectorVectorToDenseMatrix(hessian);
62}
63
64DenseMatrix Function::centralDifference(DenseVector x) const
65{
66 DenseMatrix dx(1, x.size());
67 double h = 1e-6; // perturbation step size
68 double hForward = 0.5 * h;
69 double hBackward = 0.5 * h;
70
71 for (unsigned int i = 0; i < getNumVariables(); ++i)
72 {
73 DenseVector xForward(x);
74 xForward(i) = xForward(i) + hForward;
75 DenseVector xBackward(x);
76 xBackward(i) = xBackward(i) - hBackward;
77 double yForward = eval(xForward);
78 double yBackward = eval(xBackward);
79 dx(i) = (yForward - yBackward) / (hBackward + hForward);
80 }
81
82 return dx;
83}
84
85DenseMatrix Function::secondOrderCentralDifference(DenseVector x) const
86{
87 DenseMatrix ddx(getNumVariables(), getNumVariables());
88 double h = 1e-6; // perturbation step size
89 double hForward = 0.5 * h;
90 double hBackward = 0.5 * h;
91
92 for (size_t i = 0; i < getNumVariables(); ++i)
93 {
94 for (size_t j = 0; j < getNumVariables(); ++j)
95 {
96 DenseVector x0(x);
97 DenseVector x1(x);
98 DenseVector x2(x);
99 DenseVector x3(x);
100 x0(i) = x0(i) + hForward;
101 x0(j) = x0(j) + hForward;
102 x1(i) = x1(i) - hBackward;
103 x1(j) = x1(j) + hForward;
104 x2(i) = x2(i) + hForward;
105 x2(j) = x2(j) - hBackward;
106 x3(i) = x3(i) - hBackward;
107 x3(j) = x3(j) - hBackward;
108 ddx(i, j) = (eval(x0) - eval(x1) - eval(x2) + eval(x3)) / (h * h);
109 }
110 }
111
112 return ddx;
113}
114
115} // namespace SPLINTER