12template <
typename _Scalar>
struct CostSumTpl : CostFunctionBaseTpl<_Scalar> {
14 using Scalar = _Scalar;
16 using Base = CostFunctionBaseTpl<Scalar>;
17 using BasePtr = shared_ptr<Base>;
19 std::vector<BasePtr> components_;
26 const std::vector<Scalar> &weights)
28 assert(components_.size() ==
weights_.size());
31 std::size_t numComponents()
const {
return components_.size(); }
33 auto clone()
const {
return std::make_shared<CostSumTpl>(*
this); }
35 Scalar
call(
const ConstVectorRef &x)
const {
37 for (std::size_t i = 0; i < numComponents(); i++) {
38 result_ +=
weights_[i] * components_[i]->call(x);
43 void computeGradient(
const ConstVectorRef &x, VectorRef out)
const {
45 for (std::size_t i = 0; i < numComponents(); i++) {
46 out.noalias() = out +
weights_[i] * components_[i]->computeGradient(x);
50 void computeHessian(
const ConstVectorRef &x, MatrixRef out)
const {
52 for (std::size_t i = 0; i < numComponents(); i++) {
53 out.noalias() = out +
weights_[i] * components_[i]->computeHessian(x);
59 void addComponent(shared_ptr<Base> comp,
const Scalar w = 1.) {
60 components_.push_back(comp);
70 components_.insert(components_.end(), other.components_.begin(),
71 other.components_.end());
73 other.weights_.end());
79 weight = rhs * weight;
85 friend std::ostream &operator<<(std::ostream &ostr,
87 const std::size_t nc = cost.numComponents();
88 ostr <<
"CostSum(num_components=" << nc;
89 ostr <<
", weights=(";
90 for (std::size_t i = 0; i < nc; i++) {
91 ostr << cost.weights_[i];
100 friend auto operator*(
CostSumTpl const &self, Scalar a)
101 -> shared_ptr<CostSumTpl> {
102 auto out = self.clone();
107 friend auto operator*(Scalar a,
CostSumTpl const &self) {
return self * a; }
109 friend auto operator-(
CostSumTpl const &self) {
110 return self *
static_cast<Scalar
>(-1.);
CostSumTpl(int nx, int ndx, const std::vector< BasePtr > &comps, const std::vector< Scalar > &weights)
Constructor with a predefined vector of components.