WaveBlocksND
continuous_sqrt.hpp
Go to the documentation of this file.
1 #pragma once
2 
3 #include <complex>
4 #include <stdexcept>
5 
6 #include "pi.hpp"
7 
8 
9 namespace waveblocks {
10  namespace math {
25  template<class T>
27  {
28  private:
32  std::complex<T> sqrt_;
33 
38  T state_;
39 
43  bool empty_;
44 
45  public:
52  : sqrt_()
53  , state_()
54  , empty_(true)
55  { }
56 
62  ContinuousSqrt(std::complex<T> sqrt)
63  : sqrt_(sqrt)
64  , state_(std::arg(sqrt))
65  , empty_(false)
66  { }
67 
75  static T continuate(T ref, T arg)
76  {
77  const T PI = pi<T>();
78  const T RANGE = 0.25*PI; // 0.5*pi allows all inputs
79 
80  // determine, how long one needs to rotate the reference angle counter-clock-wise
81  // to hit the angle of the 1st root in the domain = [-2*pi;2*pi].
82  T rot = arg - ref;
83 
84  // force rotation into domain [-pi;pi]
85  while (rot >= PI) {
86  rot -= 2.0*PI;
87  }
88  while (rot < -PI) {
89  rot += 2.0*PI;
90  }
91 
92  if (-RANGE < rot && rot < RANGE) {
93  return arg;
94  }
95  else if (rot > PI-RANGE || rot < -PI+RANGE) {
96  if (arg > 0.0)
97  return arg - PI;
98  else
99  return arg + PI;
100  }
101  else {
102  throw std::runtime_error("continuous_sqrt: too large deviation between computed square root and reference solution");
103  }
104  }
105 
115  std::complex<T> operator()(std::complex<T> input)
116  {
117  if (empty_) {
118  state_ = 0.5*std::arg(input); // choose principal solution
119  empty_ = false;
120  } else {
121  state_ = continuate(state_, 0.5*std::arg(input) );
122  }
123 
124  sqrt_ = std::polar(std::sqrt(std::abs(input)), state_);
125 
126  return sqrt_;
127  }
128 
132  std::complex<T> operator()() const
133  {
134  return sqrt_;
135  }
140  T get_state(void) const
141  {
142  return state_;
143  }
144  };
145  }
146 }
std::complex< T > operator()() const
Retrieve the stored reference solution.
Definition: continuous_sqrt.hpp:132
std::complex< T > operator()(std::complex< T > input)
Solves the quadratic equation .
Definition: continuous_sqrt.hpp:115
Definition: coefficients_file_parser.cpp:10
Definition: stdarray2stream.hpp:7
std::complex< T > sqrt_
Definition: continuous_sqrt.hpp:32
T get_state(void) const
getter for state state
Definition: continuous_sqrt.hpp:140
ContinuousSqrt()
Delayes initialization of the stored reference solution.
Definition: continuous_sqrt.hpp:51
bool empty_
Definition: continuous_sqrt.hpp:43
ContinuousSqrt(std::complex< T > sqrt)
Initializes the stored reference solution to a chosen value.
Definition: continuous_sqrt.hpp:62
static T continuate(T ref, T arg)
Definition: continuous_sqrt.hpp:75
T state_
Definition: continuous_sqrt.hpp:38
This class deals with the issue, that the square root of complex numbers is not unique.
Definition: continuous_sqrt.hpp:26