tinyopt 700
Tinyopt, a lightweight, header only optimization library
Loading...
Searching...
No Matches
utils.h
1// Copyright 2026 Julien Michot.
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include <algorithm>
7#include <cmath>
8#include <stdexcept>
9#include <type_traits>
10
11#include <tinyopt/types.h>
12
13namespace tinyopt {
14
16constexpr inline int SQRT(int N) {
17 if (N <= 1) return N;
18 int left = 1, right = N / 2;
19 int result = 0;
20 while (left <= right) {
21 int mid = left + (right - left) / 2;
22 if (mid <= N / mid) {
23 left = mid + 1;
24 result = mid;
25 } else {
26 right = mid - 1;
27 }
28 }
29 return result;
30};
31
32template <typename Scalar = double>
33inline constexpr Scalar FloatEpsilon() {
34 /*static*/ const Scalar eps = static_cast<Scalar>(std::is_same_v<Scalar, float> ? 1e-4f : 1e-7f);
35 return eps;
36}
37
38template <typename Scalar = double>
39inline constexpr Scalar FloatEpsilon2() {
40 /*static*/ const Scalar eps = static_cast<Scalar>(std::is_same_v<Scalar, float> ? 1e-8f : 1e-14f);
41 return eps;
42}
43
45#ifndef _MSC_VER // due to error C3493...
46#define If(condition, ValueOnTrue, ValueOnFalse) \
47 [&]() { \
48 if constexpr (condition) \
49 return ValueOnTrue; \
50 else \
51 return ValueOnFalse; \
52 }()
53#endif
54
55template <typename T>
56T MaxAbsDiff(const Eigen::SparseMatrix<T> &mat1, const Eigen::SparseMatrix<T> &mat2) {
57 if (mat1.rows() != mat2.rows() || mat1.cols() != mat2.cols()) {
58 throw std::invalid_argument("Matrices must have the same dimensions.");
59 }
60
61 T maxDiff = 0;
62 for (int k = 0; k < mat1.outerSize(); ++k) {
63 for (typename Eigen::SparseMatrix<T>::InnerIterator it1(mat1, k); it1; ++it1) {
64 T val2 = 0;
65 for (typename Eigen::SparseMatrix<T>::InnerIterator it2(mat2, k); it2; ++it2) {
66 if (it2.row() == it1.row()) {
67 val2 = it2.value();
68 break;
69 }
70 }
71 maxDiff = std::max(maxDiff, std::abs(it1.value() - val2));
72 }
73 }
74
75 for (int k = 0; k < mat2.outerSize(); ++k) {
76 for (typename Eigen::SparseMatrix<T>::InnerIterator it2(mat2, k); it2; ++it2) {
77 T val1 = 0;
78 bool found = false;
79 for (typename Eigen::SparseMatrix<T>::InnerIterator it1(mat1, k); it1; ++it1) {
80 if (it1.row() == it2.row()) {
81 val1 = it1.value();
82 found = true;
83 break;
84 }
85 }
86 if (!found) maxDiff = std::max(maxDiff, std::abs(val1 - it2.value()));
87 }
88 }
89 return maxDiff;
90}
91
92} // namespace tinyopt