27 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
28 OptimizableGraph::Vertex* BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::createFrom(){
29 return new VertexXiType();
32 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
33 OptimizableGraph::Vertex* BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::createTo(){
34 return new VertexXjType();
38 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
39 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::resize(
size_t size)
42 std::cerr <<
"WARNING, attempting to resize binary edge " << BaseEdge<D, E>::id() <<
" to " << size << std::endl;
44 BaseEdge<D, E>::resize(size);
47 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
48 bool BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::allVerticesFixed()
const 50 return (static_cast<const VertexXiType*> (_vertices[0])->fixed() &&
51 static_cast<const VertexXjType*> (_vertices[1])->fixed());
54 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
55 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::constructQuadraticForm()
57 VertexXiType* from =
static_cast<VertexXiType*
>(_vertices[0]);
58 VertexXjType* to =
static_cast<VertexXjType*
>(_vertices[1]);
61 const JacobianXiOplusType& A = jacobianOplusXi();
62 const JacobianXjOplusType& B = jacobianOplusXj();
65 bool fromNotFixed = !(from->fixed());
66 bool toNotFixed = !(to->fixed());
68 if (fromNotFixed || toNotFixed) {
70 from->lockQuadraticForm();
71 to->lockQuadraticForm();
73 const InformationType& omega = _information;
74 Matrix<double, D, 1> omega_r = - omega * _error;
75 if (this->robustKernel() == 0) {
77 Matrix<double, VertexXiType::Dimension, D> AtO = A.transpose() * omega;
78 from->b().noalias() += A.transpose() * omega_r;
79 from->A().noalias() += AtO*A;
82 _hessianTransposed.noalias() += B.transpose() * AtO.transpose();
84 _hessian.noalias() += AtO * B;
88 to->b().noalias() += B.transpose() * omega_r;
89 to->A().noalias() += B.transpose() * omega * B;
92 double error = this->chi2();
94 this->robustKernel()->robustify(error, rho);
95 InformationType weightedOmega = this->robustInformation(rho);
101 from->b().noalias() += A.transpose() * omega_r;
102 from->A().noalias() += A.transpose() * weightedOmega * A;
104 if (_hessianRowMajor)
105 _hessianTransposed.noalias() += B.transpose() * weightedOmega * A;
107 _hessian.noalias() += A.transpose() * weightedOmega * B;
111 to->b().noalias() += B.transpose() * omega_r;
112 to->A().noalias() += B.transpose() * weightedOmega * B;
116 to->unlockQuadraticForm();
117 from->unlockQuadraticForm();
122 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
123 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::linearizeOplus(JacobianWorkspace& jacobianWorkspace)
125 new (&_jacobianOplusXi) JacobianXiOplusType(jacobianWorkspace.workspaceForVertex(0), D, Di);
126 new (&_jacobianOplusXj) JacobianXjOplusType(jacobianWorkspace.workspaceForVertex(1), D, Dj);
130 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
131 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::linearizeOplus()
133 VertexXiType* vi =
static_cast<VertexXiType*
>(_vertices[0]);
134 VertexXjType* vj =
static_cast<VertexXjType*
>(_vertices[1]);
136 bool iNotFixed = !(vi->fixed());
137 bool jNotFixed = !(vj->fixed());
139 if (!iNotFixed && !jNotFixed)
143 vi->lockQuadraticForm();
144 vj->lockQuadraticForm();
147 const double delta = 1e-9;
148 const double scalar = 1.0 / (2*delta);
149 ErrorVector errorBak;
150 ErrorVector errorBeforeNumeric = _error;
154 double add_vi[VertexXiType::Dimension];
155 std::fill(add_vi, add_vi + VertexXiType::Dimension, 0.0);
157 for (
int d = 0;
d < VertexXiType::Dimension; ++
d) {
172 _jacobianOplusXi.col(d) = scalar * errorBak;
178 double add_vj[VertexXjType::Dimension];
179 std::fill(add_vj, add_vj + VertexXjType::Dimension, 0.0);
181 for (
int d = 0;
d < VertexXjType::Dimension; ++
d) {
196 _jacobianOplusXj.col(d) = scalar * errorBak;
200 _error = errorBeforeNumeric;
202 vj->unlockQuadraticForm();
203 vi->unlockQuadraticForm();
207 template <
int D,
typename E,
typename VertexXiType,
typename VertexXjType>
208 void BaseBinaryEdge<D, E, VertexXiType, VertexXjType>::mapHessianMemory(
double* d,
int i,
int j,
bool rowMajor)
213 new (&_hessianTransposed) HessianBlockTransposedType(d, VertexXjType::Dimension, VertexXiType::Dimension);
215 new (&_hessian) HessianBlockType(d, VertexXiType::Dimension, VertexXjType::Dimension);
217 _hessianRowMajor = rowMajor;