mirror of
https://github.com/wpilibsuite/allwpilib
synced 2026-06-19 00:41:43 +00:00
This fixes a bug in Sleipnir's Newton solver (the exit status was inaccurate because unconstrained optimization problems can't be infeasible).
224 lines
7.5 KiB
Diff
224 lines
7.5 KiB
Diff
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
From: Tyler Veness <calcmogul@gmail.com>
|
|
Date: Wed, 29 May 2024 16:29:55 -0700
|
|
Subject: [PATCH 01/10] Use fmtlib
|
|
|
|
---
|
|
include/sleipnir/autodiff/expression_type.hpp | 16 +++++++----
|
|
include/sleipnir/optimization/problem.hpp | 1 +
|
|
.../optimization/solver/exit_status.hpp | 16 +++++++----
|
|
include/sleipnir/util/assert.hpp | 5 ++--
|
|
include/sleipnir/util/print.hpp | 27 ++++++++++---------
|
|
5 files changed, 40 insertions(+), 25 deletions(-)
|
|
|
|
diff --git a/include/sleipnir/autodiff/expression_type.hpp b/include/sleipnir/autodiff/expression_type.hpp
|
|
index 12d0568f628d5b97c0c2f5291851d4b20921f9d3..d06d32dac6c7b6faeedefeaa107cedac8446a3ab 100644
|
|
--- a/include/sleipnir/autodiff/expression_type.hpp
|
|
+++ b/include/sleipnir/autodiff/expression_type.hpp
|
|
@@ -4,9 +4,10 @@
|
|
|
|
#include <stdint.h>
|
|
|
|
-#include <format>
|
|
#include <utility>
|
|
|
|
+#include <fmt/base.h>
|
|
+
|
|
namespace slp {
|
|
|
|
/// Expression type.
|
|
@@ -27,14 +28,16 @@ enum class ExpressionType : uint8_t {
|
|
|
|
} // namespace slp
|
|
|
|
+// @cond Suppress Doxygen
|
|
+
|
|
/// Formatter for ExpressionType.
|
|
template <>
|
|
-struct std::formatter<slp::ExpressionType> {
|
|
+struct fmt::formatter<slp::ExpressionType> {
|
|
/// Parse format string.
|
|
///
|
|
/// @param ctx Format parse context.
|
|
/// @return Format parse context iterator.
|
|
- constexpr auto parse(std::format_parse_context& ctx) {
|
|
+ constexpr auto parse(fmt::format_parse_context& ctx) {
|
|
return m_underlying.parse(ctx);
|
|
}
|
|
|
|
@@ -45,7 +48,8 @@ struct std::formatter<slp::ExpressionType> {
|
|
/// @param ctx Format context.
|
|
/// @return Format context iterator.
|
|
template <typename FmtContext>
|
|
- auto format(const slp::ExpressionType& type, FmtContext& ctx) const {
|
|
+ constexpr auto format(const slp::ExpressionType& type,
|
|
+ FmtContext& ctx) const {
|
|
using enum slp::ExpressionType;
|
|
|
|
switch (type) {
|
|
@@ -65,5 +69,7 @@ struct std::formatter<slp::ExpressionType> {
|
|
}
|
|
|
|
private:
|
|
- std::formatter<const char*> m_underlying;
|
|
+ fmt::formatter<const char*> m_underlying;
|
|
};
|
|
+
|
|
+// @endcond
|
|
diff --git a/include/sleipnir/optimization/problem.hpp b/include/sleipnir/optimization/problem.hpp
|
|
index a9553ffbcfed568c48f7d789d8b127790dfddb91..3de6d5bf89a65fe07784350c3b1a4691dfc0c822 100644
|
|
--- a/include/sleipnir/optimization/problem.hpp
|
|
+++ b/include/sleipnir/optimization/problem.hpp
|
|
@@ -15,6 +15,7 @@
|
|
|
|
#include <Eigen/Core>
|
|
#include <Eigen/SparseCore>
|
|
+#include <fmt/chrono.h>
|
|
#include <gch/small_vector.hpp>
|
|
|
|
#include "sleipnir/autodiff/expression_type.hpp"
|
|
diff --git a/include/sleipnir/optimization/solver/exit_status.hpp b/include/sleipnir/optimization/solver/exit_status.hpp
|
|
index 0a48df7423b5a3dccd8e611e91befd32487fafdc..8786d6d64ac44ac88133df65a79636ec133b1b64 100644
|
|
--- a/include/sleipnir/optimization/solver/exit_status.hpp
|
|
+++ b/include/sleipnir/optimization/solver/exit_status.hpp
|
|
@@ -4,9 +4,10 @@
|
|
|
|
#include <stdint.h>
|
|
|
|
-#include <format>
|
|
#include <utility>
|
|
|
|
+#include <fmt/base.h>
|
|
+
|
|
namespace slp {
|
|
|
|
/// Solver exit status. Negative values indicate failure.
|
|
@@ -45,14 +46,16 @@ enum class ExitStatus : int8_t {
|
|
|
|
} // namespace slp
|
|
|
|
+// @cond Suppress Doxygen
|
|
+
|
|
/// Formatter for ExitStatus.
|
|
template <>
|
|
-struct std::formatter<slp::ExitStatus> {
|
|
+struct fmt::formatter<slp::ExitStatus> {
|
|
/// Parses format string.
|
|
///
|
|
/// @param ctx Format parse context.
|
|
/// @return Format parse context iterator.
|
|
- constexpr auto parse(std::format_parse_context& ctx) {
|
|
+ constexpr auto parse(fmt::format_parse_context& ctx) {
|
|
return m_underlying.parse(ctx);
|
|
}
|
|
|
|
@@ -63,7 +66,8 @@ struct std::formatter<slp::ExitStatus> {
|
|
/// @param ctx Format context.
|
|
/// @return Format context iterator.
|
|
template <typename FmtContext>
|
|
- auto format(const slp::ExitStatus& exit_status, FmtContext& ctx) const {
|
|
+ constexpr auto format(const slp::ExitStatus& exit_status,
|
|
+ FmtContext& ctx) const {
|
|
using enum slp::ExitStatus;
|
|
|
|
switch (exit_status) {
|
|
@@ -97,5 +101,7 @@ struct std::formatter<slp::ExitStatus> {
|
|
}
|
|
|
|
private:
|
|
- std::formatter<const char*> m_underlying;
|
|
+ fmt::formatter<const char*> m_underlying;
|
|
};
|
|
+
|
|
+// @endcond
|
|
diff --git a/include/sleipnir/util/assert.hpp b/include/sleipnir/util/assert.hpp
|
|
index 29dfe5416530a476417de3a4b6434d3b28d73120..783a0e71a1cb54bd1d6d17fa9d2bedd2038a8ef5 100644
|
|
--- a/include/sleipnir/util/assert.hpp
|
|
+++ b/include/sleipnir/util/assert.hpp
|
|
@@ -3,16 +3,17 @@
|
|
#pragma once
|
|
|
|
#ifdef SLEIPNIR_PYTHON
|
|
-#include <format>
|
|
#include <source_location>
|
|
#include <stdexcept>
|
|
|
|
+#include <fmt/format.h>
|
|
+
|
|
/// Throws an exception in Python.
|
|
#define slp_assert(condition) \
|
|
do { \
|
|
if (!(condition)) { \
|
|
auto location = std::source_location::current(); \
|
|
- throw std::invalid_argument(std::format( \
|
|
+ throw std::invalid_argument(fmt::format( \
|
|
"{}:{}: {}: Assertion `{}' failed.", location.file_name(), \
|
|
location.line(), location.function_name(), #condition)); \
|
|
} \
|
|
diff --git a/include/sleipnir/util/print.hpp b/include/sleipnir/util/print.hpp
|
|
index d436bf297b85cf84fad642fa43aa97063e7d6ebb..b2920580eea0297fc387b5168df78a1515a5dd60 100644
|
|
--- a/include/sleipnir/util/print.hpp
|
|
+++ b/include/sleipnir/util/print.hpp
|
|
@@ -4,47 +4,48 @@
|
|
|
|
#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
|
|
#include <cstdio>
|
|
-#include <print>
|
|
#include <system_error>
|
|
#include <utility>
|
|
+
|
|
+#include <fmt/base.h>
|
|
#endif
|
|
|
|
namespace slp {
|
|
|
|
#ifndef SLEIPNIR_DISABLE_DIAGNOSTICS
|
|
|
|
-/// Wrapper around std::print() that squelches write failure exceptions.
|
|
+/// Wrapper around fmt::print() that squelches write failure exceptions.
|
|
template <typename... T>
|
|
-void print(std::format_string<T...> fmt, T&&... args) {
|
|
+void print(fmt::format_string<T...> fmt, T&&... args) {
|
|
try {
|
|
- std::print(fmt, std::forward<T>(args)...);
|
|
+ fmt::print(fmt, std::forward<T>(args)...);
|
|
} catch (const std::system_error&) {
|
|
}
|
|
}
|
|
|
|
-/// Wrapper around std::print() that squelches write failure exceptions.
|
|
+/// Wrapper around fmt::print() that squelches write failure exceptions.
|
|
template <typename... T>
|
|
-void print(std::FILE* f, std::format_string<T...> fmt, T&&... args) {
|
|
+void print(std::FILE* f, fmt::format_string<T...> fmt, T&&... args) {
|
|
try {
|
|
- std::print(f, fmt, std::forward<T>(args)...);
|
|
+ fmt::print(f, fmt, std::forward<T>(args)...);
|
|
} catch (const std::system_error&) {
|
|
}
|
|
}
|
|
|
|
-/// Wrapper around std::println() that squelches write failure exceptions.
|
|
+/// Wrapper around fmt::println() that squelches write failure exceptions.
|
|
template <typename... T>
|
|
-void println(std::format_string<T...> fmt, T&&... args) {
|
|
+void println(fmt::format_string<T...> fmt, T&&... args) {
|
|
try {
|
|
- std::println(fmt, std::forward<T>(args)...);
|
|
+ fmt::println(fmt, std::forward<T>(args)...);
|
|
} catch (const std::system_error&) {
|
|
}
|
|
}
|
|
|
|
-/// Wrapper around std::println() that squelches write failure exceptions.
|
|
+/// Wrapper around fmt::println() that squelches write failure exceptions.
|
|
template <typename... T>
|
|
-void println(std::FILE* f, std::format_string<T...> fmt, T&&... args) {
|
|
+void println(std::FILE* f, fmt::format_string<T...> fmt, T&&... args) {
|
|
try {
|
|
- std::println(f, fmt, std::forward<T>(args)...);
|
|
+ fmt::println(f, fmt, std::forward<T>(args)...);
|
|
} catch (const std::system_error&) {
|
|
}
|
|
}
|