This bugzilla service is closed. All entries have been migrated to https://gitlab.com/libeigen/eigen
View | Details | Raw Unified | Return to bug 1286
Collapse All | Expand All

(-)a/Eigen/src/Core/CoreEvaluators.h (-5 / +56 lines)
Lines 332-347 struct unary_evaluator<Transpose<ArgType Link Here
332
protected:
332
protected:
333
  evaluator<ArgType> m_argImpl;
333
  evaluator<ArgType> m_argImpl;
334
};
334
};
335
335
336
// -------------------- CwiseNullaryOp --------------------
336
// -------------------- CwiseNullaryOp --------------------
337
// Like Matrix and Array, this is not really a unary expression, so we directly specialize evaluator.
337
// Like Matrix and Array, this is not really a unary expression, so we directly specialize evaluator.
338
// Likewise, there is not need to more sophisticated dispatching here.
338
// Likewise, there is not need to more sophisticated dispatching here.
339
339
340
template<typename Scalar,typename NullaryOp,
341
         bool has_nullary = has_nullary_operator<NullaryOp>::value,
342
         bool has_unary   = has_unary_operator<NullaryOp>::value,
343
         bool has_binary  = has_binary_operator<NullaryOp>::value>
344
struct nullary_wrapper
345
{
346
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, Index i, Index j) const { return op(i,j); }
347
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, Index i) const { return op(i); }
348
349
  template <typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, Index i, Index j) const { return op.template packetOp<T>(i,j); }
350
  template <typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, Index i) const { return op.template packetOp<T>(i); }
351
};
352
353
template<typename Scalar,typename NullaryOp>
354
struct nullary_wrapper<Scalar,NullaryOp,true,false,false>
355
{
356
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, ...) const { return op(); }
357
  template <typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, ...) const { return op.template packetOp<T>(); }
358
};
359
360
template<typename Scalar,typename NullaryOp>
361
struct nullary_wrapper<Scalar,NullaryOp,false,false,true>
362
{
363
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, Index i, Index j=0) const { return op(i,j); }
364
  template <typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, Index i, Index j=0) const { return op.template packetOp<T>(i,j); }
365
};
366
367
// We need the following specialization for vector-only functors assigned to a runtime vector,
368
// for instance, using linspace and assigning a RowVectorXd to a MatrixXd or even a row of a MatrixXd.
369
// In this case, i==0 and j is used for the actual iteration.
370
template<typename Scalar,typename NullaryOp>
371
struct nullary_wrapper<Scalar,NullaryOp,false,true,false>
372
  : nullary_wrapper<Scalar,NullaryOp,false,true,true> // to get the identity wrapper
373
{
374
  typedef nullary_wrapper<Scalar,NullaryOp,false,true,true> base;
375
  using base::operator();
376
  using base::packetOp;
377
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar operator()(const NullaryOp& op, Index i, Index j) const {
378
    eigen_assert(i==0 || j==0);
379
    return op(i+j);
380
  }
381
  template <typename T> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE T packetOp(const NullaryOp& op, Index i, Index j) const {
382
    eigen_assert(i==0 || j==0);
383
    return op.template packetOp<T>(i+j);
384
  }
385
};
386
387
template<typename Scalar,typename NullaryOp>
388
struct nullary_wrapper<Scalar,NullaryOp,false,false,false> {};
389
340
template<typename NullaryOp, typename PlainObjectType>
390
template<typename NullaryOp, typename PlainObjectType>
341
struct evaluator<CwiseNullaryOp<NullaryOp,PlainObjectType> >
391
struct evaluator<CwiseNullaryOp<NullaryOp,PlainObjectType> >
342
  : evaluator_base<CwiseNullaryOp<NullaryOp,PlainObjectType> >
392
  : evaluator_base<CwiseNullaryOp<NullaryOp,PlainObjectType> >
343
{
393
{
344
  typedef CwiseNullaryOp<NullaryOp,PlainObjectType> XprType;
394
  typedef CwiseNullaryOp<NullaryOp,PlainObjectType> XprType;
345
  typedef typename internal::remove_all<PlainObjectType>::type PlainObjectTypeCleaned;
395
  typedef typename internal::remove_all<PlainObjectType>::type PlainObjectTypeCleaned;
346
  
396
  
347
  enum {
397
  enum {
Lines 351-401 struct evaluator<CwiseNullaryOp<NullaryO Link Here
351
          &  (  HereditaryBits
401
          &  (  HereditaryBits
352
              | (functor_has_linear_access<NullaryOp>::ret  ? LinearAccessBit : 0)
402
              | (functor_has_linear_access<NullaryOp>::ret  ? LinearAccessBit : 0)
353
              | (functor_traits<NullaryOp>::PacketAccess    ? PacketAccessBit : 0)))
403
              | (functor_traits<NullaryOp>::PacketAccess    ? PacketAccessBit : 0)))
354
          | (functor_traits<NullaryOp>::IsRepeatable ? 0 : EvalBeforeNestingBit),
404
          | (functor_traits<NullaryOp>::IsRepeatable ? 0 : EvalBeforeNestingBit),
355
    Alignment = AlignedMax
405
    Alignment = AlignedMax
356
  };
406
  };
357
407
358
  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& n)
408
  EIGEN_DEVICE_FUNC explicit evaluator(const XprType& n)
359
    : m_functor(n.functor()) 
409
    : m_functor(n.functor()), m_wrapper()
360
  {
410
  {
361
    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
411
    EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
362
  }
412
  }
363
413
364
  typedef typename XprType::CoeffReturnType CoeffReturnType;
414
  typedef typename XprType::CoeffReturnType CoeffReturnType;
365
415
366
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
416
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
367
  CoeffReturnType coeff(Index row, Index col) const
417
  CoeffReturnType coeff(Index row, Index col) const
368
  {
418
  {
369
    return m_functor(row, col);
419
    return m_wrapper(m_functor, row, col);
370
  }
420
  }
371
421
372
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
422
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
373
  CoeffReturnType coeff(Index index) const
423
  CoeffReturnType coeff(Index index) const
374
  {
424
  {
375
    return m_functor(index);
425
    return m_wrapper(m_functor,index);
376
  }
426
  }
377
427
378
  template<int LoadMode, typename PacketType>
428
  template<int LoadMode, typename PacketType>
379
  EIGEN_STRONG_INLINE
429
  EIGEN_STRONG_INLINE
380
  PacketType packet(Index row, Index col) const
430
  PacketType packet(Index row, Index col) const
381
  {
431
  {
382
    return m_functor.template packetOp<Index,PacketType>(row, col);
432
    return m_wrapper.template packetOp<PacketType>(m_functor,row, col);
383
  }
433
  }
384
434
385
  template<int LoadMode, typename PacketType>
435
  template<int LoadMode, typename PacketType>
386
  EIGEN_STRONG_INLINE
436
  EIGEN_STRONG_INLINE
387
  PacketType packet(Index index) const
437
  PacketType packet(Index index) const
388
  {
438
  {
389
    return m_functor.template packetOp<Index,PacketType>(index);
439
    return m_wrapper.template packetOp<PacketType>(m_functor,index);
390
  }
440
  }
391
441
392
protected:
442
protected:
393
  const NullaryOp m_functor;
443
  const NullaryOp m_functor;
444
  const internal::nullary_wrapper<CoeffReturnType,NullaryOp> m_wrapper;
394
};
445
};
395
446
396
// -------------------- CwiseUnaryOp --------------------
447
// -------------------- CwiseUnaryOp --------------------
397
448
398
template<typename UnaryOp, typename ArgType>
449
template<typename UnaryOp, typename ArgType>
399
struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
450
struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
400
  : evaluator_base<CwiseUnaryOp<UnaryOp, ArgType> >
451
  : evaluator_base<CwiseUnaryOp<UnaryOp, ArgType> >
401
{
452
{
(-)a/Eigen/src/Core/CwiseNullaryOp.h (-25 / +2 lines)
Lines 15-31 namespace Eigen { Link Here
15
namespace internal {
15
namespace internal {
16
template<typename NullaryOp, typename PlainObjectType>
16
template<typename NullaryOp, typename PlainObjectType>
17
struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType> > : traits<PlainObjectType>
17
struct traits<CwiseNullaryOp<NullaryOp, PlainObjectType> > : traits<PlainObjectType>
18
{
18
{
19
  enum {
19
  enum {
20
    Flags = traits<PlainObjectType>::Flags & RowMajorBit
20
    Flags = traits<PlainObjectType>::Flags & RowMajorBit
21
  };
21
  };
22
};
22
};
23
}
23
24
} // namespace internal
24
25
25
/** \class CwiseNullaryOp
26
/** \class CwiseNullaryOp
26
  * \ingroup Core_Module
27
  * \ingroup Core_Module
27
  *
28
  *
28
  * \brief Generic expression of a matrix where all coefficients are defined by a functor
29
  * \brief Generic expression of a matrix where all coefficients are defined by a functor
29
  *
30
  *
30
  * \tparam NullaryOp template functor implementing the operator
31
  * \tparam NullaryOp template functor implementing the operator
31
  * \tparam PlainObjectType the underlying plain matrix/array type
32
  * \tparam PlainObjectType the underlying plain matrix/array type
Lines 65-104 class CwiseNullaryOp : public internal:: Link Here
65
            && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
66
            && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
66
    }
67
    }
67
68
68
    EIGEN_DEVICE_FUNC
69
    EIGEN_DEVICE_FUNC
69
    EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); }
70
    EIGEN_STRONG_INLINE Index rows() const { return m_rows.value(); }
70
    EIGEN_DEVICE_FUNC
71
    EIGEN_DEVICE_FUNC
71
    EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); }
72
    EIGEN_STRONG_INLINE Index cols() const { return m_cols.value(); }
72
73
73
    EIGEN_DEVICE_FUNC
74
    EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
75
    {
76
      return m_functor(rowId, colId);
77
    }
78
79
    template<int LoadMode>
80
    EIGEN_STRONG_INLINE PacketScalar packet(Index rowId, Index colId) const
81
    {
82
      return m_functor.packetOp(rowId, colId);
83
    }
84
85
    EIGEN_DEVICE_FUNC
86
    EIGEN_STRONG_INLINE const Scalar coeff(Index index) const
87
    {
88
      return m_functor(index);
89
    }
90
91
    template<int LoadMode>
92
    EIGEN_STRONG_INLINE PacketScalar packet(Index index) const
93
    {
94
      return m_functor.packetOp(index);
95
    }
96
97
    /** \returns the functor representing the nullary operation */
74
    /** \returns the functor representing the nullary operation */
98
    EIGEN_DEVICE_FUNC
75
    EIGEN_DEVICE_FUNC
99
    const NullaryOp& functor() const { return m_functor; }
76
    const NullaryOp& functor() const { return m_functor; }
100
77
101
  protected:
78
  protected:
102
    const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
79
    const internal::variable_if_dynamic<Index, RowsAtCompileTime> m_rows;
103
    const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
80
    const internal::variable_if_dynamic<Index, ColsAtCompileTime> m_cols;
104
    const NullaryOp m_functor;
81
    const NullaryOp m_functor;
(-)a/Eigen/src/Core/functors/NullaryFunctors.h (-28 / +9 lines)
Lines 13-32 Link Here
13
namespace Eigen {
13
namespace Eigen {
14
14
15
namespace internal {
15
namespace internal {
16
16
17
template<typename Scalar>
17
template<typename Scalar>
18
struct scalar_constant_op {
18
struct scalar_constant_op {
19
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
19
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const scalar_constant_op& other) : m_other(other.m_other) { }
20
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
20
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE scalar_constant_op(const Scalar& other) : m_other(other) { }
21
  template<typename Index>
21
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() () const { return m_other; }
22
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; }
22
  template<typename PacketType>
23
  template<typename Index, typename PacketType>
23
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packetOp() const { return internal::pset1<PacketType>(m_other); }
24
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const PacketType packetOp(Index, Index = 0) const { return internal::pset1<PacketType>(m_other); }
25
  const Scalar m_other;
24
  const Scalar m_other;
26
};
25
};
27
template<typename Scalar>
26
template<typename Scalar>
28
struct functor_traits<scalar_constant_op<Scalar> >
27
struct functor_traits<scalar_constant_op<Scalar> >
29
{ enum { Cost = 0 /* as the constant value should be loaded in register only once for the whole expression */,
28
{ enum { Cost = 0 /* as the constant value should be loaded in register only once for the whole expression */,
30
         PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; };
29
         PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; };
31
30
32
template<typename Scalar> struct scalar_identity_op {
31
template<typename Scalar> struct scalar_identity_op {
Lines 141-188 template <typename Scalar, typename Pack Link Here
141
{
140
{
142
  linspaced_op(const Scalar& low, const Scalar& high, Index num_steps)
141
  linspaced_op(const Scalar& low, const Scalar& high, Index num_steps)
143
    : impl((num_steps==1 ? high : low),high,num_steps)
142
    : impl((num_steps==1 ? high : low),high,num_steps)
144
  {}
143
  {}
145
144
146
  template<typename Index>
145
  template<typename Index>
147
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); }
146
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); }
148
147
149
  // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since
148
  template<typename Packet,typename Index>
150
  // there row==0 and col is used for the actual iteration.
151
  template<typename Index>
152
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const 
153
  {
154
    eigen_assert(col==0 || row==0);
155
    return impl(col + row);
156
  }
157
158
  template<typename Index, typename Packet>
159
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); }
149
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); }
160
150
161
  // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since
162
  // there row==0 and col is used for the actual iteration.
163
  template<typename Index, typename Packet>
164
  EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const
165
  {
166
    eigen_assert(col==0 || row==0);
167
    return impl.packetOp(col + row);
168
  }
169
170
  // This proxy object handles the actual required temporaries, the different
151
  // This proxy object handles the actual required temporaries, the different
171
  // implementations (random vs. sequential access) as well as the
152
  // implementations (random vs. sequential access) as well as the
172
  // correct piping to size 2/4 packet operations.
153
  // correct piping to size 2/4 packet operations.
173
  // As long as we don't have a Bresenham-like implementation for linear-access and integer types,
154
  // As long as we don't have a Bresenham-like implementation for linear-access and integer types,
174
  // we have to by-pass RandomAccess for integer types. See bug 698.
155
  // we have to by-pass RandomAccess for integer types. See bug 698.
175
  const linspaced_op_impl<Scalar,PacketType,(NumTraits<Scalar>::IsInteger?true:RandomAccess),NumTraits<Scalar>::IsInteger> impl;
156
  const linspaced_op_impl<Scalar,PacketType,(NumTraits<Scalar>::IsInteger?true:RandomAccess),NumTraits<Scalar>::IsInteger> impl;
176
};
157
};
177
158
178
// all functors allow linear access, except scalar_identity_op. So we fix here a quick meta
159
// Linear access is automatically determined from the operator() prototypes available for the given functor.
179
// to indicate whether a functor allows linear access, just always answering 'yes' except for
160
// If it exposes an operator()(i,j), then we assume the i and j coefficients are required independently
180
// scalar_identity_op.
161
// and linear access is not possible. In all other cases, linear access is enabled.
181
template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; };
162
// Users should not have to deal with this struture.
182
template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; };
163
template<typename Functor> struct functor_has_linear_access { enum { ret = !has_binary_operator<Functor>::value }; };
183
164
184
} // end namespace internal
165
} // end namespace internal
185
166
186
} // end namespace Eigen
167
} // end namespace Eigen
187
168
188
#endif // EIGEN_NULLARY_FUNCTORS_H
169
#endif // EIGEN_NULLARY_FUNCTORS_H
(-)a/Eigen/src/Core/util/Meta.h (+43 lines)
Lines 17-32 Link Here
17
#endif
17
#endif
18
18
19
#if EIGEN_COMP_ICC>=1600 &&  __cplusplus >= 201103L
19
#if EIGEN_COMP_ICC>=1600 &&  __cplusplus >= 201103L
20
#include <cstdint>
20
#include <cstdint>
21
#endif
21
#endif
22
22
23
namespace Eigen {
23
namespace Eigen {
24
24
25
typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
26
27
/**
28
 * \brief The Index type as used for the API.
29
 * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
30
 * \sa \blank \ref TopicPreprocessorDirectives, StorageIndex.
31
 */
32
33
typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
34
25
namespace internal {
35
namespace internal {
26
36
27
/** \internal
37
/** \internal
28
  * \file Meta.h
38
  * \file Meta.h
29
  * This file contains generic metaprogramming classes which are not specifically related to Eigen.
39
  * This file contains generic metaprogramming classes which are not specifically related to Eigen.
30
  * \note In case you wonder, yes we're aware that Boost already provides all these features,
40
  * \note In case you wonder, yes we're aware that Boost already provides all these features,
31
  * we however don't want to add a dependency to Boost.
41
  * we however don't want to add a dependency to Boost.
32
  */
42
  */
Lines 366-381 struct has_ReturnType Link Here
366
  typedef char no[2];
376
  typedef char no[2];
367
377
368
  template <typename C> static yes& testFunctor(typename C::ReturnType const *);
378
  template <typename C> static yes& testFunctor(typename C::ReturnType const *);
369
  template <typename C> static no& testFunctor(...);
379
  template <typename C> static no& testFunctor(...);
370
380
371
  enum { value = sizeof(testFunctor<T>(0)) == sizeof(yes) };
381
  enum { value = sizeof(testFunctor<T>(0)) == sizeof(yes) };
372
};
382
};
373
383
384
template<int> struct any_int {};
385
template<typename T> const T& return_ref();
386
387
struct meta_yes { char data[1]; };
388
struct meta_no  { char data[2]; };
389
390
template <typename T>
391
struct has_nullary_operator
392
{
393
  template <typename C> static meta_yes testFunctor(C const *,any_int< sizeof(return_ref<C>()()) > * = 0);
394
  static meta_no testFunctor(...);
395
396
  enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
397
};
398
399
template <typename T>
400
struct has_unary_operator
401
{
402
  template <typename C> static meta_yes testFunctor(C const *,any_int< sizeof(return_ref<C>()(Index(0))) > * = 0);
403
  static meta_no testFunctor(...);
404
405
  enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
406
};
407
408
template <typename T>
409
struct has_binary_operator
410
{
411
  template <typename C> static meta_yes testFunctor(C const *,any_int< sizeof(return_ref<C>()(Index(0),Index(0))) > * = 0);
412
  static meta_no testFunctor(...);
413
414
  enum { value = sizeof(testFunctor(static_cast<T*>(0))) == sizeof(meta_yes) };
415
};
416
374
/** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer.
417
/** \internal In short, it computes int(sqrt(\a Y)) with \a Y an integer.
375
  * Usage example: \code meta_sqrt<1023>::ret \endcode
418
  * Usage example: \code meta_sqrt<1023>::ret \endcode
376
  */
419
  */
377
template<int Y,
420
template<int Y,
378
         int InfX = 0,
421
         int InfX = 0,
379
         int SupX = ((Y==1) ? 1 : Y/2),
422
         int SupX = ((Y==1) ? 1 : Y/2),
380
         bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) >
423
         bool Done = ((SupX-InfX)<=1 ? true : ((SupX*SupX <= Y) && ((SupX+1)*(SupX+1) > Y))) >
381
                                // use ?: instead of || just to shut up a stupid gcc 4.3 warning
424
                                // use ?: instead of || just to shut up a stupid gcc 4.3 warning
(-)a/Eigen/src/Core/util/XprHelper.h (-10 lines)
Lines 19-44 Link Here
19
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X() {} \
19
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X() {} \
20
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X(const X& ) {}
20
    EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE X(const X& ) {}
21
#else
21
#else
22
  #define EIGEN_EMPTY_STRUCT_CTOR(X)
22
  #define EIGEN_EMPTY_STRUCT_CTOR(X)
23
#endif
23
#endif
24
24
25
namespace Eigen {
25
namespace Eigen {
26
26
27
typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE DenseIndex;
28
29
/**
30
 * \brief The Index type as used for the API.
31
 * \details To change this, \c \#define the preprocessor symbol \c EIGEN_DEFAULT_DENSE_INDEX_TYPE.
32
 * \sa \blank \ref TopicPreprocessorDirectives, StorageIndex.
33
 */
34
35
typedef EIGEN_DEFAULT_DENSE_INDEX_TYPE Index;
36
37
namespace internal {
27
namespace internal {
38
28
39
template<typename IndexDest, typename IndexSrc>
29
template<typename IndexDest, typename IndexSrc>
40
EIGEN_DEVICE_FUNC
30
EIGEN_DEVICE_FUNC
41
inline IndexDest convert_index(const IndexSrc& idx) {
31
inline IndexDest convert_index(const IndexSrc& idx) {
42
  // for sizeof(IndexDest)>=sizeof(IndexSrc) compilers should be able to optimize this away:
32
  // for sizeof(IndexDest)>=sizeof(IndexSrc) compilers should be able to optimize this away:
43
  eigen_internal_assert(idx <= NumTraits<IndexDest>::highest() && "Index value to big for target type");
33
  eigen_internal_assert(idx <= NumTraits<IndexDest>::highest() && "Index value to big for target type");
44
  return IndexDest(idx);
34
  return IndexDest(idx);
(-)a/doc/CustomizingEigen_NullaryExpr.dox (+1 lines)
Lines 54-63 We are now all set to try our new featur Link Here
54
If all the fragments are combined, the following output is produced,
54
If all the fragments are combined, the following output is produced,
55
showing that the program works as expected:
55
showing that the program works as expected:
56
56
57
\include make_circulant2.out
57
\include make_circulant2.out
58
58
59
This implementation of \c makeCirculant is much simpler than \ref TopicNewExpressionType "defining a new expression" from scratch.
59
This implementation of \c makeCirculant is much simpler than \ref TopicNewExpressionType "defining a new expression" from scratch.
60
60
61
*/
61
*/
62
62
}
63
}
63
64
(-)a/doc/special_examples/random_cpp11.cpp (-1 / +1 lines)
Lines 2-14 Link Here
2
#include <iostream>
2
#include <iostream>
3
#include <random>
3
#include <random>
4
4
5
using namespace Eigen;
5
using namespace Eigen;
6
6
7
int main() {
7
int main() {
8
  std::default_random_engine generator;
8
  std::default_random_engine generator;
9
  std::poisson_distribution<int> distribution(4.1);
9
  std::poisson_distribution<int> distribution(4.1);
10
  auto poisson = [&] (Eigen::Index) {return distribution(generator);};
10
  auto poisson = [&] () {return distribution(generator);};
11
11
12
  RowVectorXi v = RowVectorXi::NullaryExpr(10, poisson );
12
  RowVectorXi v = RowVectorXi::NullaryExpr(10, poisson );
13
  std::cout << v << "\n";
13
  std::cout << v << "\n";
14
}
14
}
(-)a/test/nullary.cpp (+34 lines)
Lines 99-121 void testVectorType(const VectorType& ba Link Here
99
    m.tail(size-1).setLinSpaced(low, high);
99
    m.tail(size-1).setLinSpaced(low, high);
100
    VERIFY_IS_APPROX(m(size-1), high);
100
    VERIFY_IS_APPROX(m(size-1), high);
101
  }
101
  }
102
}
102
}
103
103
104
template<typename MatrixType>
104
template<typename MatrixType>
105
void testMatrixType(const MatrixType& m)
105
void testMatrixType(const MatrixType& m)
106
{
106
{
107
  using std::abs;
107
  const Index rows = m.rows();
108
  const Index rows = m.rows();
108
  const Index cols = m.cols();
109
  const Index cols = m.cols();
110
  typedef typename MatrixType::Scalar Scalar;
111
  typedef typename MatrixType::RealScalar RealScalar;
112
113
  Scalar s1;
114
  do {
115
    s1 = internal::random<Scalar>();
116
  } while(abs(s1)<RealScalar(1e-5) && (!NumTraits<Scalar>::IsInteger));
109
117
110
  MatrixType A;
118
  MatrixType A;
111
  A.setIdentity(rows, cols);
119
  A.setIdentity(rows, cols);
112
  VERIFY(equalsIdentity(A));
120
  VERIFY(equalsIdentity(A));
113
  VERIFY(equalsIdentity(MatrixType::Identity(rows, cols)));
121
  VERIFY(equalsIdentity(MatrixType::Identity(rows, cols)));
122
123
124
  A = MatrixType::Constant(rows,cols,s1);
125
  Index i = internal::random<Index>(0,rows-1);
126
  Index j = internal::random<Index>(0,cols-1);
127
  VERIFY_IS_APPROX( MatrixType::Constant(rows,cols,s1)(i,j), s1 );
128
  VERIFY_IS_APPROX( MatrixType::Constant(rows,cols,s1).coeff(i,j), s1 );
129
  VERIFY_IS_APPROX( A(i,j), s1 );
114
}
130
}
115
131
116
void test_nullary()
132
void test_nullary()
117
{
133
{
118
  CALL_SUBTEST_1( testMatrixType(Matrix2d()) );
134
  CALL_SUBTEST_1( testMatrixType(Matrix2d()) );
119
  CALL_SUBTEST_2( testMatrixType(MatrixXcf(internal::random<int>(1,300),internal::random<int>(1,300))) );
135
  CALL_SUBTEST_2( testMatrixType(MatrixXcf(internal::random<int>(1,300),internal::random<int>(1,300))) );
120
  CALL_SUBTEST_3( testMatrixType(MatrixXf(internal::random<int>(1,300),internal::random<int>(1,300))) );
136
  CALL_SUBTEST_3( testMatrixType(MatrixXf(internal::random<int>(1,300),internal::random<int>(1,300))) );
121
  
137
  
Lines 132-140 void test_nullary() Link Here
132
    CALL_SUBTEST_9( testVectorType(VectorXi(internal::random<int>(1,300))) );
148
    CALL_SUBTEST_9( testVectorType(VectorXi(internal::random<int>(1,300))) );
133
    CALL_SUBTEST_9( testVectorType(Matrix<int,1,1>()) );
149
    CALL_SUBTEST_9( testVectorType(Matrix<int,1,1>()) );
134
  }
150
  }
135
151
136
#ifdef EIGEN_TEST_PART_6
152
#ifdef EIGEN_TEST_PART_6
137
  // Assignment of a RowVectorXd to a MatrixXd (regression test for bug #79).
153
  // Assignment of a RowVectorXd to a MatrixXd (regression test for bug #79).
138
  VERIFY( (MatrixXd(RowVectorXd::LinSpaced(3, 0, 1)) - RowVector3d(0, 0.5, 1)).norm() < std::numeric_limits<double>::epsilon() );
154
  VERIFY( (MatrixXd(RowVectorXd::LinSpaced(3, 0, 1)) - RowVector3d(0, 0.5, 1)).norm() < std::numeric_limits<double>::epsilon() );
139
#endif
155
#endif
156
157
#ifdef EIGEN_TEST_PART_10
158
  // check some internal logic
159
  VERIFY((  internal::has_nullary_operator<internal::scalar_constant_op<double> >::value ));
160
  VERIFY(( !internal::has_unary_operator<internal::scalar_constant_op<double> >::value ));
161
  VERIFY(( !internal::has_binary_operator<internal::scalar_constant_op<double> >::value ));
162
  VERIFY((  internal::functor_has_linear_access<internal::scalar_constant_op<double> >::ret ));
163
164
  VERIFY(( !internal::has_nullary_operator<internal::scalar_identity_op<double> >::value ));
165
  VERIFY(( !internal::has_unary_operator<internal::scalar_identity_op<double> >::value ));
166
  VERIFY((  internal::has_binary_operator<internal::scalar_identity_op<double> >::value ));
167
  VERIFY(( !internal::functor_has_linear_access<internal::scalar_identity_op<double> >::ret ));
168
169
  VERIFY(( !internal::has_nullary_operator<internal::linspaced_op<float,float,false> >::value ));
170
  VERIFY((  internal::has_unary_operator<internal::linspaced_op<float,float,false> >::value ));
171
  VERIFY(( !internal::has_binary_operator<internal::linspaced_op<float,float,false> >::value ));
172
  VERIFY((  internal::functor_has_linear_access<internal::linspaced_op<float,float,false> >::ret ));
173
#endif
140
}
174
}

Return to bug 1286