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