Skip to content

Commit

Permalink
docs: api-reference for sophus::manifold
Browse files Browse the repository at this point in the history
  • Loading branch information
strasdat committed Nov 9, 2023
1 parent 3787cf9 commit 9792bec
Show file tree
Hide file tree
Showing 10 changed files with 346 additions and 84 deletions.
4 changes: 2 additions & 2 deletions cpp/sophus/common/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#include <random>
#include <type_traits>

// \cond HIDDEN_SYMBOLS
// BEGIN(exclude from doxygen) \cond HIDDEN_SYMBOLS
// from <farm_ng/core/logging/format.h>cd
#define SOPHUS_FORMAT(...) FARM_FORMAT(__VA_ARGS__)

Expand All @@ -47,7 +47,7 @@
// from <farm_ng/core/logging/expected.h>
#define SOPHUS_TRY(...) FARM_TRY(__VA_ARGS__)
#define SOPHUS_UNEXPECTED(...) FARM_UNEXPECTED(__VA_ARGS__)
// \endcond
// END(exclude from doxygen) \endcond

namespace sophus {

Expand Down
63 changes: 26 additions & 37 deletions cpp/sophus/linalg/vector_space_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,43 +22,6 @@ namespace sophus {
template <class TPoint>
struct PointTraits;

/// Trait for a scalar valued point.
///
/// Mathematically, we consider a point an element of a "vector space". In this
/// case, the vector space is one-dimensional.
template <concepts::ScalarType TPoint>
struct PointTraits<TPoint> {
/// Scalar type
using Scalar = TPoint;

/// Is floating point number?
static bool constexpr kIsFloatingPoint = std::is_floating_point_v<Scalar>;
/// Is integer number?
static bool constexpr kIsInteger = std::is_integral_v<Scalar>;

/// number of rows - this is a scalar hence always 1
static int constexpr kRows = 1;
/// number of columns - this is a scalar hence always 1
static int constexpr kCols = 1;

/// Point set contains infinity?
static bool constexpr kHasInfinity =
std::numeric_limits<Scalar>::has_infinity;
/// Point set contains quite NAN?
static bool constexpr kHasQuietNan =
std::numeric_limits<Scalar>::has_quiet_NaN;
/// Point set contains signaling NAN?
static bool constexpr kHasSignalingNan =
std::numeric_limits<Scalar>::has_signaling_NaN;

/// Lowest value (e.g. typically large negative number)
static TPoint lowest() { return std::numeric_limits<Scalar>::lowest(); };
/// Smallest positive value
static TPoint min() { return std::numeric_limits<Scalar>::min(); };
/// Greatest value
static TPoint max() { return std::numeric_limits<Scalar>::max(); };
};

/// Trait for a multi-dimensional point.
///
/// Mathematically, we consider a point an element of a "vector space".
Expand Down Expand Up @@ -106,4 +69,30 @@ struct PointTraits<TPoint> {
/// ... plus a bunch more if we need them
};

// BEGIN(exclude from doxygen) \cond HIDDEN_SYMBOLS

// Single scalar specialization (1-dim case) of PointTraits
template <concepts::ScalarType TPoint>
struct PointTraits<TPoint> {
using Scalar = TPoint;

static bool constexpr kIsFloatingPoint = std::is_floating_point_v<Scalar>;
static bool constexpr kIsInteger = std::is_integral_v<Scalar>;

static int constexpr kRows = 1;
static int constexpr kCols = 1;

static bool constexpr kHasInfinity =
std::numeric_limits<Scalar>::has_infinity;
static bool constexpr kHasQuietNan =
std::numeric_limits<Scalar>::has_quiet_NaN;
static bool constexpr kHasSignalingNan =
std::numeric_limits<Scalar>::has_signaling_NaN;

static TPoint lowest() { return std::numeric_limits<Scalar>::lowest(); };
static TPoint min() { return std::numeric_limits<Scalar>::min(); };
static TPoint max() { return std::numeric_limits<Scalar>::max(); };
};
// END(exclude from doxygen) \endcond

} // namespace sophus
1 change: 1 addition & 0 deletions cpp/sophus/manifold/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ set(sophus_manifold_src_prefixes
product_manifold
quaternion
unit_vector
vector_manifold
)

set(sophus_manifold_h)
Expand Down
65 changes: 65 additions & 0 deletions cpp/sophus/manifold/complex.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,45 +13,66 @@

namespace sophus {

/// Generic complex number implementation
///
/// Impl class without any storage, but only static methods.
template <class TScalar>
class ComplexImpl {
public:
/// The underlying scalar type.
using Scalar = TScalar;
/// A complex number is a tuple.
static int constexpr kNumParams = 2;
/// Complex multiplication is commutative (and it is a field itself).
static bool constexpr kIsCommutative = true;

/// Parameter storage type - to be passed to static functions.
using Params = Eigen::Vector<Scalar, kNumParams>;

/// Return type of binary operator
///
/// In particular relevant mixing different scalars (such as double and
/// ceres::Jet).
template <class TCompatibleScalar>
using ParamsReturn = Eigen::Vector<
typename Eigen::ScalarBinaryOpTraits<Scalar, TCompatibleScalar>::
ReturnType,
2>;

// factories

/// Returns zero constant which is (0, 0).
static auto zero() -> Eigen::Vector<Scalar, 2> {
return Eigen::Vector<Scalar, 2>::Zero();
}

/// Returns one constant which is (1, 0).
static auto one() -> Eigen::Vector<Scalar, 2> {
return Eigen::Vector<Scalar, 2>(1.0, 0.0);
}

/// There are no particular constraints on the complex space and this function
/// returns always true.
static auto areParamsValid(Params const& /*unused*/)
-> sophus::Expected<Success> {
return sophus::Expected<Success>{};
}

/// Returns examples of valid parameters.
static auto paramsExamples() -> std::vector<Params> {
return pointExamples<Scalar, 2>();
}

/// Since there are no invalid parameters, this return an empty list.
static auto invalidParamsExamples() -> std::vector<Params> {
return std::vector<Params>({});
}

// operations

/// Complex addition given two complex numbers (a,i) and (b,j).
///
/// Returns (a+b, i+j).
template <class TCompatibleScalar>
static auto addition(
Eigen::Vector<Scalar, 2> const& lhs_real_imag,
Expand All @@ -60,6 +81,9 @@ class ComplexImpl {
return lhs_real_imag + rhs_real_imag;
}

/// Complex multiplication given two complex numbers (a,i) and (b,j).
///
/// Returns (a+b-i*j, a*j+b*i).
template <class TCompatibleScalar>
static auto multiplication(
Eigen::Vector<Scalar, 2> const& lhs_real_imag,
Expand All @@ -73,93 +97,134 @@ class ComplexImpl {
lhs_real_imag.y() * rhs_real_imag.x());
}

/// Given input (a,i), return complex conjugate (a, -i).
static auto conjugate(Eigen::Vector<Scalar, 2> const& a)
-> Eigen::Vector<Scalar, 2> {
return Eigen::Vector<Scalar, 2>(a.x(), -a.y());
}

/// Given input (a,i) return complex inverse (a, -i) / (a**2 + i**2).
static auto inverse(Eigen::Vector<Scalar, 2> const& real_imag)
-> Eigen::Vector<Scalar, 2> {
return conjugate(real_imag) / squaredNorm(real_imag);
}

/// Given input (a,i), returns complex norm sqrt(a**2 + i**2).
static auto norm(Eigen::Vector<Scalar, 2> const& real_imag) -> Scalar {
using std::hypot;
return hypot(real_imag.x(), real_imag.y());
}

/// Given input (a,i), returns square of complex norm a**2 + i**2.
static auto squaredNorm(Eigen::Vector<Scalar, 2> const& real_imag) -> Scalar {
return real_imag.squaredNorm();
}
};

/// Complex number class template.
///
/// A complex number is manifold with additional structure. In particular,
/// it is - like the quaternion numbers - a division ring and fulfills the
/// sophus::concepts::DivisionRingConcept. Furthermore, it is has commutative
/// multiplication (as opposed to the quaternion numbers) and hence is a field.
/// The complex numbers are the only other field of real numbers in addition to
/// the real numbers itself.
template <class TScalar>
class Complex {
public:
/// The underlying scalar type.
using Scalar = TScalar;
/// Type of the imaginary part is also a Scalar and hence has the some type
/// than the real part.
using Imag = Scalar;
/// The stateless implementation.
using Impl = ComplexImpl<Scalar>;

/// A complex number is a tuple.
static int constexpr kNumParams = 2;

/// Parameter storage type.
using Params = Eigen::Vector<Scalar, kNumParams>;

/// Return type of binary operator
///
/// In particular relevant mixing different scalars (such as double and
/// ceres::Jet).
template <class TCompatibleScalar>
using ComplexReturn =
Complex<typename Eigen::ScalarBinaryOpTraits<Scalar, TCompatibleScalar>::
ReturnType>;

// constructors and factories

/// Default constructor creates a zero complex number (0, 0).
Complex() : params_(Impl::zero()) {}

/// Copy constructor
Complex(Complex const&) = default;
/// Copy assignment
auto operator=(Complex const&) -> Complex& = default;

/// Returns zero complex number (0, 0).
static auto zero() -> Complex { return Complex::fromParams(Impl::zero()); }

/// Returns identity complex number (1, 0).
static auto one() -> Complex { return Complex::fromParams(Impl::one()); }

/// Constructs complex number from params tuple.
static auto fromParams(Params const& params) -> Complex {
Complex z(UninitTag{});
z.setParams(params);
return z;
}

/// Returns params tuple.
[[nodiscard]] auto params() const -> Params const& { return params_; }

/// Set state using params tuple.
void setParams(Params const& params) { params_ = params; }

/// Returns reference to real scalar.
auto real() -> Scalar& { return params_[0]; }
/// Returns reference to real scalar.
[[nodiscard]] auto real() const -> Scalar const& { return params_[0]; }

/// Returns reference to imaginary scalar.
auto imag() -> Scalar& { return params_[1]; }
/// Returns reference to imaginary scalar.
[[nodiscard]] auto imag() const -> Scalar const& { return params_[1]; }

/// Complex addition
template <class TCompatibleScalar>
auto operator+(Complex<TCompatibleScalar> const& other) const
-> ComplexReturn<TCompatibleScalar> {
return Complex::fromParams(Impl::addition(this->params_, other.params()));
}

/// Complex multiplication
template <class TCompatibleScalar>
auto operator*(Complex<TCompatibleScalar> const& other) const
-> ComplexReturn<TCompatibleScalar> {
return ComplexReturn<TCompatibleScalar>::fromParams(
Impl::multiplication(this->params_, other.params()));
}

/// Complex conjugate
[[nodiscard]] auto conjugate() const -> Complex {
return Complex::fromParams(Impl::conjugate(this->params_));
}

/// Complex inverse
[[nodiscard]] auto inverse() const -> Complex {
return Complex::fromParams(Impl::inverse(this->params_));
}

/// Complex norm
[[nodiscard]] auto norm() const -> Scalar {
return Impl::norm(this->params_);
}

/// Square of complex norm
[[nodiscard]] auto squaredNorm() const -> Scalar {
return Impl::squaredNorm(this->params_);
}
Expand Down
Loading

0 comments on commit 9792bec

Please sign in to comment.