Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / sccomp / qa / unit / SwarmSolverTest.cxx
blob6403de068a9157402dde7f329a19d5e7db5baf1d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <sal/config.h>
12 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
13 #include <com/sun/star/frame/Desktop.hpp>
14 #include <com/sun/star/lang/XServiceInfo.hpp>
15 #include <com/sun/star/sheet/XSolver.hpp>
16 #include <com/sun/star/sheet/XSolverDescription.hpp>
17 #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
18 #include <com/sun/star/sheet/XSpreadsheet.hpp>
19 #include <com/sun/star/text/XTextRange.hpp>
20 #include <com/sun/star/beans/XPropertySet.hpp>
22 #include <test/calc_unoapi_test.hxx>
24 #include <address.hxx>
26 using namespace css;
28 namespace
30 class SwarmSolverTest : public CalcUnoApiTest
32 uno::Reference<lang::XComponent> mxComponent;
33 void testUnconstrained();
34 void testVariableBounded();
35 void testVariableConstrained();
36 void testTwoVariables();
37 void testMultipleVariables();
39 public:
40 SwarmSolverTest()
41 : CalcUnoApiTest("sccomp/qa/unit/data")
45 virtual void tearDown() override;
47 CPPUNIT_TEST_SUITE(SwarmSolverTest);
48 CPPUNIT_TEST(testUnconstrained);
49 CPPUNIT_TEST(testVariableBounded);
50 CPPUNIT_TEST(testVariableConstrained);
51 CPPUNIT_TEST(testMultipleVariables);
52 CPPUNIT_TEST(testTwoVariables);
53 CPPUNIT_TEST_SUITE_END();
56 void SwarmSolverTest::tearDown()
58 if (mxComponent.is())
59 closeDocument(mxComponent);
62 void SwarmSolverTest::testUnconstrained()
64 CPPUNIT_ASSERT(!mxComponent.is());
66 OUString aFileURL;
67 createFileURL("Simple.ods", aFileURL);
68 mxComponent = loadFromDesktop(aFileURL);
70 CPPUNIT_ASSERT_MESSAGE("Component not loaded", mxComponent.is());
72 uno::Reference<sheet::XSpreadsheetDocument> xDocument(mxComponent, uno::UNO_QUERY_THROW);
73 uno::Reference<container::XIndexAccess> xIndex(xDocument->getSheets(), uno::UNO_QUERY_THROW);
74 uno::Reference<sheet::XSpreadsheet> xSheet(xIndex->getByIndex(0), uno::UNO_QUERY_THROW);
76 uno::Reference<table::XCell> xCell;
78 uno::Reference<sheet::XSolver> xSolver;
79 OUString sSolverName("com.sun.star.comp.Calc.SwarmSolver");
81 xSolver.set(m_xContext->getServiceManager()->createInstanceWithContext(sSolverName, m_xContext),
82 uno::UNO_QUERY_THROW);
84 table::CellAddress aObjective(0, 1, 1);
86 // "changing cells" - unknown variables
87 uno::Sequence<table::CellAddress> aVariables(1);
88 aVariables[0] = table::CellAddress(0, 1, 0);
90 // constraints
91 uno::Sequence<sheet::SolverConstraint> aConstraints;
93 // initialize solver
94 xSolver->setDocument(xDocument);
95 xSolver->setObjective(aObjective);
96 xSolver->setVariables(aVariables);
97 xSolver->setConstraints(aConstraints);
98 xSolver->setMaximize(false);
100 // test results
101 xSolver->solve();
102 CPPUNIT_ASSERT(xSolver->getSuccess());
103 uno::Sequence<double> aSolution = xSolver->getSolution();
105 CPPUNIT_ASSERT_EQUAL(aSolution.getLength(), aVariables.getLength());
106 // It happens that the unconstrained test does not find a solution in the
107 // timeframe or number of generations it has available as the search space is
108 // too big and the values might not converge to solution. So for now just run
109 // the test so we know for sure the algorithm is guaranteed to finish
110 // and doesn't cause any seg faults.
111 //CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, aSolution[0], .9);
114 void SwarmSolverTest::testVariableBounded()
116 CPPUNIT_ASSERT(!mxComponent.is());
118 OUString aFileURL;
119 createFileURL("Simple.ods", aFileURL);
120 mxComponent = loadFromDesktop(aFileURL);
122 CPPUNIT_ASSERT_MESSAGE("Component not loaded", mxComponent.is());
124 uno::Reference<sheet::XSpreadsheetDocument> xDocument(mxComponent, uno::UNO_QUERY_THROW);
125 uno::Reference<container::XIndexAccess> xIndex(xDocument->getSheets(), uno::UNO_QUERY_THROW);
126 uno::Reference<sheet::XSpreadsheet> xSheet(xIndex->getByIndex(0), uno::UNO_QUERY_THROW);
128 uno::Reference<table::XCell> xCell;
130 uno::Reference<sheet::XSolver> xSolver;
131 OUString sSolverName("com.sun.star.comp.Calc.SwarmSolver");
133 xSolver.set(m_xContext->getServiceManager()->createInstanceWithContext(sSolverName, m_xContext),
134 uno::UNO_QUERY_THROW);
136 table::CellAddress aObjective(0, 1, 1);
138 // "changing cells" - unknown variables
139 uno::Sequence<table::CellAddress> aVariables(1);
140 aVariables[0] = table::CellAddress(0, 1, 0);
142 // constraints
143 uno::Sequence<sheet::SolverConstraint> aConstraints(2);
144 aConstraints[0].Left = table::CellAddress(0, 1, 0);
145 aConstraints[0].Operator = sheet::SolverConstraintOperator_LESS_EQUAL;
146 aConstraints[0].Right <<= 100.0;
148 aConstraints[1].Left = table::CellAddress(0, 1, 0);
149 aConstraints[1].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
150 aConstraints[1].Right <<= -100.0;
152 // initialize solver
153 xSolver->setDocument(xDocument);
154 xSolver->setObjective(aObjective);
155 xSolver->setVariables(aVariables);
156 xSolver->setConstraints(aConstraints);
157 xSolver->setMaximize(false);
159 // test results
160 xSolver->solve();
161 CPPUNIT_ASSERT(xSolver->getSuccess());
162 uno::Sequence<double> aSolution = xSolver->getSolution();
164 CPPUNIT_ASSERT_EQUAL(aSolution.getLength(), aVariables.getLength());
165 CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, aSolution[0], 1E-5);
168 void SwarmSolverTest::testVariableConstrained()
170 CPPUNIT_ASSERT(!mxComponent.is());
172 OUString aFileURL;
173 createFileURL("Simple.ods", aFileURL);
174 mxComponent = loadFromDesktop(aFileURL);
176 CPPUNIT_ASSERT_MESSAGE("Component not loaded", mxComponent.is());
178 uno::Reference<sheet::XSpreadsheetDocument> xDocument(mxComponent, uno::UNO_QUERY_THROW);
179 uno::Reference<container::XIndexAccess> xIndex(xDocument->getSheets(), uno::UNO_QUERY_THROW);
180 uno::Reference<sheet::XSpreadsheet> xSheet(xIndex->getByIndex(0), uno::UNO_QUERY_THROW);
182 uno::Reference<table::XCell> xCell;
184 uno::Reference<sheet::XSolver> xSolver;
185 OUString sSolverName("com.sun.star.comp.Calc.SwarmSolver");
187 xSolver.set(m_xContext->getServiceManager()->createInstanceWithContext(sSolverName, m_xContext),
188 uno::UNO_QUERY_THROW);
190 table::CellAddress aObjective(0, 1, 1);
192 // "changing cells" - unknown variables
193 uno::Sequence<table::CellAddress> aVariables(1);
194 aVariables[0] = table::CellAddress(0, 1, 0);
196 // constraints
197 uno::Sequence<sheet::SolverConstraint> aConstraints(3);
198 aConstraints[0].Left = table::CellAddress(0, 1, 0);
199 aConstraints[0].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
200 aConstraints[0].Right <<= -50000.0;
202 aConstraints[1].Left = table::CellAddress(0, 1, 0);
203 aConstraints[1].Operator = sheet::SolverConstraintOperator_LESS_EQUAL;
204 aConstraints[1].Right <<= 0.0;
206 aConstraints[2].Left = table::CellAddress(0, 1, 1);
207 aConstraints[2].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
208 aConstraints[2].Right <<= 10.0;
210 // initialize solver
211 xSolver->setDocument(xDocument);
212 xSolver->setObjective(aObjective);
213 xSolver->setVariables(aVariables);
214 xSolver->setConstraints(aConstraints);
215 xSolver->setMaximize(false);
217 // test results
218 xSolver->solve();
219 CPPUNIT_ASSERT(xSolver->getSuccess());
220 uno::Sequence<double> aSolution = xSolver->getSolution();
222 CPPUNIT_ASSERT_EQUAL(aSolution.getLength(), aVariables.getLength());
223 CPPUNIT_ASSERT_DOUBLES_EQUAL(-0.741657, aSolution[0], 1E-5);
226 void SwarmSolverTest::testTwoVariables()
228 CPPUNIT_ASSERT(!mxComponent.is());
230 OUString aFileURL;
231 createFileURL("TwoVariables.ods", aFileURL);
232 mxComponent = loadFromDesktop(aFileURL);
234 CPPUNIT_ASSERT_MESSAGE("Component not loaded", mxComponent.is());
236 uno::Reference<sheet::XSpreadsheetDocument> xDocument(mxComponent, uno::UNO_QUERY_THROW);
237 uno::Reference<container::XIndexAccess> xIndex(xDocument->getSheets(), uno::UNO_QUERY_THROW);
238 uno::Reference<sheet::XSpreadsheet> xSheet(xIndex->getByIndex(0), uno::UNO_QUERY_THROW);
240 uno::Reference<table::XCell> xCell;
242 uno::Reference<sheet::XSolver> xSolver;
243 OUString sSolverName("com.sun.star.comp.Calc.SwarmSolver");
245 xSolver.set(m_xContext->getServiceManager()->createInstanceWithContext(sSolverName, m_xContext),
246 uno::UNO_QUERY_THROW);
248 table::CellAddress aObjective(0, 1, 5);
250 // "changing cells" - unknown variables
251 uno::Sequence<table::CellAddress> aVariables(2);
252 aVariables[0] = table::CellAddress(0, 1, 2);
253 aVariables[1] = table::CellAddress(0, 1, 3);
255 // constraints
256 uno::Sequence<sheet::SolverConstraint> aConstraints(4);
258 aConstraints[0].Left = table::CellAddress(0, 1, 2);
259 aConstraints[0].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
260 aConstraints[0].Right <<= -100.0;
262 aConstraints[1].Left = table::CellAddress(0, 1, 3);
263 aConstraints[1].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
264 aConstraints[1].Right <<= -100.0;
266 aConstraints[2].Left = table::CellAddress(0, 1, 2);
267 aConstraints[2].Operator = sheet::SolverConstraintOperator_LESS_EQUAL;
268 aConstraints[2].Right <<= 100.0;
270 aConstraints[3].Left = table::CellAddress(0, 1, 3);
271 aConstraints[3].Operator = sheet::SolverConstraintOperator_LESS_EQUAL;
272 aConstraints[3].Right <<= 100.0;
274 // initialize solver
275 xSolver->setDocument(xDocument);
276 xSolver->setObjective(aObjective);
277 xSolver->setVariables(aVariables);
278 xSolver->setConstraints(aConstraints);
279 xSolver->setMaximize(true);
281 // test results
282 xSolver->solve();
283 CPPUNIT_ASSERT(xSolver->getSuccess());
284 uno::Sequence<double> aSolution = xSolver->getSolution();
286 CPPUNIT_ASSERT_EQUAL(aVariables.getLength(), aSolution.getLength());
287 CPPUNIT_ASSERT_DOUBLES_EQUAL(0.666667, aSolution[0], 1E-5);
288 CPPUNIT_ASSERT_DOUBLES_EQUAL(-1.666667, aSolution[1], 1E-5);
291 void SwarmSolverTest::testMultipleVariables()
293 CPPUNIT_ASSERT(!mxComponent.is());
295 OUString aFileURL;
296 createFileURL("MultiVariable.ods", aFileURL);
297 mxComponent = loadFromDesktop(aFileURL);
299 CPPUNIT_ASSERT_MESSAGE("Component not loaded", mxComponent.is());
301 uno::Reference<sheet::XSpreadsheetDocument> xDocument(mxComponent, uno::UNO_QUERY_THROW);
302 uno::Reference<container::XIndexAccess> xIndex(xDocument->getSheets(), uno::UNO_QUERY_THROW);
303 uno::Reference<sheet::XSpreadsheet> xSheet(xIndex->getByIndex(0), uno::UNO_QUERY_THROW);
305 uno::Reference<table::XCell> xCell;
307 uno::Reference<sheet::XSolver> xSolver;
308 OUString sSolverName("com.sun.star.comp.Calc.SwarmSolver");
310 xSolver.set(m_xContext->getServiceManager()->createInstanceWithContext(sSolverName, m_xContext),
311 uno::UNO_QUERY_THROW);
313 uno::Reference<beans::XPropertySet> xPropSet(xSolver, uno::UNO_QUERY_THROW);
314 xPropSet->setPropertyValue("Integer", uno::makeAny(true));
316 table::CellAddress aObjective(0, 5, 7);
318 // "changing cells" - unknown variables
319 uno::Sequence<table::CellAddress> aVariables(4);
320 aVariables[0] = table::CellAddress(0, 6, 1);
321 aVariables[1] = table::CellAddress(0, 6, 2);
322 aVariables[2] = table::CellAddress(0, 6, 3);
323 aVariables[3] = table::CellAddress(0, 6, 4);
325 // constraints
326 uno::Sequence<sheet::SolverConstraint> aConstraints(12);
328 aConstraints[0].Left = table::CellAddress(0, 1, 5);
329 aConstraints[0].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
330 aConstraints[0].Right <<= table::CellAddress(0, 1, 6);
332 aConstraints[1].Left = table::CellAddress(0, 2, 5);
333 aConstraints[1].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
334 aConstraints[1].Right <<= table::CellAddress(0, 2, 6);
336 aConstraints[2].Left = table::CellAddress(0, 3, 5);
337 aConstraints[2].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
338 aConstraints[2].Right <<= table::CellAddress(0, 3, 6);
340 aConstraints[3].Left = table::CellAddress(0, 4, 5);
341 aConstraints[3].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
342 aConstraints[3].Right <<= table::CellAddress(0, 4, 6);
344 aConstraints[4].Left = table::CellAddress(0, 6, 1);
345 aConstraints[4].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
346 aConstraints[4].Right <<= 0.0;
348 aConstraints[5].Left = table::CellAddress(0, 6, 2);
349 aConstraints[5].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
350 aConstraints[5].Right <<= 0.0;
352 aConstraints[6].Left = table::CellAddress(0, 6, 3);
353 aConstraints[6].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
354 aConstraints[6].Right <<= 0.0;
356 aConstraints[7].Left = table::CellAddress(0, 6, 4);
357 aConstraints[7].Operator = sheet::SolverConstraintOperator_GREATER_EQUAL;
358 aConstraints[7].Right <<= 0.0;
360 aConstraints[8].Left = table::CellAddress(0, 6, 1);
361 aConstraints[8].Operator = sheet::SolverConstraintOperator_LESS_EQUAL;
362 aConstraints[8].Right <<= 10000.0;
364 aConstraints[9].Left = table::CellAddress(0, 6, 2);
365 aConstraints[9].Operator = sheet::SolverConstraintOperator_LESS_EQUAL;
366 aConstraints[9].Right <<= 10000.0;
368 aConstraints[10].Left = table::CellAddress(0, 6, 3);
369 aConstraints[10].Operator = sheet::SolverConstraintOperator_LESS_EQUAL;
370 aConstraints[10].Right <<= 10000.0;
372 aConstraints[11].Left = table::CellAddress(0, 6, 4);
373 aConstraints[11].Operator = sheet::SolverConstraintOperator_LESS_EQUAL;
374 aConstraints[11].Right <<= 10000.0;
376 // initialize solver
377 xSolver->setDocument(xDocument);
378 xSolver->setObjective(aObjective);
379 xSolver->setVariables(aVariables);
380 xSolver->setConstraints(aConstraints);
381 xSolver->setMaximize(false);
383 // test results
384 xSolver->solve();
385 CPPUNIT_ASSERT(xSolver->getSuccess());
386 uno::Sequence<double> aSolution = xSolver->getSolution();
388 CPPUNIT_ASSERT_EQUAL(aVariables.getLength(), aSolution.getLength());
389 #if 0
390 // Disable for now, needs algorithm stability improvements
391 CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, aSolution[0], 1E-5);
392 CPPUNIT_ASSERT_DOUBLES_EQUAL(3.0, aSolution[1], 1E-5);
393 CPPUNIT_ASSERT_DOUBLES_EQUAL(1.0, aSolution[2], 1E-5);
394 CPPUNIT_ASSERT_DOUBLES_EQUAL(0.0, aSolution[3], 1E-5);
395 #endif
398 CPPUNIT_TEST_SUITE_REGISTRATION(SwarmSolverTest);
401 CPPUNIT_PLUGIN_IMPLEMENT();
403 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */