Line data Source code
1 : /*
2 : * File: TestQuadraticLoss.cpp
3 : * Author: chung
4 : *
5 : * Created on Oct 29, 2015, 7:32:54 PM
6 : */
7 :
8 : #include "TestQuadraticLoss.h"
9 : #include "QuadraticLoss.h"
10 :
11 :
12 1 : CPPUNIT_TEST_SUITE_REGISTRATION(TestQuadraticLoss);
13 :
14 3 : TestQuadraticLoss::TestQuadraticLoss() {
15 3 : }
16 :
17 6 : TestQuadraticLoss::~TestQuadraticLoss() {
18 6 : }
19 :
20 3 : void TestQuadraticLoss::setUp() {
21 3 : }
22 :
23 3 : void TestQuadraticLoss::tearDown() {
24 3 : }
25 :
26 1 : void TestQuadraticLoss::testCall() {
27 1 : const size_t n = 10;
28 : const double weights_data[n] = {
29 : 0.157613081677548,
30 : 0.970592781760616,
31 : 0.957166948242946,
32 : 0.485375648722841,
33 : 0.800280468888800,
34 : 0.141886338627215,
35 : 0.421761282626275,
36 : 0.915735525189067,
37 : 0.792207329559554,
38 : 0.959492426392903
39 1 : };
40 : const double p_data[n] = {
41 : 2.665186895272925,
42 : -3.441210320907452,
43 : -3.206611374504095,
44 : -2.428496083274627,
45 : -8.832852485984688,
46 : 4.315140878445295,
47 : 0.975571618368594,
48 : -2.264784957509110,
49 : 4.110895620285683,
50 : -5.134549256561094,
51 1 : };
52 1 : Matrix w(n, 1, weights_data);
53 2 : Matrix p(n, 1, p_data);
54 :
55 1 : Function *quadLoss = new QuadraticLoss(w, p);
56 :
57 : const double xdata[n] = {
58 : -0.511212230427454,
59 : -1.207235208036790,
60 : 1.596033695827509,
61 : 1.564292983187142,
62 : -4.324399586622282,
63 : -0.150256480981343,
64 : -0.824395096045192,
65 : 3.138536437643633,
66 : 5.466328345197420,
67 : 5.546366488071987
68 1 : };
69 2 : Matrix x(n, 1, xdata);
70 2 : Matrix grad(n, 1);
71 :
72 : double f0;
73 : double f;
74 1 : const double f_expected = 97.181889336760406;
75 1 : const double tol = 1e-8;
76 1 : _ASSERT(quadLoss->category().defines_f());
77 1 : int status = quadLoss->call(x, f0, grad);
78 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
79 1 : status = quadLoss->call(x, f, grad);
80 1 : _ASSERT_EQ(f, f0);
81 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
82 1 : _ASSERT_NUM_EQ(f_expected, f, tol);
83 :
84 : const double grad_expected_data[n] = {
85 : -0.500642054839506,
86 : 2.168280119185122,
87 : 4.596933125463330,
88 : 1.938002583347348,
89 : 3.608026800264816,
90 : -0.633578881844680,
91 : -0.759156270155760,
92 : 4.948013355555519,
93 : 1.073783739399957,
94 : 10.248257763916156
95 1 : };
96 2 : Matrix grad_expected(n, 1, grad_expected_data);
97 :
98 1 : _ASSERT_EQ(grad_expected, grad);
99 :
100 : double f_2;
101 1 : status = quadLoss->call(x, f_2);
102 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
103 1 : _ASSERT_NUM_EQ(f, f_2, tol);
104 :
105 2 : delete quadLoss;
106 1 : }
107 :
108 1 : void TestQuadraticLoss::testCallConj() {
109 1 : const size_t n = 10;
110 : const double weights_data[n] = {
111 : 8.407172559836626,
112 : 2.542821789715310,
113 : 8.142848260688163,
114 : 2.435249687249893,
115 : 9.292636231872278,
116 : 3.499837659848088,
117 : 1.965952504312082,
118 : 2.510838579760311,
119 : 6.160446761466392,
120 : 4.732888489027292
121 1 : };
122 : const double p_data[n] = {
123 : -11.658439314820487,
124 : -11.479527788985941,
125 : 1.048747160164940,
126 : 7.222540322250016,
127 : 25.854912526162416,
128 : -6.668906707013855,
129 : 1.873310245789398,
130 : -0.824944253709554,
131 : -19.330229178509867,
132 : -4.389661539347733
133 1 : };
134 1 : Matrix w(n, 1, weights_data);
135 2 : Matrix p(n, 1, p_data);
136 :
137 1 : Function *quadLoss = new QuadraticLoss(w, p);
138 :
139 : const double xdata[n] = {
140 : -3.589357682910247,
141 : 1.680751059507811,
142 : -1.776064164658021,
143 : 0.200185666278645,
144 : -1.089057859981095,
145 : 0.607041589298709,
146 : -1.200653124267468,
147 : 0.979930642347896,
148 : 1.478726247208948,
149 : 3.423775565963109
150 1 : };
151 2 : Matrix x(n, 1, xdata);
152 :
153 2 : Matrix grad(n, 1);
154 : double f_star;
155 1 : double f_star_expected = -53.127646012575340;
156 1 : const double tol = 1e-8;
157 1 : _ASSERT(quadLoss->category().defines_conjugate());
158 1 : _ASSERT(quadLoss->category().defines_conjugate_grad());
159 1 : int status = quadLoss->callConj(x, f_star, grad);
160 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
161 1 : _ASSERT_NUM_EQ(f_star_expected, f_star, tol);
162 :
163 : const double grad_expected_data[n] = {
164 : -12.085379247046644,
165 : -10.818549081667255,
166 : 0.830633779220282,
167 : 7.304743665638888,
168 : 25.737716734483215,
169 : -6.495458207884025,
170 : 1.262586883127290,
171 : -0.434664030103367,
172 : -19.090193625170070,
173 : -3.666260687225234
174 1 : };
175 2 : Matrix grad_expected(n, 1, grad_expected_data);
176 :
177 1 : _ASSERT_EQ(grad_expected, grad);
178 :
179 : double f_star2;
180 1 : _ASSERT(quadLoss->category().defines_conjugate());
181 1 : status = quadLoss->callConj(x, f_star2);
182 1 : _ASSERT_EQ(ForBESUtils::STATUS_OK, status);
183 1 : _ASSERT_NUM_EQ(f_star, f_star2, tol);
184 :
185 2 : delete quadLoss;
186 1 : }
187 :
188 1 : void TestQuadraticLoss::testCategory() {
189 1 : Function * ql = new QuadraticLoss();
190 1 : std::list<FunctionOntologicalClass> list;
191 1 : list = ql->category().getSuperclasses();
192 1 : _ASSERT_EQ(static_cast<long unsigned int> (2), list.size());
193 1 : bool loss_found = false;
194 1 : bool quad_found = false;
195 3 : for (std::list<FunctionOntologicalClass>::iterator it = list.begin(); it != list.end(); ++it) {
196 2 : loss_found = loss_found || it->getName().compare("LossFunction") == 0;
197 2 : quad_found = quad_found || it->getName().compare("Quadratic") == 0;
198 : }
199 1 : _ASSERT(loss_found);
200 1 : _ASSERT(quad_found);
201 1 : _ASSERT(ql->category().defines_f());
202 1 : _ASSERT(ql->category().defines_grad());
203 1 : _ASSERT(ql->category().defines_conjugate());
204 1 : _ASSERT(ql->category().defines_conjugate_grad());
205 1 : _ASSERT_NOT(ql->category().defines_hessian());
206 1 : _ASSERT_NOT(ql->category().defines_hessian_conj());
207 1 : _ASSERT_NOT(ql->category().defines_prox());
208 1 : delete ql;
209 4 : }
|