Line data Source code
1 : /*
2 : * File: TestHuber.cpp
3 : * Author: Pantelis Sopasakis
4 : *
5 : * Created on Oct 30, 2015, 2:19: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 "TestHuber.h"
22 : #include "HuberLoss.h"
23 :
24 :
25 1 : CPPUNIT_TEST_SUITE_REGISTRATION(TestHuber);
26 :
27 2 : TestHuber::TestHuber() {
28 2 : }
29 :
30 4 : TestHuber::~TestHuber() {
31 4 : }
32 :
33 2 : void TestHuber::setUp() {
34 2 : }
35 :
36 2 : void TestHuber::tearDown() {
37 2 : }
38 :
39 : const static double X[] = {
40 : 0.106216344928664,
41 : 0.372409740055537,
42 : 0.198118402542975,
43 : 0.489687638016024,
44 : 0.339493413390758,
45 : 0.951630464777727,
46 : 0.920332039836564,
47 : 0.052676997680793,
48 : 0.737858095516997,
49 : 0.269119426398556
50 : };
51 :
52 : const static double D[] = {
53 : 1.4374274329354852,
54 : 0.3054708068289311,
55 : -0.0290824365339767,
56 : -0.8234036458714026,
57 : -0.7637012146815048,
58 : -0.2048482849078404,
59 : 0.8995586109397722,
60 : 1.0842669895961112,
61 : 1.1927942674890943,
62 : -0.3403099725494878
63 : };
64 :
65 1 : void TestHuber::testHessian() {
66 1 : const size_t n = 10;
67 1 : const double * xdata = X;
68 1 : Matrix x(n, 1, xdata);
69 1 : const double delta = 0.2;
70 1 : Function * huber = new HuberLoss(delta);
71 :
72 2 : Matrix Hz(n, 1);
73 1 : const double * ddata = D;
74 2 : Matrix z(n, 1, ddata);
75 1 : int status = huber->hessianProduct(x, z, Hz);
76 1 : _ASSERT(ForBESUtils::is_status_ok(status));
77 :
78 : double fstar;
79 1 : _ASSERT(!huber->category().defines_conjugate());
80 1 : _ASSERT_EQ(ForBESUtils::STATUS_UNDEFINED_FUNCTION, huber->callConj(x, fstar));
81 :
82 : /* test the assignment operator */
83 1 : Function * huber2 = new HuberLoss(delta);
84 1 : _ASSERT_OK(*huber = *huber);
85 2 : _ASSERT_EXCEPTION(*huber2 = *huber, std::logic_error);
86 :
87 1 : }
88 :
89 1 : void TestHuber::testCall() {
90 1 : const size_t n = 10;
91 1 : const double * xdata = X;
92 1 : Matrix x(n, 1, xdata);
93 1 : const double delta = 0.2;
94 1 : Function * huber = new HuberLoss(delta);
95 :
96 : double f;
97 2 : Matrix grad(n, 1);
98 :
99 1 : _ASSERT(huber->category().defines_f());
100 1 : int status = huber->call(x, f, grad);
101 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
102 1 : const double tol = 1e-12;
103 1 : _ASSERT_NUM_EQ(3.513800016594281, f, tol);
104 :
105 1 : status = huber->call(x, f);
106 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
107 1 : _ASSERT_NUM_EQ(3.513800016594281, f, tol);
108 :
109 : const double grad_expected_data[n] = {
110 : 0.531081724643320,
111 : 1.000000000000000,
112 : 0.990592012714875,
113 : 1.000000000000000,
114 : 1.000000000000000,
115 : 1.000000000000000,
116 : 1.000000000000000,
117 : 0.263384988403965,
118 : 1.000000000000000,
119 : 1.000000000000000
120 1 : };
121 :
122 2 : Matrix grad_expected(n, 1, grad_expected_data);
123 :
124 1 : _ASSERT_EQ(grad_expected, grad);
125 :
126 2 : delete huber;
127 4 : }
128 :
|