Line data Source code
1 : /*
2 : * File: Function.cpp
3 : * Author: Pantelis Sopasakis
4 : *
5 : * Created on July 9, 2015, 3:35 AM
6 : *
7 : * ForBES is free software: you can redistribute it and/or modify
8 : * it under the terms of the GNU Lesser General Public License as published by
9 : * the Free Software Foundation, either version 3 of the License, or
10 : * (at your option) any later version.
11 : *
12 : * ForBES is distributed in the hope that it will be useful,
13 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : * GNU Lesser General Public License for more details.
16 : *
17 : * You should have received a copy of the GNU Lesser General Public License
18 : * along with ForBES. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include "Function.h"
22 :
23 156 : Function::Function() {
24 156 : }
25 :
26 148 : Function::~Function() {
27 148 : }
28 :
29 : //LCOV_EXCL_START
30 :
31 : int Function::call(Matrix& x, double& f) {
32 : return ForBESUtils::STATUS_UNDEFINED_FUNCTION;
33 : }
34 :
35 : int Function::call(Matrix& x, double& f, Matrix& grad) {
36 : return ForBESUtils::STATUS_UNDEFINED_FUNCTION;
37 : }
38 : //LCOV_EXCL_STOP
39 :
40 1 : int Function::hessianProduct(Matrix& x, Matrix& z, Matrix& Hz) {
41 1 : const double epsilon = 1e-8;
42 1 : const double one_over_epsilon = 1e8;
43 :
44 : /* t = x + epsilon * z */
45 1 : Matrix t(x);
46 1 : Matrix::add(t, epsilon, z, 1.0);
47 :
48 :
49 2 : Matrix grad_x(x.getNrows(), x.getNcols());
50 :
51 : double f;
52 : /* Hz = nabla f(x+e*z) */
53 1 : int status = call(t, f, Hz);
54 :
55 : /* grad_x = nabla f(x) */
56 1 : status = std::max(status, call(x, f, grad_x));
57 :
58 : /* Hz = (nabla f(t) - nabla f(x))/epsilon */
59 1 : Hz -= grad_x;
60 1 : Hz *= one_over_epsilon;
61 :
62 2 : return status;
63 : }
64 :
65 2 : int Function::callConj(Matrix& x, double& f_star) {
66 2 : return ForBESUtils::STATUS_UNDEFINED_FUNCTION;
67 : }
68 :
69 1 : int Function::callConj(Matrix& x, double& f_star, Matrix& grad) {
70 1 : return ForBESUtils::STATUS_UNDEFINED_FUNCTION;
71 : }
72 :
73 0 : int Function::hessianProductConj(Matrix& x, Matrix& z, Matrix& Hz) {
74 0 : const double epsilon = 1e-8;
75 0 : const double one_over_epsilon = 1e8;
76 :
77 : /* t = x + epsilon * z */
78 0 : Matrix t(x);
79 0 : Matrix::add(t, epsilon, z, 1.0);
80 :
81 :
82 0 : Matrix grad_x(x.getNrows(), x.getNcols());
83 : double f;
84 0 : int status = callConj(t, f, Hz);
85 0 : status = std::max(status, callConj(x, f, grad_x));
86 0 : Hz -= grad_x;
87 0 : Hz *= one_over_epsilon;
88 0 : return status;
89 : }
90 :
91 : //LCOV_EXCL_START
92 : int Function::callProx(Matrix& x, double gamma, Matrix& prox) {
93 : return ForBESUtils::STATUS_UNDEFINED_FUNCTION;
94 : }
95 :
96 : int Function::callProx(Matrix& x, double gamma, Matrix& prox, double& f_at_prox) {
97 : return ForBESUtils::STATUS_UNDEFINED_FUNCTION;
98 : }
99 : //LCOV_EXCL_STOP
100 :
101 2 : Function& Function::operator=(const Function& right) {
102 2 : if (this == &right) { // Check for self-assignment!
103 2 : return *this;
104 : } else {
105 : // otherwise it should not be allowed to use operator= on Functions!
106 : // an error should be thrown
107 1 : throw logic_error("It is not allowed to copy Function objects; operator= is not supported.");
108 : }
109 78 : }
|