funcy  1.6.1
scale.h
1 #pragma once
2 
3 #include <funcy/concepts.h>
4 #include <funcy/util/chainer.h>
5 #include <funcy/util/derivative_wrappers.h>
6 #include <funcy/util/evaluate_if_present.h>
7 #include <funcy/util/mathop_traits.h>
8 #include <funcy/util/type_traits.h>
9 
10 #include <type_traits>
11 #include <utility>
12 
13 namespace funcy::mathop
14 {
19  template < class Scalar, Function F >
20  struct Scale : Chainer< Scale< Scalar, F > >
21  {
27  constexpr Scale( Scalar a_, F&& f_ )
28  : a( a_ ), f( std::move( f_ ) ), value( multiply_via_traits( a, f() ) )
29  {
30  }
31 
37  constexpr Scale( Scalar a_, const F& f_ )
38  : a( a_ ), f( f_ ), value( multiply_via_traits( a, f() ) )
39  {
40  }
41 
47  template < class... InitF >
48  constexpr Scale(
49  Scalar a_,
50  InitF&&... f_ ) requires std::is_constructible_v< F, std::decay_t< InitF >... >
51  : a( a_ ), f( std::forward< InitF >( f_ )... ), value( multiply_via_traits( a, f() ) )
52  {
53  }
54 
56  template < class Arg >
57  void update( const Arg& x )
58  {
59  update_if_present( f, x );
60  value = multiply_via_traits( a, f() );
61  }
62 
64  template < int index, class Arg >
65  void update( const Arg& x )
66  {
67  update_if_present< index >( f, x );
68  value = multiply_via_traits( a, f() );
69  }
70 
71  template < class... IndexedArgs >
72  void bulk_update( IndexedArgs&&... args )
73  {
74  bulk_update_if_present( f, std::forward< IndexedArgs >( args )... );
75  value = multiply_via_traits( a, f() );
76  }
77 
79  constexpr decltype( auto ) d0() const noexcept
80  {
81  return value;
82  }
83 
85  template < int idx, class Arg, class IndexedArg = IndexedType< Arg, idx > >
86  auto d1( const Arg& dx ) const requires( D1< F, IndexedArg >::present )
87  {
88  return multiply_via_traits( a, D1_< F, IndexedArg >::apply( f, dx ) );
89  }
90 
92  template < int idx, int idy, class ArgX, class ArgY,
93  class IndexedArgX = IndexedType< ArgX, idx >,
94  class IndexedArgY = IndexedType< ArgY, idy > >
95  auto d2( const ArgX& dx, const ArgY& dy ) const
96  requires( D2< F, IndexedArgX, IndexedArgY >::present )
97  {
98  return multiply_via_traits( a, D2_< F, IndexedArgX, IndexedArgY >::apply( f, dx, dy ) );
99  }
100 
102  template < int idx, int idy, int idz, class ArgX, class ArgY, class ArgZ,
103  class IndexedArgX = IndexedType< ArgX, idx >,
104  class IndexedArgY = IndexedType< ArgY, idy >,
105  class IndexedArgZ = IndexedType< ArgZ, idz > >
106  auto d3( const ArgX& dx, const ArgY& dy, const ArgZ& dz ) const
107  requires( D3< F, IndexedArgX, IndexedArgY, IndexedArgZ >::present )
108  {
109  return multiply_via_traits(
110  a, D3_< F, IndexedArgX, IndexedArgY, IndexedArgZ >::apply( f, dx, dy, dz ) );
111  }
112 
113  private:
114  Scalar a = 1.;
115  F f;
116  std::decay_t< decltype( std::declval< F >()() ) > value;
117  };
118 } // namespace funcy::mathop
constexpr Scale(Scalar a_, InitF &&... f_) requires std
Constructor passing arguments to function constructor.
Definition: scale.h:48
auto d3(const ArgX &dx, const ArgY &dy, const ArgZ &dz) const requires(D3< F
Third directional derivative.
void update(const Arg &x)
Update variable corresponding to index.
Definition: scale.h:65
auto d1(const Arg &dx) const requires(D1< F
First directional derivative.
Mathematical operations and corresponding differentation rules.
void update(const Arg &x)
Update point of evaluation.
Definition: scale.h:57
Definition: type_traits.h:54
constexpr Scale(Scalar a_, const F &f_)
Constructor passing arguments to function constructor.
Definition: scale.h:37
auto d2(const ArgX &dx, const ArgY &dy) const requires(D2< F
Second directional derivative.
Scaling of some function with a double .
Definition: scale.h:20
constexpr Scale(Scalar a_, F &&f_)
Constructor passing arguments to function constructor.
Definition: scale.h:27