16 template <s
int04 D,
typename E,
typename VertexXi,
typename VertexXj>
23 static constexpr int Di = VertexXiType::Dimension;
24 static constexpr int Dj = VertexXjType::Dimension;
32 typedef Eigen::Map<Eigen::Matrix<g_type, Di, Dj>
33 , Eigen::Matrix<g_type, Di, Dj>::Flags & Eigen::PacketAccessBit
36 typedef Eigen::Map<Eigen::Matrix<g_type, Dj, Di>
37 , Eigen::Matrix<g_type, Di, Dj>::Flags& Eigen::PacketAccessBit
76 lib_assert(i < 2,
"index out of bounds");
79 lib_assert(
dynamic_cast<VertexXi*
>(v) !=
nullptr,
"Invalid vertex type");
84 lib_assert(
dynamic_cast<VertexXj*
>(v) !=
nullptr,
"Invalid vertex type");
100 const bool fromNotFixed = !from->fixed();
101 const bool toNotFixed = !to->fixed();
102 if (!(fromNotFixed || toNotFixed))
108 const auto At = A.transpose().eval();
109 const auto Bt = B.transpose().eval();
110 const auto omega_error = (omega *
_error).eval();
120 const g_type err = this->
chi2();
121 EIGEN_ALIGN32 Eigen::Vector3<g_type> rho;
127 const auto AtOmega = (At * omega_eff).eval();
128 const auto BtOmega = (Bt * omega_eff).eval();
132 from->b().noalias() -= At * (omega_error * w_b);
133 from->A().noalias() += AtOmega * A;
138 to->b().noalias() -= Bt * (omega_error * w_b);
139 to->A().noalias() += BtOmega * B;
142 if (fromNotFixed && toNotFixed)
144 const auto Hij = (AtOmega * B).eval();
162 bool fromNotFixed = !(
m_a->fixed());
163 bool toNotFixed = !(
m_b->fixed());
165 if (fromNotFixed || toNotFixed)
172 m_a->b().noalias() += A.transpose() * (-omega *
_error);
173 m_a->A().noalias() += (A.transpose() * omega) * A;
179 _hessian.noalias() += (A.transpose() * omega) * B;
188 m_b->b().noalias() += B.transpose() * (-omega *
_error);
189 m_b->A().noalias() += B.transpose() * omega * B;
200 EIGEN_ALIGN32 Eigen::Vector3<g_type> rho;
205 auto a_trans = A.transpose();
206 auto b_trans = B.transpose();
207 auto b_weight_omega = weightedOmega * B;
210 auto a_weight_omega = weightedOmega * A;
211 m_a->b().noalias() += a_trans * -omega *
_error * rho[1];
212 m_a->A().noalias() += a_trans * a_weight_omega;
218 _hessian.noalias() += a_trans * b_weight_omega;
227 m_b->b().noalias() += b_trans * -omega *
_error * rho[1];
230 m_b->A().noalias() += b_trans * b_weight_omega;
241 return m_a->fixed() &&
m_b->fixed();
249 lib_assert(jacobianWorkspace.maxNumVertices() >= 2,
"Bad vertex size");
250 lib_assert(jacobianWorkspace.maxDimension() >= D *
Dj,
"Bad vertex dimension");
265 bool iNotFixed = !(vi->fixed());
266 bool jNotFixed = !(vj->fixed());
268 if (!iNotFixed && !jNotFixed)
270 const g_type delta = g_type(1e-9);
271 const g_type scalar = g_type(1.0) / (2 * delta);
278 g_type add_vi[VertexXiType::Dimension];
279 std::fill(add_vi, add_vi + VertexXiType::Dimension, g_type(0.0));
281 for (
int d = 0; d < VertexXiType::Dimension; ++d)
304 g_type add_vj[VertexXjType::Dimension];
305 std::fill(add_vj, add_vj + VertexXjType::Dimension, g_type(0.0));
307 for (
int d = 0; d < VertexXjType::Dimension; ++d)
327 _error = errorBeforeNumeric;
363 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
virtual void linearizeOplus()
Numerically linearizes the oplus operator by finite differences for both vertices.
const JacobianXjOplusType & jacobianOplusXj() const
returns the result of the linearization in the manifold space for the node xj
Eigen::Matrix< g_type, D, Dj >::AlignedMapType JacobianXjOplusType
Jacobian type w.r.t. vertex Xj.
Eigen::Map< Eigen::Matrix< g_type, Dj, Di >, Eigen::Matrix< g_type, Di, Dj >::Flags &Eigen::PacketAccessBit ? Eigen::Aligned :Eigen::Unaligned > HessianBlockTransposedType
Mapped transposed Hessian block type.
static constexpr int Dj
Dimension of the second vertex.
const JacobianXiOplusType & jacobianOplusXi() const
returns the result of the linearization in the manifold space for the node xi
Eigen::Map< Eigen::Matrix< g_type, Di, Dj >, Eigen::Matrix< g_type, Di, Dj >::Flags &Eigen::PacketAccessBit ? Eigen::Aligned :Eigen::Unaligned > HessianBlockType
Mapped Hessian block type.
static constexpr int Di
Dimension of the first vertex.
void linearizeOplusAndConstructQuadraticForm(JacobianWorkspace &jacobianWorkspace) final override
Linearizes the oplus operator and constructs the quadratic form in one step.
bool allVerticesFixed() const final override
Returns true if both vertices are fixed.
Eigen::Matrix< g_type, D, Di >::AlignedMapType JacobianXiOplusType
Jacobian type w.r.t. vertex Xi.
HessianBlockTransposedType _hessianTransposed
Mapped transposed Hessian block.
bool _hessianRowMajor
Whether the Hessian block is stored in row-major order.
HessianBlockType _hessian
Mapped Hessian block for the off-diagonal (i,j) entry.
virtual void setVertex(uint04 i, HyperGraph::HGVertex *v) final override
Sets vertex i to the given pointer, with type-checking.
virtual const HyperGraph::HGVertex * vertex(uint04 i) const final override
Returns a const pointer to vertex i (0 or 1).
VertexXj * m_b
Pointer to the second (target) vertex.
VertexXi * m_a
Pointer to the first (source) vertex.
JacobianXiOplusType _jacobianOplusXi
Jacobian of the error w.r.t. vertex Xi.
BaseEdge< D, E >::InformationType InformationType
The information matrix type.
BaseEdge< D, E >::Measurement Measurement
The measurement type.
VertexXj VertexXjType
Type of the second (target) vertex.
void mapHessianMemory(g_type *d, int i, int j, bool rowMajor) final override
Maps the Hessian block memory to an external buffer.
JacobianXjOplusType _jacobianOplusXj
Jacobian of the error w.r.t. vertex Xj.
VertexXi VertexXiType
Type of the first (source) vertex.
BaseEdge< D, E >::ErrorVector ErrorVector
The error vector type.
BaseBinaryEdge()
Constructs an empty binary edge with null-mapped Hessian and Jacobian memory.
virtual HyperGraph::HGVertex * vertex(uint04 i) final override
Returns a mutable pointer to vertex i (0 or 1).
virtual uint04 vertexCount() const final override
Returns the number of vertices (always 2 for binary edges).
void constructQuadraticForm2()
Constructs the quadratic form using an optimized evaluation order.
void constructQuadraticForm()
Constructs the quadratic form (Hessian blocks and gradient) from the linearized edge.
Base class for edges with a fixed-size error vector and measurement type.
g_type chi2() const final override
InformationType robustInformation(const Eigen::Vector3< g_type > &rho) const
static constexpr sint04 Dimension
InformationType _information
Eigen::Matrix< g_type, t_dims, t_dims > InformationType
Fixed-size information (inverse covariance) matrix type.
const InformationType & information() const
Returns a const reference to the information matrix.
const ErrorVector & error() const
Eigen::Matrix< g_type, t_dims, 1 > ErrorVector
Fixed-size error vector type.
E Measurement
The measurement type stored by this edge.
abstract Vertex, your types must derive from that one
provide memory workspace for computing the Jacobians
virtual void computeError()=0
Computes the error of the edge and stores it internally.
RobustKernel * robustKernel() const
if NOT NULL, error of this edge will be robustifed with the kernel
virtual void robustify(g_type squaredError, Eigen::Vector3< g_type > &rho) const =0
compute the scaling factor for a error: The error is e^T Omega e The output rho is rho[0]: The actual...
The primary namespace for the NDEVR SDK.
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.