MCPcopy Create free account
hub / github.com/PatWie/CppNumericalSolvers / ProdExpression

Class ProdExpression

include/cppoptlib/function_expressions.h:260–315  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

258template <typename F, typename G,
259 DifferentiabilityMode TMode = MinDifferentiability<F, G>::value>
260struct ProdExpression
261 : public FunctionInterface<typename F::ScalarType, TMode, F::Dimension> {
262 static_assert(
263 F::Dimension == G::Dimension,
264 "Compile-time dimension mismatch: F and G must have the same dimension.");
265 static_assert(
266 std::is_same<typename F::ScalarType, typename G::ScalarType>::value,
267 "Compile-time scalar-type mismatch: F and G must have the same scalar "
268 "type.");
269
270 static constexpr int Dimension = F::Dimension;
271 using ScalarType = typename F::ScalarType;
272 using VectorType = Eigen::Matrix<ScalarType, Dimension, 1>;
273 using MatrixType = Eigen::Matrix<ScalarType, Dimension, Dimension>;
274 static constexpr DifferentiabilityMode Differentiability = TMode;
275
276 F f;
277 G g;
278
279 ProdExpression(const F& f_, const G& g_) : f(f_), g(g_) {}
280
281 virtual ScalarType operator()(const VectorType& x, VectorType* grad = nullptr,
282 MatrixType* hess = nullptr) const override {
283 if constexpr (TMode == DifferentiabilityMode::None) {
284 return f(x) * g(x);
285 } else if constexpr (TMode == DifferentiabilityMode::First) {
286 VectorType grad_f(x.size()), grad_g(x.size());
287 ScalarType fx = f(x, &grad_f);
288 ScalarType gx = g(x, &grad_g);
289 if (grad) {
290 // Product rule: (f*g)' = f'*g + f*g'
291 *grad = gx * grad_f + fx * grad_g;
292 }
293 return fx * gx;
294 } else { // Second order
295 VectorType grad_f(x.size()), grad_g(x.size());
296 MatrixType hess_f(x.size(), x.size()), hess_g(x.size(), x.size());
297 ScalarType fx = f(x, &grad_f, &hess_f);
298 ScalarType gx = g(x, &grad_g, &hess_g);
299 if (grad) {
300 *grad = gx * grad_f + fx * grad_g;
301 }
302 if (hess) {
303 // Hessian: f''*g + f'*g' (symmetric) + f*g''
304 *hess = gx * hess_f + fx * hess_g + grad_f * grad_g.transpose() +
305 grad_g * grad_f.transpose();
306 }
307 return fx * gx;
308 }
309 }
310
311 virtual std::unique_ptr<FunctionInterface<ScalarType, TMode, Dimension>>
312 clone() const override {
313 return std::make_unique<ProdExpression<F, G, TMode>>(f, g);
314 }
315};
316
317// --- Helper Expression for min{0, f(x)}

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected