1 // -*- C++ -*-
2 /**
3 * @brief NearestPointProblem allows to describe an optimization problem
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 <cstdlib>
22
23 #include "openturns/NearestPointProblem.hxx"
24 #include "openturns/ResourceMap.hxx"
25 #include "openturns/PersistentObjectFactory.hxx"
26 #include "openturns/LinearFunction.hxx"
27 #include "openturns/QuadraticFunction.hxx"
28
29 BEGIN_NAMESPACE_OPENTURNS
30
31 CLASSNAMEINIT(NearestPointProblem)
32
33 static const Factory<NearestPointProblem> Factory_NearestPointProblem;
34
35 /* Default constructor */
NearestPointProblem()36 NearestPointProblem::NearestPointProblem()
37 : OptimizationProblemImplementation()
38 , levelValue_(0.0)
39 {
40 // Nothing to do
41 }
42
43 /* Constructor for nearest point problem */
NearestPointProblem(const Function & levelFunction,Scalar levelValue)44 NearestPointProblem::NearestPointProblem(const Function & levelFunction,
45 Scalar levelValue)
46 : OptimizationProblemImplementation()
47 , levelValue_(levelValue)
48 {
49 setLevelFunction(levelFunction);
50 }
51
52 /* Virtual constructor */
clone() const53 NearestPointProblem * NearestPointProblem::clone() const
54 {
55 return new NearestPointProblem(*this);
56 }
57
58
59 /* Level function accessor */
getLevelFunction() const60 Function NearestPointProblem::getLevelFunction() const
61 {
62 return levelFunction_;
63 }
64
setLevelFunction(const Function & levelFunction)65 void NearestPointProblem::setLevelFunction(const Function & levelFunction)
66 {
67 if (levelFunction.getOutputDimension() != 1) throw InvalidArgumentException(HERE) << "Error: level function has an output dimension=" << levelFunction.getOutputDimension() << " but only dimension 1 is supported.";
68
69 levelFunction_ = levelFunction;
70 dimension_ = levelFunction_.getInputDimension();
71 // Update objective function
72 const Point center(dimension_);
73 const Point constant(1);
74 const Matrix linear(dimension_, 1);
75 const IdentityMatrix identity(dimension_);
76 const SymmetricTensor quadratic(dimension_, 1, *(identity.getImplementation().get()));
77 objective_ = QuadraticFunction(center, constant, linear, quadratic);
78 setNearestPointConstraints();
79 setVariablesType(Indices(dimension_, CONTINUOUS));
80 }
81
hasLevelFunction() const82 Bool NearestPointProblem::hasLevelFunction() const
83 {
84 return true;
85 }
86
87 /* Level value accessor */
getLevelValue() const88 Scalar NearestPointProblem::getLevelValue() const
89 {
90 return levelValue_;
91 }
92
setLevelValue(Scalar levelValue)93 void NearestPointProblem::setLevelValue(Scalar levelValue)
94 {
95 levelValue_ = levelValue;
96 if (levelFunction_.getEvaluation().getImplementation()->isActualImplementation()) setNearestPointConstraints();
97 }
98
setNearestPointConstraints()99 void NearestPointProblem::setNearestPointConstraints()
100 {
101 const Point center(dimension_);
102 const Matrix linear(dimension_, 1);
103 LinearFunction constantFunction(center, Point(1, levelValue_), linear.transpose());
104 Function equalityConstraint(levelFunction_);
105 equalityConstraint_ = equalityConstraint.operator - (constantFunction);
106 inequalityConstraint_ = Function();
107 }
108
clearLevelFunction()109 void NearestPointProblem::clearLevelFunction()
110 {
111 if (levelFunction_.getEvaluation().getImplementation()->isActualImplementation())
112 {
113 LOGWARN(OSS() << "Clearing level function");
114 levelFunction_ = Function();
115 }
116 levelValue_ = 0.0;
117 }
118
119
120 /* String converter */
__repr__() const121 String NearestPointProblem::__repr__() const
122 {
123 OSS oss;
124 oss << "class=" << NearestPointProblem::GetClassName();
125 oss << " level function=" << levelFunction_.__repr__()
126 << " level value=" << levelValue_
127 << " dimension=" << dimension_;
128 return oss;
129 }
130
131 /* Method save() stores the object through the StorageManager */
save(Advocate & adv) const132 void NearestPointProblem::save(Advocate & adv) const
133 {
134 OptimizationProblemImplementation::save(adv);
135 adv.saveAttribute( "levelFunction_", levelFunction_ );
136 adv.saveAttribute( "levelValue_", levelValue_ );
137 }
138
139 /* Method load() reloads the object from the StorageManager */
load(Advocate & adv)140 void NearestPointProblem::load(Advocate & adv)
141 {
142 OptimizationProblemImplementation::load(adv);
143 adv.loadAttribute( "levelFunction_", levelFunction_ );
144 adv.loadAttribute( "levelValue_", levelValue_ );
145 }
146
147 END_NAMESPACE_OPENTURNS
148