LinearizedFactor.cpp
Go to the documentation of this file.
1 /* ----------------------------------------------------------------------------
2 
3  * GTSAM Copyright 2010, Georgia Tech Research Corporation,
4  * Atlanta, Georgia 30332-0415
5  * All Rights Reserved
6  * Authors: Frank Dellaert, et al. (see THANKS for the full author list)
7 
8  * See LICENSE for the license information
9 
10  * -------------------------------------------------------------------------- */
11 
19 #include <iostream>
20 
21 namespace gtsam {
22 
23 /* ************************************************************************* */
25  const GaussianFactor::shared_ptr& gaussian, const Values& lin_points)
26 : NonlinearFactor(gaussian->keys())
27 {
28  // Extract the keys and linearization points
29  for(const Key& key: gaussian->keys()) {
30  // extract linearization point
31  assert(lin_points.exists(key));
32  this->lin_points_.insert(key, lin_points.at(key));
33  }
34 }
35 
36 /* ************************************************************************* */
37 // LinearizedJacobianFactor
38 /* ************************************************************************* */
40 }
41 
42 /* ************************************************************************* */
44  const JacobianFactor::shared_ptr& jacobian, const Values& lin_points)
45 : Base(jacobian, lin_points) {
46 
47  // Create the dims array
48  size_t *dims = (size_t *)alloca(sizeof(size_t) * (jacobian->size() + 1));
49  size_t index = 0;
50  for(JacobianFactor::const_iterator iter = jacobian->begin(); iter != jacobian->end(); ++iter) {
51  dims[index++] = jacobian->getDim(iter);
52  }
53  dims[index] = 1;
54 
55  // Update the BlockInfo accessor
56  Ab_ = VerticalBlockMatrix(dims, dims+jacobian->size()+1, jacobian->rows());
57  // Get the Ab matrix from the Jacobian factor, with any covariance baked in
58  Ab_.matrix() = jacobian->augmentedJacobian();
59 }
60 
61 /* ************************************************************************* */
62 void LinearizedJacobianFactor::print(const std::string& s, const KeyFormatter& keyFormatter) const {
63 
64  std::cout << s << std::endl;
65 
66  std::cout << "Nonlinear Keys: ";
67  for(const Key& key: this->keys())
68  std::cout << keyFormatter(key) << " ";
69  std::cout << std::endl;
70 
71  for(const_iterator key=begin(); key!=end(); ++key) {
72  std::cout << "A[" << keyFormatter(*key) << "]=\n" << A(*key) << std::endl;
73  }
74  std::cout << "b=\n" << b() << std::endl;
75 
76  lin_points_.print("Linearization Point: ");
77 }
78 
79 /* ************************************************************************* */
81 
82  const This *e = dynamic_cast<const This*> (&expected);
83  if (e) {
84 
85  Matrix thisMatrix = this->Ab_.range(0, Ab_.nBlocks());
86  Matrix rhsMatrix = e->Ab_.range(0, Ab_.nBlocks());
87 
88  return Base::equals(expected, tol)
89  && lin_points_.equals(e->lin_points_, tol)
90  && equal_with_abs_tol(thisMatrix, rhsMatrix, tol);
91  } else {
92  return false;
93  }
94 }
95 
96 /* ************************************************************************* */
98  Vector errorVector = error_vector(c);
99  return 0.5 * errorVector.dot(errorVector);
100 }
101 
102 /* ************************************************************************* */
103 std::shared_ptr<GaussianFactor>
105 
106  // Create the 'terms' data structure for the Jacobian constructor
107  std::vector<std::pair<Key, Matrix> > terms;
108  for(Key key: keys()) {
109  terms.push_back(std::make_pair(key, this->A(key)));
110  }
111 
112  // compute rhs
113  Vector b = -error_vector(c);
114 
115  return std::shared_ptr<GaussianFactor>(new JacobianFactor(terms, b, noiseModel::Unit::Create(dim())));
116 }
117 
118 /* ************************************************************************* */
120 
121  Vector errorVector = -b();
122 
123  for(Key key: this->keys()) {
124  const Value& newPt = c.at(key);
125  const Value& linPt = lin_points_.at(key);
126  Vector d = linPt.localCoordinates_(newPt);
127  const constABlock A = this->A(key);
128  errorVector += A * d;
129  }
130 
131  return errorVector;
132 }
133 
134 /* ************************************************************************* */
135 // LinearizedHessianFactor
136 /* ************************************************************************* */
138 }
139 
140 /* ************************************************************************* */
142  const HessianFactor::shared_ptr& hessian, const Values& lin_points)
143  : Base(hessian, lin_points), info_(hessian->info()) {}
144 
145 /* ************************************************************************* */
146 void LinearizedHessianFactor::print(const std::string& s, const KeyFormatter& keyFormatter) const {
147 
148  std::cout << s << std::endl;
149 
150  std::cout << "Nonlinear Keys: ";
151  for(const Key& key: this->keys())
152  std::cout << keyFormatter(key) << " ";
153  std::cout << std::endl;
154 
155  gtsam::print(Matrix(info_.selfadjointView()), "Ab^T * Ab: ");
156 
157  lin_points_.print("Linearization Point: ");
158 }
159 
160 /* ************************************************************************* */
162 
163  const This *e = dynamic_cast<const This*> (&expected);
164  if (e) {
165 
166  Matrix thisMatrix = this->info_.selfadjointView();
167  thisMatrix(thisMatrix.rows()-1, thisMatrix.cols()-1) = 0.0;
168  Matrix rhsMatrix = e->info_.selfadjointView();
169  rhsMatrix(rhsMatrix.rows()-1, rhsMatrix.cols()-1) = 0.0;
170 
171  return Base::equals(expected, tol)
172  && lin_points_.equals(e->lin_points_, tol)
173  && equal_with_abs_tol(thisMatrix, rhsMatrix, tol);
174  } else {
175  return false;
176  }
177 }
178 
179 /* ************************************************************************* */
181 
182  // Construct an error vector in key-order from the Values
183  Vector dx = Vector::Zero(dim());
184  size_t index = 0;
185  for(unsigned int i = 0; i < this->size(); ++i){
186  Key key = this->keys()[i];
187  const Value& newPt = c.at(key);
188  const Value& linPt = lin_points_.at(key);
189  dx.segment(index, linPt.dim()) = linPt.localCoordinates_(newPt);
190  index += linPt.dim();
191  }
192 
193  // error 0.5*(f - 2*x'*g + x'*G*x)
194  double f = constantTerm();
195  double xtg = dx.dot(linearTerm());
196  double xGx = dx.transpose() * squaredTerm() * dx;
197 
198  return 0.5 * (f - 2.0 * xtg + xGx);
199 }
200 
201 /* ************************************************************************* */
202 std::shared_ptr<GaussianFactor>
204 
205  // Construct an error vector in key-order from the Values
206  Vector dx = Vector::Zero(dim());
207  size_t index = 0;
208  for(unsigned int i = 0; i < this->size(); ++i){
209  Key key = this->keys()[i];
210  const Value& newPt = c.at(key);
211  const Value& linPt = lin_points_.at(key);
212  dx.segment(index, linPt.dim()) = linPt.localCoordinates_(newPt);
213  index += linPt.dim();
214  }
215 
216  // f2 = f1 - 2*dx'*g1 + dx'*G1*dx
217  //newInfo(this->size(), this->size())(0,0) += -2*dx.dot(linearTerm()) + dx.transpose() * squaredTerm().selfadjointView<Eigen::Upper>() * dx;
218  double f = constantTerm() - 2*dx.dot(linearTerm()) + dx.transpose() * squaredTerm() * dx;
219 
220  // g2 = g1 - G1*dx
221  //newInfo.rangeColumn(0, this->size(), this->size(), 0) -= squaredTerm().selfadjointView<Eigen::Upper>() * dx;
222  Vector g = linearTerm() - squaredTerm() * dx;
223  std::vector<Vector> gs;
224  std::size_t offset = 0;
225  for(DenseIndex i = 0; i < info_.nBlocks()-1; ++i) {
226  const std::size_t dim = info_.getDim(i);
227  gs.push_back(g.segment(offset, dim));
228  offset += dim;
229  }
230 
231  // G2 = G1
232  // Do Nothing
233  std::vector<Matrix> Gs;
234  for(DenseIndex i = 0; i < info_.nBlocks()-1; ++i) {
235  Gs.push_back(info_.diagonalBlock(i));
236  for(DenseIndex j = i + 1; j < info_.nBlocks()-1; ++j) {
237  Gs.push_back(info_.aboveDiagonalBlock(i, j));
238  }
239  }
240 
241  // Create a Hessian Factor from the modified info matrix
242  //return std::shared_ptr<GaussianFactor>(new HessianFactor(js, newInfo));
243  return std::shared_ptr<GaussianFactor>(new HessianFactor(keys(), Gs, gs, f));
244 }
245 
246 } // \namespace aspn
void print(const Matrix &A, const string &s, ostream &stream)
Definition: Matrix.cpp:155
const gtsam::Symbol key('X', 0)
std::shared_ptr< This > shared_ptr
A shared_ptr to this class.
DenseIndex nBlocks() const
Block count.
const ValueType at(Key j) const
Definition: Values-inl.h:204
Matrix expected
Definition: testMatrix.cpp:971
bool equals(const NonlinearFactor &expected, double tol=1e-9) const override
size_t size() const
Definition: Factor.h:159
Vector error_vector(const Values &c) const
Eigen::MatrixXd Matrix
Definition: base/Matrix.h:39
Scalar Scalar * c
Definition: benchVecAdd.cpp:17
set noclip points set clip one set noclip two set bar set border lt lw set xdata set ydata set zdata set x2data set y2data set boxwidth set dummy y set format x g set format y g set format x2 g set format y2 g set format z g set angles radians set nogrid set key title set key left top Right noreverse box linetype linewidth samplen spacing width set nolabel set noarrow set nologscale set logscale x set set pointsize set encoding default set nopolar set noparametric set set set set surface set nocontour set clabel set mapping cartesian set nohidden3d set cntrparam order set cntrparam linear set cntrparam levels auto set cntrparam points set size set set xzeroaxis lt lw set x2zeroaxis lt lw set yzeroaxis lt lw set y2zeroaxis lt lw set tics in set ticslevel set tics set mxtics default set mytics default set mx2tics default set my2tics default set xtics border mirror norotate autofreq set ytics border mirror norotate autofreq set ztics border nomirror norotate autofreq set nox2tics set noy2tics set timestamp bottom norotate offset
const Matrix & matrix() const
iterator iter(handle obj)
Definition: pytypes.h:2273
std::shared_ptr< GaussianFactor > linearize(const Values &c) const override
size_t dim() const override
virtual Vector localCoordinates_(const Value &value) const =0
ptrdiff_t DenseIndex
The index type for Eigen objects.
Definition: types.h:108
void g(const string &key, int i)
Definition: testBTree.cpp:41
static shared_ptr Create(size_t dim)
Definition: NoiseModel.h:610
else if n * info
virtual bool equals(const NonlinearFactor &f, double tol=1e-9) const
const_iterator end() const
Definition: Factor.h:148
void print(const std::string &str="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const
Definition: Values.cpp:66
Eigen::SelfAdjointView< constBlock, Eigen::Upper > selfadjointView(DenseIndex I, DenseIndex J) const
Return the square sub-matrix that contains blocks(i:j, i:j).
DenseIndex nBlocks() const
Block count.
double error(const Values &c) const override
Eigen::VectorXd Vector
Definition: Vector.h:38
size_t dim() const override
A dummy factor that allows a linear factor to act as a nonlinear factor.
const constBVector b() const
Point2(* f)(const Point3 &, OptionalJacobian< 2, 3 >)
Array< double, 1, 3 > e(1./3., 0.5, 2.)
RealScalar s
bool equals(const Values &other, double tol=1e-9) const
Definition: Values.cpp:77
std::shared_ptr< This > shared_ptr
shared_ptr to this class
std::function< std::string(Key)> KeyFormatter
Typedef for a function to format a key, i.e. to convert it to a string.
Definition: Key.h:35
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
virtual size_t dim() const =0
std::shared_ptr< This > shared_ptr
shared_ptr to this class
bool equal_with_abs_tol(const Eigen::DenseBase< MATRIX > &A, const Eigen::DenseBase< MATRIX > &B, double tol=1e-9)
Definition: base/Matrix.h:80
Block range(DenseIndex startBlock, DenseIndex endBlock)
traits
Definition: chartTesting.h:28
const constABlock A() const
bool equals(const NonlinearFactor &expected, double tol=1e-9) const override
Expression of a fixed-size or dynamic-size block.
Definition: Block.h:103
std::shared_ptr< GaussianFactor > linearize(const Values &c) const override
Eigen::SelfAdjointView< constBlock, Eigen::Upper > squaredTerm() const
double error(const Values &c) const override
A Gaussian factor using the canonical parameters (information form)
const KeyVector & keys() const
Access the factor&#39;s involved variable keys.
Definition: Factor.h:142
void insert(Key j, const Value &val)
Definition: Values.cpp:155
const G double tol
Definition: Group.h:86
Eigen::SelfAdjointView< Block, Eigen::Upper > diagonalBlock(DenseIndex J)
Return the J&#39;th diagonal block as a self adjoint view.
KeyVector::const_iterator const_iterator
Const iterator over keys.
Definition: Factor.h:82
const KeyVector keys
DenseIndex getDim(DenseIndex block) const
Number of dimensions for variable on this diagonal block.
const_iterator begin() const
Definition: Factor.h:145
bool exists(Key j) const
Definition: Values.cpp:93
void print(const std::string &s="", const KeyFormatter &keyFormatter=DefaultKeyFormatter) const override
std::uint64_t Key
Integer nonlinear key type.
Definition: types.h:102
constBlock aboveDiagonalBlock(DenseIndex I, DenseIndex J) const
Get block above the diagonal (I, J).
std::ptrdiff_t j


gtsam
Author(s):
autogenerated on Tue Jul 4 2023 02:34:33