funcy  1.6.1
subtraction.h
1 #pragma once
2 
3 #include <funcy/concepts.h>
4 #include <funcy/util/chainer.h>
5 #include <funcy/util/compute_subtraction.h>
6 #include <funcy/util/derivative_wrappers.h>
7 #include <funcy/util/evaluate_if_present.h>
8 #include <funcy/util/mathop_traits.h>
9 #include <funcy/util/type_traits.h>
10 
11 #include <utility>
12 
13 namespace funcy::mathop
14 {
19  template < Function F, Function G >
20  struct Subtraction : Chainer< Subtraction< F, G > >
21  {
27  constexpr Subtraction( const F& f_, const G& g_ )
28  : f( f_ ), g( g_ ), value( subtract_via_traits( f(), g() ) )
29  {
30  }
31 
37  constexpr Subtraction( F&& f_, const G& g_ )
38  : f( std::move( f_ ) ), g( g_ ), value( subtract_via_traits( f(), g() ) )
39  {
40  }
41 
47  constexpr Subtraction( const F& f_, G&& g_ )
48  : f( f_ ), g( std::move( g_ ) ), value( subtract_via_traits( f(), g() ) )
49  {
50  }
51 
57  constexpr Subtraction( F&& f_, G&& g_ )
58  : f( std::move( f_ ) ), g( std::move( g_ ) ), value( subtract_via_traits( f(), g() ) )
59  {
60  }
61 
67  template < class InitF, class InitG >
68  constexpr Subtraction( InitF&& f_, InitG&& g_ ) requires(
69  std::is_constructible_v< F, std::decay_t< InitF > >&&
70  std::is_constructible_v< G, std::decay_t< InitG > > &&
71  !Function< InitF > && !Function< InitG > )
72  : f( std::forward< InitF >( f_ ) ), g( std::forward< InitG >( g_ ) ),
73  value( subtract_via_traits( f(), g() ) )
74  {
75  }
76 
78  template < class Arg >
79  void update( Arg&& x )
80  {
81  update_if_present( f, x );
82  update_if_present( g, std::forward< Arg >( x ) );
83  value = subtract_via_traits( f(), g() );
84  }
85 
87  template < int index, class Arg >
88  void update( Arg&& x )
89  {
90  update_if_present< index >( f, x );
91  update_if_present< index >( g, std::forward< Arg >( x ) );
92  value = subtract_via_traits( f(), g() );
93  }
94 
95  template < class... IndexedArgs >
96  void bulk_update( IndexedArgs&&... args )
97  {
98  bulk_update_if_present( f, args... );
99  bulk_update_if_present( g, std::forward< IndexedArgs >( args )... );
100  value = subtract_via_traits( f(), g() );
101  }
102 
104  constexpr decltype( auto ) d0() const noexcept
105  {
106  return value;
107  }
108 
110  template < int id, class Arg, class IndexedArg = IndexedType< std::decay_t< Arg >, id > >
111  auto d1( Arg&& dx ) const
112  requires( ComputeSubtraction< D1< F, IndexedArg >, D1< G, IndexedArg > >::present )
113  {
114  return ComputeSubtraction< D1< F, IndexedArg >, D1< G, IndexedArg > >(
115  f, g, std::forward< Arg >( dx ) )();
116  }
117 
119  template < int idx, int idy, class ArgX, class ArgY,
120  class IndexedArgX = IndexedType< std::decay_t< ArgX >, idx >,
121  class IndexedArgY = IndexedType< std::decay_t< ArgY >, idy > >
122  auto d2( ArgX&& dx, ArgY&& dy ) const
123  requires( ComputeSubtraction< D2< F, IndexedArgX, IndexedArgY >,
124  D2< G, IndexedArgX, IndexedArgY > >::present )
125  {
126  return ComputeSubtraction< D2< F, IndexedArgX, IndexedArgY >,
127  D2< G, IndexedArgX, IndexedArgY > >(
128  f, g, std::forward< ArgX >( dx ), std::forward< ArgY >( dy ) )();
129  }
130 
132  template < int idx, int idy, int idz, class ArgX, class ArgY, class ArgZ,
133  class IndexedArgX = IndexedType< std::decay_t< ArgX >, idx >,
134  class IndexedArgY = IndexedType< std::decay_t< ArgY >, idy >,
135  class IndexedArgZ = IndexedType< std::decay_t< ArgZ >, idz > >
136  auto d3( ArgX&& dx, ArgY&& dy, ArgZ&& dz ) const requires(
137  ComputeSubtraction< D3< F, IndexedArgX, IndexedArgY, IndexedArgZ >,
138  D3< G, IndexedArgX, IndexedArgY, IndexedArgZ > >::present )
139  {
140  return ComputeSubtraction< D3< F, IndexedArgX, IndexedArgY, IndexedArgZ >,
141  D3< G, IndexedArgX, IndexedArgY, IndexedArgZ > >(
142  f, g, std::forward< ArgX >( dx ), std::forward< ArgY >( dy ),
143  std::forward< ArgZ >( dz ) )();
144  }
145 
146  private:
147  F f;
148  G g;
149  decay_t< decltype( subtract_via_traits( std::declval< F >()(), std::declval< G >()() ) ) >
150  value;
151  };
152 } // namespace funcy::mathop
Subtraction of functions of type F and G.
Definition: subtraction.h:20
constexpr Subtraction(F &&f_, const G &g_)
Constructor.
Definition: subtraction.h:37
auto d3(ArgX &&dx, ArgY &&dy, ArgZ &&dz) const requires(ComputeSubtraction< D3< F
Third directional derivative.
constexpr Subtraction(InitF &&f_, InitG &&g_) requires(std
Constructor.
Definition: subtraction.h:68
constexpr Subtraction(F &&f_, G &&g_)
Constructor.
Definition: subtraction.h:57
Mathematical operations and corresponding differentation rules.
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
void update(Arg &&x)
Update variable corresponding to index.
Definition: subtraction.h:88
constexpr Subtraction(const F &f_, G &&g_)
Constructor.
Definition: subtraction.h:47
constexpr Subtraction(const F &f_, const G &g_)
Constructor.
Definition: subtraction.h:27
auto d1(Arg &&dx) const requires(ComputeSubtraction< D1< F
First directional derivative.
void update(Arg &&x)
Update point of evaluation.
Definition: subtraction.h:79
auto d2(ArgX &&dx, ArgY &&dy) const requires(ComputeSubtraction< D2< F
Second directional derivative.