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 / +114 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
149
};
150
};
150
         
151
151
// The generic default implementation for dense block simplu forward to the internal::BlockImpl_dense
152
// Fuse any Block<Block<X>> expressions as a Block<X> expression
153
// This is the non-const specialization
154
template<typename XprType, int BlockRows0, int BlockCols0, bool InnerPanel0, int BlockRows, int BlockCols, bool InnerPanel>
155
class Block<Block<XprType, BlockRows0, BlockCols0, InnerPanel0>, BlockRows, BlockCols, InnerPanel>
156
  : public Block<XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0>
157
{
158
    typedef Block<XprType,BlockRows0,BlockCols0,InnerPanel0> ArgType;
159
    typedef Block<XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0> Base;
160
public:
161
    using Base::operator=;
162
163
    /** Column or Row constructor
164
      */
165
    EIGEN_DEVICE_FUNC
166
    template<typename OtherBlock>
167
    inline Block(OtherBlock &blk, Index i)
168
      : Base(blk.nestedExpression(),
169
             blk.startRow() + ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) ? i : 0),
170
             blk.startCol() + ((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
171
             BlockRows==1 ? 1 : blk.rows(),
172
             BlockCols==1 ? 1 : blk.cols()
173
            )
174
    {
175
      eigen_assert( (i>=0) && (
176
          ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) && i<blk.rows())
177
        ||((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) && i<blk.cols())));
178
    }
179
180
    /** Fixed-size constructor
181
      */
182
    EIGEN_DEVICE_FUNC
183
    template<typename OtherBlock>
184
    inline Block(OtherBlock &blk, Index startRow, Index startCol)
185
      : Base(blk.nestedExpression(),
186
             blk.startRow() + startRow,
187
             blk.startCol() + startCol)
188
    {
189
      EIGEN_STATIC_ASSERT(Base::RowsAtCompileTime!=Dynamic && Base::ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
190
      eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= blk.rows()
191
             && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= blk.cols());
192
    }
193
194
    /** Dynamic-size constructor
195
      */
196
    EIGEN_DEVICE_FUNC
197
    template<typename OtherBlock>
198
    inline Block(OtherBlock &blk, Index startRow, Index startCol, Index blockRows, Index blockCols)
199
      : Base(blk.nestedExpression(), blk.startRow() + startRow, blk.startCol() + startCol, blockRows, blockCols)
200
    {
201
      eigen_assert((Base::RowsAtCompileTime==Dynamic || Base::RowsAtCompileTime==blockRows)
202
          && (Base::ColsAtCompileTime==Dynamic || Base::ColsAtCompileTime==blockCols));
203
      eigen_assert(startRow >= 0 && blockRows >= 0 && startRow  <= blk.rows() - blockRows
204
          && startCol >= 0 && blockCols >= 0 && startCol <= blk.cols() - blockCols);
205
    }
206
};
207
208
// Fuse any Block<const Block<X>> expressions as a Block<const X> expression
209
// This is the const specialization
210
template<typename XprType, int BlockRows0, int BlockCols0, bool InnerPanel0, int BlockRows, int BlockCols, bool InnerPanel>
211
class Block<const Block<XprType, BlockRows0, BlockCols0, InnerPanel0>, BlockRows, BlockCols, InnerPanel>
212
  : public Block<const XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0>
213
{
214
    typedef Block<XprType, BlockRows0, BlockCols0, InnerPanel0> ArgType;
215
    typedef Block<const XprType,BlockRows,BlockCols,InnerPanel && InnerPanel0> Base;
216
public:
217
    using Base::operator=;
218
219
    /** Column or Row constructor
220
      */
221
    EIGEN_DEVICE_FUNC
222
    inline Block(const ArgType &blk, Index i)
223
      : Base(blk.nestedExpression(),
224
             blk.startRow() + ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) ? i : 0),
225
             blk.startCol() + ((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) ? i : 0),
226
             BlockRows==1 ? 1 : blk.rows(),
227
             BlockCols==1 ? 1 : blk.cols()
228
            )
229
    {
230
      eigen_assert( (i>=0) && (
231
          ((BlockRows==1) && (BlockCols==ArgType::ColsAtCompileTime) && i<blk.rows())
232
        ||((BlockRows==ArgType::RowsAtCompileTime) && (BlockCols==1) && i<blk.cols())));
233
    }
234
235
    /** Fixed-size constructor
236
      */
237
    EIGEN_DEVICE_FUNC
238
    inline Block(const ArgType &blk, Index startRow, Index startCol)
239
      : Base(blk.nestedExpression(),
240
             blk.startRow() + startRow,
241
             blk.startCol() + startCol)
242
    {
243
      EIGEN_STATIC_ASSERT(Base::RowsAtCompileTime!=Dynamic && Base::ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
244
      eigen_assert(startRow >= 0 && BlockRows >= 0 && startRow + BlockRows <= blk.rows()
245
             && startCol >= 0 && BlockCols >= 0 && startCol + BlockCols <= blk.cols());
246
    }
247
248
    /** Dynamic-size constructor
249
      */
250
    EIGEN_DEVICE_FUNC
251
    inline Block(const ArgType &blk, Index startRow, Index startCol, Index blockRows, Index blockCols)
252
      : Base(blk.nestedExpression(), blk.startRow() + startRow, blk.startCol() + startCol, blockRows, blockCols)
253
    {
254
      eigen_assert((Base::RowsAtCompileTime==Dynamic || Base::RowsAtCompileTime==blockRows)
255
          && (Base::ColsAtCompileTime==Dynamic || Base::ColsAtCompileTime==blockCols));
256
      eigen_assert(startRow >= 0 && blockRows >= 0 && startRow  <= blk.rows() - blockRows
257
          && startCol >= 0 && blockCols >= 0 && startCol <= blk.cols() - blockCols);
258
    }
259
};
260
261
// 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...
262
// that must be specialized for direct and non-direct access...
153
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
263
template<typename XprType, int BlockRows, int BlockCols, bool InnerPanel>
154
class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
264
class BlockImpl<XprType, BlockRows, BlockCols, InnerPanel, Dense>
155
  : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel>
265
  : public internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel>
156
{
266
{
157
    typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
267
    typedef internal::BlockImpl_dense<XprType, BlockRows, BlockCols, InnerPanel> Impl;
158
    typedef typename XprType::StorageIndex StorageIndex;
268
    typedef typename XprType::StorageIndex StorageIndex;
159
  public:
269
  public:
(-)a/test/block.cpp (+111 lines)
Lines 178-193 template<typename MatrixType> void block Link Here
178
  VERIFY_IS_EQUAL(dv, dm);
178
  VERIFY_IS_EQUAL(dv, dm);
179
  dm.setZero();
179
  dm.setZero();
180
  dv.setZero();
180
  dv.setZero();
181
  dm = m1.row(r1).segment(c1,c2-c1+1).transpose();
181
  dm = m1.row(r1).segment(c1,c2-c1+1).transpose();
182
  dv = m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0);
182
  dv = m1.transpose().block(c1,r1,c2-c1+1,r2-r1+1).col(0);
183
  VERIFY_IS_EQUAL(dv, dm);
183
  VERIFY_IS_EQUAL(dv, dm);
184
}
184
}
185
185
186
template<typename T>
187
bool same_type(const T&, const T&) { return true; }
188
189
template<typename Expr, typename Ref, typename ExprFused>
190
void checkbb(const DenseBase<Expr> &a_xpr, const DenseBase<Ref> &a_ref, const DenseBase<ExprFused> &a_xprfused)
191
{
192
  const Expr& xpr(a_xpr.derived());
193
  const Ref& ref(a_ref.derived());
194
  const ExprFused& xprfused(a_xprfused.derived());
195
196
  VERIFY_IS_APPROX(xprfused, ref);
197
198
  VERIFY(same_type<ExprFused>(xpr, xprfused));
199
200
  VERIFY_IS_EQUAL(ExprFused::Flags, Expr::Flags);
201
  VERIFY_IS_EQUAL(ExprFused::RowsAtCompileTime, Expr::RowsAtCompileTime);
202
  VERIFY_IS_EQUAL(ExprFused::ColsAtCompileTime, Expr::ColsAtCompileTime);
203
204
  typedef internal::evaluator<ExprFused> EvalFused;
205
  typedef internal::evaluator<Expr> EvalExpr;
206
  VERIFY_IS_EQUAL(EvalFused::Flags, EvalExpr::Flags);
207
  VERIFY_IS_EQUAL(EvalFused::Alignment, EvalExpr::Alignment);
208
209
  VERIFY_IS_APPROX(xpr.derived(), ref);
210
  VERIFY_IS_APPROX(xpr, ref);
211
}
212
213
template<typename MatrixType>
214
void check_block_block_fusion(const MatrixType &m)
215
{
216
  Index rows = m.rows();
217
  Index cols = m.cols();
218
219
  MatrixType m1 = MatrixType::Random(rows, cols),
220
             m2 = MatrixType::Random(rows, cols);
221
222
  Index r1 = internal::random<Index>(0,rows-1);
223
  Index c1 = internal::random<Index>(0,cols-1);
224
  Index nr1 = internal::random<Index>(1,rows-r1);
225
  Index nc1 = internal::random<Index>(1,cols-c1);
226
227
  Index r2 = internal::random<Index>(0,nr1-1);
228
  Index c2 = internal::random<Index>(0,nc1-1);
229
  Index nr2 = internal::random<Index>(1,nr1-r2);
230
  Index nc2 = internal::random<Index>(1,nc1-c2);
231
232
  CALL_SUBTEST( checkbb(m1.block(r1,c1, nr1,nc1).block(r2,c2,nr2,nc2),
233
                        m1.block(r1,c1, nr1,nc1).eval().block(r2,c2,nr2,nc2).eval(),
234
                        m1.block(r1+r2, c1+c2, nr2, nc2)) );
235
  CALL_SUBTEST( checkbb((m1+m2).block(r1,c1, nr1,nc1).block(r2,c2,nr2,nc2),
236
                        (m1+m2).block(r1,c1, nr1,nc1).eval().block(r2,c2,nr2,nc2).eval(),
237
                        (m1+m2).block(r1+r2, c1+c2, nr2, nc2)) );
238
239
  CALL_SUBTEST( checkbb(m1.block(r1,c1, nr1,nc1).row(r2),
240
                        m1.block(r1,c1, nr1,nc1).eval().row(r2).eval(),
241
                        m1.template block<1,Dynamic>(r1+r2, c1, 1, nc1)) );
242
  CALL_SUBTEST( checkbb((m1+m2).block(r1,c1, nr1,nc1).row(r2),
243
                        (m1+m2).block(r1,c1, nr1,nc1).eval().row(r2).eval(),
244
                        (m1+m2).template block<1,Dynamic>(r1+r2, c1, 1, nc1)) );
245
246
  CALL_SUBTEST( checkbb(m1.block(r1,c1, nr1,nc1).col(c2),
247
                        m1.block(r1,c1, nr1,nc1).eval().col(c2).eval(),
248
                        m1.template block<Dynamic,1>(r1, c1+c2, nr1, 1)) );
249
  CALL_SUBTEST( checkbb((m1+m2).block(r1,c1, nr1,nc1).col(c2),
250
                        (m1+m2).block(r1,c1, nr1,nc1).eval().col(c2).eval(),
251
                        (m1+m2).template block<Dynamic,1>(r1, c1+c2, nr1, 1)) );
252
253
  CALL_SUBTEST( checkbb(m1.row(r1).segment(c1,nc1),
254
                        m1.row(r1).eval().segment(c1,nc1).eval(),
255
                        m1.template block<1,Dynamic>(r1, c1, 1, nc1)) );
256
  CALL_SUBTEST( checkbb((m1+m2).row(r1).segment(c1,nc1),
257
                        (m1+m2).row(r1).eval().segment(c1,nc1).eval(),
258
                        (m1+m2).template block<1,Dynamic>(r1, c1, 1, nc1)) );
259
260
  CALL_SUBTEST( checkbb(m1.col(c1).segment(r1,nr1),
261
                        m1.col(c1).eval().segment(r1,nr1).eval(),
262
                        m1.template block<Dynamic,1>(r1, c1, nr1, 1)) );
263
  CALL_SUBTEST( checkbb((m1+m2).col(c1).segment(r1,nr1),
264
                        (m1+m2).col(c1).eval().segment(r1,nr1).eval(),
265
                        (m1+m2).template block<Dynamic,1>(r1, c1, nr1, 1)) );
266
267
  CALL_SUBTEST( checkbb(m1.middleCols(c1,nc1).col(c2).segment(r1,nr1),
268
                        m1.middleCols(c1,nc1).eval().col(c2).eval().segment(r1,nr1).eval(),
269
                        m1.template block<Dynamic,1>(r1, c1+c2, nr1, 1)) );
270
  CALL_SUBTEST( checkbb((m1+m2).middleCols(c1,nc1).col(c2).segment(r1,nr1),
271
                        (m1+m2).middleCols(c1,nc1).eval().col(c2).eval().segment(r1,nr1).eval(),
272
                        (m1+m2).template block<Dynamic,1>(r1, c1+c2, nr1, 1)) );
273
274
  CALL_SUBTEST( checkbb(m1.row(r1).col(c1),
275
                        m1.row(r1).eval().col(c1).eval(),
276
                        m1.template block<1,1>(r1, c1)) );
277
  CALL_SUBTEST( checkbb((m1+m2).row(r1).col(c1),
278
                        (m1+m2).row(r1).eval().col(c1).eval(),
279
                        (m1+m2).template block<1,1>(r1, c1)) );
280
281
  CALL_SUBTEST( checkbb(m1.row(r1).col(c1).segment(0,1),
282
                        m1.row(r1).eval().col(c1).eval().segment(0,1).eval(),
283
                        m1.template block<Dynamic,1>(r1, c1, 1,1)) );
284
  CALL_SUBTEST( checkbb((m1+m2).row(r1).col(c1).segment(0,1),
285
                        (m1+m2).row(r1).eval().col(c1).eval().segment(0,1).eval(),
286
                        (m1+m2).template block<Dynamic,1>(r1, c1, 1,1)) );
287
}
186
288
187
template<typename MatrixType>
289
template<typename MatrixType>
188
void compare_using_data_and_stride(const MatrixType& m)
290
void compare_using_data_and_stride(const MatrixType& m)
189
{
291
{
190
  typedef typename MatrixType::Index Index;
292
  typedef typename MatrixType::Index Index;
191
  Index rows = m.rows();
293
  Index rows = m.rows();
192
  Index cols = m.cols();
294
  Index cols = m.cols();
193
  Index size = m.size();
295
  Index size = m.size();
Lines 246-259 void test_block() Link Here
246
    CALL_SUBTEST_2( block(Matrix4d()) );
348
    CALL_SUBTEST_2( block(Matrix4d()) );
247
    CALL_SUBTEST_3( block(MatrixXcf(3, 3)) );
349
    CALL_SUBTEST_3( block(MatrixXcf(3, 3)) );
248
    CALL_SUBTEST_4( block(MatrixXi(8, 12)) );
350
    CALL_SUBTEST_4( block(MatrixXi(8, 12)) );
249
    CALL_SUBTEST_5( block(MatrixXcd(20, 20)) );
351
    CALL_SUBTEST_5( block(MatrixXcd(20, 20)) );
250
    CALL_SUBTEST_6( block(MatrixXf(20, 20)) );
352
    CALL_SUBTEST_6( block(MatrixXf(20, 20)) );
251
353
252
    CALL_SUBTEST_8( block(Matrix<float,Dynamic,4>(3, 4)) );
354
    CALL_SUBTEST_8( block(Matrix<float,Dynamic,4>(3, 4)) );
253
355
356
    CALL_SUBTEST_9( check_block_block_fusion(MatrixXi(internal::random(1,50), internal::random(1,50))) );
357
    CALL_SUBTEST_9( check_block_block_fusion(Matrix4i()) );
358
    CALL_SUBTEST_9( check_block_block_fusion(Matrix3i()) );
359
360
    CALL_SUBTEST_9( check_block_block_fusion(MatrixXd(internal::random(1,50), internal::random(1,50))) );
361
    CALL_SUBTEST_9( check_block_block_fusion(Matrix4d()) );
362
    CALL_SUBTEST_9( check_block_block_fusion(Matrix3d()) );
363
    CALL_SUBTEST_9( check_block_block_fusion(Matrix2d()) );
364
254
#ifndef EIGEN_DEFAULT_TO_ROW_MAJOR
365
#ifndef EIGEN_DEFAULT_TO_ROW_MAJOR
255
    CALL_SUBTEST_6( data_and_stride(MatrixXf(internal::random(5,50), internal::random(5,50))) );
366
    CALL_SUBTEST_6( data_and_stride(MatrixXf(internal::random(5,50), internal::random(5,50))) );
256
    CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(internal::random(5,50), internal::random(5,50))) );
367
    CALL_SUBTEST_7( data_and_stride(Matrix<int,Dynamic,Dynamic,RowMajor>(internal::random(5,50), internal::random(5,50))) );
257
#endif
368
#endif
258
  }
369
  }
259
}
370
}

Return to bug 408