1 // -*- C++ -*-
2 /**
3 * @brief The test file of class SQP for standard methods
4 *
5 * Copyright 2005-2021 Airbus-EDF-IMACS-ONERA-Phimeca
6 *
7 * This library 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 * This library 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 this library. If not, see <http://www.gnu.org/licenses/>.
19 *
20 */
21 #include "openturns/OT.hxx"
22 #include "openturns/OTtestcode.hxx"
23
24 using namespace OT;
25 using namespace OT::Test;
26
printPoint(const Point & point,const UnsignedInteger digits)27 inline String printPoint(const Point & point, const UnsignedInteger digits)
28 {
29 OSS oss;
30 oss << "[";
31 Scalar eps = pow(0.1, 1.0 * digits);
32 for (UnsignedInteger i = 0; i < point.getDimension(); i++)
33 {
34 oss << std::fixed << std::setprecision(digits) << (i == 0 ? "" : ",") << Bulk<double>(((std::abs(point[i]) < eps) ? std::abs(point[i]) : point[i]));
35 }
36 oss << "]";
37 return oss;
38 }
39
main(int,char * [])40 int main(int, char *[])
41 {
42 TESTPREAMBLE;
43 OStream fullprint(std::cout);
44
45 try
46 {
47
48 // Test function operator ()
49 Description input(4);
50 input[0] = "x1";
51 input[1] = "x2";
52 input[2] = "x3";
53 input[3] = "x4";
54 SymbolicFunction levelFunction(input, Description(1, "x1+2*x2-3*x3+4*x4"));
55 // Add a finite difference gradient to the function,
56 NonCenteredFiniteDifferenceGradient myGradient(1e-7, levelFunction.getEvaluation());
57 /** Substitute the gradient */
58 levelFunction.setGradient(new NonCenteredFiniteDifferenceGradient(myGradient));
59 Point startingPoint(4, 0.0);
60 SQP mySQPAlgorithm(NearestPointProblem(levelFunction, 3.0));
61 mySQPAlgorithm.setStartingPoint(startingPoint);
62 fullprint << "mySQPAlgorithm=" << mySQPAlgorithm << std::endl;
63 mySQPAlgorithm.run();
64 fullprint << "result=" << printPoint(mySQPAlgorithm.getResult().getOptimalPoint(), 4) << std::endl;
65 fullprint << "multipliers=" << printPoint(mySQPAlgorithm.getResult().computeLagrangeMultipliers(), 4) << std::endl;
66 }
67 catch (TestFailed & ex)
68 {
69 std::cerr << ex << std::endl;
70 return ExitCode::Error;
71 }
72
73 try
74 {
75 Description input(4);
76 input[0] = "x1";
77 input[1] = "x2";
78 input[2] = "x3";
79 input[3] = "x4";
80 SymbolicFunction levelFunction(input, Description(1, "x1*cos(x1)+2*x2*x3-3*x3+4*x3*x4"));
81 // Add a finite difference gradient to the function, as SQP algorithm
82 // needs it
83 CenteredFiniteDifferenceGradient myGradient(1e-7, levelFunction.getEvaluation());
84 /** Substitute the gradient */
85 levelFunction.setGradient(new CenteredFiniteDifferenceGradient(myGradient));
86
87 // Add a finite difference hessian to the function, as SQP algorithm
88 // needs it
89 CenteredFiniteDifferenceHessian myHessian(1e-3, levelFunction.getEvaluation());
90 /** Substitute the hessian */
91 levelFunction.setHessian(new CenteredFiniteDifferenceHessian(myHessian));
92 Point startingPoint(4, 0.0);
93 SQP mySQPAlgorithm(NearestPointProblem(levelFunction, 3.0));
94 mySQPAlgorithm.setStartingPoint(startingPoint);
95 fullprint << "mySQPAlgorithm=" << mySQPAlgorithm << std::endl;
96 mySQPAlgorithm.run();
97 OptimizationResult result(mySQPAlgorithm.getResult());
98 fullprint << "result = " << printPoint(result.getOptimalPoint(), 4) << std::endl;
99 fullprint << "multipliers = " << printPoint(result.computeLagrangeMultipliers(), 4) << std::endl;
100 Graph convergence(result.drawErrorHistory());
101 fullprint << "evaluation calls number=" << levelFunction.getEvaluationCallsNumber() << std::endl;
102 fullprint << "gradient calls number=" << levelFunction.getGradientCallsNumber() << std::endl;
103 fullprint << "hessian calls number=" << levelFunction.getHessianCallsNumber() << std::endl;
104 }
105 catch (TestFailed & ex)
106 {
107 std::cerr << ex << std::endl;
108 return ExitCode::Error;
109 }
110
111 return ExitCode::Success;
112 }
113