math_utils.h Source File

CPP API: math_utils.h Source File
math_utils.h
Go to the documentation of this file.
1 /*
2 * Copyright (C) 2020-2026 MEmilio
3 *
4 * Authors: Rene Schmieding
5 *
6 * Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
19 */
20 #ifndef MIO_MATH_MATH_UTILS_H
21 #define MIO_MATH_MATH_UTILS_H
22 
23 #include "memilio/config.h"
24 #include "memilio/io/io.h"
25 #include "memilio/math/eigen.h" // IWYU pragma: keep
26 
27 namespace mio
28 {
29 
38 template <typename FP>
39 IOResult<void> map_to_nonnegative(Eigen::Ref<Eigen::VectorX<FP>> x, const FP tolerance = Limits<FP>::zero_tolerance())
40 {
41  assert(tolerance > 0);
42  FP positive{0.0}, negative{0.0};
43  for (auto& v : x) {
44  if (v >= FP{0.0}) {
45  positive += v;
46  }
47  else {
48  negative -= v;
49  v = FP{0.0};
50  }
51  }
52  // check if there is anything to do
53  if (negative > tolerance) {
54  // check if sum >= 0. otherwise, we cannot preserve it
55  if (positive >= negative) [[likely]] {
56  x = x * (1 - negative / positive);
57  }
58  else {
59  x.array() = (negative - positive) / x.size(); // = abs(positive - negative) / x.size()
61  "Failed to map vector to nonnegative values, total sum is negative.");
62  }
63  }
64  return success();
65 }
66 
77 template <typename Type, typename Intermediate>
78 inline auto evaluate_intermediate(Intermediate&& x)
79 {
80  if constexpr (is_ad_type_v<Type>) {
81  return static_cast<Type>(x);
82  }
83  else {
84  return std::forward<Intermediate>(x);
85  }
86 }
87 
88 } // namespace mio
89 
90 #endif // MIO_MATH_MATH_UTILS_H
A collection of classes to simplify handling of matrix shapes in meta programming.
Definition: models/abm/analyze_result.h:30
auto failure(const IOStatus &s)
Create an object that is implicitly convertible to an error IOResult<T>.
Definition: io.h:380
auto evaluate_intermediate(Intermediate &&x)
Evaluate an intermediate expression to its underlying type, if necessary.
Definition: math_utils.h:78
auto success()
Create an object that is implicitly convertible to a succesful IOResult<void>.
Definition: io.h:359
IOResult< void > map_to_nonnegative(Eigen::Ref< Eigen::VectorX< FP >> x, const FP tolerance=Limits< FP >::zero_tolerance())
Map a vector onto nonnegative values while preserving its nonnegative sum.
Definition: math_utils.h:39
boost::outcome_v2::unchecked< T, IOStatus > IOResult
Value-or-error type for operations that return a value but can fail.
Definition: io.h:353
Type specific limits for floating-points.
Definition: memilio/config.h:59