Line data Source code
1 : /*
2 : * File: TestHingeLoss.cpp
3 : * Author: chung
4 : *
5 : * Created on Oct 29, 2015, 11:36:49 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 "TestHingeLoss.h"
22 : #include "HingeLoss.h"
23 : #include "MatrixFactory.h"
24 : #include <iostream>
25 :
26 :
27 1 : CPPUNIT_TEST_SUITE_REGISTRATION(TestHingeLoss);
28 :
29 3 : TestHingeLoss::TestHingeLoss() {
30 3 : }
31 :
32 6 : TestHingeLoss::~TestHingeLoss() {
33 6 : }
34 :
35 3 : void TestHingeLoss::setUp() {
36 3 : }
37 :
38 3 : void TestHingeLoss::tearDown() {
39 3 : }
40 :
41 1 : void TestHingeLoss::testCall() {
42 1 : const size_t n = 140;
43 1 : Matrix b = MatrixFactory::MakeRandomMatrix(n, 1, 0.0, 10.0, Matrix::MATRIX_DENSE);
44 2 : Matrix x = MatrixFactory::MakeRandomMatrix(n, 1, 0.0, 10.0, Matrix::MATRIX_DENSE);
45 1 : const double mu = 1.5;
46 1 : Function * hinge = new HingeLoss(b, mu);
47 : double f;
48 1 : _ASSERT(hinge->category().defines_f());
49 1 : int status = hinge->call(x, f);
50 1 : _ASSERT(ForBESUtils::is_status_ok(status));
51 1 : delete hinge;
52 :
53 1 : hinge = new HingeLoss(b);
54 1 : Function * hinge1 = new HingeLoss(b, 1.0);
55 1 : status = hinge->call(x, f);
56 1 : _ASSERT(ForBESUtils::is_status_ok(status));
57 : double f1;
58 1 : status = hinge1->call(x, f1);
59 1 : _ASSERT(ForBESUtils::is_status_ok(status));
60 1 : _ASSERT_NUM_EQ(f, f1, 1e-9);
61 :
62 1 : delete hinge;
63 2 : delete hinge1;
64 :
65 1 : }
66 :
67 1 : void TestHingeLoss::testCall2() {
68 1 : const size_t n = 5;
69 : const double bdata[] = {
70 : 0.659605252908307,
71 : 0.518594942510538,
72 : 0.972974554763863,
73 : 0.648991492712356,
74 : 0.800330575352401
75 1 : };
76 : const double xdata[n] = {
77 : 4.537977087269195,
78 : 4.323915037834617,
79 : -8.253137954020456,
80 : 0.834698148589140,
81 : 1.331710076071617
82 1 : };
83 1 : Matrix b(n, 1, bdata);
84 2 : Matrix x(n, 1, xdata);
85 :
86 1 : const double mu = 0.7;
87 :
88 1 : Function * hinge = new HingeLoss(b, mu);
89 :
90 : double f;
91 1 : _ASSERT(hinge->category().defines_f());
92 1 : int status = hinge->call(x, f);
93 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
94 1 : _ASSERT_NUM_EQ(6.641866860160479, f, 1e-11);
95 2 : delete hinge;
96 1 : }
97 :
98 1 : void TestHingeLoss::testCallProx() {
99 1 : const size_t n = 5;
100 : const double bdata[] = {
101 : 0.659605252908307,
102 : 0.518594942510538,
103 : 0.972974554763863,
104 : 0.648991492712356,
105 : 0.800330575352401
106 1 : };
107 : const double xdata[n] = {
108 : 4.537977087269195,
109 : 4.323915037834617,
110 : -8.253137954020456,
111 : 0.834698148589140,
112 : 1.331710076071617
113 1 : };
114 1 : Matrix b(n, 1, bdata);
115 2 : Matrix x(n, 1, xdata);
116 :
117 1 : const double mu = 0.7;
118 1 : const double gamma = 1.5;
119 :
120 1 : Function * hinge = new HingeLoss(b, mu);
121 : /*
122 : * pre-load some garbage values into prox to make sure they don't affect the result.
123 : */
124 2 : Matrix prox = MatrixFactory::MakeRandomMatrix(n, 1, 10.0, 1.0);
125 1 : _ASSERT(hinge->category().defines_prox());
126 1 : int status = hinge->callProx(x, gamma, prox);
127 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
128 :
129 : const double prox_expected_data[n] = {
130 : 4.537977087269195,
131 : 4.323915037834617,
132 : -6.791453098989512,
133 : 0.648991492712356,
134 : 1.331710076071617
135 1 : };
136 2 : Matrix prox_expected(n, 1, prox_expected_data);
137 :
138 1 : _ASSERT_EQ(prox_expected, prox);
139 :
140 : double f_at_prox;
141 1 : status = hinge->callProx(x, gamma, prox, f_at_prox);
142 1 : _ASSERT_EQ(prox_expected, prox);
143 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
144 1 : _ASSERT_NUM_EQ(5.73070476830318, f_at_prox, 1e-12);
145 :
146 2 : delete hinge;
147 4 : }
148 :
|