File indexing completed on 2025-01-18 09:39:33
0001
0002
0003
0004
0005 #ifndef BOOST_MATH_COMPLEX_ASIN_INCLUDED
0006 #define BOOST_MATH_COMPLEX_ASIN_INCLUDED
0007
0008 #ifndef BOOST_MATH_COMPLEX_DETAILS_INCLUDED
0009 # include <boost/math/complex/details.hpp>
0010 #endif
0011 #ifndef BOOST_MATH_LOG1P_INCLUDED
0012 # include <boost/math/special_functions/log1p.hpp>
0013 #endif
0014 #include <boost/math/tools/assert.hpp>
0015
0016 #ifdef BOOST_NO_STDC_NAMESPACE
0017 namespace std{ using ::sqrt; using ::fabs; using ::acos; using ::asin; using ::atan; using ::atan2; }
0018 #endif
0019
0020 namespace boost{ namespace math{
0021
0022 template<class T>
0023 [[deprecated("Replaced by C++11")]] inline std::complex<T> asin(const std::complex<T>& z)
0024 {
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037 static const T one = static_cast<T>(1);
0038
0039 static const T half = static_cast<T>(0.5L);
0040 static const T a_crossover = static_cast<T>(10);
0041 static const T b_crossover = static_cast<T>(0.6417L);
0042 static const T s_pi = boost::math::constants::pi<T>();
0043 static const T half_pi = s_pi / 2;
0044 static const T log_two = boost::math::constants::ln_two<T>();
0045 static const T quarter_pi = s_pi / 4;
0046 #ifdef _MSC_VER
0047 #pragma warning(push)
0048 #pragma warning(disable:4127)
0049 #endif
0050
0051
0052
0053
0054 T x = std::fabs(z.real());
0055 T y = std::fabs(z.imag());
0056 T real, imag;
0057
0058
0059
0060
0061
0062
0063
0064 if((boost::math::isnan)(x))
0065 {
0066 if((boost::math::isnan)(y))
0067 return std::complex<T>(x, x);
0068 if((boost::math::isinf)(y))
0069 {
0070 real = x;
0071 imag = std::numeric_limits<T>::infinity();
0072 }
0073 else
0074 return std::complex<T>(x, x);
0075 }
0076 else if((boost::math::isnan)(y))
0077 {
0078 if(x == 0)
0079 {
0080 real = 0;
0081 imag = y;
0082 }
0083 else if((boost::math::isinf)(x))
0084 {
0085 real = y;
0086 imag = std::numeric_limits<T>::infinity();
0087 }
0088 else
0089 return std::complex<T>(y, y);
0090 }
0091 else if((boost::math::isinf)(x))
0092 {
0093 if((boost::math::isinf)(y))
0094 {
0095 real = quarter_pi;
0096 imag = std::numeric_limits<T>::infinity();
0097 }
0098 else
0099 {
0100 real = half_pi;
0101 imag = std::numeric_limits<T>::infinity();
0102 }
0103 }
0104 else if((boost::math::isinf)(y))
0105 {
0106 real = 0;
0107 imag = std::numeric_limits<T>::infinity();
0108 }
0109 else
0110 {
0111
0112
0113
0114 if((y == 0) && (x <= one))
0115 return std::complex<T>(std::asin(z.real()), z.imag());
0116
0117
0118
0119
0120
0121
0122 T safe_max = detail::safe_max(static_cast<T>(8));
0123 T safe_min = detail::safe_min(static_cast<T>(4));
0124
0125 T xp1 = one + x;
0126 T xm1 = x - one;
0127
0128 if((x < safe_max) && (x > safe_min) && (y < safe_max) && (y > safe_min))
0129 {
0130 T yy = y * y;
0131 T r = std::sqrt(xp1*xp1 + yy);
0132 T s = std::sqrt(xm1*xm1 + yy);
0133 T a = half * (r + s);
0134 T b = x / a;
0135
0136 if(b <= b_crossover)
0137 {
0138 real = std::asin(b);
0139 }
0140 else
0141 {
0142 T apx = a + x;
0143 if(x <= one)
0144 {
0145 real = std::atan(x/std::sqrt(half * apx * (yy /(r + xp1) + (s-xm1))));
0146 }
0147 else
0148 {
0149 real = std::atan(x/(y * std::sqrt(half * (apx/(r + xp1) + apx/(s+xm1)))));
0150 }
0151 }
0152
0153 if(a <= a_crossover)
0154 {
0155 T am1;
0156 if(x < one)
0157 {
0158 am1 = half * (yy/(r + xp1) + yy/(s - xm1));
0159 }
0160 else
0161 {
0162 am1 = half * (yy/(r + xp1) + (s + xm1));
0163 }
0164 imag = boost::math::log1p(am1 + std::sqrt(am1 * (a + one)));
0165 }
0166 else
0167 {
0168 imag = std::log(a + std::sqrt(a*a - one));
0169 }
0170 }
0171 else
0172 {
0173
0174
0175
0176 if(y <= (std::numeric_limits<T>::epsilon() * std::fabs(xm1)))
0177 {
0178 if(x < one)
0179 {
0180 real = std::asin(x);
0181 imag = y / std::sqrt(-xp1*xm1);
0182 }
0183 else
0184 {
0185 real = half_pi;
0186 if(((std::numeric_limits<T>::max)() / xp1) > xm1)
0187 {
0188
0189 imag = boost::math::log1p(xm1 + std::sqrt(xp1*xm1));
0190 }
0191 else
0192 {
0193 imag = log_two + std::log(x);
0194 }
0195 }
0196 }
0197 else if(y <= safe_min)
0198 {
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212 BOOST_MATH_ASSERT(x == 1);
0213 real = half_pi - std::sqrt(y);
0214 imag = std::sqrt(y);
0215 }
0216 else if(std::numeric_limits<T>::epsilon() * y - one >= x)
0217 {
0218 real = x/y;
0219 imag = log_two + std::log(y);
0220 }
0221 else if(x > one)
0222 {
0223 real = std::atan(x/y);
0224 T xoy = x/y;
0225 imag = log_two + std::log(y) + half * boost::math::log1p(xoy*xoy);
0226 }
0227 else
0228 {
0229 T a = std::sqrt(one + y*y);
0230 real = x/a;
0231 imag = half * boost::math::log1p(static_cast<T>(2)*y*(y+a));
0232 }
0233 }
0234 }
0235
0236
0237
0238
0239 if((boost::math::signbit)(z.real()))
0240 real = (boost::math::changesign)(real);
0241 if((boost::math::signbit)(z.imag()))
0242 imag = (boost::math::changesign)(imag);
0243
0244 return std::complex<T>(real, imag);
0245 #ifdef _MSC_VER
0246 #pragma warning(pop)
0247 #endif
0248 }
0249
0250 } }
0251
0252 #endif