【C++】sophus : types.hpp 类型别名(三)

这段 C++ 头文件定义了用于线性代数的常用类型别名和实用函数,主要使用了 Eigen 库。它的目标是为向量、矩阵、直线和超平面提供方便的简写和通用操作。

以下是详细的分解:

1. 类型别名:

  • 向量:

     定义Vector<Scalar, M, Options> 为大小为M 的 Eigen 列向量。为常用大小(2、3、4、6、7)和数据类型(float、double)提供了别名:Vector2fVector3d 等。

  • 矩阵:

     定义Matrix<Scalar, M, N> 为大小为MxN 的 Eigen 矩阵。为常用大小(2、3、4、6、7)的方阵和数据类型提供了别名:Matrix2fMatrix3d 等。

  • 参数化直线:

     定义ParametrizedLine<Scalar, N, Options> 为N 维的 Eigen 参数化直线。为 2D 和 3D 直线以及 float 和 double 类型提供了别名:ParametrizedLine2fParametrizedLine3d 等。

  • 超平面:

     定义Hyperplane<Scalar, N, Options> 为N 维的 Eigen 超平面。为 2D 和 3D 超平面以及 float 和 double 类型提供了别名:Hyperplane2fHyperplane3d 等。

  • 作为超平面的平面和直线:

     定义Plane3 为 3D 的HyperplaneLine2 为 2D 的Hyperplane,并提供 float 和 double 版本的别名。

2. 实用函数(使用基于 traits 的方法进行通用实现):

  • maxMetric(p0, p1)

     计算两个标量或矩阵p0 和p1 之间的最大元素差。

  • setToZero(p)

     将标量或矩阵p 设置为零。

  • setElementAt(p, value, i)

     将标量或向量p 的第i 个元素设置为value。如果p 是标量,则i 必须为 0。

  • squaredNorm(p)

     计算标量或向量p 的平方欧几里得范数。

  • transpose(p)

     如果p 是矩阵,则返回p.transpose();如果p 是标量,则直接返回p

3. 类型 traits:

  • IsFloatingPoint<T>

     一个类型 trait,用于检查T 是否为浮点类型(标量或矩阵)。

  • GetScalar<T>

     一个类型 trait,用于从标量或矩阵类型T 中提取标量类型。

  • IsFixedSizeVector<Vector, NumDimensions>

     一个类型 trait,用于检查给定的Vector 类型是否为具有特定维数的固定大小向量。

4. 内部细节(命名空间details):

此命名空间包含使用模板特化的实用函数的实现细节。这允许根据输入是标量还是矩阵使用不同的实现。例如,MaxMetric 对标量使用abs(),对矩阵使用lpNorm<Eigen::Infinity>()。类似地,SetToZero 对标量使用直接赋值,对矩阵使用setZero()

总结: 该头文件提供了一组方便且通用的工具,用于使用 Eigen 处理线性代数对象。它通过提供类型别名和可用于标量和矩阵的通用函数来简化代码。模板特化和类型 traits 的使用使代码高效且可扩展。

简单来说,这个头文件就是定义了一些常用的数学类型(向量、矩阵、直线、平面),并且提供了一些方便的函数来操作这些类型,例如求最大差、置零、设置元素、求平方范数和转置。它使用 Eigen 库作为底层实现,并且通过模板和 traits 提供了很好的通用性和扩展性。

/// 常见类型别名。
#pragma once // 防止头文件被重复包含
#include <type_traits> // 导入类型特征库#include "common.hpp" // 导入自定义的 common.hpp 头文件
namespace Sophus { // 定义名为 Sophus 的命名空间
// 定义一个模板别名,表示 Eigen 库中的向量类型template <class Scalar, int M, int Options = 0>using Vector = Eigen::Matrix<Scalar, M, 1, Options>;
// 定义一些具体的向量类型别名,例如 Vector2 表示二维向量template <class Scalar, int Options = 0>using Vector2 = Vector<Scalar, 2, Options>;using Vector2f = Vector2<float>; // 浮点型二维向量using Vector2d = Vector2<double>; // 双精度型二维向量
template <class Scalar, int Options = 0>using Vector3 = Vector<Scalar, 3, Options>;using Vector3f = Vector3<float>; // 浮点型三维向量using Vector3d = Vector3<double>; // 双精度型三维向量
template <class Scalar>using Vector4 = Vector<Scalar, 4>;using Vector4f = Vector4<float>; // 浮点型四维向量using Vector4d = Vector4<double>; // 双精度型四维向量
template <class Scalar>using Vector6 = Vector<Scalar, 6>;using Vector6f = Vector6<float>; // 浮点型六维向量using Vector6d = Vector6<double>; // 双精度型六维向量
template <class Scalar>using Vector7 = Vector<Scalar, 7>;using Vector7f = Vector7<float>; // 浮点型七维向量using Vector7d = Vector7<double>; // 双精度型七维向量
// 定义矩阵类型的模板别名template <class Scalar, int M, int N>using Matrix = Eigen::Matrix<Scalar, M, N>;
// 定义具体的矩阵类型别名,例如 Matrix2 表示 2x2 矩阵template <class Scalar>using Matrix2 = Matrix<Scalar, 2, 2>;using Matrix2f = Matrix2<float>; // 浮点型 2x2 矩阵using Matrix2d = Matrix2<double>; // 双精度型 2x2 矩阵
template <class Scalar>using Matrix3 = Matrix<Scalar, 3, 3>;using Matrix3f = Matrix3<float>; // 浮点型 3x3 矩阵using Matrix3d = Matrix3<double>; // 双精度型 3x3 矩阵
template <class Scalar>using Matrix4 = Matrix<Scalar, 4, 4>;using Matrix4f = Matrix4<float>; // 浮点型 4x4 矩阵using Matrix4d = Matrix4<double>; // 双精度型 4x4 矩阵
template <class Scalar>using Matrix6 = Matrix<Scalar, 6, 6>;using Matrix6f = Matrix6<float>; // 浮点型 6x6 矩阵using Matrix6d = Matrix6<double>; // 双精度型 6x6 矩阵
template <class Scalar>using Matrix7 = Matrix<Scalar, 7, 7>;using Matrix7f = Matrix7<float>; // 浮点型 7x7 矩阵using Matrix7d = Matrix7<double>; // 双精度型 7x7 矩阵
// 参数化直线的模板别名template <class Scalar, int N, int Options = 0>using ParametrizedLine = Eigen::ParametrizedLine<Scalar, N, Options>;
template <class Scalar, int Options = 0>using ParametrizedLine3 = ParametrizedLine<Scalar, 3, Options>;using ParametrizedLine3f = ParametrizedLine3<float>; // 浮点型三维参数化直线using ParametrizedLine3d = ParametrizedLine3<double>; // 双精度型三维参数化直线
template <class Scalar, int Options = 0>using ParametrizedLine2 = ParametrizedLine<Scalar, 2, Options>;using ParametrizedLine2f = ParametrizedLine2<float>; // 浮点型二维参数化直线using ParametrizedLine2d = ParametrizedLine2<double>; // 双精度型二维参数化直线
// 超平面的模板别名template <class Scalar, int N, int Options = 0>using Hyperplane = Eigen::Hyperplane<Scalar, N, Options>;
template <class Scalar, int Options = 0>using Hyperplane3 = Eigen::Hyperplane<Scalar, 3, Options>;using Hyperplane3f = Hyperplane3<float>; // 浮点型三维超平面using Hyperplane3d = Hyperplane3<double>; // 双精度型三维超平面
template <class Scalar, int Options = 0>using Hyperplane2 = Eigen::Hyperplane<Scalar, 2, Options>;using Hyperplane2f = Hyperplane2<float>; // 浮点型二维超平面using Hyperplane2d = Hyperplane2<double>; // 双精度型二维超平面
namespace details { // 定义内部命名空间 details
template <class Scalar>class MaxMetric { // 定义一个名为 MaxMetric 的模板类,计算最大度量 public:  static Scalar impl(Scalar s0, Scalar s1) { // 静态方法,计算标量之间的最大差值    using std::abs;    return abs(s0 - s1); // 返回绝对值  }};
template <class Scalar, int M, int N>class MaxMetric<Matrix<Scalar, M, N>> { // 针对矩阵的 MaxMetric 模板特化 public:  static Scalar impl(Matrix<Scalar, M, N> const& p0, Matrix<Scalar, M, N> const& p1) {    return (p0 - p1).template lpNorm<Eigen::Infinity>(); // 返回最大度量  }};
template <class Scalar>class SetToZero { // 定义一个模板类 SetToZero public:  static void impl(Scalar& s) { s = Scalar(0); } // 静态方法,将标量置零};
template <class Scalar, int M, int N>class SetToZero<Matrix<Scalar, M, N>> { // 针对矩阵的 SetToZero 模板特化 public:  static void impl(Matrix<Scalar, M, N>& v) { v.setZero(); } // 将矩阵置零};
template <class T1, class Scalar>class SetElementAt; // 声明 SetElementAt 模板类
template <class Scalar>class SetElementAt<Scalar, Scalar> { // 针对标量的 SetElementAt 模板特化 public:  static void impl(Scalar& s, Scalar value, int at) { // 静态方法,设置标量的值    SOPHUS_ENSURE(at == 0, "is {}", (at)); // 保证位置为 0    s = value;  }};
template <class Scalar, int N>class SetElementAt<Vector<Scalar, N>, Scalar> { // 针对向量的 SetElementAt 模板特化 public:  static void impl(Vector<Scalar, N>& v, Scalar value, int at) { // 设置向量某个元素的值    SOPHUS_ENSURE(at >= 0 && at < N, "is {}", (at)); // 保证位置有效    v[at] = value;  }};
template <class Scalar>class SquaredNorm { // 定义一个计算平方范数的模板类 public:  static Scalar impl(Scalar const& s) { return s * s; } // 对标量,直接返回平方};
template <class Scalar, int N>class SquaredNorm<Matrix<Scalar, N, 1>> { // 针对向量的 SquaredNorm 模板特化 public:  static Scalar impl(Matrix<Scalar, N, 1> const& s) { return s.squaredNorm(); } // 返回向量的平方范数};
template <class Scalar>class Transpose { // 定义一个计算转置的模板类 public:  static Scalar impl(Scalar const& s) { return s; } // 对标量,直接返回自身};
template <class Scalar, int M, int N>class Transpose<Matrix<Scalar, M, N>> { // 针对矩阵的 Transpose 模板特化 public:  static Matrix<Scalar, M, N> impl(Matrix<Scalar, M, N> const& s) {    return s.transpose(); // 返回矩阵的转置  }};}  // namespace details
// 返回两个点的最大度量,点可以是矩阵或标量template <class T>auto maxMetric(T const& p0, T const& p1)    -> decltype(details::MaxMetric<T>::impl(p0, p1)) {  return details::MaxMetric<T>::impl(p0, p1);}
// 将点 p 置为零,p 可以是矩阵或标量template <class T>void setToZero(T& p) {  return details::SetToZero<T>::impl(p);}
// 设置 p 的第 i 个元素的值为 value,p 可以是矩阵或标量,如果 p 是标量,i 必须为 0template <class T, class Scalar>void setElementAt(T& p, Scalar value, int i) {  return details::SetElementAt<T, Scalar>::impl(p, value, i);}
// 返回 p 的平方 2-范数,p 可以是向量或标量template <class T>auto squaredNorm(T const& p) -> decltype(details::SquaredNorm<T>::impl(p)) {  return details::SquaredNorm<T>::impl(p);}
// 返回 p 的转置,如果 p 是矩阵,直接返回 p,如果是标量,则直接返回 ptemplate <class T>auto transpose(T const& p) -> decltype(details::Transpose<T>::impl(T())) {  return details::Transpose<T>::impl(p);}
// 判断是否为浮点数类型template <class Scalar>struct IsFloatingPoint {  static bool const value = std::is_floating_point<Scalar>::value;};
template <class Scalar, int M, int N>struct IsFloatingPoint<Matrix<Scalar, M, N>> {  static bool const value = std::is_floating_point<Scalar>::value;};
// 获取标量类型template <class Scalar_>struct GetScalar {  using Scalar = Scalar_;};
template <class Scalar_, int M, int N>struct GetScalar<Matrix<Scalar_, M, N>> {  using Scalar = Scalar_;};
// 如果向量类型是固定大小,则 IsFixedSizeVector::value 将为 truetemplate <typename Vector, int NumDimensions,          typename = typename std::enable_if_t<Vector::RowsAtCompileTime ==                                                   NumDimensions &&                                               Vector::ColsAtCompileTime == 1>>struct IsFixedSizeVector : std::true_type {};
// 在 3D 中,平面是超平面template <class T>using Plane3 = Eigen::Hyperplane<T, 3>;using Plane3d = Plane3<double>;using Plane3f = Plane3<float>;
// 在 2D 中,直线是超平面template <class T>using Line2 = Eigen::Hyperplane<T, 2>;using Line2d = Line2<double>;using Line2f = Line2<float>;
}  // namespace Sophus

这段代码定义了一些常用的类型别名和辅助工具,以简化在Sophus库中使用Eigen库矩阵和向量操作的编程工作。下面是对代码的总结和解释:

文件头和命名空间

/// @file/// Common type aliases.#pragmaonce// 防止头文件重复包含#include<type_traits>#include"common.hpp"namespace Sophus{// 定义Sophus命名空间

向量别名

template<classScalar,int M,int Options=0>using Vector= Eigen::Matrix<Scalar, M,1, Options>;// 定义向量别名template<classScalar,int Options=0>using Vector2= Vector<Scalar,2, Options>;// 定义二维向量别名using Vector2f= Vector2<float>;// 定义二维浮点向量别名using Vector2d= Vector2<double>;// 定义二维双精度向量别名template<classScalar,int Options=0>using Vector3= Vector<Scalar,3, Options>;// 定义三维向量别名using Vector3f= Vector3<float>;// 定义三维浮点向量别名using Vector3d= Vector3<double>;// 定义三维双精度向量别名template<classScalar>using Vector4= Vector<Scalar,4>;// 定义四维向量别名using Vector4f= Vector4<float>;// 定义四维浮点向量别名using Vector4d= Vector4<double>;// 定义四维双精度向量别名template<classScalar>using Vector6= Vector<Scalar,6>;// 定义六维向量别名using Vector6f= Vector6<float>;// 定义六维浮点向量别名using Vector6d= Vector6<double>;// 定义六维双精度向量别名template<classScalar>using Vector7= Vector<Scalar,7>;// 定义七维向量别名using Vector7f= Vector7<float>;// 定义七维浮点向量别名using Vector7d= Vector7<double>;// 定义七维双精度向量别名

矩阵别名

template<classScalar,int M,int N>using Matrix= Eigen::Matrix<Scalar, M, N>;// 定义矩阵别名template<classScalar>using Matrix2= Matrix<Scalar,2,2>;// 定义2x2矩阵别名using Matrix2f= Matrix2<float>;// 定义2x2浮点矩阵别名using Matrix2d= Matrix2<double>;// 定义2x2双精度矩阵别名template<classScalar>using Matrix3= Matrix<Scalar,3,3>;// 定义3x3矩阵别名using Matrix3f= Matrix3<float>;// 定义3x3浮点矩阵别名using Matrix3d= Matrix3<double>;// 定义3x3双精度矩阵别名template<classScalar>using Matrix4= Matrix<Scalar,4,4>;// 定义4x4矩阵别名using Matrix4f= Matrix4<float>;// 定义4x4浮点矩阵别名using Matrix4d= Matrix4<double>;// 定义4x4双精度矩阵别名template<classScalar>using Matrix6= Matrix<Scalar,6,6>;// 定义6x6矩阵别名using Matrix6f= Matrix6<float>;// 定义6x6浮点矩阵别名using Matrix6d= Matrix6<double>;// 定义6x6双精度矩阵别名template<classScalar>using Matrix7= Matrix<Scalar,7,7>;// 定义7x7矩阵别名using Matrix7f= Matrix7<float>;// 定义7x7浮点矩阵别名using Matrix7d= Matrix7<double>;// 定义7x7双精度矩阵别名

参数化直线和超平面别名

template<classScalar,int N,int Options=0>using ParametrizedLine= Eigen::ParametrizedLine<Scalar, N, Options>;// 定义参数化直线别名template<classScalar,int Options=0>using ParametrizedLine3= ParametrizedLine<Scalar,3, Options>;// 定义三维参数化直线别名using ParametrizedLine3f= ParametrizedLine3<float>;// 定义三维浮点参数化直线别名using ParametrizedLine3d= ParametrizedLine3<double>;// 定义三维双精度参数化直线别名template<classScalar,int Options=0>using ParametrizedLine2= ParametrizedLine<Scalar,2, Options>;// 定义二维参数化直线别名using ParametrizedLine2f= ParametrizedLine2<float>;// 定义二维浮点参数化直线别名using ParametrizedLine2d= ParametrizedLine2<double>;// 定义二维双精度参数化直线别名template<classScalar,int N,int Options=0>using Hyperplane= Eigen::Hyperplane<Scalar, N, Options>;// 定义超平面别名template<classScalar,int Options=0>using Hyperplane3= Eigen::Hyperplane<Scalar,3, Options>;// 定义三维超平面别名using Hyperplane3f= Hyperplane3<float>;// 定义三维浮点超平面别名using Hyperplane3d= Hyperplane3<double>;// 定义三维双精度超平面别名template<classScalar,int Options=0>using Hyperplane2= Eigen::Hyperplane<Scalar,2, Options>;// 定义二维超平面别名using Hyperplane2f= Hyperplane2<float>;// 定义二维浮点超平面别名using Hyperplane2d= Hyperplane2<double>;// 定义二维双精度超平面别名

细节辅助类

namespace details {template <class Scalar>class MaxMetric { public:  static Scalar impl(Scalar s0, Scalar s1) {    using std::abs;    return abs(s0 - s1); // 计算两个标量之间的最大距离  }};template <class Scalar, int M, int N>class MaxMetric<Matrix<Scalar, M, N>> { public:  static Scalar impl(Matrix<Scalar, M, N> const& p0,                     Matrix<Scalar, M, N> const& p1) {    return (p0 - p1).template lpNorm<Eigen::Infinity>(); // 计算两个矩阵之间的最大距离  }};template <class Scalar>class SetToZero { public:  static void impl(Scalar& s) { s = Scalar(0); } // 将标量设为零};template <class Scalar, int M, int N>class SetToZero<Matrix<Scalar, M, N>> { public:  static void impl(Matrix<Scalar, M, N>& v) { v.setZero(); } // 将矩阵设为零};template <class T1, class Scalar>class SetElementAt;template <class Scalar>class SetElementAt<Scalar, Scalar> { public:  static void impl(Scalar& s, Scalar value, int at) {    SOPHUS_ENSURE(at == 0, "is {}", (at)); // 确保索引为0    s = value; // 设置标量的值  }};template <class Scalar, int N>class SetElementAt<Vector<Scalar, N>, Scalar> { public:  static void impl(Vector<Scalar, N>& v, Scalar value, int at) {    SOPHUS_ENSURE(at >= 0 && at < N, "is {}", (at)); // 确保索引在有效范围内    v[at] = value; // 设置向量指定位置的值  }};template <class Scalar>class SquaredNorm { public:  static Scalar impl(Scalar const& s) { return s * s; } // 返回标量的平方};template <class Scalar, int N>class SquaredNorm<Matrix<Scalar, N, 1>> { public:  static Scalar impl(Matrix<Scalar, N, 1> const& s) { return s.squaredNorm(); } // 返回向量的平方范数};template <class Scalar>class Transpose { public:  static Scalar impl(Scalar const& s) { return s; } // 返回标量自身};template <class Scalar, int M, int N>class Transpose<Matrix<Scalar, M, N>> { public:  static Matrix<Scalar, M, N> impl(Matrix<Scalar, M, N> const& s) {    return s.transpose(); // 返回矩阵的转置  }};}  // namespace details

公用函数模板

/// 返回两个点之间的最大度量值,点可以是矩阵或标量。template <class T>auto maxMetric(T const& p0, T const& p1)    -> decltype(details::MaxMetric<T>::impl(p0, p1)) {  return details::MaxMetric<T>::impl(p0, p1); // 调用MaxMetric的实现函数}/// 将点设为零,点可以是矩阵或标量。template <class T>void setToZero(T& p) {  return details::SetToZero<T>::impl(p); // 调用SetToZero的实现函数}/// 设置点的第i个分量为给定值,点可以是矩阵或标量。如果点是标量,i必须为0。template <class T, class Scalar>void setElementAt(T& p, Scalar value, int i) {  return details::SetElementAt<T, Scalar>::impl(p, value, i); // 调用SetElementAt的实现函数}/// 返回点的平方2-范数,点可以是向量或标量。template <class T>auto squaredNorm(T const& p) -> decltype(details::SquaredNorm<T>::impl(p)) {  return details::SquaredNorm<T>::impl(p); // 调用SquaredNorm的实现函数}/// 如果点是矩阵,返回其转置;如果是标量,则直接返回点本身。template <class T>auto transpose(T const& p) -> decltype(details::Transpose<T>::impl(T())) {  return details::Transpose<T>::impl(p); // 调用Transpose的实现函数}template <class Scalar>struct IsFloatingPoint {  static bool const value = std::is_floating_point<Scalar>::value; // 判断类型是否为浮点数};template <class Scalar, int M, int N>struct IsFloatingPoint<Matrix<Scalar, M, N>> {  static bool const value = std::is_floating_point<Scalar>::value; // 判断矩阵元素类型是否为浮点数};template <class Scalar_>struct GetScalar {  using Scalar = Scalar_; // 获取标量类型};template <class Scalar_, int M, int N>struct GetScalar<Matrix<Scalar_, M, N>> {  using Scalar = Scalar_; // 获取矩阵的标量类型};/// 如果向量类型是固定大小的,则IsFixedSizeVector::value为true。template <typename Vector, int NumDimensions,          typename = typename std::enable_if_t<Vector::RowsAtCompileTime ==                                                   NumDimensions &&                                               Vector::ColsAtCompileTime == 1>>struct IsFixedSizeVector : std::true_type {}; // 判断向量是否为固定大小/// 三维空间中的平面是超平面。template <class T>using Plane3 = Eigen::Hyperplane<T, 3>; // 定义三维平面别名using Plane3d = Plane3<double>; // 定义三维双精度平面别名using Plane3f = Plane3<float>; // 定义三维浮点平面别名/// 二维空间中的直线是超平面。template <class T>using Line2 = Eigen::Hyperplane<T, 2>; // 定义二维直线别名using Line2d = Line2<double>; // 定义二维双精度直线别名using Line2f = Line2<float>; // 定义二维浮点直线别名}  // namespace Sophus

这段代码定义了一些常用的类型别名和辅助函数模板,用于简化矩阵和向量的操作。它通过模板编程,提供了向量和矩阵的类型别名,以及一些常用的数学操作的实现,如计算最大度量、设置为零、设置指定元素的值、计算平方范数和转置操作。通过这些类型别名和辅助函数,可以更方便地进行数学运算,提高代码的可读性和可维护性。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值