Line data Source code
1 : /*
2 : * File: HuberLoss.cpp
3 : * Author: Pantelis Sopasakis
4 : *
5 : * Created on October 30, 2015, 1:57 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 "HuberLoss.h"
22 : #include <cmath>
23 :
24 5 : HuberLoss::HuberLoss(double delta) :
25 5 : Function(), m_delta(delta) {
26 5 : }
27 :
28 4 : HuberLoss::~HuberLoss() {
29 4 : }
30 :
31 1 : int HuberLoss::call(Matrix& x, double& f) {
32 : //LCOV_EXCL_START
33 : if (!x.isColumnVector()) {
34 : throw std::invalid_argument("x must be a column-vector");
35 : }
36 : //LCOV_EXCL_STOP
37 1 : f = 0.0;
38 11 : for (size_t i = 0; i < x.getNrows(); i++) {
39 : double xi;
40 10 : xi = x[i];
41 10 : if (std::abs(xi) <= m_delta) {
42 3 : f += std::pow(xi, 2) / (2.0 * m_delta);
43 : } else {
44 7 : f += std::abs(xi) - m_delta / 2.0;
45 : }
46 : }
47 1 : return ForBESUtils::STATUS_OK;
48 : }
49 :
50 355 : int HuberLoss::call(Matrix& x, double& f, Matrix& grad) {
51 : //LCOV_EXCL_START
52 : if (!x.isColumnVector()) {
53 : throw std::invalid_argument("x must be a column-vector");
54 : }
55 : //LCOV_EXCL_STOP
56 355 : f = 0.0;
57 755 : for (size_t i = 0; i < x.getNrows(); i++) {
58 : double xi;
59 400 : xi = x[i];
60 400 : if (std::abs(xi) <= m_delta) {
61 186 : f += std::pow(xi, 2) / (2.0 * m_delta);
62 186 : grad[i] = xi / m_delta;
63 : } else {
64 214 : f += std::abs(xi) - m_delta / 2.0;
65 214 : grad[i] = std::signbit(xi) ? -1.0 : 1.0;
66 : }
67 : }
68 355 : return ForBESUtils::STATUS_OK;
69 : }
70 :
71 5 : FunctionOntologicalClass HuberLoss::category() {
72 5 : FunctionOntologicalClass huberLoss("HuberLoss");
73 5 : huberLoss.set_defines_f(true);
74 5 : huberLoss.set_defines_grad(true);
75 5 : huberLoss.add_superclass(FunctionOntologyRegistry::loss());
76 5 : return huberLoss;
77 9 : }
78 :
79 :
|