|
||||
File indexing completed on 2025-01-19 09:23:28
0001 // This file is part of the Acts project. 0002 // 0003 // Copyright (C) 2018-2022 CERN for the benefit of the Acts project 0004 // 0005 // This Source Code Form is subject to the terms of the Mozilla Public 0006 // License, v. 2.0. If a copy of the MPL was not distributed with this 0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 0008 0009 #pragma once 0010 0011 #include "Acts/Definitions/Algebra.hpp" 0012 0013 #include <algorithm> 0014 #include <array> 0015 #include <cassert> 0016 #include <cmath> 0017 #include <iomanip> 0018 #include <limits> 0019 #include <ostream> 0020 #include <sstream> 0021 0022 namespace Acts { 0023 0024 /// A constrained step class for the steppers. 0025 /// 0026 /// This class is symmetrical for forward and backward propagation. The sign of 0027 /// the propagation direction should not enter here but rather be applied the 0028 /// step is actually taken. 0029 /// 0030 /// As simple as this class looks it hides a few very important details: 0031 /// - Overstepping handling. The step size sign will flip if we happened to pass 0032 /// our target. 0033 /// - Convergence handling. Smaller and smaller step sizes have to be used in 0034 /// order to converge on a target. 0035 /// 0036 /// Because of the points mentioned above, the update function will always 0037 /// prefer negative step sizes. A side effect of this is that we will propagate 0038 /// in the opposite direction if the target is "behind us". 0039 /// 0040 /// The hierarchy is: 0041 /// - Overstepping resolution / backpropagation 0042 /// - Convergence 0043 /// - Step into the void with `std::numeric_limits<Scalar>::max()` 0044 class ConstrainedStep { 0045 public: 0046 using Scalar = ActsScalar; 0047 0048 /// the types of constraints 0049 /// from actor - this would be a typical navigation step 0050 /// from aborter - this would be a target condition 0051 /// from user - this is user given for what reason ever 0052 enum Type : int { actor = 0, aborter = 1, user = 2 }; 0053 0054 constexpr ConstrainedStep() = default; 0055 0056 /// constructor from Scalar 0057 /// @param value is the user given initial value 0058 constexpr explicit ConstrainedStep(Scalar value) { setUser(value); } 0059 0060 /// set accuracy by one Scalar 0061 /// 0062 /// this will set only the accuracy, as this is the most 0063 /// exposed to the Propagator 0064 /// 0065 /// @param value is the new accuracy value 0066 constexpr void setAccuracy(Scalar value) { 0067 assert(value > 0 && "ConstrainedStep accuracy must be > 0."); 0068 // set the accuracy value 0069 m_accuracy = value; 0070 } 0071 0072 /// set user by one Scalar 0073 /// 0074 /// @param value is the new user value 0075 constexpr void setUser(Scalar value) { 0076 // TODO enable assert; see https://github.com/acts-project/acts/issues/2543 0077 // assert(value != 0 && "ConstrainedStep user must be != 0."); 0078 // set the user value 0079 m_values[user] = value; 0080 } 0081 0082 /// returns the min step size 0083 constexpr Scalar value() const { 0084 Scalar min = *std::min_element(m_values.begin(), m_values.end()); 0085 // accuracy is always positive and therefore handled separately 0086 Scalar result = std::min(std::abs(min), m_accuracy); 0087 return std::signbit(min) ? -result : result; 0088 } 0089 0090 /// Access a specific value 0091 /// 0092 /// @param type is the requested parameter type 0093 constexpr Scalar value(Type type) const { return m_values[type]; } 0094 0095 /// Access the accuracy value 0096 constexpr Scalar accuracy() const { return m_accuracy; } 0097 0098 /// release a certain constraint value 0099 /// 0100 /// @param type is the constraint type to be released 0101 constexpr void release(Type type) { m_values[type] = kNotSet; } 0102 0103 /// release accuracy 0104 constexpr void releaseAccuracy() { m_accuracy = kNotSet; } 0105 0106 /// Update the step size of a certain type 0107 /// 0108 /// Only navigation and target abortion step size 0109 /// updates may change the sign due to overstepping 0110 /// 0111 /// @param value is the new value to be updated 0112 /// @param type is the constraint type 0113 /// @param releaseStep Allow step size to increase again 0114 constexpr void update(Scalar value, Type type, bool releaseStep = false) { 0115 if (releaseStep) { 0116 release(type); 0117 } 0118 // check the current value and set it if appropriate 0119 // this will also allow signed values due to overstepping 0120 if (std::abs(value) < std::abs(m_values[type])) { 0121 // TODO enable assert; see 0122 // https://github.com/acts-project/acts/issues/2543 0123 // assert(value != 0 && "ConstrainedStep user must be != 0."); 0124 m_values[type] = value; 0125 } 0126 } 0127 0128 std::ostream& toStream(std::ostream& os) const { 0129 // Helper method to avoid unreadable screen output 0130 auto streamValue = [&](Scalar val) { 0131 os << std::setw(5); 0132 if (std::abs(val) == kNotSet) { 0133 os << (val > 0 ? "+∞" : "-∞"); 0134 } else { 0135 os << val; 0136 } 0137 }; 0138 0139 os << "("; 0140 streamValue(m_accuracy); 0141 os << ", "; 0142 streamValue(value(actor)); 0143 os << ", "; 0144 streamValue(value(aborter)); 0145 os << ", "; 0146 streamValue(value(user)); 0147 os << ")"; 0148 0149 return os; 0150 } 0151 0152 std::string toString() const { 0153 std::stringstream dstream; 0154 toStream(dstream); 0155 return dstream.str(); 0156 } 0157 0158 private: 0159 inline static constexpr auto kNotSet = std::numeric_limits<Scalar>::max(); 0160 0161 /// the step size tuple 0162 std::array<Scalar, 3> m_values = {kNotSet, kNotSet, kNotSet}; 0163 /// the accuracy value - this can vary up and down given a good step estimator 0164 Scalar m_accuracy = kNotSet; 0165 }; 0166 0167 inline std::ostream& operator<<(std::ostream& os, const ConstrainedStep& step) { 0168 return step.toStream(os); 0169 } 0170 0171 } // namespace Acts
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |