@@ -31,7 +31,7 @@ namespace detail {
3131/* * Convenience base class to add aliases `X1`, `X2`, ..., `X6` -> ValueType<N>.
3232 * Usage example:
3333 * ```
34- * class MyFactor : public NoiseModelFactorN< Pose3, Point3>,
34+ * class MyFactor : public NoiseModelFactorT<Vector, Pose3, Point3>,
3535 * public NoiseModelFactorAliases<Pose3, Point3> {
3636 * // class implementation ...
3737 * };
@@ -94,9 +94,9 @@ struct NoiseModelFactorAliases<T1, T2, T3, T4, T5, T6, TExtra...> {
9494 * between a Pose3 and Point3 could be implemented like so:
9595 *
9696 * ~~~~~~~~~~~~~~~~~~~~{.cpp}
97- * class MyFactor : public NoiseModelFactorN< Pose3, Point3> {
97+ * class MyFactor : public NoiseModelFactorT<Vector, Pose3, Point3> {
9898 * public:
99- * using Base = NoiseModelFactorN< Pose3, Point3>;
99+ * using Base = NoiseModelFactorT<Vector, Pose3, Point3>;
100100 *
101101 * MyFactor(Key pose_key, Key point_key, const SharedNoiseModel& noiseModel)
102102 * : Base(noiseModel, pose_key, point_key) {}
@@ -121,7 +121,7 @@ struct NoiseModelFactorAliases<T1, T2, T3, T4, T5, T6, TExtra...> {
121121 * return Vector1(error);
122122 * }
123123 * };
124- *
124+ *
125125 * // Unit Test
126126 * TEST(NonlinearFactor, MyFactor) {
127127 * MyFactor f(X(1), X(2), noiseModel::Unit::Create(1));
@@ -138,8 +138,8 @@ struct NoiseModelFactorAliases<T1, T2, T3, T4, T5, T6, TExtra...> {
138138 * are typically more general than just vectors, e.g., Rot3 or Pose3, which are
139139 * objects in non-linear manifolds (Lie groups).
140140 */
141- template <class ... ValueTypes>
142- class NoiseModelFactorN
141+ template <class OutputVec , class ... ValueTypes>
142+ class NoiseModelFactorT
143143 : public NoiseModelFactor,
144144 public detail::NoiseModelFactorAliases<ValueTypes...> {
145145 public:
@@ -148,9 +148,9 @@ class NoiseModelFactorN
148148
149149 using NoiseModelFactor::unwhitenedError;
150150
151- protected:
151+ protected:
152152 using Base = NoiseModelFactor;
153- using This = NoiseModelFactorN< ValueTypes...>;
153+ using This = NoiseModelFactorT<OutputVec, ValueTypes...>;
154154
155155 // / @name SFINAE aliases
156156 // / @{
@@ -173,23 +173,26 @@ class NoiseModelFactorN
173173 * are all references to a matrix or not. It will be used
174174 * to choose the right overload of evaluateError.
175175 */
176- template <typename Ret, typename ...Args>
177- using AreAllMatrixRefs = std:: enable_if_t <(... &&
178- std::is_convertible<Args, Matrix&>::value), Ret>;
179-
180- template <typename Arg>
176+ template <typename Ret, typename ... Args>
177+ using AreAllMatrixRefs =
178+ std::enable_if_t <(... && std:: is_convertible<Args, Matrix&>::value), Ret>;
179+
180+ template <typename Arg>
181181 using IsMatrixPointer = std::is_same<typename std::decay_t <Arg>, Matrix*>;
182182
183- template <typename Arg>
184- using IsNullpointer = std::is_same<typename std::decay_t <Arg>, std::nullptr_t >;
183+ template <typename Arg>
184+ using IsNullpointer =
185+ std::is_same<typename std::decay_t <Arg>, std::nullptr_t >;
185186
186187 /* * A helper alias to check if a list of args
187188 * are all pointers to a matrix or not. It will be used
188189 * to choose the right overload of evaluateError.
189190 */
190- template <typename Ret, typename ...Args>
191- using AreAllMatrixPtrs = std::enable_if_t <(... &&
192- (IsMatrixPointer<Args>::value || IsNullpointer<Args>::value)), Ret>;
191+ template <typename Ret, typename ... Args>
192+ using AreAllMatrixPtrs =
193+ std::enable_if_t <(... && (IsMatrixPointer<Args>::value ||
194+ IsNullpointer<Args>::value)),
195+ Ret>;
193196
194197 // / @}
195198
@@ -211,12 +214,12 @@ class NoiseModelFactorN
211214 template <typename T = void >
212215 using MatrixTypeT = Matrix;
213216
214- public:
217+ public:
215218 /* *
216219 * The type of the I'th template param can be obtained as ValueType<I>.
217220 * I is 1-indexed for backwards compatibility/consistency! So for example,
218221 * ```
219- * using Factor = NoiseModelFactorN< Pose3, Point3>;
222+ * using Factor = NoiseModelFactorT<Vector, Pose3, Point3>;
220223 * Factor::ValueType<1> // Pose3
221224 * Factor::ValueType<2> // Point3
222225 * // Factor::ValueType<0> // ERROR! Will not compile.
@@ -236,55 +239,55 @@ class NoiseModelFactorN
236239 typename std::tuple_element<I - 1 , std::tuple<ValueTypes...>>::type;
237240
238241 public:
239-
240242 // / @name Constructors
241243 // / @{
242244
243245 // / Default Constructor for I/O
244- NoiseModelFactorN () {}
246+ NoiseModelFactorT () {}
245247
246248 /* *
247249 * Constructor.
248- * Example usage: NoiseModelFactorN (noise, key1, key2, ..., keyN)
250+ * Example usage: NoiseModelFactorT (noise, key1, key2, ..., keyN)
249251 * @param noiseModel Shared pointer to noise model.
250252 * @param keys Keys for the variables in this factor, passed in as separate
251253 * arguments.
252254 */
253- NoiseModelFactorN (const SharedNoiseModel& noiseModel,
255+ NoiseModelFactorT (const SharedNoiseModel& noiseModel,
254256 KeyType<ValueTypes>... keys)
255257 : Base(noiseModel, std::array<Key, N>{keys...}) {}
256258
257259 /* *
258260 * Constructor.
259- * Example usage: `NoiseModelFactorN(noise, {key1, key2, ..., keyN})`
260- * Example usage: `NoiseModelFactorN(noise, keys)` where keys is a vector<Key>
261+ * Example usage: `NoiseModelFactorT(noise, {key1, key2, ..., keyN})`
262+ * Example usage: `NoiseModelFactorT(noise, keys)` where keys is a
263+ * vector<Key>
261264 * @param noiseModel Shared pointer to noise model.
262265 * @param keys A container of keys for the variables in this factor.
263266 */
264267 template <typename CONTAINER = std::initializer_list<Key>,
265268 typename = IsContainerOfKeys<CONTAINER>>
266- NoiseModelFactorN (const SharedNoiseModel& noiseModel, CONTAINER keys)
269+ NoiseModelFactorT (const SharedNoiseModel& noiseModel, CONTAINER keys)
267270 : Base(noiseModel, keys) {
268271 if (keys.size () != N) {
269272 throw std::invalid_argument (
270- " NoiseModelFactorN : wrong number of keys given" );
273+ " NoiseModelFactorT : wrong number of keys given" );
271274 }
272275 }
273276
274277 // / @}
275278
276- ~NoiseModelFactorN () override {}
279+ ~NoiseModelFactorT () override {}
277280
278281 /* * Returns a key. Usage: `key<I>()` returns the I'th key.
279282 * I is 1-indexed for backwards compatibility/consistency! So for example,
280283 * ```
281- * NoiseModelFactorN< Pose3, Point3> factor(noise, key1, key2);
284+ * NoiseModelFactorT<Vector, Pose3, Point3> factor(noise, key1, key2);
282285 * key<1>() // = key1
283286 * key<2>() // = key2
284287 * // key<0>() // ERROR! Will not compile
285288 * // key<3>() // ERROR! Will not compile
286289 * ```
287- *
290+ *
288291 * Note that, if your class is templated AND you are trying to call `key<1>`
289292 * inside your class, due to dependent types you need the `template` keyword:
290293 * `this->key1()`.
@@ -314,11 +317,9 @@ class NoiseModelFactorN
314317 * @param[out] H A vector of (dynamic) matrices whose size should be equal to
315318 * n. The Jacobians w.r.t. each variable will be output in this parameter.
316319 */
317- Vector unwhitenedError (
318- const Values& x,
319- OptionalMatrixVecType H = nullptr ) const override {
320- return unwhitenedError (gtsam::index_sequence_for<ValueTypes...>{}, x,
321- H);
320+ Vector unwhitenedError (const Values& x,
321+ OptionalMatrixVecType H = nullptr ) const override {
322+ return unwhitenedError (gtsam::index_sequence_for<ValueTypes...>{}, x, H);
322323 }
323324
324325 // / @}
@@ -347,15 +348,15 @@ class NoiseModelFactorN
347348 * as separate arguments.
348349 * @param[out] H The Jacobian with respect to each variable (optional).
349350 */
350- virtual Vector evaluateError (const ValueTypes&... x,
351- OptionalMatrixTypeT<ValueTypes>... H) const = 0;
351+ virtual OutputVec evaluateError (
352+ const ValueTypes&... x, OptionalMatrixTypeT<ValueTypes>... H) const = 0;
352353
353354 /* * If all the optional arguments are matrices then redirect the call to
354355 * the one which takes pointers.
355356 * To get access to this version of the function from derived classes
356357 * one will need to use the "using" keyword and specify that like this:
357358 * public:
358- * using NoiseModelFactorN <list the value types here>::evaluateError;
359+ * using NoiseModelFactorT <list the value types here>::evaluateError;
359360 */
360361 Vector evaluateError (const ValueTypes&... x,
361362 MatrixTypeT<ValueTypes>&... H) const {
@@ -380,24 +381,27 @@ class NoiseModelFactorN
380381 * and the jacobians are l-value references to matrices.
381382 * e.g. `const Vector error = factor.evaluateError(pose, point, Hpose);`
382383 */
383- template <typename ... OptionalJacArgs, typename = IndexIsValid<sizeof ...(OptionalJacArgs) + 1 >>
384- inline AreAllMatrixRefs<Vector, OptionalJacArgs...> evaluateError (const ValueTypes&... x,
385- OptionalJacArgs&&... H) const {
384+ template <typename ... OptionalJacArgs,
385+ typename = IndexIsValid<sizeof ...(OptionalJacArgs) + 1 >>
386+ inline AreAllMatrixRefs<Vector, OptionalJacArgs...> evaluateError (
387+ const ValueTypes&... x, OptionalJacArgs&&... H) const {
386388 return evaluateError (x..., (&H)...);
387389 }
388390
389391 /* * Some (but not all) optional Jacobians are omitted (function overload)
390392 * and the jacobians are pointers to matrices.
391393 * e.g. `const Vector error = factor.evaluateError(pose, point, &Hpose);`
392394 */
393- template <typename ... OptionalJacArgs, typename = IndexIsValid<sizeof ...(OptionalJacArgs) + 1 >>
394- inline AreAllMatrixPtrs<Vector, OptionalJacArgs...> evaluateError (const ValueTypes&... x,
395- OptionalJacArgs&&... H) const {
395+ template <typename ... OptionalJacArgs,
396+ typename = IndexIsValid<sizeof ...(OptionalJacArgs) + 1 >>
397+ inline AreAllMatrixPtrs<Vector, OptionalJacArgs...> evaluateError (
398+ const ValueTypes&... x, OptionalJacArgs&&... H) const {
396399 // If they are pointer version, ensure to cast them all to be Matrix* types
397- // This will ensure any arguments inferred as std::nonetype_t are cast to (Matrix*) nullptr
398- // This guides the compiler to the correct overload which is the one that takes pointers
399- return evaluateError (x...,
400- std::forward<OptionalJacArgs>(H)..., static_cast <OptionalMatrixType>(OptionalNone));
400+ // This will ensure any arguments inferred as std::nonetype_t are cast to
401+ // (Matrix*) nullptr This guides the compiler to the correct overload which
402+ // is the one that takes pointers
403+ return evaluateError (x..., std::forward<OptionalJacArgs>(H)...,
404+ static_cast <OptionalMatrixType>(OptionalNone));
401405 }
402406
403407 // / @}
@@ -406,14 +410,13 @@ class NoiseModelFactorN
406410 /* * Pack expansion with index_sequence template pattern, used to index into
407411 * `keys_` and `H`.
408412 *
409- * Example: For `NoiseModelFactorN< Pose3, Point3>`, the call would look like:
410- * `const Vector error = unwhitenedError(0, 1, values, H);`
413+ * Example: For `NoiseModelFactorT<Vector, Pose3, Point3>`, the call would
414+ * look like: `const Vector error = unwhitenedError(0, 1, values, H);`
411415 */
412416 template <std::size_t ... Indices>
413- inline Vector unwhitenedError (
414- gtsam::index_sequence<Indices...>, //
415- const Values& x,
416- OptionalMatrixVecType H = nullptr ) const {
417+ inline Vector unwhitenedError (gtsam::index_sequence<Indices...>, //
418+ const Values& x,
419+ OptionalMatrixVecType H = nullptr ) const {
417420 if (this ->active (x)) {
418421 if (H) {
419422 return evaluateError (x.at <ValueTypes>(keys_[Indices])...,
@@ -440,9 +443,7 @@ class NoiseModelFactorN
440443 // / @name Shortcut functions `key1()` -> `key<1>()`
441444 // / @{
442445
443- inline Key key1 () const {
444- return key<1 >();
445- }
446+ inline Key key1 () const { return key<1 >(); }
446447 template <int I = 2 >
447448 inline Key key2 () const {
448449 static_assert (I <= N, " Index out of bounds" );
@@ -471,7 +472,15 @@ class NoiseModelFactorN
471472
472473 // / @}
473474
474- }; // \class NoiseModelFactorN
475+ }; // \class NoiseModelFactorT
476+
477+ /* *
478+ * @brief Noise model factor with N value types and dynamic-sized error vector
479+ *
480+ * @tparam ValueTypes
481+ */
482+ template <class ... ValueTypes>
483+ using NoiseModelFactorN = NoiseModelFactorT<Vector, ValueTypes...>;
475484
476485#define NoiseModelFactor1 NoiseModelFactorN
477486#define NoiseModelFactor2 NoiseModelFactorN
0 commit comments