// -*- C++ -*- /** * @brief NearestPointProblem allows to describe an optimization problem * * Copyright 2005-2021 Airbus-EDF-IMACS-ONERA-Phimeca * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . * */ #include #include "openturns/NearestPointProblem.hxx" #include "openturns/ResourceMap.hxx" #include "openturns/PersistentObjectFactory.hxx" #include "openturns/LinearFunction.hxx" #include "openturns/QuadraticFunction.hxx" BEGIN_NAMESPACE_OPENTURNS CLASSNAMEINIT(NearestPointProblem) static const Factory Factory_NearestPointProblem; /* Default constructor */ NearestPointProblem::NearestPointProblem() : OptimizationProblemImplementation() , levelValue_(0.0) { // Nothing to do } /* Constructor for nearest point problem */ NearestPointProblem::NearestPointProblem(const Function & levelFunction, Scalar levelValue) : OptimizationProblemImplementation() , levelValue_(levelValue) { setLevelFunction(levelFunction); } /* Virtual constructor */ NearestPointProblem * NearestPointProblem::clone() const { return new NearestPointProblem(*this); } /* Level function accessor */ Function NearestPointProblem::getLevelFunction() const { return levelFunction_; } void NearestPointProblem::setLevelFunction(const Function & levelFunction) { if (levelFunction.getOutputDimension() != 1) throw InvalidArgumentException(HERE) << "Error: level function has an output dimension=" << levelFunction.getOutputDimension() << " but only dimension 1 is supported."; levelFunction_ = levelFunction; dimension_ = levelFunction_.getInputDimension(); // Update objective function const Point center(dimension_); const Point constant(1); const Matrix linear(dimension_, 1); const IdentityMatrix identity(dimension_); const SymmetricTensor quadratic(dimension_, 1, *(identity.getImplementation().get())); objective_ = QuadraticFunction(center, constant, linear, quadratic); setNearestPointConstraints(); setVariablesType(Indices(dimension_, CONTINUOUS)); } Bool NearestPointProblem::hasLevelFunction() const { return true; } /* Level value accessor */ Scalar NearestPointProblem::getLevelValue() const { return levelValue_; } void NearestPointProblem::setLevelValue(Scalar levelValue) { levelValue_ = levelValue; if (levelFunction_.getEvaluation().getImplementation()->isActualImplementation()) setNearestPointConstraints(); } void NearestPointProblem::setNearestPointConstraints() { const Point center(dimension_); const Matrix linear(dimension_, 1); LinearFunction constantFunction(center, Point(1, levelValue_), linear.transpose()); Function equalityConstraint(levelFunction_); equalityConstraint_ = equalityConstraint.operator - (constantFunction); inequalityConstraint_ = Function(); } void NearestPointProblem::clearLevelFunction() { if (levelFunction_.getEvaluation().getImplementation()->isActualImplementation()) { LOGWARN(OSS() << "Clearing level function"); levelFunction_ = Function(); } levelValue_ = 0.0; } /* String converter */ String NearestPointProblem::__repr__() const { OSS oss; oss << "class=" << NearestPointProblem::GetClassName(); oss << " level function=" << levelFunction_.__repr__() << " level value=" << levelValue_ << " dimension=" << dimension_; return oss; } /* Method save() stores the object through the StorageManager */ void NearestPointProblem::save(Advocate & adv) const { OptimizationProblemImplementation::save(adv); adv.saveAttribute( "levelFunction_", levelFunction_ ); adv.saveAttribute( "levelValue_", levelValue_ ); } /* Method load() reloads the object from the StorageManager */ void NearestPointProblem::load(Advocate & adv) { OptimizationProblemImplementation::load(adv); adv.loadAttribute( "levelFunction_", levelFunction_ ); adv.loadAttribute( "levelValue_", levelValue_ ); } END_NAMESPACE_OPENTURNS