GCC Code Coverage Report


Directory: ./
File: include/hpp/constraints/matrix-view.hh
Date: 2025-05-05 12:19:30
Exec Total Coverage
Lines: 236 241 97.9%
Branches: 63 109 57.8%

Line Branch Exec Source
1 // Copyright (c) 2017, Joseph Mirabel
2 // Authors: Joseph Mirabel (joseph.mirabel@laas.fr)
3 //
4
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // 1. Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //
12 // 2. Redistributions in binary form must reproduce the above copyright
13 // notice, this list of conditions and the following disclaimer in the
14 // documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 // HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 // DAMAGE.
28
29 #ifndef HPP_CONSTRAINTS_MATRIX_VIEW_HH
30 #define HPP_CONSTRAINTS_MATRIX_VIEW_HH
31
32 #include <Eigen/Core>
33 #include <hpp/constraints/fwd.hh>
34 #include <hpp/pinocchio/util.hh>
35 #include <hpp/util/indent.hh>
36 #include <iostream>
37 #include <vector>
38
39 #define HPP_EIGEN_USE_EVALUATOR EIGEN_VERSION_AT_LEAST(3, 2, 92)
40
41 namespace Eigen {
42
43 /// \addtogroup hpp_constraints_tools
44 /// \{
45
46 /// List of integer intervals
47 ///
48 /// Used to select blocks in a vector or in a matrix.
49 struct BlockIndex {
50 /// Index of vector or matrix
51 typedef hpp::constraints::size_type size_type;
52 /// Interval of indices [first, first + second - 1]
53 typedef hpp::constraints::segment_t segment_t;
54 /// vector of segments
55 typedef hpp::constraints::segments_t segments_t;
56
57 /// Return the number of indices in the vector of segments.
58 /// \param a vector of segments
59 static size_type cardinal(const segments_t& a);
60
61 /// Build a vector of segments from an array of Boolean.
62 /// \param array array of Boolean values
63 /// \return the vector of segments corresponding to true values in the
64 /// input.
65 template <typename Derived>
66 static segments_t fromLogicalExpression(
67 const Eigen::ArrayBase<Derived>& array);
68
69 /// Sort segments in increasing order.
70 /// Compare lower bounds of intervals and lengths if lower bounds are equal.
71 static void sort(segments_t& a);
72
73 /// Build a sequence of non overlapping segments.
74 /// \param a a vector of segments
75 /// \note assumes a is sorted
76 static void shrink(segments_t& a);
77
78 /// Whether two segments overlap.
79 static bool overlap(const segment_t& a, const segment_t& b);
80
81 /// Compute the union of tws segments.
82 static segments_t sum(const segment_t& a, const segment_t& b);
83
84 /// In place addition of a segment_t to segments_t.
85 static void add(segments_t& a, const segment_t& b);
86
87 /// In place addition of segments_t to segments_t.
88 static void add(segments_t& a, const segments_t& b);
89
90 /// Compute the set difference between two segments.
91 static segments_t difference(const segment_t& a, const segment_t& b);
92
93 /// Compute the set difference between a vector of segments and a segment.
94 /// \note assumes a is sorted
95 static segments_t difference(const segments_t& a, const segment_t& b);
96
97 /// Compute the set difference between a segment and a vector of segments.
98 /// \note assume b is sorted
99 static segments_t difference(const segment_t& a, const segments_t& b);
100
101 /// Compute the set difference between two vectors of segments.
102 /// \note assume a and b are sorted
103 static segments_t difference(const segments_t& a, const segments_t& b);
104
105 /// Split a set of segment into two sets of segments
106 /// \param segments input set of segments,
107 /// \param cardinal cardinal of the first set of segments,
108 /// \return the first set of segments.
109 ///
110 /// The second set is stored in the input set of segments.
111 static segments_t split(segments_t& segments, const size_type& cardinal);
112
113 /// Extract a subset of a set of segments
114 /// \param segments input set of segments
115 /// \param start beginning of extracted set of segments (cardinal of subset
116 /// left behind in input set of segments)
117 /// \param cardinal cardinal of extracted set of segments,
118 /// \return subset of segments.
119 static segments_t extract(const segments_t& segments, size_type start,
120 size_type cardinal);
121 }; // struct BlockIndex
122
123 template <typename ArgType, int _Rows, int _Cols, bool _allRows, bool _allCols>
124 class MatrixBlockView;
125
126 /// Collection of indices of matrix blocks
127 /// \param _allRows whether the collection is composed of full columns
128 /// \param _allCols whether the collection is composed of full rows
129 ///
130 /// This class enables a user to virtually create a matrix that concatenates
131 /// blocks of a larger matrix.
132 ///
133 /// The smaller matrix is built by methods \ref lview and \ref rview
134 /// \li \ref lview returns a smaller matrix that can be written in,
135 /// \li \ref rview returns a smaller matrix that cannot be written in.
136 template <bool _allRows = false, bool _allCols = false>
137 class MatrixBlocks;
138
139 /// \}
140
141 template <bool _allRows = false, bool _allCols = false>
142 class MatrixBlocksRef;
143
144 namespace internal {
145 template <bool condition>
146 struct static_if {
147 template <class Then, class Else>
148 14498 static constexpr inline Then& rr(Then& f, Else&) {
149 14498 return f;
150 }
151 template <class Then, class Else>
152 452840 static constexpr inline Then pp(Then f, Else) {
153 452840 return f;
154 }
155 };
156 template <>
157 struct static_if<false> {
158 template <class Then, class Else>
159 330606 static constexpr inline Else& rr(Then&, Else& s) {
160 330606 return s;
161 }
162 template <class Then, class Else>
163 823303 static constexpr inline Else pp(Then, Else s) {
164 823303 return s;
165 }
166 };
167
168 struct empty_struct {
169 typedef MatrixXd::Index Index;
170 constexpr empty_struct() = default;
171 template <typename In_t>
172 265821 constexpr empty_struct(In_t) {}
173 template <typename In0_t, typename In1_t>
174 2 constexpr empty_struct(In0_t, In1_t) {}
175 266 static constexpr inline Index size() { return 1; }
176 452833 inline constexpr const Index& operator[](const Index& i) const { return i; }
177 };
178
179 template <bool _allRows, bool _allCols>
180 struct traits<MatrixBlocks<_allRows, _allCols> > {
181 enum { AllRows = _allRows, AllCols = _allCols };
182 typedef
183 typename internal::conditional<_allRows, internal::empty_struct,
184 BlockIndex::segments_t>::type RowIndices_t;
185 typedef
186 typename internal::conditional<_allCols, internal::empty_struct,
187 BlockIndex::segments_t>::type ColIndices_t;
188 };
189
190 template <bool _allRows, bool _allCols>
191 struct traits<MatrixBlocksRef<_allRows, _allCols> > {
192 enum { AllRows = _allRows, AllCols = _allCols };
193 typedef typename internal::conditional<_allRows, internal::empty_struct,
194 const BlockIndex::segments_t&>::type
195 RowIndices_t;
196 typedef typename internal::conditional<_allCols, internal::empty_struct,
197 const BlockIndex::segments_t&>::type
198 ColIndices_t;
199 };
200
201 template <typename ArgType, int _Rows, int _Cols, bool _allRows, bool _allCols>
202 struct traits<MatrixBlockView<ArgType, _Rows, _Cols, _allRows, _allCols> > {
203 #if HPP_EIGEN_USE_EVALUATOR
204 typedef typename ArgType::StorageIndex StorageIndex;
205 #else // HPP_EIGEN_USE_EVALUATOR
206 typedef typename ArgType::Index Index;
207 #endif // HPP_EIGEN_USE_EVALUATOR
208 typedef typename traits<ArgType>::StorageKind StorageKind;
209 typedef typename traits<ArgType>::XprKind XprKind;
210 typedef typename ArgType::Scalar Scalar;
211 enum {
212 #if !HPP_EIGEN_USE_EVALUATOR
213 CoeffReadCost = ArgType::CoeffReadCost,
214 #endif // !HPP_EIGEN_USE_EVALUATOR
215 Flags = ~PacketAccessBit & ~DirectAccessBit & ~ActualPacketAccessBit &
216 ~LinearAccessBit & ArgType::Flags,
217 RowsAtCompileTime = (_allRows ? ArgType::RowsAtCompileTime : _Rows),
218 ColsAtCompileTime = (_allCols ? ArgType::ColsAtCompileTime : _Cols),
219 MaxRowsAtCompileTime = ArgType::MaxRowsAtCompileTime,
220 MaxColsAtCompileTime = ArgType::MaxColsAtCompileTime
221 };
222 };
223
224 #if HPP_EIGEN_USE_EVALUATOR
225 template <typename Derived, typename ArgType, int _Rows, int _Cols,
226 bool _allRows, bool _allCols, typename Functor, typename Scalar>
227 struct Assignment<Derived,
228 MatrixBlockView<ArgType, _Rows, _Cols, _allRows, _allCols>,
229 Functor, Dense2Dense, Scalar> {
230 typedef MatrixBlockView<ArgType, _Rows, _Cols, _allRows, _allCols>
231 OtherDerived;
232 169387 static EIGEN_STRONG_INLINE void run(Derived& dst, const OtherDerived& src,
233 const Functor& func) {
234 169387 dst.resize(src.rows(), src.cols());
235 typedef Block<Derived> BlockDerived;
236 typedef Assignment<BlockDerived, typename OtherDerived::BlockConstXprType,
237 Functor>
238 AssignmentType;
239
2/2
✓ Branch 2 taken 89169 times.
✓ Branch 3 taken 89043 times.
339031 for (typename OtherDerived::block_iterator b(src); b.valid(); ++b) {
240
3/6
✓ Branch 1 taken 89162 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 89163 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 89168 times.
✗ Branch 10 not taken.
169644 BlockDerived bdst(dst.block(b.ro(), b.co(), b.rs(), b.cs()));
241
3/6
✓ Branch 1 taken 89168 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 89162 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 89165 times.
✗ Branch 8 not taken.
169642 AssignmentType::run(bdst, src._block(b), func);
242 }
243 169393 }
244 };
245 #else // HPP_EIGEN_USE_EVALUATOR
246 template <typename Derived, typename ArgType, int _Rows, int _Cols,
247 bool _allRows, bool _allCols>
248 struct assign_selector<
249 Derived, MatrixBlockView<ArgType, _Rows, _Cols, _allRows, _allCols>, false,
250 false> {
251 typedef MatrixBlockView<ArgType, _Rows, _Cols, _allRows, _allCols>
252 OtherDerived;
253 static EIGEN_STRONG_INLINE Derived& run(Derived& dst,
254 const OtherDerived& other) {
255 other.writeTo(dst);
256 return dst;
257 }
258 template <typename ActualDerived, typename ActualOtherDerived>
259 static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst,
260 const ActualOtherDerived& other) {
261 other.evalTo(dst);
262 return dst;
263 }
264 };
265 template <typename Derived, typename ArgType, int _Rows, int _Cols,
266 bool _allRows, bool _allCols>
267 struct assign_selector<
268 Derived, MatrixBlockView<ArgType, _Rows, _Cols, _allRows, _allCols>, false,
269 true> {
270 typedef MatrixBlockView<ArgType, _Rows, _Cols, _allRows, _allCols>
271 OtherDerived;
272 static EIGEN_STRONG_INLINE Derived& run(Derived& dst,
273 const OtherDerived& other) {
274 other.writeTo(dst.transpose());
275 return dst;
276 }
277 template <typename ActualDerived, typename ActualOtherDerived>
278 static EIGEN_STRONG_INLINE Derived& evalTo(ActualDerived& dst,
279 const ActualOtherDerived& other) {
280 Transpose<ActualDerived> dstTrans(dst);
281 other.evalTo(dstTrans);
282 return dst;
283 }
284 };
285 #endif // HPP_EIGEN_USE_EVALUATOR
286
287 template <typename Src, typename Dst>
288 struct eval_matrix_block_view_to {};
289 template <typename Src, typename _ArgType, int _Rows, int _Cols, bool _allRows,
290 bool _allCols>
291 struct eval_matrix_block_view_to<
292 Src, MatrixBlockView<_ArgType, _Rows, _Cols, _allRows, _allCols> > {
293 // MatrixBlockView <- matrix
294 typedef MatrixBlockView<_ArgType, _Rows, _Cols, _allRows, _allCols> Dst;
295 112702 static void run(const Src& src, Dst& dst) {
296
5/5
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 44991 times.
✓ Branch 3 taken 69613 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 3 times.
201094 for (typename Dst::block_iterator b(dst); b.valid(); ++b)
297
6/12
✓ Branch 1 taken 44997 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 44997 times.
✗ Branch 5 not taken.
✓ Branch 9 taken 44997 times.
✗ Branch 10 not taken.
✓ Branch 12 taken 44997 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 44997 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 44997 times.
✗ Branch 19 not taken.
88392 dst._block(b) = src.block(b.ro(), b.co(), b.rs(), b.cs());
298 112702 }
299 };
300 template <typename _ArgType, int _Rows, int _Cols, bool _allRows, bool _allCols,
301 typename Dst>
302 struct eval_matrix_block_view_to<
303 MatrixBlockView<_ArgType, _Rows, _Cols, _allRows, _allCols>, Dst> {
304 // matrix <- MatrixBlockView
305 typedef MatrixBlockView<_ArgType, _Rows, _Cols, _allRows, _allCols> Src;
306 10044 static void run(const Src& src, Dst& dst) {
307
5/5
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 8369 times.
✓ Branch 3 taken 8251 times.
✓ Branch 4 taken 6 times.
✓ Branch 5 taken 3 times.
20330 for (typename Src::block_iterator b(src); b.valid(); ++b)
308
6/12
✓ Branch 1 taken 8375 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 8375 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 8375 times.
✗ Branch 8 not taken.
✓ Branch 12 taken 8375 times.
✗ Branch 13 not taken.
✓ Branch 15 taken 8375 times.
✗ Branch 16 not taken.
✓ Branch 18 taken 8375 times.
✗ Branch 19 not taken.
10286 dst.block(b.ro(), b.co(), b.rs(), b.cs()) = src._block(b);
309 10044 }
310 };
311 template <typename _ArgType, int _Rows, int _Cols, bool _allRows, bool _allCols,
312 typename _ArgType2, int _Rows2, int _Cols2, bool _allRows2,
313 bool _allCols2>
314 struct eval_matrix_block_view_to<
315 MatrixBlockView<_ArgType, _Rows, _Cols, _allRows, _allCols>,
316 MatrixBlockView<_ArgType2, _Rows2, _Cols2, _allRows2, _allCols2> > {
317 // MatrixBlockView <- MatrixBlockView
318 typedef MatrixBlockView<_ArgType, _Rows, _Cols, _allRows, _allCols> Src;
319 typedef MatrixBlockView<_ArgType2, _Rows2, _Cols2, _allRows2, _allCols2> Dst;
320 13432 static void run(const Src& src, Dst& dst) {
321
1/2
✓ Branch 1 taken 3 times.
✗ Branch 2 not taken.
13432 typename Dst::block_iterator db(dst);
322
3/4
✓ Branch 2 taken 25238 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 25238 times.
✓ Branch 6 taken 13424 times.
38690 for (typename Src::block_iterator sb(src); sb.valid(); ++sb) {
323
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 25238 times.
25258 assert(db.valid());
324
3/6
✓ Branch 1 taken 25238 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 25238 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 25238 times.
✗ Branch 8 not taken.
25258 dst._block(db) = src._block(sb);
325
1/2
✓ Branch 1 taken 25238 times.
✗ Branch 2 not taken.
25258 ++db;
326 }
327
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 13424 times.
13432 assert(!db.valid());
328 13432 }
329 };
330
331 template <typename ReturnType, typename View, bool AllRows = View::AllRows,
332 bool AllCols = View::AllCols>
333 struct access_block_from_matrix_block_view {
334 typedef typename View::size_type size_type;
335 template <typename Derived>
336 50702 static ReturnType run(Derived& d, size_type r, size_type c, size_type rs,
337 size_type cs) {
338 50702 return ReturnType(d, r, c, rs, cs);
339 }
340 };
341 template <typename ReturnType, typename View>
342 struct access_block_from_matrix_block_view<ReturnType, View, false, true> {
343 typedef typename View::size_type size_type;
344 template <typename Derived>
345 303702 static ReturnType run(Derived& d, size_type r, size_type, size_type rs,
346 size_type) {
347 303702 return d.middleRows(r, rs);
348 }
349 };
350 template <typename ReturnType, typename View>
351 struct access_block_from_matrix_block_view<ReturnType, View, true, false> {
352 typedef typename View::size_type size_type;
353 template <typename Derived>
354 352 static ReturnType run(Derived& d, size_type, size_type c, size_type,
355 size_type cs) {
356 352 return d.middleCols(c, cs);
357 }
358 };
359
360 struct dont_print_indices {
361 template <typename BlockIndexType>
362 static void run(std::ostream&, const BlockIndexType&) {}
363 };
364 struct print_indices {
365 template <typename BlockIndexType>
366 63 static void run(std::ostream& os, const BlockIndexType& bi) {
367
2/2
✓ Branch 1 taken 86 times.
✓ Branch 2 taken 63 times.
149 for (std::size_t i = 0; i < bi.size(); ++i)
368 86 os << "[ " << bi[i].first << ", " << bi[i].second << "], ";
369 63 }
370 };
371
372 #if HPP_EIGEN_USE_EVALUATOR
373 template <typename ArgType, int _Rows, int _Cols, bool _allRows, bool _allCols>
374 struct unary_evaluator<
375 MatrixBlockView<ArgType, _Rows, _Cols, _allRows, _allCols> >
376 : evaluator_base<
377 MatrixBlockView<ArgType, _Rows, _Cols, _allRows, _allCols> > {
378 typedef MatrixBlockView<ArgType, _Rows, _Cols, _allRows, _allCols> XprType;
379
380 enum {
381 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
382 Flags = ~PacketAccessBit & ~DirectAccessBit & ~ActualPacketAccessBit &
383 ~LinearAccessBit & ArgType::Flags,
384 Alignment = 0
385 };
386 EIGEN_DEVICE_FUNC explicit unary_evaluator(const XprType& view)
387 : m_view(view) {}
388
389 const XprType& m_view;
390 };
391 #endif // HPP_EIGEN_USE_EVALUATOR
392 } // namespace internal
393
394 #define EIGEN_MATRIX_BLOCKS_PUBLIC_INTERFACE(Derived) \
395 enum { AllRows = _allRows, AllCols = _allCols }; \
396 typedef MatrixBlocksBase<Derived> Base; \
397 typedef typename Base::size_type size_type; \
398 typedef typename Base::segments_t segments_t; \
399 typedef typename Base::segment_t segment_t; \
400 typedef typename Base::RowIndices_t RowIndices_t; \
401 typedef typename Base::ColIndices_t ColIndices_t;
402
403 /// \addtogroup hpp_constraints_tools
404 /// \{
405
406 template <typename Derived>
407 class MatrixBlocksBase {
408 public:
409 enum {
410 AllRows = internal::traits<Derived>::AllRows,
411 AllCols = internal::traits<Derived>::AllCols,
412 OneDimension = bool(AllRows) || bool(AllCols)
413 };
414 /// Index of vector or matrix
415 typedef hpp::constraints::size_type size_type;
416 /// Interval of indices [first, first + second - 1]
417 typedef BlockIndex::segment_t segment_t;
418 /// vector of segments
419 typedef BlockIndex::segments_t segments_t;
420 typedef typename internal::traits<Derived>::RowIndices_t RowIndices_t;
421 typedef typename internal::traits<Derived>::ColIndices_t ColIndices_t;
422
423 /// Smaller matrix composed by concatenation of the blocks
424 template <typename MatrixType, int _Rows = MatrixType::RowsAtCompileTime,
425 int _Cols = MatrixType::ColsAtCompileTime>
426 struct View {
427 typedef MatrixBlockView<MatrixType, _Rows, _Cols, AllRows, AllCols> type;
428 }; // struct View
429
430 1720577 Derived const& derived() const { return static_cast<Derived const&>(*this); }
431 Derived& derived() { return static_cast<Derived&>(*this); }
432
433 /// Writable view of the smaller matrix
434 /// \param other matrix to whick block are extracted
435 /// \return writable view of the smaller matrix composed by concatenation
436 /// of blocks.
437 template <typename MatrixType>
438 121828 EIGEN_STRONG_INLINE typename View<MatrixType>::type lview(
439 const MatrixBase<MatrixType>& other) const {
440 121828 MatrixType& o = const_cast<MatrixBase<MatrixType>&>(other).derived();
441 if (Derived::OneDimension)
442 120906 return typename View<MatrixType>::type(o, nbIndices(), indices());
443 else
444 922 return typename View<MatrixType>::type(o, nbRows(), rows(), nbCols(),
445 1844 cols());
446 }
447
448 /// Non-writable view of the smaller matrix
449 /// \param other matrix to whick block are extracted
450 /// \return non-writable view of the smaller matrix composed by
451 /// concatenation of blocks.
452 template <typename MatrixType>
453 221180 EIGEN_STRONG_INLINE typename View<const MatrixType>::type rview(
454 const MatrixBase<MatrixType>& other) const {
455 if (Derived::OneDimension)
456 172734 return typename View<const MatrixType>::type(other.derived(), nbIndices(),
457 345476 indices());
458 else
459 48444 return typename View<const MatrixType>::type(other.derived(), nbRows(),
460 96888 rows(), nbCols(), cols());
461 }
462
463 55 MatrixBlocksRef<AllCols, AllRows> transpose() const {
464 73 return MatrixBlocksRef<AllCols, AllRows>(nbCols(), cols(), nbRows(),
465 104 rows());
466 }
467
468 24296 MatrixBlocksRef<AllRows, true> keepRows() const {
469 assert(!AllRows);
470 24296 return MatrixBlocksRef<AllRows, true>(nbRows(), rows());
471 }
472
473 1 MatrixBlocksRef<true, AllCols> keepCols() const {
474 assert(!AllCols);
475 1 return MatrixBlocksRef<true, AllCols>(nbCols(), cols());
476 }
477
478 /// Return row or column indices as a vector of segments
479 ///
480 /// \return rows indices if not all rows are selected
481 /// (see template parameter _allRows),
482 /// column indices if all rows are selected.
483 555901 inline const segments_t& indices() const {
484 555901 return internal::static_if<AllRows>::rr(cols(), rows());
485 }
486
487 /// Return row indices
488 /// \warning _allRows should be false
489 654050 inline const RowIndices_t& rows() const { return derived().rows(); }
490
491 /// Return column indices
492 /// \warning _allCols should be false
493 605423 inline const ColIndices_t& cols() const { return derived().cols(); }
494
495 /// Return number of row or column indices
496 ///
497 /// \return number of rows indices if not all rows are selected
498 /// (see template parameter _allRows),
499 /// number of column indices if all rows are selected.
500 313493 inline const size_type& nbIndices() const {
501 313493 return AllRows ? nbCols() : nbRows();
502 }
503
504 /// Return number of row indices
505 /// \warning _allRows should be false
506 293102 inline const size_type& nbRows() const { return derived().nbRows(); }
507
508 /// Return number of column indices
509 /// \warning _allCols should be false
510 27378 inline const size_type& nbCols() const { return derived().nbCols(); }
511
512 /// Extract a block
513 /// \param i, j, ni, nj upper left corner and lengths of the block
514 /// \return new instance
515 MatrixBlocks<AllRows, AllCols> block(size_type i, size_type j, size_type ni,
516 size_type nj) const {
517 return MatrixBlocks<AllRows, AllCols>(BlockIndex::extract(rows(), i, ni),
518 BlockIndex::extract(cols(), j, nj));
519 }
520
521 /// Extract a set of rows
522 /// \param i, ni start and length of the set of rows
523 /// \return new instance
524 MatrixBlocks<AllRows, AllCols> middleRows(size_type i, size_type ni) const {
525 return MatrixBlocks<AllRows, AllCols>(BlockIndex::extract(rows(), i, ni),
526 cols());
527 }
528
529 /// Extract a set of cols
530 /// \param j, nj start and length of the set of rows
531 /// \return new instance
532 MatrixBlocks<AllRows, AllCols> middleCols(size_type j, size_type nj) const {
533 return MatrixBlocks<AllRows, AllCols>(rows(),
534 BlockIndex::extract(cols(), j, nj));
535 }
536
537 protected:
538 /// Empty constructor
539 317454 MatrixBlocksBase() {}
540
541 /// Copy constructor
542 8802 MatrixBlocksBase(const MatrixBlocksBase&) {}
543 }; // class MatrixBlocks
544
545 template <bool _allRows, bool _allCols>
546 class MatrixBlocks
547 : public MatrixBlocksBase<MatrixBlocks<_allRows, _allCols> > {
548 public:
549 EIGEN_MATRIX_BLOCKS_PUBLIC_INTERFACE(MatrixBlocks)
550
551 /// Empty constructor
552 121252 MatrixBlocks() : m_nbRows(0), m_nbCols(0), m_rows(), m_cols() {}
553
554 /// Constructor by vectors of segments
555 /// \param rows set of row indices,
556 /// \param cols set of column indices,
557 /// \warning rows and cols must be sorted
558 1181 MatrixBlocks(const segments_t& rows, const segments_t& cols)
559 1181 : m_nbRows(BlockIndex::cardinal(rows)),
560 1181 m_nbCols(BlockIndex::cardinal(cols)),
561 1181 m_rows(rows),
562
1/2
✓ Branch 2 taken 1181 times.
✗ Branch 3 not taken.
2362 m_cols(cols) {}
563
564 /// Constructor by vectors of segments
565 /// \param nbRows number of rows,
566 /// \param nbCols number of columns,
567 /// \param rows set of row indices,
568 /// \param cols set of column indices,
569 /// \warning rows and cols must be sorted
570 MatrixBlocks(const size_type& nbRows, const RowIndices_t& rows,
571 const size_type& nbCols, const ColIndices_t& cols)
572 : m_nbRows(nbRows), m_nbCols(nbCols), m_rows(rows), m_cols(cols) {}
573
574 /// Constructor of single block
575 /// \param start indice for row and column
576 /// \param size number of indices in the block (row and column)
577 /// \note if all rows or all columns are selected (template parameter)
578 /// the block will contain all rows, respectively all columns.
579 2 MatrixBlocks(size_type start, size_type size)
580 2 : m_nbRows(_allRows ? 0 : size),
581 2 m_nbCols(_allCols ? 0 : size),
582
1/2
✓ Branch 3 taken 2 times.
✗ Branch 4 not taken.
2 m_rows(1, BlockIndex::segment_t(start, size)),
583 4 m_cols(1, BlockIndex::segment_t(start, size)) {}
584
585 /// Constructor by a collection of indices
586 /// \param idx collections of indices (for rows and columns)
587 /// \warning idx must be sorted and shrinked
588 /// \note if all rows or all columns are selected (template parameter)
589 /// the block will contain all rows, respectively all columns.
590 137104 MatrixBlocks(const segments_t& idx)
591 137104 : m_nbRows(_allRows ? 0 : BlockIndex::cardinal(idx)),
592 137104 m_nbCols(_allCols ? 0 : BlockIndex::cardinal(idx)),
593 137104 m_rows(idx),
594
1/2
✓ Branch 2 taken 52910 times.
✗ Branch 3 not taken.
274208 m_cols(idx) {}
595
596 /// Constructor of a single block
597 /// \param idx segment of row and column indices
598 /// \note if all rows or all columns are selected (template parameter)
599 /// the block will contain all rows, respectively all columns.
600 MatrixBlocks(const segment_t& idx)
601 : m_nbRows(_allRows ? 0 : idx.second),
602 m_nbCols(_allCols ? 0 : idx.second),
603 m_rows(segments_t(1, idx)),
604 m_cols(segments_t(1, idx)) {}
605
606 /// Copy constructor
607 template <typename MBDerived>
608 31 MatrixBlocks(const MatrixBlocksBase<MBDerived>& other)
609 31 : m_nbRows(other.nbRows()),
610 31 m_nbCols(other.nbCols()),
611 31 m_rows(other.rows()),
612
1/2
✓ Branch 2 taken 29 times.
✗ Branch 3 not taken.
62 m_cols(other.cols()) {
613 EIGEN_STATIC_ASSERT((bool(AllRows) == bool(MBDerived::AllRows)) &&
614 (bool(AllCols) == bool(MBDerived::AllCols)),
615 YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
616 31 }
617
618
1/2
✓ Branch 3 taken 1146 times.
✗ Branch 4 not taken.
8792 MatrixBlocks(const MatrixBlocks& other) = default;
619
620 61252 MatrixBlocks& operator=(const MatrixBlocks& other) {
621 61252 m_nbRows = other.m_nbRows;
622 61252 m_nbCols = other.m_nbCols;
623 35458 m_rows = other.m_rows;
624 26869 m_cols = other.m_cols;
625 61252 return *this;
626 }
627 /// Clear rows
628 10655 inline void clearRows() {
629 10655 m_rows.clear();
630 10655 m_nbRows = 0;
631 10655 }
632
633 /// Clear cols
634 inline void clearCols() {
635 m_cols.clear();
636 m_nbCols = 0;
637 }
638
639 /// Add consecutive rows
640 /// \param row first row to add
641 /// \param size number of rows to add
642 78093 inline void addRow(const size_type& row, const size_type size) {
643
1/2
✓ Branch 2 taken 78093 times.
✗ Branch 3 not taken.
78093 m_rows.push_back(segment_t(row, size));
644 78093 m_nbRows += size;
645 78093 }
646
647 /// Add consecutive columns
648 /// \param col first column to add
649 /// \param size number of columns to add
650 7557 inline void addCol(const size_type& col, const size_type size) {
651
1/2
✓ Branch 2 taken 7557 times.
✗ Branch 3 not taken.
7557 m_cols.push_back(segment_t(col, size));
652 7557 m_nbCols += size;
653 7557 }
654
655 /// Selectively recompute set of rows
656 /// \tparam Sort whether set of rows should be sorted,
657 /// \tparam Shrink whether set of rows should be shrunk,
658 /// \tparam Cardinal whether number of rows should be recomputed
659 template <bool Sort, bool Shrink, bool Cardinal>
660 19233 inline void updateRows() {
661 19233 update<Sort, Shrink, Cardinal>(m_rows, m_nbRows);
662 19233 }
663
664 /// Selectively recompute set of columns
665 /// \tparam Sort whether set of columns should be sorted,
666 /// \tparam Shrink whether set of columns should be shrunk,
667 /// \tparam Cardinal whether number of columns should be recomputed
668 template <bool Sort, bool Shrink, bool Cardinal>
669 inline void updateCols() {
670 update<Sort, Shrink, Cardinal>(m_cols, m_nbCols);
671 }
672
673 /// Return row indices
674 /// \warning _allRows should be false
675 655165 inline const RowIndices_t& rows() const { return m_rows; }
676
677 /// Return column indices
678 /// \warning _allCols should be false
679 580595 inline const ColIndices_t& cols() const { return m_cols; }
680
681 /// Return number of row indices
682 /// \warning _allRows should be false
683 246817 inline const size_type& nbRows() const { return m_nbRows; }
684
685 /// Return number of column indices
686 /// \warning _allCols should be false
687 40896 inline const size_type& nbCols() const { return m_nbCols; }
688
689 template <bool Sort, bool Shrink, bool Cardinal>
690 51688 inline void updateIndices() {
691 51688 update<Sort, Shrink, Cardinal>(
692 51688 internal::static_if<_allRows>::rr(m_cols, m_rows),
693 51688 _allRows ? m_nbCols : m_nbRows);
694 51688 }
695
696 size_type m_nbRows, m_nbCols;
697 RowIndices_t m_rows;
698 ColIndices_t m_cols;
699
700 private:
701 template <bool Sort, bool Shrink, bool Cardinal>
702 63343 static inline void update(segments_t& b, size_type& idx) {
703 37499 if (Sort) BlockIndex::sort(b);
704 63343 if (Shrink) BlockIndex::shrink(b);
705 63343 if (Cardinal) idx = BlockIndex::cardinal(b);
706 63343 }
707 }; // class MatrixBlocks
708
709 /// \cond
710 template <bool _allRows, bool _allCols>
711 class MatrixBlocksRef
712 : public MatrixBlocksBase<MatrixBlocksRef<_allRows, _allCols> > {
713 public:
714 EIGEN_MATRIX_BLOCKS_PUBLIC_INTERFACE(MatrixBlocksRef)
715
716 /// Constructor by vectors of segments
717 /// \param rows set of row indices,
718 /// \param cols set of column indices,
719 /// \warning rows and cols must be sorted
720 55 MatrixBlocksRef(const size_type& nbRows, const RowIndices_t& rows,
721 const size_type& nbCols, const ColIndices_t& cols)
722 55 : m_nbRows(nbRows), m_nbCols(nbCols), m_rows(rows), m_cols(cols) {}
723
724 /// Constructor by two (row or col) MatrixBlocks
725 template <typename Derived1, typename Derived2>
726 1620 MatrixBlocksRef(const MatrixBlocksBase<Derived1>& rows,
727 const MatrixBlocksBase<Derived2>& cols)
728 1620 : m_nbRows(rows.nbIndices()),
729 1620 m_nbCols(cols.nbIndices()),
730 1620 m_rows(rows.indices()),
731 3240 m_cols(cols.indices()) {
732 EIGEN_STATIC_ASSERT(
733 bool(Derived1::OneDimension) && bool(Derived2::OneDimension),
734 YOU_MIXED_MATRICES_OF_DIFFERENT_SIZES);
735 1620 }
736
737 /// Constructor by a collection of indices
738 /// \param idx collections of indices (for rows and columns)
739 /// \warning idx must be sorted and shrinked
740 /// \note if all rows or all columns are selected (template parameter)
741 /// the block will contain all rows, respectively all columns.
742 24299 MatrixBlocksRef(const size_type& nidx, const segments_t& idx)
743 24299 : m_nbRows(_allRows ? 0 : nidx),
744 24299 m_nbCols(_allCols ? 0 : nidx),
745 24299 m_rows(idx),
746 24299 m_cols(idx) {}
747
748 /// Copy constructor
749 10 MatrixBlocksRef(const MatrixBlocksRef& other)
750 : Base(other),
751 10 m_nbRows(other.nbRows()),
752 10 m_nbCols(other.nbCols()),
753 10 m_rows(other.rows()),
754 20 m_cols(other.cols()) {}
755
756 /// Return row indices
757 /// \warning _allRows should be false
758 50690 inline const RowIndices_t& rows() const { return m_rows; }
759
760 /// Return column indices
761 /// \warning _allCols should be false
762 50690 inline const ColIndices_t& cols() const { return m_cols; }
763
764 /// Return number of row indices
765 /// \warning _allRows should be false
766 50604 inline const size_type& nbRows() const { return m_nbRows; }
767
768 /// Return number of column indices
769 /// \warning _allCols should be false
770 2014 inline const size_type& nbCols() const { return m_nbCols; }
771
772 const size_type m_nbRows, m_nbCols;
773 RowIndices_t m_rows;
774 ColIndices_t m_cols;
775 }; // class MatrixBlocksRef
776 /// \endcond
777
778 template <typename Derived>
779 54 std::ostream& operator<<(std::ostream& os,
780 const MatrixBlocksBase<Derived>& mbi) {
781 typedef
782 typename internal::conditional<Derived::AllRows,
783 internal::dont_print_indices,
784 internal::print_indices>::type row_printer;
785 typedef
786 typename internal::conditional<Derived::AllCols,
787 internal::dont_print_indices,
788 internal::print_indices>::type col_printer;
789 if (!Derived::AllRows) {
790 48 os << "Rows: ";
791 48 row_printer::run(os, mbi.rows());
792 6 if (!Derived::AllCols) os << hpp::iendl;
793 }
794 if (!Derived::AllCols) {
795 12 os << "Cols: ";
796 12 col_printer::run(os, mbi.cols());
797 }
798 54 return os;
799 }
800
801 typedef Eigen::MatrixBlocks<false, true> RowBlockIndices;
802 typedef Eigen::MatrixBlocks<true, false> ColBlockIndices;
803
804 /// A view of an Eigen matrix.
805 ///
806 /// Instances of MatrixBlockView are easily built from a MatrixBlocks object.
807 ///
808 /// As of the date of this documentation, this class does not support all
809 /// operations on matrices.
810 /// See tests/matrix-view.cc for a list of supported features.
811 ///
812 /// Although it is usually not useful to iterate over the blocks, it is
813 /// possible to do it as follows:
814 /// \code
815 /// MatrixBlockView view = ...;
816 /// for (MatrixBlockView::block_iterator block (view); block.valid(); ++block)
817 /// {
818 /// // Access the current block
819 /// view._block(block); // Returns an Eigen::Block object.
820 /// // For the current block
821 /// block.ri() // row, input
822 /// block.ci() // col, input
823 /// block.ro() // row, output
824 /// block.co() // col, output
825 /// block.rs() // number of rows
826 /// block.cs() // number of cols
827 /// }
828 /// \endcode
829 /// \sa MatrixBlocks, MatrixBlockView::block_iterator
830 template <typename _ArgType, int _Rows = _ArgType::RowsAtCompileTime,
831 int _Cols = _ArgType::ColsAtCompileTime, bool _allRows = false,
832 bool _allCols = false>
833 class MatrixBlockView
834 : public MatrixBase<
835 MatrixBlockView<_ArgType, _Rows, _Cols, _allRows, _allCols> > {
836 public:
837 typedef hpp::constraints::size_type size_type;
838 enum { Rows = _Rows, Cols = _Cols, AllRows = _allRows, AllCols = _allCols };
839 struct block_iterator {
840 const MatrixBlockView& view;
841 size_type row, col;
842 internal::variable_if_dynamic<size_type, (_allRows ? 0 : Dynamic)> _ro;
843 internal::variable_if_dynamic<size_type, (_allCols ? 0 : Dynamic)> _co;
844 387622 block_iterator(const MatrixBlockView& v)
845 387622 : view(v), row(0), col(0), _ro(0), _co(0) {}
846 /// <b>R</b>ow in the <b>O</b>utput matrix
847 285368 size_type ro() const { return _ro.value(); }
848 /// <b>C</b>ol in the <b>O</b>utput matrix
849 285366 size_type co() const { return _co.value(); }
850 /// <b>R</b>ow in the <b>I</b>nput matrix
851 386272 size_type ri() const {
852
1/2
✓ Branch 1 taken 193138 times.
✗ Branch 2 not taken.
386276 return internal::static_if<AllRows>::pp(std::make_pair(0, view.m_nbRows),
853 386272 view.m_rows[row])
854 386270 .first;
855 }
856 /// <b>C</b>ol in the <b>I</b>nput matrix
857 386268 size_type ci() const {
858
1/2
✓ Branch 1 taken 193141 times.
✗ Branch 2 not taken.
386270 return internal::static_if<AllCols>::pp(std::make_pair(0, view.m_nbCols),
859 386268 view.m_cols[col])
860 386276 .first;
861 }
862 /// number of <b>R</b>ow<b>S</b>
863 1057362 size_type rs() const {
864
1/2
✓ Branch 1 taken 528686 times.
✗ Branch 2 not taken.
1057382 return internal::static_if<AllRows>::pp(std::make_pair(0, view.m_nbRows),
865 1057362 view.m_rows[row])
866 1057358 .second;
867 }
868 /// number of <b>C</b>ol<b>S</b>
869 722368 size_type cs() const {
870
1/2
✓ Branch 1 taken 361184 times.
✗ Branch 2 not taken.
722360 return internal::static_if<AllCols>::pp(std::make_pair(0, view.m_nbCols),
871 722368 view.m_cols[col])
872 722366 .second;
873 }
874 // ++it
875 386240 block_iterator& operator++() {
876 if (!AllRows) {
877 385732 _ro.setValue(_ro.value() + rs());
878 } else {
879 assert(view.m_rows.size() == 1);
880
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 254 times.
508 assert(row == 0);
881 }
882 386240 ++row;
883
2/2
✓ Branch 1 taken 168898 times.
✓ Branch 2 taken 24225 times.
386240 if (row == (size_type)view.m_rows.size()) {
884 337796 row = 0;
885 337796 _ro.setValue(0);
886 if (!AllCols) {
887 50744 _co.setValue(_co.value() + cs());
888 }
889 337794 ++col;
890 if (AllCols) {
891 // All the blocks have been iterated on.
892
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 143525 times.
287050 assert(!valid());
893 }
894 // if (col < (size_type)view.m_cols.size()) _co.setValue(0);
895 }
896 386244 return *this;
897 };
898 // it++
899 block_iterator operator++(int) {
900 block_iterator copy(*this);
901 operator++();
902 return copy;
903 };
904 1060886 constexpr bool valid() const {
905
2/2
✓ Branch 1 taken 504758 times.
✓ Branch 2 taken 25235 times.
2069496 return (AllRows || view.m_rows.size() > 0) &&
906
3/3
✓ Branch 0 taken 167499 times.
✓ Branch 1 taken 312415 times.
✓ Branch 2 taken 24844 times.
2070408 (col < (size_type)(AllCols ? 1 : view.m_cols.size()));
907 }
908 };
909 typedef MatrixBase<
910 MatrixBlockView<_ArgType, _Rows, _Cols, _allRows, _allCols> >
911 Base;
912 EIGEN_GENERIC_PUBLIC_INTERFACE(MatrixBlockView)
913
914 typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime> PlainObject;
915 // typedef typename internal::ref_selector<MatrixBlockView>::type Nested;
916 typedef _ArgType ArgType;
917 typedef typename internal::ref_selector<ArgType>::type ArgTypeNested;
918 typedef typename internal::remove_all<ArgType>::type NestedExpression;
919 // typedef typename Base::CoeffReturnType CoeffReturnType;
920 // typedef typename Base::Scalar Scalar;
921
922 template <typename Derived>
923 struct block_t {
924 typedef Block<Derived,
925 (AllRows ? Derived::RowsAtCompileTime : Eigen::Dynamic),
926 (AllCols ? Derived::ColsAtCompileTime : Eigen::Dynamic),
927 (AllCols ? (bool)Derived::IsRowMajor
928 : (AllRows ? (bool)!Derived::IsRowMajor : false))>
929 type;
930 };
931 typedef typename block_t<ArgType>::type BlockXprType;
932 typedef typename block_t<const ArgType>::type BlockConstXprType;
933
934 typedef MatrixBlocks<_allRows, _allCols> MatrixIndices_t;
935 typedef typename MatrixIndices_t::segments_t Indices_t;
936 typedef typename internal::conditional<_allRows, const internal::empty_struct,
937 const Indices_t&>::type RowIndices_t;
938 typedef typename internal::conditional<_allCols, const internal::empty_struct,
939 const Indices_t&>::type ColIndices_t;
940
941 // using Base::operator=;
942
943 49735 MatrixBlockView(ArgType& arg, const size_type& nbRows,
944 const RowIndices_t rows, const size_type& nbCols,
945 const ColIndices_t cols)
946 49735 : m_arg(arg),
947 49735 m_nbRows(nbRows),
948 49735 m_rows(rows),
949 49735 m_nbCols(nbCols),
950 49735 m_cols(cols) {}
951
952 /// Valid only when _allRows or _allCols is true
953 337916 MatrixBlockView(ArgType& arg, const size_type& nbIndices,
954 const Indices_t& indices)
955 337916 : m_arg(arg),
956 337916 m_nbRows(_allRows ? arg.rows() : nbIndices),
957 337916 m_rows(indices),
958 337916 m_nbCols(_allCols ? arg.cols() : nbIndices),
959 675418 m_cols(indices) {}
960
961 256037 EIGEN_STRONG_INLINE size_type rows() const { return m_nbRows; }
962 142214 EIGEN_STRONG_INLINE size_type cols() const { return m_nbCols; }
963
964 EIGEN_STRONG_INLINE CoeffReturnType coeff(size_type index) const {
965 assert(false &&
966 "It is not possible to access the coefficients of "
967 "MatrixBlockView this way.");
968 }
969 EIGEN_STRONG_INLINE CoeffReturnType coeff(size_type row,
970 size_type col) const {
971 assert(false &&
972 "It is not possible to access the coefficients of "
973 "MatrixBlockView this way.");
974 }
975 EIGEN_STRONG_INLINE Scalar& coeffRef(size_type index) {
976 assert(false &&
977 "It is not possible to access the coefficients of "
978 "MatrixBlockView this way.");
979 }
980 EIGEN_STRONG_INLINE Scalar& coeffRef(size_type row, const size_type& col) {
981 assert(false &&
982 "It is not possible to access the coefficients of "
983 "MatrixBlockView this way.");
984 }
985 template <typename Dest>
986 10044 EIGEN_STRONG_INLINE void evalTo(Dest& dst) const {
987 10044 internal::eval_matrix_block_view_to<MatrixBlockView, Dest>::run(*this, dst);
988 10044 }
989
990 template <typename Dest>
991 10044 EIGEN_STRONG_INLINE void writeTo(Dest& dst) const {
992 10044 dst.resize(rows(), cols());
993 10044 evalTo(dst.derived());
994 10044 }
995
996 9719 EIGEN_STRONG_INLINE PlainObject eval() const {
997 9719 PlainObject dst;
998
1/2
✓ Branch 1 taken 8145 times.
✗ Branch 2 not taken.
9719 writeTo(dst);
999 9719 return dst;
1000 }
1001
1002 template <typename OtherDerived>
1003 165481 EIGEN_STRONG_INLINE MatrixBlockView& operator=(
1004 const EigenBase<OtherDerived>& other) {
1005 EIGEN_STATIC_ASSERT_LVALUE(ArgType);
1006 165481 internal::eval_matrix_block_view_to<OtherDerived, MatrixBlockView>::run(
1007 26848 other.derived(), *this);
1008 165481 return *this;
1009 }
1010
1011 32 EIGEN_STRONG_INLINE size_type _blocks() const {
1012 32 return m_rows.size() * m_cols.size();
1013 }
1014 140438 EIGEN_STRONG_INLINE BlockXprType _block(const block_iterator& b) {
1015 return internal::access_block_from_matrix_block_view<
1016 140486 BlockXprType, MatrixBlockView>::template run<ArgType>(m_arg, b.ri(),
1017 b.ci(), b.rs(),
1018 140486 b.cs());
1019 }
1020 EIGEN_STRONG_INLINE const BlockConstXprType
1021 123163 _block(const block_iterator& b) const {
1022 return internal::access_block_from_matrix_block_view<
1023 const BlockConstXprType,
1024 123163 MatrixBlockView>::template run<const ArgType>(m_arg, b.ri(), b.ci(),
1025 123167 b.rs(), b.cs());
1026 }
1027 EIGEN_STRONG_INLINE block_iterator _block_iterator() const {
1028 return block_iterator(*this);
1029 }
1030
1031 16 EIGEN_STRONG_INLINE bool isZero(
1032 const RealScalar& prec = NumTraits<Scalar>::dummy_precision()) const {
1033 36 for (block_iterator block(*this); block.valid(); ++block)
1034 28 if (!m_arg.block(block.ri(), block.ci(), block.rs(), block.cs())
1035 28 .isZero(prec))
1036 8 return false;
1037 8 return true;
1038 }
1039
1040 ArgType& m_arg;
1041 size_type m_nbRows;
1042 RowIndices_t m_rows;
1043 size_type m_nbCols;
1044 ColIndices_t m_cols;
1045 }; // MatrixBlockView
1046
1047 ///\}
1048
1049 } // namespace Eigen
1050
1051 #include <hpp/constraints/impl/matrix-view-operation.hh>
1052 #include <hpp/constraints/impl/matrix-view.hh>
1053
1054 #undef HPP_EIGEN_USE_EVALUATOR
1055
1056 namespace hpp {
1057 template <int Option>
1058 struct prettyPrint<constraints::segment_t, Option> {
1059 static std::ostream& run(std::ostream& os, const constraints::segment_t& s) {
1060 return os << "[ " << s.first << ", " << s.first + s.second << " ]";
1061 }
1062 };
1063 } // namespace hpp
1064
1065 #endif // HPP_CONSTRAINTS_MATRIX_VIEW_HH
1066