stator
A math, geometry, and utility library
constants.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 #include <ratio>
23 
24 namespace sym {
30  template<std::intmax_t Num, std::intmax_t Denom = 1>
31  struct C: std::ratio<Num, Denom> {
32  operator double() const {
33  return double(Num) / double(Denom);
34  }
35  };
36 
37  namespace detail {
39  template<class stdratio>
40  struct C_wrap {
42  };
43  }
44 
46  template<class T> struct is_C { static const bool value = false; };
47 
48  template<std::intmax_t N, std::intmax_t D> struct is_C<C<N,D> > { static const bool value = true; };
49 
51  typedef C<0> Null;
53  typedef C<1> Unity;
54 
57 
60 
62  template<std::intmax_t Num, std::intmax_t Denom>
63  inline std::ostream& operator<<(std::ostream& os, const C<Num, Denom>) {
64  os << "C<" << Num;
65  if (Denom != 1)
66  os << "," << Denom;
67  return os << ">()";
68  }
69 
71  inline std::ostream& operator<<(std::ostream& os, const C<1,4>) {
72  return (os << "©¼");
73 
74  }
75 
77  inline std::ostream& operator<<(std::ostream& os, const C<1,2>) {
78  return (os << "©½");
79  }
80 
82  inline std::ostream& operator<<(std::ostream& os, const C<3,4>) {
83  return (os << "©¾");
84  }
85 
87  inline std::ostream& operator<<(std::ostream& os, const pi) { os << "π"; return os; }
89  inline std::ostream& operator<<(std::ostream& os, const e) { os << "e"; return os; }
90 
96  template<size_t i> struct Factorial {
97  typedef C<i * Factorial<i - 1>::value::num, 1> value;
98  };
99 
100  template<> struct Factorial<1> {
101  typedef C<1, 1> value;
102  };
103 
104  template<> struct Factorial<0> {
105  typedef C<1, 1> value;
106  };
107 
108  template<std::intmax_t n1, std::intmax_t d1, std::intmax_t n2, std::intmax_t d2>
109  constexpr auto operator+(C<n1, d1>, C<n2, d2>) -> STATOR_AUTORETURN((typename detail::C_wrap<std::ratio_add<std::ratio<n1,d1>, std::ratio<n2,d2> > >::type()));
110 
111  template<std::intmax_t n1, std::intmax_t d1, std::intmax_t n2, std::intmax_t d2>
112  constexpr auto operator-(C<n1, d1>, C<n2, d2>) -> STATOR_AUTORETURN((typename detail::C_wrap<std::ratio_subtract<std::ratio<n1,d1>, std::ratio<n2,d2> > >::type()));
113 
114  template<std::intmax_t n1, std::intmax_t d1, std::intmax_t n2, std::intmax_t d2>
115  constexpr auto operator*(C<n1, d1>, C<n2, d2>) -> STATOR_AUTORETURN((typename detail::C_wrap<std::ratio_multiply<std::ratio<n1,d1>, std::ratio<n2,d2> > >::type()));
116 
117  template<std::intmax_t n1, std::intmax_t d1, std::intmax_t n2, std::intmax_t d2>
118  constexpr auto operator/(C<n1, d1>, C<n2, d2>) -> STATOR_AUTORETURN((typename detail::C_wrap<std::ratio_divide<std::ratio<n1,d1>, std::ratio<n2,d2> > >::type()));
119 
120  template<std::intmax_t n1, std::intmax_t d1, std::intmax_t n2, std::intmax_t d2>
121  constexpr bool operator==(const C<n1, d1>&, const C<n2, d2>&)
122  { return std::ratio_equal<std::ratio<n1, d1>, std::ratio<n2, d2> >::value; }
123 
124  template<class T, typename = typename std::enable_if<!is_C<T>::value>::type>
125  T operator+(const T& l, Null) { return l; }
126  template<class T, typename = typename std::enable_if<!is_C<T>::value>::type>
127  T operator+(Null, const T& r) { return r; }
128  template<class T, typename = typename std::enable_if<!is_C<T>::value>::type>
129  T operator-(const T& l, Null) { return l; }
130  template<class T, typename = typename std::enable_if<!is_C<T>::value>::type>
131  auto operator-(Null, const T& r) -> STATOR_AUTORETURN(-r);
132  template<class T, typename = typename std::enable_if<!is_C<T>::value>::type>
133  Null operator*(const T&, Null) { return Null(); }
134  template<class T, typename = typename std::enable_if<!is_C<T>::value>::type>
135  Null operator*(Null, const T&) { return Null(); }
136 
137  template<class T, typename = typename std::enable_if<!is_C<T>::value>::type>
138  auto operator*(const T& a, Unity) -> STATOR_AUTORETURN(a);
139  template<class T, typename = typename std::enable_if<!is_C<T>::value>::type>
140  auto operator*(Unity, const T& a) -> STATOR_AUTORETURN(a);
141 
147  template<size_t i> struct InvFactorial {
149  };
150 
151  template<class T>
152  inline std::ostream& operator<<(std::ostream& os, const std::complex<T>& c) {
153  if (c.imag() == 0)
154  return (os << c.real());
155  if (c.imag() < 0)
156  return (os << "(" <<c.real() << " - " << std::abs(c.imag()) << "i)");
157  return (os << "(" <<c.real() << " + " << c.imag() << "i)");
158  }
159 
160  template<class C_arg, class factor, class offset = std::ratio<0> >
162  static const bool value = (std::ratio_divide<std::ratio_subtract<std::ratio<C_arg::num, C_arg::den>, std::ratio<offset::num, offset::den> >, std::ratio<factor::num, factor::den> >::den == 1);
163  };
164 
165  //simplify sin(i * pi)
166  template<std::intmax_t num, std::intmax_t den,
167  typename = typename std::enable_if<is_whole_factor<std::ratio<num, den>, pi>::value>::type>
168  constexpr Null sin_Cimpl(const C<num, den>& a, detail::choice<0>) { return {}; }
169 
170  template<std::intmax_t num, std::intmax_t den,
171  typename = typename std::enable_if<is_whole_factor<std::ratio<num, den>, pi, decltype(pi() / C<2>())>::value>::type>
172  constexpr Unity sin_Cimpl(const C<num, den>& a, detail::choice<0>) { return {}; }
173 
174  template<std::intmax_t num, std::intmax_t den,
175  typename = typename std::enable_if<is_whole_factor<std::ratio<num, den>, pi>::value>::type>
176  constexpr Unity cos_Cimpl(const C<num, den>& a, detail::choice<0>) { return {}; }
177 
178  template<std::intmax_t num, std::intmax_t den,
179  typename = typename std::enable_if<is_whole_factor<std::ratio<num, den>, pi, decltype(pi() / C<2>())>::value>::type>
180  constexpr Null cos_Cimpl(const C<num, den>& a, detail::choice<0>) { return {}; }
181 
182  template<std::intmax_t num, std::intmax_t den>
184 
185  template<std::intmax_t num, std::intmax_t den>
187 
188  template<std::intmax_t num, std::intmax_t den>
189  constexpr C<(1 - 2 * (num < 0)) * num, (1 - 2 * (den < 0)) * den> abs(const C<num, den>& a) { return {}; }
190 }
A class which recursively inherits from itself to allow ambiguous function definition ordering...
Definition: config.hpp:65
detail::C_wrap< stator::constant_ratio::e >::type e
A symbolic/compile-time rational approximation of .
Definition: constants.hpp:59
C< 0 > Null
A symbolic representation of zero.
Definition: constants.hpp:51
auto N(const T &a) -> STATOR_AUTORETURN(simplify< NConfig >(a))
A variant of simplify that converts compile time symbols into numbers.
auto operator-(const Arg &l) -> STATOR_AUTORETURN(C<-1 >() *l) template< class LHS, class RHS, typename=typename std::enable_if< ApplySymbolicOps< LHS, RHS >::value >::type > auto operator+(const LHS &l, const RHS &r) -> STATOR_AUTORETURN((AddOp< decltype(store(l)), decltype(store(r))>(l, r))) template< class LHS, class RHS, typename=typename std::enable_if< ApplySymbolicOps< LHS, RHS >::value >::type > auto operator*(const LHS &l, const RHS &r) -> STATOR_AUTORETURN((MultiplyOp< decltype(store(l)), decltype(store(r))>(l, r))) template< class LHS, class RHS, typename=typename std::enable_if< ApplySymbolicOps< LHS, RHS >::value >::type > auto operator-(const LHS &l, const RHS &r) -> STATOR_AUTORETURN((SubtractOp< decltype(store(l)), decltype(store(r))>(l, r))) template< class LHS, class RHS, typename=typename std::enable_if< ApplySymbolicOps< LHS, RHS >::value >::type > auto operator/(const LHS &l, const RHS &r) -> STATOR_AUTORETURN((DivideOp< decltype(store(l)), decltype(store(r))>(l, r))) template< class LHS, class RHS, typename=typename std::enable_if< ApplySymbolicOps< LHS, RHS >::value >::type > auto pow(const LHS &l, const RHS &r) -> STATOR_AUTORETURN((PowerOp< decltype(store(l)), decltype(store(r))>(l, r)))
Symbolic unary negation operator.
C< i *Factorial< i - 1 >::value::num, 1 > value
Definition: constants.hpp:97
constexpr bool operator==(const C< n1, d1 > &, const C< n2, d2 > &)
Definition: constants.hpp:121
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
C< stdratio::num, stdratio::den > type
Definition: constants.hpp:41
std::ostream & operator<<(std::ostream &os, const C< Num, Denom >)
Output operator for compile-time constant (C types).
Definition: constants.hpp:63
constexpr auto operator/(C< n1, d1 >, C< n2, d2 >) -> STATOR_AUTORETURN((typename detail::C_wrap< std::ratio_divide< std::ratio< n1, d1 >, std::ratio< n2, d2 > > >::type()))
Arg operator+(const Arg &l)
Symbolic unary positive operator.
Definition: binary_ops.hpp:215
C< 1 > Unity
A symbolic representation of one.
Definition: constants.hpp:53
constexpr auto operator*(C< n1, d1 >, C< n2, d2 >) -> STATOR_AUTORETURN((typename detail::C_wrap< std::ratio_multiply< std::ratio< n1, d1 >, std::ratio< n2, d2 > > >::type()))
detail::C_wrap< stator::constant_ratio::pi >::type pi
A symbolic/compile-time rational approximation of .
Definition: constants.hpp:56
auto sin(const C< num, den > &a) -> STATOR_AUTORETURN(sin_Cimpl(a, detail::select_overload
Definition: constants.hpp:183
#define STATOR_AUTORETURN(EXPR)
A convenience Macro for defining auto return type functions.
Definition: config.hpp:51
The stator symbolic math library.
constexpr Unity cos_Cimpl(const C< num, den > &a, detail::choice< 0 >)
Definition: constants.hpp:176
Symbolic Factorial function.
Definition: constants.hpp:96
constexpr C<(1 - 2 *(num< 0)) *num,(1 - 2 *(den< 0)) *den > abs(const C< num, den > &a)
Definition: constants.hpp:189
C< Factorial< i >::value::den, Factorial< i >::value::num > value
Definition: constants.hpp:148
Compile time type-test for compile-time constants C.
Definition: constants.hpp:46
constexpr Null sin_Cimpl(const C< num, den > &a, detail::choice< 0 >)
Definition: constants.hpp:168
A class used to start the ambiguous function definition ordering calculation.
Definition: config.hpp:76
Symbolic Inverse factorial function.
Definition: constants.hpp:147
Conversion operator from std::ratio to C.
Definition: constants.hpp:40