Line data Source code
1 : // SPDX-License-Identifier: BSD-3-Clause 2 : // Copyright (c) 2023 Scipp contributors (https://github.com/scipp) 3 : #include "scipp/variable/inv.h" 4 : 5 : #include "scipp/common/overloaded.h" 6 : #include "scipp/core/element/arg_list.h" 7 : #include "scipp/core/spatial_transforms.h" 8 : #include "scipp/core/transform_common.h" 9 : 10 : #include "scipp/variable/transform.h" 11 : 12 : namespace scipp::variable { 13 : namespace element { 14 : constexpr auto inv = 15 : overloaded{core::element::arg_list<Eigen::Matrix3d, Eigen::Affine3d, 16 : core::Translation, core::Quaternion>, 17 : core::transform_flags::expect_no_variance_arg<0>, 18 : core::transform_flags::expect_no_variance_arg<1>, 19 24 : [](const auto &transform) { return transform.inverse(); }, 20 18 : [](const units::Unit &) { 21 : // The resulting unit depends on the dtype; 22 : // the calling code assigns it. 23 18 : return units::none; 24 : }}; 25 : } // namespace element 26 : 27 : namespace { 28 18 : bool is_transform_with_translation(const Variable &var) { 29 18 : const auto dt = var.dtype(); 30 18 : return dt == dtype<Eigen::Affine3d> || dt == dtype<scipp::core::Translation>; 31 : } 32 : 33 : // Translations: The unit stays the same because translations are additive. 34 : // Affine transforms: The unit applies only to the translation part, see above. 35 : // Linear transforms: Can scale the input, the unit is multiplicative. 36 : // Rotations: A unit is ill-defined, but use 1/u to cancel out any unit 37 : // in case the user sets one manually. 38 18 : auto result_unit(const Variable &var) { 39 24 : return is_transform_with_translation(var) ? var.unit() 40 24 : : units::one / var.unit(); 41 : } 42 : 43 : } // namespace 44 : 45 18 : Variable inv(const Variable &var) { 46 18 : auto res = variable::transform(var, element::inv, "inverse"); 47 18 : res.setUnit(result_unit(var)); 48 18 : return res; 49 0 : } 50 : } // namespace scipp::variable