This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen
View | Details | Raw Unified | Return to bug 408 | Differences between
and this patch

Collapse All | Expand All

(-)a/Eigen/src/Core/Block.h (-4 / +274 lines)
Lines 1-12 Link Here
1
// This file is part of Eigen, a lightweight C++ template library
1
// This file is part of Eigen, a lightweight C++ template library
2
// for linear algebra.
2
// for linear algebra.
3
//
3
//
4
// Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
4
// Copyright (C) 2008-2016 Gael Guennebaud <gael.guennebaud@inria.fr>
5
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
6
//
6
//
7
// This Source Code Form is subject to the terms of the Mozilla
7
// This Source Code Form is subject to the terms of the Mozilla
8
// Public License v. 2.0. If a copy of the MPL was not distributed
8
// Public License v. 2.0. If a copy of the MPL was not distributed
9
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
10
11
#ifndef EIGEN_BLOCK_H
11
#ifndef EIGEN_BLOCK_H
12
#define EIGEN_BLOCK_H
12
#define EIGEN_BLOCK_H
Lines 49-65 struct traits<Block<XprType, BlockRows, Link Here
49
49
50
    // FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
50
    // FIXME, this traits is rather specialized for dense object and it needs to be cleaned further
51
    FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
51
    FlagsLvalueBit = is_lvalue<XprType>::value ? LvalueBit : 0,
52
    FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
52
    FlagsRowMajorBit = IsRowMajor ? RowMajorBit : 0,
53
    Flags = (traits<XprType>::Flags & (DirectAccessBit | (InnerPanel?CompressedAccessBit:0))) | FlagsLvalueBit | FlagsRowMajorBit,
53
    Flags = (traits<XprType>::Flags & (DirectAccessBit | (InnerPanel?CompressedAccessBit:0))) | FlagsLvalueBit | FlagsRowMajorBit,
54
    // FIXME DirectAccessBit should not be handled by expressions
54
    // FIXME DirectAccessBit should not be handled by expressions
55
    // 
55
    // 
56
    // Alignment is needed by MapBase's assertions
56
    // Alignment is needed by MapBase's assertions
57
    // We can sefely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator
57
    // We can safely set it to false here. Internal alignment errors will be detected by an eigen_internal_assert in the respective evaluator
58
    Alignment = 0
58
    Alignment = 0
59
  };
59
  };
60
};
60
};
61
61
62
template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false,
62
template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false,
63
         bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense;
63
         bool HasDirectAccess = internal::has_direct_access<XprType>::ret> class BlockImpl_dense;
64
         
64
         
65
} // end namespace internal
65
} // end namespace internal
Lines 141-159 template<typename XprType, int BlockRows Link Here
141
          Index blockRows, Index blockCols)
141
          Index blockRows, Index blockCols)
142
      : Impl(xpr, startRow, startCol, blockRows, blockCols)
142
      : Impl(xpr, startRow, startCol, blockRows, blockCols)
143
    {
143
    {
144
      eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
144
      eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
145
          && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
145
          && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
146
      eigen_assert(startRow >= 0 && blockRows >= 0 && startRow  <= xpr.rows() - blockRows
146
      eigen_assert(startRow >= 0 && blockRows >= 0 && startRow  <= xpr.rows() - blockRows
147
          && startCol >= 0 && blockCols >= 0 && startCol <= xpr.cols() - blockCols);
147
          && startCol >= 0 && blockCols >= 0 && startCol <= xpr.cols() - blockCols);
148
    }
148
    }
149
150
#ifndef EIGEN_PARSED_BY_DOXYGEN
151
    typedef Block<XprType, internal::traits<Block>::RowsAtCompileTime, 1, InnerPanel && (!Base::IsRowMajor)> ColXpr;
152
    typedef const Block<const XprType, internal::traits<Block>::RowsAtCompileTime, 1, InnerPanel && (!Base::IsRowMajor)> ConstColXpr;
153
    typedef Block<XprType, 1, internal::traits<Block>::ColsAtCompileTime, InnerPanel && Base::IsRowMajor> RowXpr;
154
    typedef const Block<const XprType, 1, internal::traits<Block>::ColsAtCompileTime, InnerPanel && Base::IsRowMajor> ConstRowXpr;
155
    typedef Block<XprType, internal::traits<Block>::RowsAtCompileTime, Dynamic, InnerPanel && (!Base::IsRowMajor)> ColsBlockXpr;
156
    typedef const Block<const XprType, internal::traits<Block>::RowsAtCompileTime, Dynamic, InnerPanel && (!Base::IsRowMajor)> ConstColsBlockXpr;
157
    typedef Block<XprType, Dynamic, internal::traits<Block>::ColsAtCompileTime, InnerPanel && Base::IsRowMajor> RowsBlockXpr;
158
    typedef const Block<const XprType, Dynamic, internal::traits<Block>::ColsAtCompileTime, InnerPanel && Base::IsRowMajor> ConstRowsBlockXpr;
159
    template<int N> struct NColsBlockXpr { typedef Block<XprType, internal::traits<Block>::RowsAtCompileTime, N, InnerPanel && (!Base::IsRowMajor)> Type; };
160
    template<int N> struct ConstNColsBlockXpr { typedef const Block<const XprType, internal::traits<Block>::RowsAtCompileTime, N, InnerPanel && (!Base::IsRowMajor)> Type; };
161
    template<int N> struct NRowsBlockXpr { typedef Block<XprType, N, internal::traits<Block>::ColsAtCompileTime, InnerPanel && Base::IsRowMajor> Type; };
162
    template<int N> struct ConstNRowsBlockXpr { typedef const Block<const XprType, N, internal::traits<Block>::ColsAtCompileTime, InnerPanel && Base::IsRowMajor> Type; };
163
    typedef Block<XprType> BlockXpr;
164
    typedef const Block<const XprType> ConstBlockXpr;
165
    template<int Rows, int Cols> struct FixedBlockXpr { typedef Block<XprType,Rows,Cols> Type; };
166
    template<int Rows, int Cols> struct ConstFixedBlockXpr { typedef Block<const XprType,Rows,Cols> Type; };
167
168
    enum {
169
      IsColVector = internal::is_column_vector_at_compile_time<Block>::value
170
    };
171
172
    typedef VectorBlock<XprType, Dynamic, IsColVector> SegmentReturnType;
173
    typedef const VectorBlock<const XprType, Dynamic, IsColVector> ConstSegmentReturnType;
174
    template<int Size> struct FixedSegmentReturnType { typedef VectorBlock<XprType, Size, IsColVector> Type; };
175
    template<int Size> struct ConstFixedSegmentReturnType { typedef const VectorBlock<const XprType, Size, IsColVector> Type; };
176
177
    using Base::rows;
178
    using Base::cols;
179
    using Base::size;
180
    #define EIGEN_BLOCK_METHODS_SKIP_TYPEDEFS
181
    typedef Block Derived;
182
    #include "../plugins/BlockMethods.h"
183
    #undef EIGEN_BLOCK_METHODS_SKIP_TYPEDEFS
184
185
    typedef typename internal::remove_const<XprType>::type XprTypeNonConst;
186
187
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
188
    EIGEN_DEVICE_FUNC
189
    inline Block( Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index i)
190
      : Impl(blk.nestedExpression(),
191
             blk.startRow() + ((BlockRows==1) && (BlockCols==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::ColsAtCompileTime) ? i : 0),
192
             blk.startCol() + ((BlockRows==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
193
             BlockRows==1 ? 1 : blk.rows(),
194
             BlockCols==1 ? 1 : blk.cols()
195
            )
196
    {
197
      eigen_assert( (i>=0) && (
198
          ((BlockRows==1) && (BlockCols==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::ColsAtCompileTime) && i<blk.rows())
199
        ||((BlockRows==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::RowsAtCompileTime) && (BlockCols==1) && i<blk.cols())));
200
    }
201
202
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
203
    EIGEN_DEVICE_FUNC
204
    inline Block(Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index startRow, Index startCol)
205
      : Impl(blk.nestedExpression(),
206
             blk.startRow() + startRow,
207
             blk.startCol() + startCol)
208
    {
209
      EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
210
      eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= blk.rows()
211
             && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= blk.cols());
212
    }
213
214
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
215
    EIGEN_DEVICE_FUNC
216
    inline Block(Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index startRow, Index startCol, Index blockRows, Index blockCols)
217
      : Impl(blk.nestedExpression(), blk.startRow() + startRow, blk.startCol() + startCol, blockRows, blockCols)
218
    {
219
      eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
220
          && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
221
      eigen_assert(startRow >= 0 && blockRows >= 0 && startRow  <= blk.rows() - blockRows
222
          && startCol >= 0 && blockCols >= 0 && startCol <= blk.cols() - blockCols);
223
    }
224
225
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
226
    EIGEN_DEVICE_FUNC
227
    inline Block( const Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index i)
228
      : Impl(blk.nestedExpression(),
229
             blk.startRow() + ((BlockRows==1) && (BlockCols==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::ColsAtCompileTime) ? i : 0),
230
             blk.startCol() + ((BlockRows==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
231
             BlockRows==1 ? 1 : blk.rows(),
232
             BlockCols==1 ? 1 : blk.cols()
233
            )
234
    {
235
      eigen_assert( (i>=0) && (
236
          ((BlockRows==1) && (BlockCols==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::ColsAtCompileTime) && i<blk.rows())
237
        ||((BlockRows==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::RowsAtCompileTime) && (BlockCols==1) && i<blk.cols())));
238
    }
239
240
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
241
    EIGEN_DEVICE_FUNC
242
    inline Block(const Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index startRow, Index startCol)
243
      : Impl(blk.nestedExpression(),
244
             blk.startRow() + startRow,
245
             blk.startCol() + startCol)
246
    {
247
      EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
248
      eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= blk.rows()
249
             && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= blk.cols());
250
    }
251
252
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
253
    EIGEN_DEVICE_FUNC
254
    inline Block(const Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index startRow, Index startCol, Index blockRows, Index blockCols)
255
      : Impl(blk.nestedExpression(), blk.startRow() + startRow, blk.startCol() + startCol, blockRows, blockCols)
256
    {
257
      eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
258
          && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
259
      eigen_assert(startRow >= 0 && blockRows >= 0 && startRow  <= blk.rows() - blockRows
260
          && startCol >= 0 && blockCols >= 0 && startCol <= blk.cols() - blockCols);
261
    }
262
263
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
264
    EIGEN_DEVICE_FUNC
265
    inline Block( const Block<const XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index i)
266
      : Impl(blk.nestedExpression(),
267
             blk.startRow() + ((BlockRows==1) && (BlockCols==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::ColsAtCompileTime) ? i : 0),
268
             blk.startCol() + ((BlockRows==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
269
             BlockRows==1 ? 1 : blk.rows(),
270
             BlockCols==1 ? 1 : blk.cols()
271
            )
272
    {
273
      eigen_assert( (i>=0) && (
274
          ((BlockRows==1) && (BlockCols==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::ColsAtCompileTime) && i<blk.rows())
275
        ||((BlockRows==Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel>::RowsAtCompileTime) && (BlockCols==1) && i<blk.cols())));
276
    }
277
278
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
279
    EIGEN_DEVICE_FUNC
280
    inline Block(const Block<const XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index startRow, Index startCol)
281
      : Impl(blk.nestedExpression(),
282
             blk.startRow() + startRow,
283
             blk.startCol() + startCol)
284
    {
285
      EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
286
      eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= blk.rows()
287
             && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= blk.cols());
288
    }
289
290
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
291
    EIGEN_DEVICE_FUNC
292
    inline Block(const Block<const XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index startRow, Index startCol, Index blockRows, Index blockCols)
293
      : Impl(blk.nestedExpression(), blk.startRow() + startRow, blk.startCol() + startCol, blockRows, blockCols)
294
    {
295
      eigen_assert((RowsAtCompileTime==Dynamic || RowsAtCompileTime==blockRows)
296
          && (ColsAtCompileTime==Dynamic || ColsAtCompileTime==blockCols));
297
      eigen_assert(startRow >= 0 && blockRows >= 0 && startRow  <= blk.rows() - blockRows
298
          && startCol >= 0 && blockCols >= 0 && startCol <= blk.cols() - blockCols);
299
    }
300
#endif
301
149
};
302
};
150
         
303
151
// The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense
304
// Fuse any Block<Block<X>> expressions as a Block<X> expression
305
// This is the non-const specialization
306
template<typename XprType, int BlockRows0, int BlockCols0, bool InnerPanel0, int BlockRows, int BlockCols, bool InnerPanel>
307
class Block<Block<XprType, BlockRows0, BlockCols0, InnerPanel0>, BlockRows, BlockCols, InnerPanel>
308
  : public Block<XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0>
309
{
310
    typedef Block<XprType,BlockRows0,BlockCols0,InnerPanel0> ArgType;
311
    typedef Block<XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0> Base;
312
public:
313
    using Base::operator=;
314
315
    /** Column or Row constructor
316
      */
317
    EIGEN_DEVICE_FUNC
318
    template<typename OtherBlock>
319
    inline Block(OtherBlock &blk, Index i)
320
      : Base(blk.nestedExpression(),
321
             blk.startRow() + ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) ? i : 0),
322
             blk.startCol() + ((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
323
             BlockRows==1 ? 1 : blk.rows(),
324
             BlockCols==1 ? 1 : blk.cols()
325
            )
326
    {
327
      eigen_assert( (i>=0) && (
328
          ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) && i<blk.rows())
329
        ||((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) && i<blk.cols())));
330
    }
331
332
    /** Fixed-size constructor
333
      */
334
    EIGEN_DEVICE_FUNC
335
    template<typename OtherBlock>
336
    inline Block(OtherBlock &blk, Index startRow, Index startCol)
337
      : Base(blk.nestedExpression(),
338
             blk.startRow() + startRow,
339
             blk.startCol() + startCol)
340
    {
341
      EIGEN_STATIC_ASSERT(Base::RowsAtCompileTime!=Dynamic && Base::ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
342
      eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= blk.rows()
343
             && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= blk.cols());
344
    }
345
346
    /** Dynamic-size constructor
347
      */
348
    EIGEN_DEVICE_FUNC
349
    template<typename OtherBlock>
350
    inline Block(OtherBlock &blk, Index startRow, Index startCol, Index blockRows, Index blockCols)
351
      : Base(blk.nestedExpression(), blk.startRow() + startRow, blk.startCol() + startCol, blockRows, blockCols)
352
    {
353
      eigen_assert((Base::RowsAtCompileTime==Dynamic || Base::RowsAtCompileTime==blockRows)
354
          && (Base::ColsAtCompileTime==Dynamic || Base::ColsAtCompileTime==blockCols));
355
      eigen_assert(startRow >= 0 && blockRows >= 0 && startRow  <= blk.rows() - blockRows
356
          && startCol >= 0 && blockCols >= 0 && startCol <= blk.cols() - blockCols);
357
    }
358
359
    // This ctor enable codes like Block<B> c = b.block(...) where B is already a Block.
360
    EIGEN_DEVICE_FUNC
361
    inline Block(const Base &blk) : Base(blk) {}
362
};
363
364
// Fuse any Block<const Block<X>> expressions as a Block<const X> expression
365
// This is the const specialization
366
template<typename XprType, int BlockRows0, int BlockCols0, bool InnerPanel0, int BlockRows, int BlockCols, bool InnerPanel>
367
class Block<const Block<XprType, BlockRows0, BlockCols0, InnerPanel0>, BlockRows, BlockCols, InnerPanel>
368
  : public Block<const XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0>
369
{
370
    typedef Block<XprType, BlockRows0, BlockCols0, InnerPanel0> ArgType;
371
    typedef Block<const XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0> Base;
372
public:
373
    using Base::operator=;
374
375
    /** Column or Row constructor
376
      */
377
    EIGEN_DEVICE_FUNC
378
    inline Block(const ArgType &blk, Index i)
379
      : Base(blk.nestedExpression(),
380
             blk.startRow() + ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) ? i : 0),
381
             blk.startCol() + ((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
382
             BlockRows==1 ? 1 : blk.rows(),
383
             BlockCols==1 ? 1 : blk.cols()
384
            )
385
    {
386
      eigen_assert( (i>=0) && (
387
          ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) && i<blk.rows())
388
        ||((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) && i<blk.cols())));
389
    }
390
391
    /** Fixed-size constructor
392
      */
393
    EIGEN_DEVICE_FUNC
394
    inline Block(const ArgType &blk, Index startRow, Index startCol)
395
      : Base(blk.nestedExpression(),
396
             blk.startRow() + startRow,
397
             blk.startCol() + startCol)
398
    {
399
      EIGEN_STATIC_ASSERT(Base::RowsAtCompileTime!=Dynamic && Base::ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
400
      eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= blk.rows()
401
             && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= blk.cols());
402
    }
403
404
    /** Dynamic-size constructor
405
      */
406
    EIGEN_DEVICE_FUNC
407
    inline Block(const ArgType &blk, Index startRow, Index startCol, Index blockRows, Index blockCols)
408
      : Base(blk.nestedExpression(), blk.startRow() + startRow, blk.startCol() + startCol, blockRows, blockCols)
409
    {
410
      eigen_assert((Base::RowsAtCompileTime==Dynamic || Base::RowsAtCompileTime==blockRows)
411
          && (Base::ColsAtCompileTime==Dynamic || Base::ColsAtCompileTime==blockCols));
412
      eigen_assert(startRow >= 0 && blockRows >= 0 && startRow  <= blk.rows() - blockRows
413
          && startCol >= 0 && blockCols >= 0 && startCol <= blk.cols() - blockCols);
414
    }
415
416
    // This ctor enable codes like Block<B> c = b.block(...) where B is already a Block.
417
    EIGEN_DEVICE_FUNC
418
    inline Block(const Base &blk) : Base(blk) {}
419
};
420
421
// The generic default implementation for dense block simply forward to the internal::BlockImpl_dense
152
// that must be specialized for direct and non-direct access...
422
// that must be specialized for direct and non-direct access...
153
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
423
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
154
class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
424
class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
155
  : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel>
425
  : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel>
156
{
426
{
157
    typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
427
    typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
158
    typedef typename XprType::StorageIndex StorageIndex;
428
    typedef typename XprType::StorageIndex StorageIndex;
159
  public:
429
  public:
(-)a/Eigen/src/Core/VectorBlock.h (-17 / +70 lines)
Lines 9-31 Link Here
9
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
10
11
#ifndef EIGEN_VECTORBLOCK_H
11
#ifndef EIGEN_VECTORBLOCK_H
12
#define EIGEN_VECTORBLOCK_H
12
#define EIGEN_VECTORBLOCK_H
13
13
14
namespace Eigen { 
14
namespace Eigen { 
15
15
16
namespace internal {
16
namespace internal {
17
template<typename VectorType, int Size>
17
template<typename VectorType, int Size, bool IsColVector>
18
struct traits<VectorBlock<VectorType, Size> >
18
struct traits<VectorBlock<VectorType, Size, IsColVector> >
19
  : public traits<Block<VectorType,
19
  : public traits<Block<VectorType, IsColVector ? Size : 1, IsColVector ? 1 : Size> >
20
                     traits<VectorType>::Flags & RowMajorBit ? 1 : Size,
20
{};
21
                     traits<VectorType>::Flags & RowMajorBit ? Size : 1> >
22
{
23
};
24
}
21
}
25
22
26
/** \class VectorBlock
23
/** \class VectorBlock
27
  * \ingroup Core_Module
24
  * \ingroup Core_Module
28
  *
25
  *
29
  * \brief Expression of a fixed-size or dynamic-size sub-vector
26
  * \brief Expression of a fixed-size or dynamic-size sub-vector
30
  *
27
  *
31
  * \tparam VectorType the type of the object in which we are taking a sub-vector
28
  * \tparam VectorType the type of the object in which we are taking a sub-vector
Lines 48-74 struct traits<VectorBlock<VectorType, Si Link Here
48
  * it does not cause a dynamic memory allocation.
45
  * it does not cause a dynamic memory allocation.
49
  *
46
  *
50
  * Here is an example illustrating the fixed-size case:
47
  * Here is an example illustrating the fixed-size case:
51
  * \include class_FixedVectorBlock.cpp
48
  * \include class_FixedVectorBlock.cpp
52
  * Output: \verbinclude class_FixedVectorBlock.out
49
  * Output: \verbinclude class_FixedVectorBlock.out
53
  *
50
  *
54
  * \sa class Block, DenseBase::segment(Index,Index,Index,Index), DenseBase::segment(Index,Index)
51
  * \sa class Block, DenseBase::segment(Index,Index,Index,Index), DenseBase::segment(Index,Index)
55
  */
52
  */
56
template<typename VectorType, int Size> class VectorBlock
53
template<typename VectorType, int Size, bool IsColVector> class VectorBlock
57
  : public Block<VectorType,
54
  : public Block<VectorType, IsColVector ? Size : 1, IsColVector ? 1 : Size>
58
                     internal::traits<VectorType>::Flags & RowMajorBit ? 1 : Size,
59
                     internal::traits<VectorType>::Flags & RowMajorBit ? Size : 1>
60
{
55
{
61
    typedef Block<VectorType,
56
    typedef Block<VectorType, IsColVector ? Size : 1, IsColVector ? 1 : Size> Base;
62
                     internal::traits<VectorType>::Flags & RowMajorBit ? 1 : Size,
57
63
                     internal::traits<VectorType>::Flags & RowMajorBit ? Size : 1> Base;
64
    enum {
65
      IsColVector = !(internal::traits<VectorType>::Flags & RowMajorBit)
66
    };
67
  public:
58
  public:
68
    EIGEN_DENSE_PUBLIC_INTERFACE(VectorBlock)
59
    EIGEN_DENSE_PUBLIC_INTERFACE(VectorBlock)
69
60
70
    using Base::operator=;
61
    using Base::operator=;
71
62
72
    /** Dynamic-size constructor
63
    /** Dynamic-size constructor
73
      */
64
      */
74
    EIGEN_DEVICE_FUNC
65
    EIGEN_DEVICE_FUNC
Lines 83-96 template<typename VectorType, int Size> Link Here
83
    /** Fixed-size constructor
74
    /** Fixed-size constructor
84
      */
75
      */
85
    EIGEN_DEVICE_FUNC
76
    EIGEN_DEVICE_FUNC
86
    inline VectorBlock(VectorType& vector, Index start)
77
    inline VectorBlock(VectorType& vector, Index start)
87
      : Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start)
78
      : Base(vector, IsColVector ? start : 0, IsColVector ? 0 : start)
88
    {
79
    {
89
      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
80
      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
90
    }
81
    }
82
83
#ifndef EIGEN_PARSED_BY_DOXYGEN
84
    typedef typename Base::XprTypeNonConst XprTypeNonConst;
85
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
86
    EIGEN_DEVICE_FUNC
87
    inline VectorBlock(Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index start, Index size)
88
      : Base(blk.nestedExpression(),
89
             blk.startRow() + (IsColVector ? start : 0),
90
             blk.startCol() + (IsColVector ? 0 : start),
91
             IsColVector ? size  : 1, IsColVector ? 1 : size)
92
    {
93
      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
94
    }
95
96
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
97
    EIGEN_DEVICE_FUNC
98
    inline VectorBlock(Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index start)
99
      : Base(blk.nestedExpression(), blk.startRow() + (IsColVector ? start : 0), blk.startCol() + (IsColVector ? 0 : start))
100
    {
101
      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
102
    }
103
104
105
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
106
    EIGEN_DEVICE_FUNC
107
    inline VectorBlock(const Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index start, Index size)
108
      : Base(blk.nestedExpression(),
109
             blk.startRow() + (IsColVector ? start : 0),
110
             blk.startCol() + (IsColVector ? 0 : start),
111
             IsColVector ? size  : 1, IsColVector ? 1 : size)
112
    {
113
      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
114
    }
115
116
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
117
    EIGEN_DEVICE_FUNC
118
    inline VectorBlock(const Block<XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index start)
119
      : Base(blk.nestedExpression(), blk.startRow() + (IsColVector ? start : 0), blk.startCol() + (IsColVector ? 0 : start))
120
    {
121
      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
122
    }
123
124
125
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
126
    EIGEN_DEVICE_FUNC
127
    inline VectorBlock(const Block<const XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index start, Index size)
128
      : Base(blk.nestedExpression(),
129
             blk.startRow() + (IsColVector ? start : 0),
130
             blk.startCol() + (IsColVector ? 0 : start),
131
             IsColVector ? size  : 1, IsColVector ? 1 : size)
132
    {
133
      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
134
    }
135
136
    template<int OtherRows,int OtherCols, bool OtherInnerPanel>
137
    EIGEN_DEVICE_FUNC
138
    inline VectorBlock(const Block<const XprTypeNonConst,OtherRows,OtherCols,OtherInnerPanel> &blk, Index start)
139
      : Base(blk.nestedExpression(), blk.startRow() + (IsColVector ? start : 0), blk.startCol() + (IsColVector ? 0 : start))
140
    {
141
      EIGEN_STATIC_ASSERT_VECTOR_ONLY(VectorBlock);
142
    }
143
#endif
91
};
144
};
92
145
93
146
94
} // end namespace Eigen
147
} // end namespace Eigen
95
148
96
#endif // EIGEN_VECTORBLOCK_H
149
#endif // EIGEN_VECTORBLOCK_H
(-)a/Eigen/src/Core/util/ForwardDeclarations.h (-1 / +3 lines)
Lines 35-50 template<typename Derived> struct access Link Here
35
                                   : (has_write_access ? WriteAccessors       : ReadOnlyAccessors)
35
                                   : (has_write_access ? WriteAccessors       : ReadOnlyAccessors)
36
  };
36
  };
37
};
37
};
38
38
39
template<typename T> struct evaluator_traits;
39
template<typename T> struct evaluator_traits;
40
40
41
template< typename T> struct evaluator;
41
template< typename T> struct evaluator;
42
42
43
template<typename T> struct is_column_vector_at_compile_time;
44
43
} // end namespace internal
45
} // end namespace internal
44
46
45
template<typename T> struct NumTraits;
47
template<typename T> struct NumTraits;
46
48
47
template<typename Derived> struct EigenBase;
49
template<typename Derived> struct EigenBase;
48
template<typename Derived> class DenseBase;
50
template<typename Derived> class DenseBase;
49
template<typename Derived> class PlainObjectBase;
51
template<typename Derived> class PlainObjectBase;
50
52
Lines 79-95 template<typename Derived> class ArrayBa Link Here
79
template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged;
81
template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged;
80
template<typename ExpressionType, template <typename> class StorageBase > class NoAlias;
82
template<typename ExpressionType, template <typename> class StorageBase > class NoAlias;
81
template<typename ExpressionType> class NestByValue;
83
template<typename ExpressionType> class NestByValue;
82
template<typename ExpressionType> class ForceAlignedAccess;
84
template<typename ExpressionType> class ForceAlignedAccess;
83
template<typename ExpressionType> class SwapWrapper;
85
template<typename ExpressionType> class SwapWrapper;
84
86
85
template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false> class Block;
87
template<typename XprType, int BlockRows=Dynamic, int BlockCols=Dynamic, bool InnerPanel = false> class Block;
86
88
87
template<typename MatrixType, int Size=Dynamic> class VectorBlock;
89
template<typename VectorType, int Size=Dynamic, bool IsColumnVector = internal::is_column_vector_at_compile_time<VectorType>::value> class VectorBlock;
88
template<typename MatrixType> class Transpose;
90
template<typename MatrixType> class Transpose;
89
template<typename MatrixType> class Conjugate;
91
template<typename MatrixType> class Conjugate;
90
template<typename NullaryOp, typename MatrixType>         class CwiseNullaryOp;
92
template<typename NullaryOp, typename MatrixType>         class CwiseNullaryOp;
91
template<typename UnaryOp,   typename MatrixType>         class CwiseUnaryOp;
93
template<typename UnaryOp,   typename MatrixType>         class CwiseUnaryOp;
92
template<typename ViewOp,    typename MatrixType>         class CwiseUnaryView;
94
template<typename ViewOp,    typename MatrixType>         class CwiseUnaryView;
93
template<typename BinaryOp,  typename Lhs, typename Rhs>  class CwiseBinaryOp;
95
template<typename BinaryOp,  typename Lhs, typename Rhs>  class CwiseBinaryOp;
94
template<typename Decomposition, typename Rhstype>        class Solve;
96
template<typename Decomposition, typename Rhstype>        class Solve;
95
template<typename XprType>                                class Inverse;
97
template<typename XprType>                                class Inverse;
(-)a/Eigen/src/Core/util/XprHelper.h (-1 / +10 lines)
Lines 223-238 template<int _Rows, int _Cols> struct si Link Here
223
  enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
223
  enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
224
};
224
};
225
225
226
template<typename XprType> struct size_of_xpr_at_compile_time
226
template<typename XprType> struct size_of_xpr_at_compile_time
227
{
227
{
228
  enum { ret = size_at_compile_time<traits<XprType>::RowsAtCompileTime,traits<XprType>::ColsAtCompileTime>::ret };
228
  enum { ret = size_at_compile_time<traits<XprType>::RowsAtCompileTime,traits<XprType>::ColsAtCompileTime>::ret };
229
};
229
};
230
230
231
template<typename T> struct is_column_vector_at_compile_time
232
{
233
  enum {
234
    value = (internal::traits<T>::ColsAtCompileTime==1 && internal::traits<T>::RowsAtCompileTime==1)
235
          ? (!(internal::traits<T>::Flags & RowMajorBit))
236
          : (internal::traits<T>::ColsAtCompileTime==1)
237
  };
238
};
239
231
/* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type,
240
/* plain_matrix_type : the difference from eval is that plain_matrix_type is always a plain matrix type,
232
 * whereas eval is a const reference in the case of a matrix
241
 * whereas eval is a const reference in the case of a matrix
233
 */
242
 */
234
243
235
template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type;
244
template<typename T, typename StorageKind = typename traits<T>::StorageKind> struct plain_matrix_type;
236
template<typename T, typename BaseClassType, int Flags> struct plain_matrix_type_dense;
245
template<typename T, typename BaseClassType, int Flags> struct plain_matrix_type_dense;
237
template<typename T> struct plain_matrix_type<T,Dense>
246
template<typename T> struct plain_matrix_type<T,Dense>
238
{
247
{
Lines 656-672 bool is_same_dense(const T1 &, const T2 Link Here
656
  return false;
665
  return false;
657
}
666
}
658
667
659
template<typename T, typename U> struct is_same_or_void { enum { value = is_same<T,U>::value }; };
668
template<typename T, typename U> struct is_same_or_void { enum { value = is_same<T,U>::value }; };
660
template<typename T> struct is_same_or_void<void,T>     { enum { value = 1 }; };
669
template<typename T> struct is_same_or_void<void,T>     { enum { value = 1 }; };
661
template<typename T> struct is_same_or_void<T,void>     { enum { value = 1 }; };
670
template<typename T> struct is_same_or_void<T,void>     { enum { value = 1 }; };
662
template<>           struct is_same_or_void<void,void>  { enum { value = 1 }; };
671
template<>           struct is_same_or_void<void,void>  { enum { value = 1 }; };
663
672
664
#ifdef EIGEN_DEBUG_ASSIGN
673
#if defined EIGEN_DEBUG_ASSIGN || defined EIGEN_DEBUG_DEMANGLING
665
std::string demangle_traversal(int t)
674
std::string demangle_traversal(int t)
666
{
675
{
667
  if(t==DefaultTraversal) return "DefaultTraversal";
676
  if(t==DefaultTraversal) return "DefaultTraversal";
668
  if(t==LinearTraversal) return "LinearTraversal";
677
  if(t==LinearTraversal) return "LinearTraversal";
669
  if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
678
  if(t==InnerVectorizedTraversal) return "InnerVectorizedTraversal";
670
  if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
679
  if(t==LinearVectorizedTraversal) return "LinearVectorizedTraversal";
671
  if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
680
  if(t==SliceVectorizedTraversal) return "SliceVectorizedTraversal";
672
  return "?";
681
  return "?";
(-)a/Eigen/src/plugins/BlockMethods.h (+2 lines)
Lines 5-20 Link Here
5
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
6
//
6
//
7
// This Source Code Form is subject to the terms of the Mozilla
7
// This Source Code Form is subject to the terms of the Mozilla
8
// Public License v. 2.0. If a copy of the MPL was not distributed
8
// Public License v. 2.0. If a copy of the MPL was not distributed
9
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
10
10
11
#ifndef EIGEN_PARSED_BY_DOXYGEN
11
#ifndef EIGEN_PARSED_BY_DOXYGEN
12
12
13
#ifndef EIGEN_BLOCK_METHODS_SKIP_TYPEDEFS
13
/** \internal expression type of a column */
14
/** \internal expression type of a column */
14
typedef Block<Derived, internal::traits<Derived>::RowsAtCompileTime, 1, !IsRowMajor> ColXpr;
15
typedef Block<Derived, internal::traits<Derived>::RowsAtCompileTime, 1, !IsRowMajor> ColXpr;
15
typedef const Block<const Derived, internal::traits<Derived>::RowsAtCompileTime, 1, !IsRowMajor> ConstColXpr;
16
typedef const Block<const Derived, internal::traits<Derived>::RowsAtCompileTime, 1, !IsRowMajor> ConstColXpr;
16
/** \internal expression type of a row */
17
/** \internal expression type of a row */
17
typedef Block<Derived, 1, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> RowXpr;
18
typedef Block<Derived, 1, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> RowXpr;
18
typedef const Block<const Derived, 1, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> ConstRowXpr;
19
typedef const Block<const Derived, 1, internal::traits<Derived>::ColsAtCompileTime, IsRowMajor> ConstRowXpr;
19
/** \internal expression type of a block of whole columns */
20
/** \internal expression type of a block of whole columns */
20
typedef Block<Derived, internal::traits<Derived>::RowsAtCompileTime, Dynamic, !IsRowMajor> ColsBlockXpr;
21
typedef Block<Derived, internal::traits<Derived>::RowsAtCompileTime, Dynamic, !IsRowMajor> ColsBlockXpr;
Lines 34-49 typedef const Block<const Derived> Const Link Here
34
/** \internal expression of a block of fixed sizes */
35
/** \internal expression of a block of fixed sizes */
35
template<int Rows, int Cols> struct FixedBlockXpr { typedef Block<Derived,Rows,Cols> Type; };
36
template<int Rows, int Cols> struct FixedBlockXpr { typedef Block<Derived,Rows,Cols> Type; };
36
template<int Rows, int Cols> struct ConstFixedBlockXpr { typedef Block<const Derived,Rows,Cols> Type; };
37
template<int Rows, int Cols> struct ConstFixedBlockXpr { typedef Block<const Derived,Rows,Cols> Type; };
37
38
38
typedef VectorBlock<Derived> SegmentReturnType;
39
typedef VectorBlock<Derived> SegmentReturnType;
39
typedef const VectorBlock<const Derived> ConstSegmentReturnType;
40
typedef const VectorBlock<const Derived> ConstSegmentReturnType;
40
template<int Size> struct FixedSegmentReturnType { typedef VectorBlock<Derived, Size> Type; };
41
template<int Size> struct FixedSegmentReturnType { typedef VectorBlock<Derived, Size> Type; };
41
template<int Size> struct ConstFixedSegmentReturnType { typedef const VectorBlock<const Derived, Size> Type; };
42
template<int Size> struct ConstFixedSegmentReturnType { typedef const VectorBlock<const Derived, Size> Type; };
43
#endif
42
44
43
#endif // not EIGEN_PARSED_BY_DOXYGEN
45
#endif // not EIGEN_PARSED_BY_DOXYGEN
44
46
45
/** \returns a dynamic-size expression of a block in *this.
47
/** \returns a dynamic-size expression of a block in *this.
46
  *
48
  *
47
  * \param startRow the first row in the block
49
  * \param startRow the first row in the block
48
  * \param startCol the first column in the block
50
  * \param startCol the first column in the block
49
  * \param blockRows the number of rows in the block
51
  * \param blockRows the number of rows in the block
(-)a/test/block.cpp (+196 lines)
Lines 3-18 Link Here
3
//
3
//
4
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
4
// Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
5
//
5
//
6
// This Source Code Form is subject to the terms of the Mozilla
6
// This Source Code Form is subject to the terms of the Mozilla
7
// Public License v. 2.0. If a copy of the MPL was not distributed
7
// Public License v. 2.0. If a copy of the MPL was not distributed
8
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
9
10
#define EIGEN_NO_STATIC_ASSERT // otherwise we fail at compile time on unused paths
10
#define EIGEN_NO_STATIC_ASSERT // otherwise we fail at compile time on unused paths
11
#define EIGEN_DEBUG_DEMANGLING
11
#include "main.h"
12
#include "main.h"
12
13
13
template<typename MatrixType, typename Index, typename Scalar>
14
template<typename MatrixType, typename Index, typename Scalar>
14
typename Eigen::internal::enable_if<!NumTraits<typename MatrixType::Scalar>::IsComplex,typename MatrixType::Scalar>::type
15
typename Eigen::internal::enable_if<!NumTraits<typename MatrixType::Scalar>::IsComplex,typename MatrixType::Scalar>::type
15
block_real_only(const MatrixType &m1, Index r1, Index r2, Index c1, Index c2, const Scalar& s1) {
16
block_real_only(const MatrixType &m1, Index r1, Index r2, Index c1, Index c2, const Scalar& s1) {
16
  // check cwise-Functions:
17
  // check cwise-Functions:
17
  VERIFY_IS_APPROX(m1.row(r1).cwiseMax(s1), m1.cwiseMax(s1).row(r1));
18
  VERIFY_IS_APPROX(m1.row(r1).cwiseMax(s1), m1.cwiseMax(s1).row(r1));
18
  VERIFY_IS_APPROX(m1.col(c1).cwiseMin(s1), m1.cwiseMin(s1).col(c1));
19
  VERIFY_IS_APPROX(m1.col(c1).cwiseMin(s1), m1.cwiseMin(s1).col(c1));
Lines 183-198 template<typename MatrixType> void block Link Here
183
  VERIFY_IS_EQUAL(dv, dm);
184
  VERIFY_IS_EQUAL(dv, dm);
184
185
185
  VERIFY_IS_EQUAL( (m1.template block<Dynamic,1>(1,0,0,1)), m1.block(1,0,0,1));
186
  VERIFY_IS_EQUAL( (m1.template block<Dynamic,1>(1,0,0,1)), m1.block(1,0,0,1));
186
  VERIFY_IS_EQUAL( (m1.template block<1,Dynamic>(0,1,1,0)), m1.block(0,1,1,0));
187
  VERIFY_IS_EQUAL( (m1.template block<1,Dynamic>(0,1,1,0)), m1.block(0,1,1,0));
187
  VERIFY_IS_EQUAL( ((m1*1).template block<Dynamic,1>(1,0,0,1)), m1.block(1,0,0,1));
188
  VERIFY_IS_EQUAL( ((m1*1).template block<Dynamic,1>(1,0,0,1)), m1.block(1,0,0,1));
188
  VERIFY_IS_EQUAL( ((m1*1).template block<1,Dynamic>(0,1,1,0)), m1.block(0,1,1,0));
189
  VERIFY_IS_EQUAL( ((m1*1).template block<1,Dynamic>(0,1,1,0)), m1.block(0,1,1,0));
189
}
190
}
190
191
192
template<typename T>
193
bool same_type(const T&, const T&) { return true; }
194
195
template<typename Expr, typename Ref, typename ExprFused>
196
void checkbb(const DenseBase<Expr> &a_xpr, const DenseBase<Ref> &a_ref, const DenseBase<ExprFused> &a_xprfused)
197
{
198
  const Expr& xpr(a_xpr.derived());
199
  const Ref& ref(a_ref.derived());
200
  const ExprFused& xprfused(a_xprfused.derived());
201
202
  VERIFY_IS_APPROX(xprfused, ref);
203
204
  VERIFY(same_type<ExprFused>(xpr, xprfused));
205
206
  if(ExprFused::Flags!=Expr::Flags)
207
    std::cerr << "Expected: " << internal::demangle_flags(ExprFused::Flags) << std::endl
208
              << "Got:      " << internal::demangle_flags(Expr::Flags) << std::endl;
209
210
  VERIFY_IS_EQUAL(ExprFused::Flags, Expr::Flags);
211
  VERIFY_IS_EQUAL(ExprFused::RowsAtCompileTime, Expr::RowsAtCompileTime);
212
  VERIFY_IS_EQUAL(ExprFused::ColsAtCompileTime, Expr::ColsAtCompileTime);
213
  VERIFY_IS_EQUAL(ExprFused::MaxRowsAtCompileTime, Expr::MaxRowsAtCompileTime);
214
  VERIFY_IS_EQUAL(ExprFused::MaxColsAtCompileTime, Expr::MaxColsAtCompileTime);
215
216
  typedef internal::evaluator<ExprFused> EvalFused;
217
  typedef internal::evaluator<Expr> EvalExpr;
218
  VERIFY_IS_EQUAL(EvalFused::Flags, EvalExpr::Flags);
219
  VERIFY_IS_EQUAL(EvalFused::Alignment, EvalExpr::Alignment);
220
221
  VERIFY_IS_APPROX(xpr.derived(), ref);
222
  VERIFY_IS_APPROX(xpr, ref);
223
}
224
225
template<typename MatrixType>
226
void block_rec(const MatrixType& a)
227
{
228
  if(a.cols()>1)
229
  {
230
    block_rec(a.leftCols(a.cols()/2));
231
    block_rec(a.rightCols(a.cols()/2));
232
  }
233
}
234
235
template<typename T> const T& make_const(const T& x) { return x; }
236
237
template<typename MatrixType>
238
void check_block_block_fusion(const MatrixType &m)
239
{
240
  Index rows = m.rows();
241
  Index cols = m.cols();
242
243
  MatrixType m1 = MatrixType::Random(rows, cols),
244
             m2 = MatrixType::Random(rows, cols);
245
246
  Index r1 = internal::random<Index>(0,rows-1);
247
  Index c1 = internal::random<Index>(0,cols-1);
248
  Index nr1 = internal::random<Index>(1,rows-r1);
249
  Index nc1 = internal::random<Index>(1,cols-c1);
250
251
  Index r2 = internal::random<Index>(0,nr1-1);
252
  Index c2 = internal::random<Index>(0,nc1-1);
253
  Index nr2 = internal::random<Index>(1,nr1-r2);
254
  Index nc2 = internal::random<Index>(1,nc1-c2);
255
256
  CALL_SUBTEST( checkbb(m1.block(r1,c1, nr1,nc1).block(r2,c2,nr2,nc2),
257
                        m1.block(r1,c1, nr1,nc1).eval().block(r2,c2,nr2,nc2).eval(),
258
                        m1.block(r1+r2, c1+c2, nr2, nc2)) );
259
  CALL_SUBTEST( checkbb(make_const(m1.block(r1,c1, nr1,nc1)).block(r2,c2,nr2,nc2),
260
                        m1.block(r1,c1, nr1,nc1).eval().block(r2,c2,nr2,nc2).eval(),
261
                        make_const(m1).block(r1+r2, c1+c2, nr2, nc2)) );
262
  CALL_SUBTEST( checkbb((m1+m2).block(r1,c1, nr1,nc1).block(r2,c2,nr2,nc2),
263
                        (m1+m2).block(r1,c1, nr1,nc1).eval().block(r2,c2,nr2,nc2).eval(),
264
                        (m1+m2).block(r1+r2, c1+c2, nr2, nc2)) );
265
266
  CALL_SUBTEST( checkbb(m1.block(r1,c1, nr1,nc1).row(r2),
267
                        m1.block(r1,c1, nr1,nc1).eval().row(r2).eval(),
268
                        m1.template block<1,Dynamic>(r1+r2, c1, 1, nc1)) );
269
  CALL_SUBTEST( checkbb(make_const(m1.block(r1,c1, nr1,nc1)).row(r2),
270
                        m1.block(r1,c1, nr1,nc1).eval().row(r2).eval(),
271
                        make_const(m1).template block<1,Dynamic>(r1+r2, c1, 1, nc1)) );
272
  CALL_SUBTEST( checkbb((m1+m2).block(r1,c1, nr1,nc1).row(r2),
273
                        (m1+m2).block(r1,c1, nr1,nc1).eval().row(r2).eval(),
274
                        (m1+m2).template block<1,Dynamic>(r1+r2, c1, 1, nc1)) );
275
276
  CALL_SUBTEST( checkbb(m1.block(r1,c1, nr1,nc1).col(c2),
277
                        m1.block(r1,c1, nr1,nc1).eval().col(c2).eval(),
278
                        m1.template block<Dynamic,1>(r1, c1+c2, nr1, 1)) );
279
  CALL_SUBTEST( checkbb(make_const(m1.block(r1,c1, nr1,nc1)).col(c2),
280
                        m1.block(r1,c1, nr1,nc1).eval().col(c2).eval(),
281
                        make_const(m1).template block<Dynamic,1>(r1, c1+c2, nr1, 1)) );
282
  CALL_SUBTEST( checkbb((m1+m2).block(r1,c1, nr1,nc1).col(c2),
283
                        (m1+m2).block(r1,c1, nr1,nc1).eval().col(c2).eval(),
284
                        (m1+m2).template block<Dynamic,1>(r1, c1+c2, nr1, 1)) );
285
286
  CALL_SUBTEST( checkbb(m1.row(r1).segment(c1,nc1),
287
                        m1.row(r1).eval().segment(c1,nc1).eval(),
288
                        m1.template block<1,Dynamic>(r1, c1, 1, nc1)) );
289
  CALL_SUBTEST( checkbb(make_const(m1.row(r1)).segment(c1,nc1),
290
                        m1.row(r1).eval().segment(c1,nc1).eval(),
291
                        make_const(m1).template block<1,Dynamic>(r1, c1, 1, nc1)) );
292
  CALL_SUBTEST( checkbb((m1+m2).row(r1).segment(c1,nc1),
293
                        (m1+m2).row(r1).eval().segment(c1,nc1).eval(),
294
                        (m1+m2).template block<1,Dynamic>(r1, c1, 1, nc1)) );
295
296
  CALL_SUBTEST( checkbb(m1.col(c1).segment(r1,nr1),
297
                        m1.col(c1).eval().segment(r1,nr1).eval(),
298
                        m1.template block<Dynamic,1>(r1, c1, nr1, 1)) );
299
  CALL_SUBTEST( checkbb(make_const(m1.col(c1)).segment(r1,nr1),
300
                        m1.col(c1).eval().segment(r1,nr1).eval(),
301
                        make_const(m1).template block<Dynamic,1>(r1, c1, nr1, 1)) );
302
  CALL_SUBTEST( checkbb((m1+m2).col(c1).segment(r1,nr1),
303
                        (m1+m2).col(c1).eval().segment(r1,nr1).eval(),
304
                        (m1+m2).template block<Dynamic,1>(r1, c1, nr1, 1)) );
305
306
  CALL_SUBTEST( checkbb(m1.middleCols(c1,nc1).col(c2).segment(r1,nr1),
307
                        m1.middleCols(c1,nc1).eval().col(c2).eval().segment(r1,nr1).eval(),
308
                        m1.template block<Dynamic,1>(r1, c1+c2, nr1, 1)) );
309
  CALL_SUBTEST( checkbb(make_const(m1.middleCols(c1,nc1)).col(c2).segment(r1,nr1),
310
                        m1.middleCols(c1,nc1).eval().col(c2).eval().segment(r1,nr1).eval(),
311
                        make_const(m1).template block<Dynamic,1>(r1, c1+c2, nr1, 1)) );
312
  CALL_SUBTEST( checkbb(make_const(m1.middleCols(c1,nc1).col(c2)).segment(r1,nr1),
313
                        m1.middleCols(c1,nc1).eval().col(c2).eval().segment(r1,nr1).eval(),
314
                        make_const(m1).template block<Dynamic,1>(r1, c1+c2, nr1, 1)) );
315
  CALL_SUBTEST( checkbb((m1+m2).middleCols(c1,nc1).col(c2).segment(r1,nr1),
316
                        (m1+m2).middleCols(c1,nc1).eval().col(c2).eval().segment(r1,nr1).eval(),
317
                        (m1+m2).template block<Dynamic,1>(r1, c1+c2, nr1, 1)) );
318
319
  CALL_SUBTEST( checkbb(m1.row(r1).col(c1),
320
                        m1.row(r1).eval().col(c1).eval(),
321
                        m1.template block<1,1>(r1, c1)) );
322
  CALL_SUBTEST( checkbb(make_const(m1.row(r1)).col(c1),
323
                        m1.row(r1).eval().col(c1).eval(),
324
                        make_const(m1).template block<1,1>(r1, c1)) );
325
  CALL_SUBTEST( checkbb((m1+m2).row(r1).col(c1),
326
                        (m1+m2).row(r1).eval().col(c1).eval(),
327
                        (m1+m2).template block<1,1>(r1, c1)) );
328
329
  CALL_SUBTEST( checkbb(m1.row(r1).col(c1).segment(0,1),
330
                        m1.row(r1).eval().col(c1).eval().segment(0,1).eval(),
331
                        m1.template block<Dynamic,1>(r1, c1, 1,1)) );
332
  CALL_SUBTEST( checkbb(make_const(m1.row(r1)).col(c1).segment(0,1),
333
                        m1.row(r1).eval().col(c1).eval().segment(0,1).eval(),
334
                        make_const(m1).template block<Dynamic,1>(r1, c1, 1,1)) );
335
  CALL_SUBTEST( checkbb(make_const(m1.row(r1).col(c1)).segment(0,1),
336
                        m1.row(r1).eval().col(c1).eval().segment(0,1).eval(),
337
                        make_const(m1).template block<Dynamic,1>(r1, c1, 1,1)) );
338
  CALL_SUBTEST( checkbb((m1+m2).row(r1).col(c1).segment(0,1),
339
                        (m1+m2).row(r1).eval().col(c1).eval().segment(0,1).eval(),
340
                        (m1+m2).template block<Dynamic,1>(r1, c1, 1,1)) );
341
342
  block_rec(m1);
343
  block_rec(m1+m2);
344
  block_rec(m1.transpose());
345
346
347
  // Check compatibility with hand-writen Block<Block<> > expression.
348
  {
349
    typedef Block<MatrixType> B;
350
    B m11 = m1.block(r1,c1,nr1,nc1);
351
    Block<B> m111 = m11.block(r2,c2,nr2,nc2);
352
    VERIFY_IS_APPROX(m111, m1.block(r1+r2,c1+c2, nr2, nc2));
353
354
    Block<B> m112(m11,r2,c2,nr2,nc2);
355
    VERIFY_IS_APPROX(m112, m1.block(r1+r2,c1+c2, nr2, nc2));
356
    CALL_SUBTEST( checkbb(m112, m1.block(r1+r2,c1+c2, nr2, nc2), m1.block(r1+r2,c1+c2, nr2, nc2)) );
357
358
    typename B::BlockXpr m113 = m11.block(r2,c2,nr2,nc2);
359
    VERIFY_IS_APPROX(m113, m1.block(r1+r2,c1+c2, nr2, nc2));
360
    CALL_SUBTEST( checkbb(m113, m1.block(r1+r2,c1+c2, nr2, nc2), m1.block(r1+r2,c1+c2, nr2, nc2)) );
361
  }
362
363
  // Check preservation of max-sizes
364
  if(m1.rows()>=2 && m2.cols()>=2) {
365
366
    typedef Block<MatrixType,2,2> B;
367
    B m3(m1,0,0);
368
    VERIFY_IS_EQUAL(m3.MaxRowsAtCompileTime, 2);
369
    VERIFY_IS_EQUAL(m3.MaxColsAtCompileTime, 2);
370
    VERIFY_IS_EQUAL((m3.block(0,0,1,1)).MaxRowsAtCompileTime, 2);
371
    VERIFY_IS_EQUAL((m3.block(0,0,1,1)).MaxColsAtCompileTime, 2);
372
373
    VERIFY_IS_EQUAL((m1.template block<2,2>(0,0).block(0,0,1,1)).MaxRowsAtCompileTime, 2);
374
    VERIFY_IS_EQUAL((m1.template block<2,2>(0,0).block(0,0,1,1)).MaxColsAtCompileTime, 2);
375
376
  }
377
}
191
378
192
template<typename MatrixType>
379
template<typename MatrixType>
193
void compare_using_data_and_stride(const MatrixType& m)
380
void compare_using_data_and_stride(const MatrixType& m)
194
{
381
{
195
  typedef typename MatrixType::Index Index;
382
  typedef typename MatrixType::Index Index;
196
  Index rows = m.rows();
383
  Index rows = m.rows();
197
  Index cols = m.cols();
384
  Index cols = m.cols();
198
  Index size = m.size();
385
  Index size = m.size();
Lines 251-264 void test_block() Link Here
251
    CALL_SUBTEST_2( block(Matrix4d()) );
438
    CALL_SUBTEST_2( block(Matrix4d()) );
252
    CALL_SUBTEST_3( block(MatrixXcf(3, 3)) );
439
    CALL_SUBTEST_3( block(MatrixXcf(3, 3)) );
253
    CALL_SUBTEST_4( block(MatrixXi(8, 12)) );
440
    CALL_SUBTEST_4( block(MatrixXi(8, 12)) );
254
    CALL_SUBTEST_5( block(MatrixXcd(20, 20)) );
441
    CALL_SUBTEST_5( block(MatrixXcd(20, 20)) );
255
    CALL_SUBTEST_6( block(MatrixXf(20, 20)) );
442
    CALL_SUBTEST_6( block(MatrixXf(20, 20)) );
256
443
257
    CALL_SUBTEST_8( block(Matrix<float,Dynamic,4>(3, 4)) );
444
    CALL_SUBTEST_8( block(Matrix<float,Dynamic,4>(3, 4)) );
258
445
446
    CALL_SUBTEST_9( check_block_block_fusion(MatrixXi(internal::random(1,50), internal::random(1,50))) );
447
    CALL_SUBTEST_9( check_block_block_fusion(Matrix4i()) );
448
    CALL_SUBTEST_9( check_block_block_fusion(Matrix3i()) );
449
450
    CALL_SUBTEST_9( check_block_block_fusion(MatrixXd(internal::random(1,50), internal::random(1,50))) );
451
    CALL_SUBTEST_9( check_block_block_fusion(Matrix4d()) );
452
    CALL_SUBTEST_9( check_block_block_fusion(Matrix3d()) );
453
    CALL_SUBTEST_9( check_block_block_fusion(Matrix2d()) );
454
259
#ifndef EIGEN_DEFAULT_TO_ROW_MAJOR
455
#ifndef EIGEN_DEFAULT_TO_ROW_MAJOR
260
    CALL_SUBTEST_6( data_and_stride(MatrixXf(internal::random(5,50), internal::random(5,50))) );
456
    CALL_SUBTEST_6( data_and_stride(MatrixXf(internal::random(5,50), internal::random(5,50))) );
261
    CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(internal::random(5,50), internal::random(5,50))) );
457
    CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(internal::random(5,50), internal::random(5,50))) );
262
#endif
458
#endif
263
  }
459
  }
264
}
460
}

Return to bug 408