funcy  1.6.1
squared.h
1 #pragma once
2 
3 #include <funcy/concepts.h>
4 #include <funcy/util/chainer.h>
5 #include <funcy/util/compute_product.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/mathop_traits.h>
10 #include <funcy/util/type_traits.h>
11 
12 #include <type_traits>
13 #include <utility>
14 
15 namespace funcy::mathop
16 {
21  template < Function F >
22  struct Squared : Chainer< Squared< F > >
23  {
24  private:
25  template < class IndexedArgX, class IndexedArgY >
26  using D2Sum = ComputeSum< ComputeProduct< D0< F >, D2< F, IndexedArgX, IndexedArgY > >,
27  ComputeProduct< D1< F, IndexedArgY >, D1< F, IndexedArgX > > >;
28 
29  template < class IndexedArgX, class IndexedArgY, class IndexedArgZ >
30  using D3Sum =
31  ComputeSum< ComputeProduct< D0< F >, D3< F, IndexedArgX, IndexedArgY, IndexedArgZ > >,
32  ComputeProduct< D1< F, IndexedArgZ >, D2< F, IndexedArgX, IndexedArgY > >,
33  ComputeProduct< D1< F, IndexedArgY >, D2< F, IndexedArgX, IndexedArgZ > >,
34  ComputeProduct< D2< F, IndexedArgY, IndexedArgZ >, D1< F, IndexedArgX > > >;
35 
36  public:
41  constexpr Squared( F&& f_ ) : f( std::move( f_ ) ), value( multiply_via_traits( f(), f() ) )
42  {
43  }
48  constexpr Squared( const F& f_ ) : f( f_ ), value( multiply_via_traits( f(), f() ) )
49  {
50  }
51 
56  template <
57  class InitF,
58  std::enable_if_t< !std::is_same< std::decay_t< InitF >, Squared >::value >* = nullptr >
59  constexpr Squared( InitF&& f_ ) requires std::is_constructible_v< F, std::decay_t< InitF > >
60  : f( std::forward< InitF >( f_ ) ), value( multiply_via_traits( f(), f() ) )
61  {
62  }
63 
65  template < class Arg >
66  void update( Arg const& x )
67  {
68  update_if_present( f, x );
69  value = multiply_via_traits( f(), f() );
70  }
71 
73  template < int index, class Arg >
74  void update( const Arg& x )
75  {
76  update_if_present< index >( f, x );
77  value = multiply_via_traits( f(), f() );
78  }
79 
80  template < class... IndexedArgs >
81  void bulk_update( IndexedArgs&&... args )
82  {
83  bulk_update_if_present( f, std::forward< IndexedArgs >( args )... );
84  value = multiply_via_traits( f(), f() );
85  }
86 
88  constexpr decltype( auto ) d0() const noexcept
89  {
90  return value;
91  }
92 
97  template < int id, class Arg, class IndexedArg = IndexedType< Arg, id > >
98  auto d1( Arg const& dx ) const
99  requires( ComputeProduct< D0< F >, D1< F, IndexedArg > >::present )
100  {
101  return multiply_via_traits(
102  2, multiply_via_traits( f(), D1_< F, IndexedArg >::apply( f, dx ) ) );
103  }
104 
110  template < int idx, int idy, class ArgX, class ArgY,
111  class IndexedArgX = IndexedType< ArgX, idx >,
112  class IndexedArgY = IndexedType< ArgY, idy > >
113  auto d2( ArgX const& dx, ArgY const& dy ) const
114  requires( D2Sum< IndexedArgX, IndexedArgY >::present )
115  {
116  return multiply_via_traits(
117  2,
118  sum( product( D0< F >( f ), D2< F, IndexedArgX, IndexedArgY >( f, dx, dy ) ),
119  product( D1< F, IndexedArgY >( f, dy ), D1< F, IndexedArgX >( f, dx ) ) )() );
120  }
121 
128  template < int idx, int idy, int idz, class ArgX, class ArgY, class ArgZ,
129  class IndexedArgX = IndexedType< ArgX, idx >,
130  class IndexedArgY = IndexedType< ArgY, idy >,
131  class IndexedArgZ = IndexedType< ArgZ, idz > >
132  auto d3( ArgX const& dx, ArgY const& dy, ArgZ const& dz ) const
133  requires( D3Sum< IndexedArgX, IndexedArgY, IndexedArgZ >::present )
134  {
135  return multiply_via_traits(
136  2, sum( product( D0< F >( f ),
137  D3< F, IndexedArgX, IndexedArgY, IndexedArgZ >( f, dx, dy, dz ) ),
138  product( D1< F, IndexedArgZ >( f, dz ),
139  D2< F, IndexedArgX, IndexedArgY >( f, dx, dy ) ),
140  product( D1< F, IndexedArgY >( f, dy ),
141  D2< F, IndexedArgX, IndexedArgZ >( f, dx, dz ) ),
142  product( D2< F, IndexedArgY, IndexedArgZ >( f, dy, dz ),
143  D1< F, IndexedArgX >( f, dx ) ) )() );
144  }
145 
146  private:
147  F f;
148  decay_t< decltype( multiply_via_traits( std::declval< F >()(), std::declval< F >()() ) ) >
149  value;
150  };
151 } // namespace funcy::mathop
void update(Arg const &x)
Update point of evaluation.
Definition: squared.h:66
auto d1(Arg const &dx) const requires(ComputeProduct< D0< F >
First directional derivative.
constexpr Squared(F &&f_)
Constructor.
Definition: squared.h:41
auto d3(ArgX const &dx, ArgY const &dy, ArgZ const &dz) const requires(D3Sum< IndexedArgX
Third directional derivative.
auto d2(ArgX const &dx, ArgY const &dy) const requires(D2Sum< IndexedArgX
Second directional derivative.
Mathematical operations and corresponding differentation rules.
Squared function .
Definition: squared.h:22
typename Decay< std::decay_t< F > >::type decay_t
Access underlying type (if it is hidden by expression templates).
Definition: type_traits.h:47
constexpr Squared(InitF &&f_) requires std
Constructor.
Definition: squared.h:59
Definition: type_traits.h:54
constexpr Squared(const F &f_)
Constructor.
Definition: squared.h:48
void update(const Arg &x)
Update variable corresponding to index.
Definition: squared.h:74