3 #include <funcy/concepts.h> 4 #include <funcy/util/chainer.h> 5 #include <funcy/util/compute_dot.h> 6 #include <funcy/util/compute_sum.h> 7 #include <funcy/util/derivative_wrappers.h> 8 #include <funcy/util/evaluate_if_present.h> 9 #include <funcy/util/type_traits.h> 11 #include <type_traits> 20 template < Function F, Function G >
21 struct Dot : Chainer< Dot< F, G > >
24 template <
class IndexedArg >
25 using D1Type = ComputeSum< ComputeDot< D1< F, IndexedArg >, D0< G > >,
26 ComputeDot< D0< F >, D1< G, IndexedArg > > >;
28 template <
class IndexedArgX,
class IndexedArgY >
29 using D2Type = ComputeSum< ComputeDot< D2< F, IndexedArgX, IndexedArgY >, D0< G > >,
30 ComputeDot< D1< F, IndexedArgX >, D1< G, IndexedArgY > >,
31 ComputeDot< D1< F, IndexedArgY >, D1< G, IndexedArgX > >,
32 ComputeDot< D0< F >, D2< G, IndexedArgX, IndexedArgY > > >;
34 template <
class IndexedArgX,
class IndexedArgY,
class IndexedArgZ >
36 ComputeSum< ComputeDot< D3< F, IndexedArgX, IndexedArgY, IndexedArgZ >, D0< G > >,
37 ComputeDot< D2< F, IndexedArgX, IndexedArgY >, D1< G, IndexedArgZ > >,
38 ComputeDot< D2< F, IndexedArgX, IndexedArgZ >, D1< G, IndexedArgY > >,
39 ComputeDot< D1< F, IndexedArgX >, D2< G, IndexedArgY, IndexedArgZ > >,
40 ComputeDot< D2< F, IndexedArgY, IndexedArgZ >, D1< G, IndexedArgX > >,
41 ComputeDot< D1< F, IndexedArgY >, D2< G, IndexedArgX, IndexedArgZ > >,
42 ComputeDot< D1< F, IndexedArgZ >, D2< G, IndexedArgX, IndexedArgY > >,
43 ComputeDot< D0< F >, D3< G, IndexedArgX, IndexedArgY, IndexedArgZ > > >;
54 constexpr
Dot( F&& f_, G&& g_ )
55 : f( std::move( f_ ) ), g( std::move( g_ ) ), value( f().
dot( g() ) )
64 constexpr
Dot( F&& f_,
const G& g_ )
65 : f( std::move( f_ ) ), g( g_ ), value( f().
dot( g() ) )
74 constexpr
Dot(
const F& f_, G&& g_ )
75 : f( f_ ), g( std::move( g_ ) ), value( f().
dot( g() ) )
84 constexpr
Dot(
const F& f_,
const G& g_ ) : f( f_ ), g( g_ ), value( f().
dot( g() ) )
93 template <
class InitF,
class InitG >
94 constexpr
Dot( InitF&& f_, InitG&& g_ ) requires(
95 std::is_constructible_v< F, std::decay_t< InitF > >&&
96 std::is_constructible_v< G, std::decay_t< InitG > > )
97 : f( std::forward< InitF >( f_ ) ), g( std::forward< InitG >( g_ ) ),
98 value( f().
dot( g() ) )
103 template <
class Arg >
106 update_if_present( f, x );
107 update_if_present( g, x );
108 value = f().dot( g() );
112 template <
int index,
class Arg >
115 update_if_present< index >( f, x );
116 update_if_present< index >( g, x );
117 value = f().dot( g() );
121 constexpr decltype(
auto ) d0()
const noexcept
130 template <
int id,
class Arg,
class IndexedArg = IndexedType< Arg,
id > >
131 ReturnType
d1( Arg
const& dx )
const requires( D1Type< IndexedArg >::present )
133 return sum( dot_impl( D1< F, IndexedArg >( f, dx ), D0< G >( g ) ),
134 dot_impl( D0< F >( f ), D1< G, IndexedArg >( g, dx ) ) )();
142 template <
int idx,
int idy,
class ArgX,
class ArgY,
145 ReturnType
d2( ArgX
const& dx, ArgY
const& dy )
const 146 requires( D2Type< IndexedArgX, IndexedArgY >::present )
149 dot_impl( D2< F, IndexedArgX, IndexedArgY >( f, dx, dy ), D0< G >( g ) ),
150 dot_impl( D1< F, IndexedArgX >( f, dx ), D1< G, IndexedArgY >( g, dy ) ),
151 dot_impl( D1< F, IndexedArgY >( f, dy ), D1< G, IndexedArgX >( g, dx ) ),
152 dot_impl( D0< F >( f ), D2< G, IndexedArgX, IndexedArgY >( g, dx, dy ) ) )();
161 template <
int idx,
int idy,
int idz,
class ArgX,
class ArgY,
class ArgZ,
165 ReturnType
d3( ArgX
const& dx, ArgY
const& dy, ArgZ
const& dz )
const 166 requires( D3Type< IndexedArgX, IndexedArgY, IndexedArgZ >::present )
168 return sum( dot_impl( D3< F, IndexedArgX, IndexedArgY, IndexedArgZ >( f, dx, dy, dz ),
170 dot_impl( D2< F, IndexedArgX, IndexedArgY >( f, dx, dy ),
171 D1< G, IndexedArgZ >( g, dz ) ),
172 dot_impl( D2< F, IndexedArgX, IndexedArgZ >( f, dx, dz ),
173 D1< G, IndexedArgY >( g, dy ) ),
174 dot_impl( D1< F, IndexedArgX >( f, dx ),
175 D2< G, IndexedArgY, IndexedArgZ >( g, dy, dz ) ),
176 dot_impl( D2< F, IndexedArgY, IndexedArgZ >( f, dy, dz ),
177 D1< G, IndexedArgX >( g, dx ) ),
178 dot_impl( D1< F, IndexedArgY >( f, dy ),
179 D2< G, IndexedArgX, IndexedArgZ >( g, dx, dz ) ),
180 dot_impl( D1< F, IndexedArgZ >( f, dz ),
181 D2< G, IndexedArgX, IndexedArgY >( g, dx, dy ) ),
182 dot_impl( D0< F >( f ), D3< G, IndexedArgX, IndexedArgY, IndexedArgZ >(
183 g, dx, dy, dz ) ) )();
ReturnType d3(ArgX const &dx, ArgY const &dy, ArgZ const &dz) const requires(D3Type< IndexedArgX
Third directional derivative.
auto dot(F &&f, G &&g)
overload of "dot"-function for the generation of functions.
Definition: generate.h:117
Dot of functions of type F and G.
Definition: dot.h:21
constexpr Dot(const F &f_, const G &g_)
Constructor passing arguments to function constructors.
Definition: dot.h:84
constexpr Dot(const F &f_, G &&g_)
Constructor passing arguments to function constructors.
Definition: dot.h:74
ReturnType d2(ArgX const &dx, ArgY const &dy) const requires(D2Type< IndexedArgX
Second directional derivative.
void update(Arg const &x)
Update point of evaluation.
Definition: dot.h:104
void update(const Arg &x)
Update variable corresponding to index.
Definition: dot.h:113
Mathematical operations and corresponding differentation rules.
ReturnType d1(Arg const &dx) const requires(D1Type< IndexedArg >
First directional derivative.
Definition: dot.h:131
typename Decay< std::decay_t< F > >::type decay_t
Access underlying type (if it is hidden by expression templates).
Definition: type_traits.h:47
Definition: type_traits.h:54
constexpr Dot(F &&f_, G &&g_)
Constructor passing arguments to function constructors.
Definition: dot.h:54
constexpr Dot(F &&f_, const G &g_)
Constructor passing arguments to function constructors.
Definition: dot.h:64
constexpr Dot(InitF &&f_, InitG &&g_) requires(std
Constructor passing arguments to function constructors.
Definition: dot.h:94