3 #include <funcy/concepts.h> 4 #include <funcy/util/compute_chain.h> 5 #include <funcy/util/compute_sum.h> 6 #include <funcy/util/derivative_wrappers.h> 7 #include <funcy/util/evaluate_if_present.h> 8 #include <funcy/util/type_traits.h> 26 template < Function F, Function G >
27 struct Chain : Chainer< Chain< F, G > >
30 using FArg = decltype( std::declval< G >()() );
32 template <
class IndexedArgX,
class IndexedArgY,
class IndexedFArgX,
35 ComputeSum< ComputeChainD2< F, D1< G, IndexedArgX >, D1< G, IndexedArgY >,
36 IndexedFArgX, IndexedFArgY >,
37 ComputeChainD1< F, D2< G, IndexedArgX, IndexedArgY >, IndexedFArgX > >;
39 template <
class IndexedArgX,
class IndexedArgY,
class IndexedArgZ,
class IndexedFArgX,
40 class IndexedFArgY,
class IndexedFArgZ >
41 using D3LazyType = ComputeSum<
42 ComputeChainD3< F, D1< G, IndexedArgX >, D1< G, IndexedArgY >, D1< G, IndexedArgZ >,
43 IndexedFArgX, IndexedFArgY, IndexedFArgZ >,
44 ComputeChainD2< F, D2< G, IndexedArgX, IndexedArgZ >, D1< G, IndexedArgY >,
45 IndexedFArgX, IndexedFArgY >,
46 ComputeChainD2< F, D1< G, IndexedArgX >, D2< G, IndexedArgY, IndexedArgZ >,
47 IndexedFArgX, IndexedFArgY >,
48 ComputeChainD2< F, D2< G, IndexedArgX, IndexedArgY >, D1< G, IndexedArgZ >,
49 IndexedFArgX, IndexedFArgZ >,
50 ComputeChainD1< F, D3< G, IndexedArgX, IndexedArgY, IndexedArgZ >, IndexedFArgX > >;
58 constexpr
Chain(
const F& f_,
const G& g_ ) : g( g_ ), f( f_ )
60 update_if_present( f, g() );
68 constexpr
Chain(
const F& f_, G&& g_ ) : g( std::move( g_ ) ), f( f_ )
70 update_if_present( f, g() );
78 constexpr
Chain( F&& f_,
const G& g_ ) : g( g_ ), f( std::move( f_ ) )
80 update_if_present( f, g() );
88 constexpr
Chain( F&& f_, G&& g_ ) : g( std::move( g_ ) ), f( std::move( f_ ) )
90 update_if_present( f, g() );
94 template <
class Arg >
97 update_if_present( g, x );
98 update_if_present( f, g() );
102 template <
int index,
class Arg >
105 update_if_present< index >( g, x );
106 update_if_present( f, g() );
109 template <
class... IndexedArgs >
110 void bulk_update( IndexedArgs&&... args )
112 bulk_update_if_present( g, std::forward< IndexedArgs >( args )... );
113 update_if_present( f, g() );
117 constexpr decltype(
auto ) d0()
const noexcept
126 template <
int id,
class Arg,
class IndexedArg = IndexedType< Arg,
id >,
127 class IndexedFArg = IndexedType< FArg,
id > >
128 auto d1( Arg
const& dx )
const 129 requires( ComputeChainD1< F, D1< G, IndexedArg >, IndexedFArg >::present )
131 return chain< IndexedFArg >( f, D1< G, IndexedArg >( g, dx ) )();
139 template <
int idx,
int idy,
class ArgX,
class ArgY,
144 auto d2( ArgX
const& dx, ArgY
const& dy )
const requires(
145 D2LazyType< IndexedArgX, IndexedArgY, IndexedFArgX, IndexedFArgY >::present )
148 chain< IndexedFArgX, IndexedFArgY >( f, D1< G, IndexedArgX >( g, dx ),
149 D1< G, IndexedArgY >( g, dy ) ),
150 chain< IndexedFArgX >( f, D2< G, IndexedArgX, IndexedArgY >( g, dx, dy ) ) )();
159 template <
int idx,
int idy,
int idz,
class ArgX,
class ArgY,
class ArgZ,
166 auto d3( ArgX
const& dx, ArgY
const& dy, ArgZ
const& dz )
const 167 requires( D3LazyType< IndexedArgX, IndexedArgY, IndexedArgZ, IndexedFArgX,
168 IndexedFArgY, IndexedFArgZ >::present )
170 D1< G, IndexedArgX > dGdx( g, dx );
171 D1< G, IndexedArgY > dGdy( g, dy );
172 D1< G, IndexedArgZ > dGdz( g, dz );
174 chain< IndexedFArgX, IndexedFArgY, IndexedFArgZ >( f, dGdx, dGdy, dGdz ),
175 chain< IndexedFArgX, IndexedFArgY >(
176 f, D2< G, IndexedArgX, IndexedArgZ >( g, dx, dz ), dGdy ),
177 chain< IndexedFArgX, IndexedFArgY >(
178 f, dGdx, D2< G, IndexedArgY, IndexedArgZ >( g, dy, dz ) ),
179 chain< IndexedFArgX, IndexedFArgZ >(
180 f, D2< G, IndexedArgX, IndexedArgY >( g, dx, dy ), dGdz ),
181 chain< IndexedFArgX >(
182 f, D3< G, IndexedArgX, IndexedArgY, IndexedArgZ >( g, dx, dy, dz ) ) )();
void update(const Arg &x)
Update point of evaluation.
Definition: chain.h:95
constexpr Chain(F &&f_, G &&g_)
Constructor taking moving the functions to be chained.
Definition: chain.h:88
auto d2(ArgX const &dx, ArgY const &dy) const requires(D2LazyType< IndexedArgX
Second directional derivative.
void update(const Arg &x)
Update variable corresponding to index.
Definition: chain.h:103
Main namespace of the funcy library.
auto d1(Arg const &dx) const requires(ComputeChainD1< F
First directional derivative.
constexpr Chain(const F &f_, const G &g_)
Constructor taking copies of the functions to be chained.
Definition: chain.h:58
auto d3(ArgX const &dx, ArgY const &dy, ArgZ const &dz) const requires(D3LazyType< IndexedArgX
Third directional derivative.
Definition: type_traits.h:54
Chain of functions and of type F resp. G.
Definition: chain.h:27
constexpr Chain(F &&f_, const G &g_)
Constructor taking moving the functions to be chained.
Definition: chain.h:78
constexpr Chain(const F &f_, G &&g_)
Constructor taking moving the functions to be chained.
Definition: chain.h:68