stator
A math, geometry, and utility library
unary_ops.hpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2017 Marcus N Campbell Bannerman <[email protected]>
3 
4  This file is part of stator.
5 
6  stator is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  stator is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with stator. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #pragma once
21 
22 namespace sym {
26 
29  template<class Arg, typename Op>
31  Arg _arg;
32  UnaryOp(Arg a): _arg(a) {}
33  };
34 
35  inline float sin(float a) { return std::sin(a); }
36  inline double sin(double a) { return std::sin(a); }
37  inline long double sin(long double a) { return std::sin(a); }
38  template<class T> std::complex<T> sin(std::complex<T> a) { return std::sin(a); }
39 
40  inline float cos(float a) { return std::cos(a); }
41  inline double cos(double a) { return std::cos(a); }
42  inline long double cos(long double a) { return std::cos(a); }
43  template<class T> std::complex<T> cos(std::complex<T> a) { return std::cos(a); }
44 
45  inline float exp(float a) { return std::exp(a); }
46  inline double exp(double a) { return std::exp(a); }
47  inline long double exp(long double a) { return std::exp(a); }
48  template<class T> std::complex<T> exp(std::complex<T> a) { return std::exp(a); }
49 
50  inline float log(float a) { return std::log(a); }
51  inline double log(double a) { return std::log(a); }
52  inline long double log(long double a) { return std::log(a); }
53  template<class T> std::complex<T> log(std::complex<T> a) { return std::log(a); }
54 
55  inline int abs(int a) { return std::abs(a); }
56  inline long abs(long a) { return std::abs(a); }
57  inline long long abs(long long a) { return std::abs(a); }
58  inline float abs(float a) { return std::abs(a); }
59  inline double abs(double a) { return std::abs(a); }
60  inline long double abs(long double a) { return std::abs(a); }
61  template<class T> T abs(std::complex<T> a) { return std::abs(a); }
62 
63  namespace detail {
64  struct Sine {
65  template<class Arg> static auto apply(const Arg& a) -> STATOR_AUTORETURN(sin(a));
66  };
67 
68  struct Cosine {
69  template<class Arg> static auto apply(const Arg& a) -> STATOR_AUTORETURN(cos(a));
70  };
71 
72  struct Exp {
73  template<class Arg> static auto apply(const Arg& a) -> STATOR_AUTORETURN(exp(a));
74  };
75 
76  struct Log {
77  template<class Arg> static auto apply(const Arg& a) -> STATOR_AUTORETURN(log(a));
78  };
79 
80  struct Absolute {
81  template<class Arg> static auto apply(const Arg& a) -> STATOR_AUTORETURN(abs(a));
82  };
83 
84  struct Arbsign {
85  template<class Arg> static auto apply(const Arg& a) -> STATOR_AUTORETURN((UnaryOp<decltype(store(a)), Arbsign>(a)));
86  };
87  }
88 
89  template<class Arg,
90  typename = typename std::enable_if<IsSymbolic<Arg>::value>::type>
91  auto sin(const Arg& arg) -> STATOR_AUTORETURN((UnaryOp<decltype(store(arg)), detail::Sine>(arg)));
92 
93  template<class Arg,
94  typename = typename std::enable_if<IsSymbolic<Arg>::value>::type>
95  auto cos(const Arg& arg) -> STATOR_AUTORETURN((UnaryOp<decltype(store(arg)), detail::Cosine>(arg)));
96 
97  template<class Arg,
98  typename = typename std::enable_if<IsSymbolic<Arg>::value>::type>
99  auto exp(const Arg& arg) -> STATOR_AUTORETURN((UnaryOp<decltype(store(arg)), detail::Exp>(arg)));
100 
101  template<class Arg,
102  typename = typename std::enable_if<IsSymbolic<Arg>::value>::type>
103  auto log(const Arg& arg) -> STATOR_AUTORETURN((UnaryOp<decltype(store(arg)), detail::Log>(arg)));
104 
105  template<class Arg,
106  typename = typename std::enable_if<IsSymbolic<Arg>::value>::type>
107  auto abs(const Arg& arg) -> STATOR_AUTORETURN((UnaryOp<decltype(store(arg)), detail::Absolute>(arg)));
108 
109  template<class Arg>
110  auto arbsign(const Arg& arg) -> STATOR_AUTORETURN((UnaryOp<decltype(store(arg)), detail::Arbsign>(arg)));
111 
112  template<class Var, class Arg> auto derivative(const UnaryOp<Arg, detail::Sine>& f, Var x)
114  template<class Var, class Arg> auto derivative(const UnaryOp<Arg, detail::Cosine>& f, Var x)
116  template<class Var, class Arg> auto derivative(const UnaryOp<Arg, detail::Exp>& f, Var x)
117  -> STATOR_AUTORETURN(derivative(f._arg, x) * f);
118  template<class Var, class Arg> auto derivative(const UnaryOp<Arg, detail::Log>& f, Var x)
119  -> STATOR_AUTORETURN(derivative(f._arg, x) / f._arg);
120  template<class Var, class Arg> auto derivative(const UnaryOp<Arg, detail::Absolute>& f, Var x)
121  -> STATOR_AUTORETURN(derivative(f._arg, x) * sym::abs(f._arg) / f._arg);
122  template<class Var, class Arg> auto derivative(const UnaryOp<Arg, detail::Arbsign>& f, Var x)
124 
125  template<class Var, class Arg1, class Arg2, class Op>
126  auto sub(const UnaryOp<Arg1, Op>& f, const Relation<Var, Arg2>& x)
127  -> STATOR_AUTORETURN(Op::apply(sub(f._arg, x)));
128 }
129 
auto cos(const Arg &arg) -> STATOR_AUTORETURN((UnaryOp< decltype(store(arg)), detail::Cosine >(arg)))
Symbolic representation of a variable.
Definition: symbolic.hpp:94
auto abs(const Arg &arg) -> STATOR_AUTORETURN((UnaryOp< decltype(store(arg)), detail::Absolute >(arg)))
float exp(float a)
Definition: unary_ops.hpp:45
auto cos(const C< num, den > &a) -> STATOR_AUTORETURN(cos_Cimpl(a, detail::select_overload
Definition: constants.hpp:186
A class representing a compile-time rational constant (i.e., std::ratio).
Definition: constants.hpp:31
float log(float a)
Definition: unary_ops.hpp:50
Symbolic representation of a variable substitution.
Definition: symbolic.hpp:76
auto sin(const C< num, den > &a) -> STATOR_AUTORETURN(sin_Cimpl(a, detail::select_overload
Definition: constants.hpp:183
auto exp(const Arg &arg) -> STATOR_AUTORETURN((UnaryOp< decltype(store(arg)), detail::Exp >(arg)))
#define STATOR_AUTORETURN(EXPR)
A convenience Macro for defining auto return type functions.
Definition: config.hpp:51
The stator symbolic math library.
auto sin(const Arg &arg) -> STATOR_AUTORETURN((UnaryOp< decltype(store(arg)), detail::Sine >(arg)))
auto arbsign(const Arg &arg) -> STATOR_AUTORETURN((UnaryOp< decltype(store(arg)), detail::Arbsign >(arg)))
auto sub(BinaryOp< LHS, Op, RHS > f, Relation< Var, Arg > x) -> STATOR_AUTORETURN_BYVALUE(Op::apply(sub(f._l, x), sub(f._r, x)))
constexpr C<(1 - 2 *(num< 0)) *num,(1 - 2 *(den< 0)) *den > abs(const C< num, den > &a)
Definition: constants.hpp:189
auto derivative(const Expression &)
Performs a symbolic derivative on the expression.
A type trait to denote symbolic terms (i.e., one that is not yet immediately evaluable to a "normal" ...
Definition: symbolic.hpp:50
UnaryOp(Arg a)
Definition: unary_ops.hpp:32
auto log(const Arg &arg) -> STATOR_AUTORETURN((UnaryOp< decltype(store(arg)), detail::Log >(arg)))
Symbolic representation of a unary operator (i.e., sin(x)).
Definition: unary_ops.hpp:30
auto store(const T &val) -> decltype(store_impl(val, select_overload
Definition: config.hpp:94