ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
manifold.h
Go to the documentation of this file.
1 // ----------------------------------------------------------------------------
2 // - CloudViewer: www.cloudViewer.org -
3 // ----------------------------------------------------------------------------
4 // Copyright (c) 2018-2024 www.cloudViewer.org
5 // SPDX-License-Identifier: MIT
6 // ----------------------------------------------------------------------------
7 
8 #pragma once
9 
10 #include <ceres/ceres.h>
11 #include <ceres/rotation.h>
12 
13 namespace colmap {
14 
15 #include <cmath>
16 
17 #include "ceres/ceres.h"
18 
19 inline void SetQuaternionManifold(ceres::Problem* problem, double* quat_xyzw) {
20 #if CERES_VERSION_MAJOR >= 3 || \
21  (CERES_VERSION_MAJOR == 2 && CERES_VERSION_MINOR >= 1)
22  problem->SetManifold(quat_xyzw, new ceres::EigenQuaternionManifold);
23 #else
24  problem->SetParameterization(quat_xyzw,
25  new ceres::EigenQuaternionParameterization);
26 #endif
27 }
28 
29 inline void SetSubsetManifold(int size,
30  const std::vector<int>& constant_params,
31  ceres::Problem* problem,
32  double* params) {
33 #if CERES_VERSION_MAJOR >= 3 || \
34  (CERES_VERSION_MAJOR == 2 && CERES_VERSION_MINOR >= 1)
35  problem->SetManifold(params,
36  new ceres::SubsetManifold(size, constant_params));
37 #else
38  problem->SetParameterization(
39  params, new ceres::SubsetParameterization(size, constant_params));
40 #endif
41 }
42 
43 template <int size>
44 inline void SetSphereManifold(ceres::Problem* problem, double* params) {
45 #if CERES_VERSION_MAJOR >= 3 || \
46  (CERES_VERSION_MAJOR == 2 && CERES_VERSION_MINOR >= 1)
47  problem->SetManifold(params, new ceres::SphereManifold<size>);
48 #else
49  problem->SetParameterization(
50  params, new ceres::HomogeneousVectorParameterization(size));
51 #endif
52 }
53 
54 // Use an exponential function to ensure the variable to be strictly positive
55 // Generally applicable for scale parameters (e.g. in colmap::Sim3d)
56 #if CERES_VERSION_MAJOR >= 3 || \
57  (CERES_VERSION_MAJOR == 2 && CERES_VERSION_MINOR >= 1)
58 template <int AmbientSpaceDimension>
59 class PositiveExponentialManifold : public ceres::Manifold {
60 public:
61  static_assert(ceres::DYNAMIC == Eigen::Dynamic,
62  "ceres::DYNAMIC needs to be the same as Eigen::Dynamic.");
63 
64  PositiveExponentialManifold() : size_{AmbientSpaceDimension} {}
65  explicit PositiveExponentialManifold(int size) : size_{size} {
66  if (AmbientSpaceDimension != Eigen::Dynamic) {
67  CHECK_EQ(AmbientSpaceDimension, size)
68  << "Specified size by template parameter differs from the "
69  "supplied "
70  "one.";
71  } else {
72  CHECK_GT(size_, 0) << "The size of the manifold needs to be a "
73  "positive integer.";
74  }
75  }
76 
77  bool Plus(const double* x,
78  const double* delta,
79  double* x_plus_delta) const override {
80  for (int i = 0; i < size_; ++i) {
81  x_plus_delta[i] = x[i] * std::exp(delta[i]);
82  }
83  return true;
84  }
85 
86  bool PlusJacobian(const double* x, double* jacobian) const override {
87  for (int i = 0; i < size_; ++i) {
88  jacobian[size_ * i + i] = x[i];
89  }
90  return true;
91  }
92 
93  virtual bool Minus(const double* y,
94  const double* x,
95  double* y_minus_x) const override {
96  for (int i = 0; i < size_; ++i) {
97  y_minus_x[i] = std::log(y[i] / x[i]);
98  }
99  return true;
100  }
101 
102  virtual bool MinusJacobian(const double* x,
103  double* jacobian) const override {
104  for (int i = 0; i < size_; ++i) {
105  jacobian[size_ * i + i] = 1.0 / x[i];
106  }
107  return true;
108  }
109 
110  int AmbientSize() const override {
111  return AmbientSpaceDimension == ceres::DYNAMIC ? size_
112  : AmbientSpaceDimension;
113  }
114  int TangentSize() const override { return AmbientSize(); }
115 
116 private:
117  const int size_{};
118 };
119 #else
121  : public ceres::LocalParameterization {
122 public:
124  CHECK_GT(size_, 0)
125  << "The size of the manifold needs to be a positive integer.";
126  }
128 
129  bool Plus(const double* x,
130  const double* delta,
131  double* x_plus_delta) const override {
132  for (int i = 0; i < size_; ++i) {
133  x_plus_delta[i] = x[i] * std::exp(delta[i]);
134  }
135  return true;
136  }
137 
138  bool ComputeJacobian(const double* x, double* jacobian) const override {
139  for (int i = 0; i < size_; ++i) {
140  jacobian[size_ * i + i] = x[i];
141  }
142  return true;
143  }
144 
145  int GlobalSize() const override { return size_; }
146  int LocalSize() const override { return size_; }
147 
148 private:
149  const int size_{};
150 };
151 
152 #endif
153 
154 template <int size>
155 inline void SetPositiveExponentialManifold(ceres::Problem* problem,
156  double* params) {
157 #if CERES_VERSION_MAJOR >= 3 || \
158  (CERES_VERSION_MAJOR == 2 && CERES_VERSION_MINOR >= 1)
159  problem->SetManifold(params, new PositiveExponentialManifold<size>);
160 #else
161  problem->SetParameterization(params,
163 #endif
164 }
165 
166 inline int ParameterBlockTangentSize(ceres::Problem* problem,
167  const double* param) {
168 #if CERES_VERSION_MAJOR >= 3 || \
169  (CERES_VERSION_MAJOR == 2 && CERES_VERSION_MINOR >= 1)
170  return problem->ParameterBlockTangentSize(param);
171 #else
172  return problem->ParameterBlockLocalSize(param);
173 #endif
174 }
175 
176 } // namespace colmap
int size
int64_t size_
Definition: FilePLY.cpp:37
bool ComputeJacobian(const double *x, double *jacobian) const override
Definition: manifold.h:138
bool Plus(const double *x, const double *delta, double *x_plus_delta) const override
Definition: manifold.h:129
normal_z y
normal_z x
int ParameterBlockTangentSize(ceres::Problem *problem, const double *param)
Definition: manifold.h:166
void SetQuaternionManifold(ceres::Problem *problem, double *quat_xyzw)
Definition: manifold.h:19
void SetPositiveExponentialManifold(ceres::Problem *problem, double *params)
Definition: manifold.h:155
void SetSubsetManifold(int size, const std::vector< int > &constant_params, ceres::Problem *problem, double *params)
Definition: manifold.h:29
void SetSphereManifold(ceres::Problem *problem, double *params)
Definition: manifold.h:44