Line data Source code
1 : /*
2 : * File: LogLogisticLoss.cpp
3 : * Author: Pantelis Sopasakis
4 : *
5 : * Created on October 29, 2015, 5:08 PM
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 "LogLogisticLoss.h"
22 : #include <cmath>
23 :
24 2 : LogLogisticLoss::LogLogisticLoss() {
25 2 : m_mu = 1.0;
26 2 : }
27 :
28 9 : LogLogisticLoss::~LogLogisticLoss() {
29 9 : }
30 :
31 3 : LogLogisticLoss::LogLogisticLoss(double mu) :
32 3 : Function(), m_mu(mu) {
33 3 : }
34 :
35 5 : int LogLogisticLoss::call(Matrix& x, double& f) {
36 : //LCOV_EXCL_START
37 : if (!x.isColumnVector()) {
38 : throw std::invalid_argument("x must be a column-vector");
39 : }
40 : //LCOV_EXCL_STOP
41 5 : f = 0.0;
42 44 : for (size_t i = 0; i < x.getNrows(); i++) {
43 39 : double si = std::exp(x[i]);
44 39 : si /= (1.0 + si);
45 39 : f -= std::log(si);
46 : }
47 5 : f *= m_mu;
48 5 : return ForBESUtils::STATUS_OK;
49 : }
50 :
51 19603 : int LogLogisticLoss::call(Matrix& x, double& f, Matrix& grad) {
52 : //LCOV_EXCL_START
53 : if (!x.isColumnVector()) {
54 : throw std::invalid_argument("x must be a column-vector");
55 : }
56 : //LCOV_EXCL_STOP
57 19603 : f = 0.0;
58 19603 : int status = ForBESUtils::STATUS_OK;
59 98022 : for (size_t i = 0; i < x.getNrows(); i++) {
60 78419 : double xi = x[i];
61 78419 : if (xi < 33) { /* because for values higher than 33,
62 : * s1 is practically equal to 1.
63 : * This saves the computational burden for
64 : * high values of x_i */
65 78419 : double si = std::exp(xi); /* si = e^xi */
66 78419 : si = si / (1 + si); /* si = e^xi / (1+e^xi) */
67 78419 : f -= std::log(si); /* f -= ln(si) */
68 78419 : grad[i] = m_mu * (si - 1); /* prox_i = mu*(si-1) */
69 : }
70 : }
71 19603 : f *= m_mu;
72 19603 : return status;
73 : }
74 :
75 5 : int LogLogisticLoss::hessianProduct(Matrix& x, Matrix& z, Matrix& Hz) {
76 : //LCOV_EXCL_START
77 : if (!x.isColumnVector()) {
78 : throw std::invalid_argument("x must be a column-vector");
79 : }
80 : //LCOV_EXCL_STOP
81 5 : int status = ForBESUtils::STATUS_OK;
82 33 : for (size_t i = 0; i < x.getNrows(); i++) {
83 28 : double xi = x[i];
84 28 : if (xi < 33) { /* because for values higher than 33,
85 : * s1 is practically equal to 1.
86 : * This saves the computational burden for
87 : * high values of x_i */
88 28 : double si = std::exp(xi); /* si = e^xi */
89 28 : si = si / (1 + si); /* si = e^xi / (1+e^xi) */
90 28 : Hz[i] = m_mu * z[i] * si * (1 - si);
91 : }
92 : }
93 5 : return status;
94 : }
95 :
96 5 : FunctionOntologicalClass LogLogisticLoss::category() {
97 5 : FunctionOntologicalClass logLogisticLoss("LogLogisticLoss");
98 5 : logLogisticLoss.set_defines_f(true);
99 5 : logLogisticLoss.set_defines_grad(true);
100 5 : logLogisticLoss.add_superclass(FunctionOntologyRegistry::loss());
101 5 : return logLogisticLoss;
102 12 : }
103 :
104 :
105 :
106 :
107 :
|