Medial Code Documentation
Loading...
Searching...
No Matches
NullaryFunctors.h
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2008-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
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
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#ifndef EIGEN_NULLARY_FUNCTORS_H
11#define EIGEN_NULLARY_FUNCTORS_H
12
13namespace Eigen {
14
15namespace internal {
16
17template<typename Scalar>
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) { }
21 template<typename Index>
22 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index, Index = 0) const { return m_other; }
23 template<typename Index, typename PacketType>
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;
26};
27template<typename Scalar>
29{ enum { Cost = 1, PacketAccess = packet_traits<Scalar>::Vectorizable, IsRepeatable = true }; };
30
31template<typename Scalar> struct scalar_identity_op {
32 EIGEN_EMPTY_STRUCT_CTOR(scalar_identity_op)
33 template<typename Index>
34 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const { return row==col ? Scalar(1) : Scalar(0); }
35};
36template<typename Scalar>
38{ enum { Cost = NumTraits<Scalar>::AddCost, PacketAccess = false, IsRepeatable = true }; };
39
40template <typename Scalar, typename Packet, bool RandomAccess> struct linspaced_op_impl;
41
42// linear access for packet ops:
43// 1) initialization
44// base = [low, ..., low] + ([step, ..., step] * [-size, ..., 0])
45// 2) each step (where size is 1 for coeff access or PacketSize for packet access)
46// base += [size*step, ..., size*step]
47//
48// TODO: Perhaps it's better to initialize lazily (so not in the constructor but in packetOp)
49// in order to avoid the padd() in operator() ?
50template <typename Scalar, typename Packet>
51struct linspaced_op_impl<Scalar,Packet,false>
52{
53 linspaced_op_impl(const Scalar& low, const Scalar& step) :
54 m_low(low), m_step(step),
57
58 template<typename Index>
59 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index i) const
60 {
61 m_base = padd(m_base, pset1<Packet>(m_step));
62 return m_low+Scalar(i)*m_step;
63 }
64
65 template<typename Index>
66 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Index) const { return m_base = padd(m_base,m_packetStep); }
67
68 const Scalar m_low;
69 const Scalar m_step;
70 const Packet m_packetStep;
71 mutable Packet m_base;
72};
73
74// random access for packet ops:
75// 1) each step
76// [low, ..., low] + ( [step, ..., step] * ( [i, ..., i] + [0, ..., size] ) )
77template <typename Scalar, typename Packet>
78struct linspaced_op_impl<Scalar,Packet,true>
79{
80 linspaced_op_impl(const Scalar& low, const Scalar& step) :
81 m_low(low), m_step(step),
82 m_lowPacket(pset1<Packet>(m_low)), m_stepPacket(pset1<Packet>(m_step)), m_interPacket(plset<Packet>(0)) {}
83
84 template<typename Index>
85 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return m_low+i*m_step; }
86
87 template<typename Index>
88 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Index i) const
89 { return internal::padd(m_lowPacket, pmul(m_stepPacket, padd(pset1<Packet>(Scalar(i)),m_interPacket))); }
90
91 const Scalar m_low;
92 const Scalar m_step;
93 const Packet m_lowPacket;
94 const Packet m_stepPacket;
95 const Packet m_interPacket;
96};
97
98// ----- Linspace functor ----------------------------------------------------------------
99
100// Forward declaration (we default to random access which does not really give
101// us a speed gain when using packet access but it allows to use the functor in
102// nested expressions).
103template <typename Scalar, typename PacketType, bool RandomAccess = true> struct linspaced_op;
104template <typename Scalar, typename PacketType, bool RandomAccess> struct functor_traits< linspaced_op<Scalar,PacketType,RandomAccess> >
105{ enum { Cost = 1, PacketAccess = packet_traits<Scalar>::HasSetLinear, IsRepeatable = true }; };
106template <typename Scalar, typename PacketType, bool RandomAccess> struct linspaced_op
107{
108 linspaced_op(const Scalar& low, const Scalar& high, Index num_steps) : impl((num_steps==1 ? high : low), (num_steps==1 ? Scalar() : (high-low)/Scalar(num_steps-1))) {}
109
110 template<typename Index>
111 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index i) const { return impl(i); }
112
113 // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since
114 // there row==0 and col is used for the actual iteration.
115 template<typename Index>
116 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Scalar operator() (Index row, Index col) const
117 {
118 eigen_assert(col==0 || row==0);
119 return impl(col + row);
120 }
121
122 template<typename Index, typename Packet>
123 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Index i) const { return impl.packetOp(i); }
124
125 // We need this function when assigning e.g. a RowVectorXd to a MatrixXd since
126 // there row==0 and col is used for the actual iteration.
127 template<typename Index, typename Packet>
128 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE const Packet packetOp(Index row, Index col) const
129 {
130 eigen_assert(col==0 || row==0);
131 return impl.packetOp(col + row);
132 }
133
134 // This proxy object handles the actual required temporaries, the different
135 // implementations (random vs. sequential access) as well as the
136 // correct piping to size 2/4 packet operations.
138};
139
140// all functors allow linear access, except scalar_identity_op. So we fix here a quick meta
141// to indicate whether a functor allows linear access, just always answering 'yes' except for
142// scalar_identity_op.
143template<typename Functor> struct functor_has_linear_access { enum { ret = 1 }; };
144template<typename Scalar> struct functor_has_linear_access<scalar_identity_op<Scalar> > { enum { ret = 0 }; };
145
146} // end namespace internal
147
148} // end namespace Eigen
149
150#endif // EIGEN_NULLARY_FUNCTORS_H
Pseudo expression representing a solving operation.
Definition Solve.h:63
Holds information about the various numeric (i.e.
Definition NumTraits.h:108
Definition NullaryFunctors.h:143
Definition XprHelper.h:107
Definition NullaryFunctors.h:40
Definition NullaryFunctors.h:107
Definition GenericPacketMath.h:90
Definition NullaryFunctors.h:18
Definition NullaryFunctors.h:31
Definition XprHelper.h:119