1 /* A few tests for the maxmin library */
3 /* Copyright (c) 2007-2018. The SimGrid Team. All rights reserved. */
5 /* This program is free software; you can redistribute it and/or modify it
6 * under the terms of the license (GNU LGPL) which comes with this package. */
8 #include "simgrid/msg.h"
9 #include "src/kernel/lmm/maxmin.hpp"
10 #include "src/surf/surf_interface.hpp"
12 #include "xbt/module.h"
13 #include "xbt/sysdep.h"
17 XBT_LOG_NEW_DEFAULT_CATEGORY(surf_test, "Messages specific for surf example");
19 using namespace simgrid::kernel;
21 #define PRINT_VAR(var) XBT_DEBUG(#var " = %g", (var)->get_value())
22 #define SHOW_EXPR(expr) XBT_DEBUG(#expr " = %g",expr)
25 /* ==l1== L2 ==L3== */
28 enum method_t { MAXMIN, LAGRANGE_RENO, LAGRANGE_VEGAS };
30 static lmm::System* new_system(method_t method, bool update)
34 return lmm::make_new_maxmin_system(update);
37 return lmm::make_new_lagrange_system(update);
39 xbt_die("Invalid method");
43 static double dichotomy(double func(double), double min, double max, double min_error)
45 double overall_error = 2 * min_error;
47 double min_func = func(min);
48 double max_func = func(max);
50 if ((min_func > 0 && max_func > 0))
52 if ((min_func < 0 && max_func < 0))
54 if ((min_func > 0 && max_func < 0))
59 while (overall_error > min_error) {
60 SHOW_EXPR(overall_error);
61 xbt_assert(min_func <= 0 || max_func <= 0);
62 xbt_assert(min_func >= 0 || max_func >= 0);
63 xbt_assert(min_func <= 0 || max_func >= 0);
70 double middle = (max + min) / 2.0;
71 if (fabs(min - middle) < 1e-12 || fabs(max - middle) < 1e-12) {
74 double middle_func = func(middle);
76 SHOW_EXPR(middle_func);
78 if (middle_func < 0) {
80 min_func = middle_func;
81 overall_error = max_func - middle_func;
82 } else if (middle_func > 0) {
84 max_func = middle_func;
85 overall_error = middle_func - min_func;
90 return ((min + max) / 2.0);
95 static double diff_lagrange_test_1(double x)
97 return -(3 / (1 + 3 * x * x / 2) - 3 / (2 * (3 * (a_test_1 - x) * (a_test_1 - x) / 2 + 1)) +
98 3 / (2 * (3 * (b_test_1 - a_test_1 + x) * (b_test_1 - a_test_1 + x) / 2 + 1)));
101 static void test1(method_t method)
106 if (method == LAGRANGE_VEGAS)
107 lmm::Lagrange::set_default_protocol_function(lmm::func_vegas_f, lmm::func_vegas_fp, lmm::func_vegas_fpi);
108 else if (method == LAGRANGE_RENO)
109 lmm::Lagrange::set_default_protocol_function(lmm::func_reno_f, lmm::func_reno_fp, lmm::func_reno_fpi);
111 lmm::System* Sys = new_system(method, true);
112 lmm::Constraint* L1 = Sys->constraint_new(nullptr, a);
113 lmm::Constraint* L2 = Sys->constraint_new(nullptr, b);
114 lmm::Constraint* L3 = Sys->constraint_new(nullptr, a);
116 lmm::Variable* R_1_2_3 = Sys->variable_new(nullptr, 1.0, -1.0, 3);
117 lmm::Variable* R_1 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
118 lmm::Variable* R_2 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
119 lmm::Variable* R_3 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
121 Sys->update_variable_weight(R_1_2_3, 1.0);
122 Sys->update_variable_weight(R_1, 1.0);
123 Sys->update_variable_weight(R_2, 1.0);
124 Sys->update_variable_weight(R_3, 1.0);
126 Sys->expand(L1, R_1_2_3, 1.0);
127 Sys->expand(L2, R_1_2_3, 1.0);
128 Sys->expand(L3, R_1_2_3, 1.0);
130 Sys->expand(L1, R_1, 1.0);
131 Sys->expand(L2, R_2, 1.0);
132 Sys->expand(L3, R_3, 1.0);
134 if (method == MAXMIN) {
138 if (method == LAGRANGE_VEGAS) {
139 x = 3 * a / 4 - 3 * b / 8 + sqrt(9 * b * b + 4 * a * a - 4 * a * b) / 8;
140 /* Computed with mupad and D_f=1.0 */
147 } else if (method == LAGRANGE_RENO) {
150 x = dichotomy(diff_lagrange_test_1, 0, a, 1e-13);
157 xbt_die( "Invalid method");
162 double max_deviation = 0.0;
163 max_deviation = std::max(max_deviation, fabs(R_1->get_value() - x));
164 max_deviation = std::max(max_deviation, fabs(R_3->get_value() - x));
165 max_deviation = std::max(max_deviation, fabs(R_2->get_value() - (b - a + x)));
166 max_deviation = std::max(max_deviation, fabs(R_1_2_3->get_value() - (a - x)));
168 if (max_deviation > 0.00001) { // Legacy value used in lagrange.c
169 XBT_WARN("Max Deviation from optimal solution : %g", max_deviation);
170 XBT_WARN("Found x = %1.20f", x);
171 XBT_WARN("Deviation from optimal solution (R_1 = %g): %1.20f", x, R_1->get_value() - x);
172 XBT_WARN("Deviation from optimal solution (R_2 = %g): %1.20f", b - a + x, R_2->get_value() - (b - a + x));
173 XBT_WARN("Deviation from optimal solution (R_3 = %g): %1.20f", x, R_3->get_value() - x);
174 XBT_WARN("Deviation from optimal solution (R_1_2_3 = %g): %1.20f", a - x, R_1_2_3->get_value() - (a - x));
183 Sys->variable_free(R_1_2_3);
184 Sys->variable_free(R_1);
185 Sys->variable_free(R_2);
186 Sys->variable_free(R_3);
190 static void test2(method_t method)
192 if (method == LAGRANGE_VEGAS)
193 lmm::Lagrange::set_default_protocol_function(lmm::func_vegas_f, lmm::func_vegas_fp, lmm::func_vegas_fpi);
194 if (method == LAGRANGE_RENO)
195 lmm::Lagrange::set_default_protocol_function(lmm::func_reno_f, lmm::func_reno_fp, lmm::func_reno_fpi);
197 lmm::System* Sys = new_system(method, true);
199 lmm::Constraint* CPU1 = Sys->constraint_new(nullptr, 200.0);
200 lmm::Constraint* CPU2 = Sys->constraint_new(nullptr, 100.0);
202 lmm::Variable* T1 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
203 lmm::Variable* T2 = Sys->variable_new(nullptr, 1.0, -1.0, 1);
205 Sys->update_variable_weight(T1, 1.0);
206 Sys->update_variable_weight(T2, 1.0);
208 Sys->expand(CPU1, T1, 1.0);
209 Sys->expand(CPU2, T2, 1.0);
216 Sys->variable_free(T1);
217 Sys->variable_free(T2);
221 static void test3(method_t method)
226 double** A = new double*[links + 5];
227 /* array to add the constraints of fictitious variables */
228 double B[15] = { 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 1, 1, 1, 1, 1 };
230 for (int i = 0; i < links + 5; i++) {
231 A[i] = new double[flows + 5];
232 for (int j = 0; j < flows + 5; j++) {
235 if (i >= links || j >= flows) {
241 /*matrix that store the constraints/topology */
242 A[0][1] = A[0][7] = 1.0;
243 A[1][1] = A[1][7] = A[1][8] = 1.0;
244 A[2][1] = A[2][8] = 1.0;
246 A[4][0] = A[4][3] = A[4][9] = 1.0;
247 A[5][0] = A[5][3] = A[5][4] = A[5][9] = 1.0;
248 A[6][0] = A[6][4] = A[6][9] = A[6][10] = 1.0;
249 A[7][2] = A[7][4] = A[7][6] = A[7][9] = A[7][10] = 1.0;
250 A[8][2] = A[8][10] = 1.0;
251 A[9][5] = A[9][6] = A[9][9] = 1.0;
258 if (method == LAGRANGE_VEGAS)
259 lmm::Lagrange::set_default_protocol_function(lmm::func_vegas_f, lmm::func_vegas_fp, lmm::func_vegas_fpi);
260 if (method == LAGRANGE_RENO)
261 lmm::Lagrange::set_default_protocol_function(lmm::func_reno_f, lmm::func_reno_fp, lmm::func_reno_fpi);
263 lmm::System* Sys = new_system(method, true);
265 /* Creates the constraints */
266 lmm::Constraint** tmp_cnst = new lmm::Constraint*[15];
267 for (int i = 0; i < 15; i++)
268 tmp_cnst[i] = Sys->constraint_new(nullptr, B[i]);
270 /* Creates the variables */
271 lmm::Variable** tmp_var = new lmm::Variable*[16];
272 for (int j = 0; j < 16; j++) {
273 tmp_var[j] = Sys->variable_new(nullptr, 1.0, -1.0, 15);
274 Sys->update_variable_weight(tmp_var[j], 1.0);
277 /* Link constraints and variables */
278 for (int i = 0; i < 15; i++)
279 for (int j = 0; j < 16; j++)
281 Sys->expand(tmp_cnst[i], tmp_var[j], 1.0);
285 for (int j = 0; j < 16; j++)
286 PRINT_VAR(tmp_var[j]);
288 for (int j = 0; j < 16; j++)
289 Sys->variable_free(tmp_var[j]);
293 for (int i = 0; i < links + 5; i++)
298 int main(int argc, char** argv)
300 MSG_init(&argc, argv);
301 XBT_INFO("***** Test 1 (Max-Min)");
303 XBT_INFO("***** Test 1 (Lagrange - Vegas)");
304 test1(LAGRANGE_VEGAS);
305 XBT_INFO("***** Test 1 (Lagrange - Reno)");
306 test1(LAGRANGE_RENO);
308 XBT_INFO("***** Test 2 (Max-Min)");
310 XBT_INFO("***** Test 2 (Lagrange - Vegas)");
311 test2(LAGRANGE_VEGAS);
312 XBT_INFO("***** Test 2 (Lagrange - Reno)");
313 test2(LAGRANGE_RENO);
315 XBT_INFO("***** Test 3 (Max-Min)");
317 XBT_INFO("***** Test 3 (Lagrange - Vegas)");
318 test3(LAGRANGE_VEGAS);
319 XBT_INFO("***** Test 3 (Lagrange - Reno)");
320 test3(LAGRANGE_RENO);