MathFunctions.h 40 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421
  1. // This file is part of Eigen, a lightweight C++ template library
  2. // for linear algebra.
  3. //
  4. // Copyright (C) 2006-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
  5. //
  6. // This Source Code Form is subject to the terms of the Mozilla
  7. // Public License v. 2.0. If a copy of the MPL was not distributed
  8. // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
  9. #ifndef EIGEN_MATHFUNCTIONS_H
  10. #define EIGEN_MATHFUNCTIONS_H
  11. // source: http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html
  12. // TODO this should better be moved to NumTraits
  13. #define EIGEN_PI 3.141592653589793238462643383279502884197169399375105820974944592307816406L
  14. namespace Eigen {
  15. // On WINCE, std::abs is defined for int only, so let's defined our own overloads:
  16. // This issue has been confirmed with MSVC 2008 only, but the issue might exist for more recent versions too.
  17. #if EIGEN_OS_WINCE && EIGEN_COMP_MSVC && EIGEN_COMP_MSVC<=1500
  18. long abs(long x) { return (labs(x)); }
  19. double abs(double x) { return (fabs(x)); }
  20. float abs(float x) { return (fabsf(x)); }
  21. long double abs(long double x) { return (fabsl(x)); }
  22. #endif
  23. namespace internal {
  24. /** \internal \class global_math_functions_filtering_base
  25. *
  26. * What it does:
  27. * Defines a typedef 'type' as follows:
  28. * - if type T has a member typedef Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl, then
  29. * global_math_functions_filtering_base<T>::type is a typedef for it.
  30. * - otherwise, global_math_functions_filtering_base<T>::type is a typedef for T.
  31. *
  32. * How it's used:
  33. * To allow to defined the global math functions (like sin...) in certain cases, like the Array expressions.
  34. * When you do sin(array1+array2), the object array1+array2 has a complicated expression type, all what you want to know
  35. * is that it inherits ArrayBase. So we implement a partial specialization of sin_impl for ArrayBase<Derived>.
  36. * So we must make sure to use sin_impl<ArrayBase<Derived> > and not sin_impl<Derived>, otherwise our partial specialization
  37. * won't be used. How does sin know that? That's exactly what global_math_functions_filtering_base tells it.
  38. *
  39. * How it's implemented:
  40. * SFINAE in the style of enable_if. Highly susceptible of breaking compilers. With GCC, it sure does work, but if you replace
  41. * the typename dummy by an integer template parameter, it doesn't work anymore!
  42. */
  43. template<typename T, typename dummy = void>
  44. struct global_math_functions_filtering_base
  45. {
  46. typedef T type;
  47. };
  48. template<typename T> struct always_void { typedef void type; };
  49. template<typename T>
  50. struct global_math_functions_filtering_base
  51. <T,
  52. typename always_void<typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl>::type
  53. >
  54. {
  55. typedef typename T::Eigen_BaseClassForSpecializationOfGlobalMathFuncImpl type;
  56. };
  57. #define EIGEN_MATHFUNC_IMPL(func, scalar) Eigen::internal::func##_impl<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>
  58. #define EIGEN_MATHFUNC_RETVAL(func, scalar) typename Eigen::internal::func##_retval<typename Eigen::internal::global_math_functions_filtering_base<scalar>::type>::type
  59. /****************************************************************************
  60. * Implementation of real *
  61. ****************************************************************************/
  62. template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
  63. struct real_default_impl
  64. {
  65. typedef typename NumTraits<Scalar>::Real RealScalar;
  66. EIGEN_DEVICE_FUNC
  67. static inline RealScalar run(const Scalar& x)
  68. {
  69. return x;
  70. }
  71. };
  72. template<typename Scalar>
  73. struct real_default_impl<Scalar,true>
  74. {
  75. typedef typename NumTraits<Scalar>::Real RealScalar;
  76. EIGEN_DEVICE_FUNC
  77. static inline RealScalar run(const Scalar& x)
  78. {
  79. using std::real;
  80. return real(x);
  81. }
  82. };
  83. template<typename Scalar> struct real_impl : real_default_impl<Scalar> {};
  84. #ifdef __CUDA_ARCH__
  85. template<typename T>
  86. struct real_impl<std::complex<T> >
  87. {
  88. typedef T RealScalar;
  89. EIGEN_DEVICE_FUNC
  90. static inline T run(const std::complex<T>& x)
  91. {
  92. return x.real();
  93. }
  94. };
  95. #endif
  96. template<typename Scalar>
  97. struct real_retval
  98. {
  99. typedef typename NumTraits<Scalar>::Real type;
  100. };
  101. /****************************************************************************
  102. * Implementation of imag *
  103. ****************************************************************************/
  104. template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
  105. struct imag_default_impl
  106. {
  107. typedef typename NumTraits<Scalar>::Real RealScalar;
  108. EIGEN_DEVICE_FUNC
  109. static inline RealScalar run(const Scalar&)
  110. {
  111. return RealScalar(0);
  112. }
  113. };
  114. template<typename Scalar>
  115. struct imag_default_impl<Scalar,true>
  116. {
  117. typedef typename NumTraits<Scalar>::Real RealScalar;
  118. EIGEN_DEVICE_FUNC
  119. static inline RealScalar run(const Scalar& x)
  120. {
  121. using std::imag;
  122. return imag(x);
  123. }
  124. };
  125. template<typename Scalar> struct imag_impl : imag_default_impl<Scalar> {};
  126. #ifdef __CUDA_ARCH__
  127. template<typename T>
  128. struct imag_impl<std::complex<T> >
  129. {
  130. typedef T RealScalar;
  131. EIGEN_DEVICE_FUNC
  132. static inline T run(const std::complex<T>& x)
  133. {
  134. return x.imag();
  135. }
  136. };
  137. #endif
  138. template<typename Scalar>
  139. struct imag_retval
  140. {
  141. typedef typename NumTraits<Scalar>::Real type;
  142. };
  143. /****************************************************************************
  144. * Implementation of real_ref *
  145. ****************************************************************************/
  146. template<typename Scalar>
  147. struct real_ref_impl
  148. {
  149. typedef typename NumTraits<Scalar>::Real RealScalar;
  150. EIGEN_DEVICE_FUNC
  151. static inline RealScalar& run(Scalar& x)
  152. {
  153. return reinterpret_cast<RealScalar*>(&x)[0];
  154. }
  155. EIGEN_DEVICE_FUNC
  156. static inline const RealScalar& run(const Scalar& x)
  157. {
  158. return reinterpret_cast<const RealScalar*>(&x)[0];
  159. }
  160. };
  161. template<typename Scalar>
  162. struct real_ref_retval
  163. {
  164. typedef typename NumTraits<Scalar>::Real & type;
  165. };
  166. /****************************************************************************
  167. * Implementation of imag_ref *
  168. ****************************************************************************/
  169. template<typename Scalar, bool IsComplex>
  170. struct imag_ref_default_impl
  171. {
  172. typedef typename NumTraits<Scalar>::Real RealScalar;
  173. EIGEN_DEVICE_FUNC
  174. static inline RealScalar& run(Scalar& x)
  175. {
  176. return reinterpret_cast<RealScalar*>(&x)[1];
  177. }
  178. EIGEN_DEVICE_FUNC
  179. static inline const RealScalar& run(const Scalar& x)
  180. {
  181. return reinterpret_cast<RealScalar*>(&x)[1];
  182. }
  183. };
  184. template<typename Scalar>
  185. struct imag_ref_default_impl<Scalar, false>
  186. {
  187. EIGEN_DEVICE_FUNC
  188. static inline Scalar run(Scalar&)
  189. {
  190. return Scalar(0);
  191. }
  192. EIGEN_DEVICE_FUNC
  193. static inline const Scalar run(const Scalar&)
  194. {
  195. return Scalar(0);
  196. }
  197. };
  198. template<typename Scalar>
  199. struct imag_ref_impl : imag_ref_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
  200. template<typename Scalar>
  201. struct imag_ref_retval
  202. {
  203. typedef typename NumTraits<Scalar>::Real & type;
  204. };
  205. /****************************************************************************
  206. * Implementation of conj *
  207. ****************************************************************************/
  208. template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
  209. struct conj_impl
  210. {
  211. EIGEN_DEVICE_FUNC
  212. static inline Scalar run(const Scalar& x)
  213. {
  214. return x;
  215. }
  216. };
  217. template<typename Scalar>
  218. struct conj_impl<Scalar,true>
  219. {
  220. EIGEN_DEVICE_FUNC
  221. static inline Scalar run(const Scalar& x)
  222. {
  223. using std::conj;
  224. return conj(x);
  225. }
  226. };
  227. template<typename Scalar>
  228. struct conj_retval
  229. {
  230. typedef Scalar type;
  231. };
  232. /****************************************************************************
  233. * Implementation of abs2 *
  234. ****************************************************************************/
  235. template<typename Scalar,bool IsComplex>
  236. struct abs2_impl_default
  237. {
  238. typedef typename NumTraits<Scalar>::Real RealScalar;
  239. EIGEN_DEVICE_FUNC
  240. static inline RealScalar run(const Scalar& x)
  241. {
  242. return x*x;
  243. }
  244. };
  245. template<typename Scalar>
  246. struct abs2_impl_default<Scalar, true> // IsComplex
  247. {
  248. typedef typename NumTraits<Scalar>::Real RealScalar;
  249. EIGEN_DEVICE_FUNC
  250. static inline RealScalar run(const Scalar& x)
  251. {
  252. return x.real()*x.real() + x.imag()*x.imag();
  253. }
  254. };
  255. template<typename Scalar>
  256. struct abs2_impl
  257. {
  258. typedef typename NumTraits<Scalar>::Real RealScalar;
  259. EIGEN_DEVICE_FUNC
  260. static inline RealScalar run(const Scalar& x)
  261. {
  262. return abs2_impl_default<Scalar,NumTraits<Scalar>::IsComplex>::run(x);
  263. }
  264. };
  265. template<typename Scalar>
  266. struct abs2_retval
  267. {
  268. typedef typename NumTraits<Scalar>::Real type;
  269. };
  270. /****************************************************************************
  271. * Implementation of norm1 *
  272. ****************************************************************************/
  273. template<typename Scalar, bool IsComplex>
  274. struct norm1_default_impl;
  275. template<typename Scalar>
  276. struct norm1_default_impl<Scalar,true>
  277. {
  278. typedef typename NumTraits<Scalar>::Real RealScalar;
  279. EIGEN_DEVICE_FUNC
  280. static inline RealScalar run(const Scalar& x)
  281. {
  282. EIGEN_USING_STD_MATH(abs);
  283. return abs(x.real()) + abs(x.imag());
  284. }
  285. };
  286. template<typename Scalar>
  287. struct norm1_default_impl<Scalar, false>
  288. {
  289. EIGEN_DEVICE_FUNC
  290. static inline Scalar run(const Scalar& x)
  291. {
  292. EIGEN_USING_STD_MATH(abs);
  293. return abs(x);
  294. }
  295. };
  296. template<typename Scalar>
  297. struct norm1_impl : norm1_default_impl<Scalar, NumTraits<Scalar>::IsComplex> {};
  298. template<typename Scalar>
  299. struct norm1_retval
  300. {
  301. typedef typename NumTraits<Scalar>::Real type;
  302. };
  303. /****************************************************************************
  304. * Implementation of hypot *
  305. ****************************************************************************/
  306. template<typename Scalar> struct hypot_impl;
  307. template<typename Scalar>
  308. struct hypot_retval
  309. {
  310. typedef typename NumTraits<Scalar>::Real type;
  311. };
  312. /****************************************************************************
  313. * Implementation of cast *
  314. ****************************************************************************/
  315. template<typename OldType, typename NewType>
  316. struct cast_impl
  317. {
  318. EIGEN_DEVICE_FUNC
  319. static inline NewType run(const OldType& x)
  320. {
  321. return static_cast<NewType>(x);
  322. }
  323. };
  324. // here, for once, we're plainly returning NewType: we don't want cast to do weird things.
  325. template<typename OldType, typename NewType>
  326. EIGEN_DEVICE_FUNC
  327. inline NewType cast(const OldType& x)
  328. {
  329. return cast_impl<OldType, NewType>::run(x);
  330. }
  331. /****************************************************************************
  332. * Implementation of round *
  333. ****************************************************************************/
  334. #if EIGEN_HAS_CXX11_MATH
  335. template<typename Scalar>
  336. struct round_impl {
  337. static inline Scalar run(const Scalar& x)
  338. {
  339. EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
  340. using std::round;
  341. return round(x);
  342. }
  343. };
  344. #else
  345. template<typename Scalar>
  346. struct round_impl
  347. {
  348. static inline Scalar run(const Scalar& x)
  349. {
  350. EIGEN_STATIC_ASSERT((!NumTraits<Scalar>::IsComplex), NUMERIC_TYPE_MUST_BE_REAL)
  351. EIGEN_USING_STD_MATH(floor);
  352. EIGEN_USING_STD_MATH(ceil);
  353. return (x > Scalar(0)) ? floor(x + Scalar(0.5)) : ceil(x - Scalar(0.5));
  354. }
  355. };
  356. #endif
  357. template<typename Scalar>
  358. struct round_retval
  359. {
  360. typedef Scalar type;
  361. };
  362. /****************************************************************************
  363. * Implementation of arg *
  364. ****************************************************************************/
  365. #if EIGEN_HAS_CXX11_MATH
  366. template<typename Scalar>
  367. struct arg_impl {
  368. static inline Scalar run(const Scalar& x)
  369. {
  370. EIGEN_USING_STD_MATH(arg);
  371. return arg(x);
  372. }
  373. };
  374. #else
  375. template<typename Scalar, bool IsComplex = NumTraits<Scalar>::IsComplex>
  376. struct arg_default_impl
  377. {
  378. typedef typename NumTraits<Scalar>::Real RealScalar;
  379. EIGEN_DEVICE_FUNC
  380. static inline RealScalar run(const Scalar& x)
  381. {
  382. return (x < Scalar(0)) ? Scalar(EIGEN_PI) : Scalar(0); }
  383. };
  384. template<typename Scalar>
  385. struct arg_default_impl<Scalar,true>
  386. {
  387. typedef typename NumTraits<Scalar>::Real RealScalar;
  388. EIGEN_DEVICE_FUNC
  389. static inline RealScalar run(const Scalar& x)
  390. {
  391. EIGEN_USING_STD_MATH(arg);
  392. return arg(x);
  393. }
  394. };
  395. template<typename Scalar> struct arg_impl : arg_default_impl<Scalar> {};
  396. #endif
  397. template<typename Scalar>
  398. struct arg_retval
  399. {
  400. typedef typename NumTraits<Scalar>::Real type;
  401. };
  402. /****************************************************************************
  403. * Implementation of log1p *
  404. ****************************************************************************/
  405. namespace std_fallback {
  406. // fallback log1p implementation in case there is no log1p(Scalar) function in namespace of Scalar,
  407. // or that there is no suitable std::log1p function available
  408. template<typename Scalar>
  409. EIGEN_DEVICE_FUNC inline Scalar log1p(const Scalar& x) {
  410. EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
  411. typedef typename NumTraits<Scalar>::Real RealScalar;
  412. EIGEN_USING_STD_MATH(log);
  413. Scalar x1p = RealScalar(1) + x;
  414. return numext::equal_strict(x1p, Scalar(1)) ? x : x * ( log(x1p) / (x1p - RealScalar(1)) );
  415. }
  416. }
  417. template<typename Scalar>
  418. struct log1p_impl {
  419. static inline Scalar run(const Scalar& x)
  420. {
  421. EIGEN_STATIC_ASSERT_NON_INTEGER(Scalar)
  422. #if EIGEN_HAS_CXX11_MATH
  423. using std::log1p;
  424. #endif
  425. using std_fallback::log1p;
  426. return log1p(x);
  427. }
  428. };
  429. template<typename Scalar>
  430. struct log1p_retval
  431. {
  432. typedef Scalar type;
  433. };
  434. /****************************************************************************
  435. * Implementation of pow *
  436. ****************************************************************************/
  437. template<typename ScalarX,typename ScalarY, bool IsInteger = NumTraits<ScalarX>::IsInteger&&NumTraits<ScalarY>::IsInteger>
  438. struct pow_impl
  439. {
  440. //typedef Scalar retval;
  441. typedef typename ScalarBinaryOpTraits<ScalarX,ScalarY,internal::scalar_pow_op<ScalarX,ScalarY> >::ReturnType result_type;
  442. static EIGEN_DEVICE_FUNC inline result_type run(const ScalarX& x, const ScalarY& y)
  443. {
  444. EIGEN_USING_STD_MATH(pow);
  445. return pow(x, y);
  446. }
  447. };
  448. template<typename ScalarX,typename ScalarY>
  449. struct pow_impl<ScalarX,ScalarY, true>
  450. {
  451. typedef ScalarX result_type;
  452. static EIGEN_DEVICE_FUNC inline ScalarX run(ScalarX x, ScalarY y)
  453. {
  454. ScalarX res(1);
  455. eigen_assert(!NumTraits<ScalarY>::IsSigned || y >= 0);
  456. if(y & 1) res *= x;
  457. y >>= 1;
  458. while(y)
  459. {
  460. x *= x;
  461. if(y&1) res *= x;
  462. y >>= 1;
  463. }
  464. return res;
  465. }
  466. };
  467. /****************************************************************************
  468. * Implementation of random *
  469. ****************************************************************************/
  470. template<typename Scalar,
  471. bool IsComplex,
  472. bool IsInteger>
  473. struct random_default_impl {};
  474. template<typename Scalar>
  475. struct random_impl : random_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
  476. template<typename Scalar>
  477. struct random_retval
  478. {
  479. typedef Scalar type;
  480. };
  481. template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y);
  482. template<typename Scalar> inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random();
  483. template<typename Scalar>
  484. struct random_default_impl<Scalar, false, false>
  485. {
  486. static inline Scalar run(const Scalar& x, const Scalar& y)
  487. {
  488. return x + (y-x) * Scalar(std::rand()) / Scalar(RAND_MAX);
  489. }
  490. static inline Scalar run()
  491. {
  492. return run(Scalar(NumTraits<Scalar>::IsSigned ? -1 : 0), Scalar(1));
  493. }
  494. };
  495. enum {
  496. meta_floor_log2_terminate,
  497. meta_floor_log2_move_up,
  498. meta_floor_log2_move_down,
  499. meta_floor_log2_bogus
  500. };
  501. template<unsigned int n, int lower, int upper> struct meta_floor_log2_selector
  502. {
  503. enum { middle = (lower + upper) / 2,
  504. value = (upper <= lower + 1) ? int(meta_floor_log2_terminate)
  505. : (n < (1 << middle)) ? int(meta_floor_log2_move_down)
  506. : (n==0) ? int(meta_floor_log2_bogus)
  507. : int(meta_floor_log2_move_up)
  508. };
  509. };
  510. template<unsigned int n,
  511. int lower = 0,
  512. int upper = sizeof(unsigned int) * CHAR_BIT - 1,
  513. int selector = meta_floor_log2_selector<n, lower, upper>::value>
  514. struct meta_floor_log2 {};
  515. template<unsigned int n, int lower, int upper>
  516. struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_down>
  517. {
  518. enum { value = meta_floor_log2<n, lower, meta_floor_log2_selector<n, lower, upper>::middle>::value };
  519. };
  520. template<unsigned int n, int lower, int upper>
  521. struct meta_floor_log2<n, lower, upper, meta_floor_log2_move_up>
  522. {
  523. enum { value = meta_floor_log2<n, meta_floor_log2_selector<n, lower, upper>::middle, upper>::value };
  524. };
  525. template<unsigned int n, int lower, int upper>
  526. struct meta_floor_log2<n, lower, upper, meta_floor_log2_terminate>
  527. {
  528. enum { value = (n >= ((unsigned int)(1) << (lower+1))) ? lower+1 : lower };
  529. };
  530. template<unsigned int n, int lower, int upper>
  531. struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus>
  532. {
  533. // no value, error at compile time
  534. };
  535. template<typename Scalar>
  536. struct random_default_impl<Scalar, false, true>
  537. {
  538. static inline Scalar run(const Scalar& x, const Scalar& y)
  539. {
  540. if (y <= x)
  541. return x;
  542. // ScalarU is the unsigned counterpart of Scalar, possibly Scalar itself.
  543. typedef typename make_unsigned<Scalar>::type ScalarU;
  544. // ScalarX is the widest of ScalarU and unsigned int.
  545. // We'll deal only with ScalarX and unsigned int below thus avoiding signed
  546. // types and arithmetic and signed overflows (which are undefined behavior).
  547. typedef typename conditional<(ScalarU(-1) > unsigned(-1)), ScalarU, unsigned>::type ScalarX;
  548. // The following difference doesn't overflow, provided our integer types are two's
  549. // complement and have the same number of padding bits in signed and unsigned variants.
  550. // This is the case in most modern implementations of C++.
  551. ScalarX range = ScalarX(y) - ScalarX(x);
  552. ScalarX offset = 0;
  553. ScalarX divisor = 1;
  554. ScalarX multiplier = 1;
  555. const unsigned rand_max = RAND_MAX;
  556. if (range <= rand_max) divisor = (rand_max + 1) / (range + 1);
  557. else multiplier = 1 + range / (rand_max + 1);
  558. // Rejection sampling.
  559. do {
  560. offset = (unsigned(std::rand()) * multiplier) / divisor;
  561. } while (offset > range);
  562. return Scalar(ScalarX(x) + offset);
  563. }
  564. static inline Scalar run()
  565. {
  566. #ifdef EIGEN_MAKING_DOCS
  567. return run(Scalar(NumTraits<Scalar>::IsSigned ? -10 : 0), Scalar(10));
  568. #else
  569. enum { rand_bits = meta_floor_log2<(unsigned int)(RAND_MAX)+1>::value,
  570. scalar_bits = sizeof(Scalar) * CHAR_BIT,
  571. shift = EIGEN_PLAIN_ENUM_MAX(0, int(rand_bits) - int(scalar_bits)),
  572. offset = NumTraits<Scalar>::IsSigned ? (1 << (EIGEN_PLAIN_ENUM_MIN(rand_bits,scalar_bits)-1)) : 0
  573. };
  574. return Scalar((std::rand() >> shift) - offset);
  575. #endif
  576. }
  577. };
  578. template<typename Scalar>
  579. struct random_default_impl<Scalar, true, false>
  580. {
  581. static inline Scalar run(const Scalar& x, const Scalar& y)
  582. {
  583. return Scalar(random(x.real(), y.real()),
  584. random(x.imag(), y.imag()));
  585. }
  586. static inline Scalar run()
  587. {
  588. typedef typename NumTraits<Scalar>::Real RealScalar;
  589. return Scalar(random<RealScalar>(), random<RealScalar>());
  590. }
  591. };
  592. template<typename Scalar>
  593. inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random(const Scalar& x, const Scalar& y)
  594. {
  595. return EIGEN_MATHFUNC_IMPL(random, Scalar)::run(x, y);
  596. }
  597. template<typename Scalar>
  598. inline EIGEN_MATHFUNC_RETVAL(random, Scalar) random()
  599. {
  600. return EIGEN_MATHFUNC_IMPL(random, Scalar)::run();
  601. }
  602. // Implementatin of is* functions
  603. // std::is* do not work with fast-math and gcc, std::is* are available on MSVC 2013 and newer, as well as in clang.
  604. #if (EIGEN_HAS_CXX11_MATH && !(EIGEN_COMP_GNUC_STRICT && __FINITE_MATH_ONLY__)) || (EIGEN_COMP_MSVC>=1800) || (EIGEN_COMP_CLANG)
  605. #define EIGEN_USE_STD_FPCLASSIFY 1
  606. #else
  607. #define EIGEN_USE_STD_FPCLASSIFY 0
  608. #endif
  609. template<typename T>
  610. EIGEN_DEVICE_FUNC
  611. typename internal::enable_if<internal::is_integral<T>::value,bool>::type
  612. isnan_impl(const T&) { return false; }
  613. template<typename T>
  614. EIGEN_DEVICE_FUNC
  615. typename internal::enable_if<internal::is_integral<T>::value,bool>::type
  616. isinf_impl(const T&) { return false; }
  617. template<typename T>
  618. EIGEN_DEVICE_FUNC
  619. typename internal::enable_if<internal::is_integral<T>::value,bool>::type
  620. isfinite_impl(const T&) { return true; }
  621. template<typename T>
  622. EIGEN_DEVICE_FUNC
  623. typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
  624. isfinite_impl(const T& x)
  625. {
  626. #ifdef __CUDA_ARCH__
  627. return (::isfinite)(x);
  628. #elif EIGEN_USE_STD_FPCLASSIFY
  629. using std::isfinite;
  630. return isfinite EIGEN_NOT_A_MACRO (x);
  631. #else
  632. return x<=NumTraits<T>::highest() && x>=NumTraits<T>::lowest();
  633. #endif
  634. }
  635. template<typename T>
  636. EIGEN_DEVICE_FUNC
  637. typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
  638. isinf_impl(const T& x)
  639. {
  640. #ifdef __CUDA_ARCH__
  641. return (::isinf)(x);
  642. #elif EIGEN_USE_STD_FPCLASSIFY
  643. using std::isinf;
  644. return isinf EIGEN_NOT_A_MACRO (x);
  645. #else
  646. return x>NumTraits<T>::highest() || x<NumTraits<T>::lowest();
  647. #endif
  648. }
  649. template<typename T>
  650. EIGEN_DEVICE_FUNC
  651. typename internal::enable_if<(!internal::is_integral<T>::value)&&(!NumTraits<T>::IsComplex),bool>::type
  652. isnan_impl(const T& x)
  653. {
  654. #ifdef __CUDA_ARCH__
  655. return (::isnan)(x);
  656. #elif EIGEN_USE_STD_FPCLASSIFY
  657. using std::isnan;
  658. return isnan EIGEN_NOT_A_MACRO (x);
  659. #else
  660. return x != x;
  661. #endif
  662. }
  663. #if (!EIGEN_USE_STD_FPCLASSIFY)
  664. #if EIGEN_COMP_MSVC
  665. template<typename T> EIGEN_DEVICE_FUNC bool isinf_msvc_helper(T x)
  666. {
  667. return _fpclass(x)==_FPCLASS_NINF || _fpclass(x)==_FPCLASS_PINF;
  668. }
  669. //MSVC defines a _isnan builtin function, but for double only
  670. EIGEN_DEVICE_FUNC inline bool isnan_impl(const long double& x) { return _isnan(x)!=0; }
  671. EIGEN_DEVICE_FUNC inline bool isnan_impl(const double& x) { return _isnan(x)!=0; }
  672. EIGEN_DEVICE_FUNC inline bool isnan_impl(const float& x) { return _isnan(x)!=0; }
  673. EIGEN_DEVICE_FUNC inline bool isinf_impl(const long double& x) { return isinf_msvc_helper(x); }
  674. EIGEN_DEVICE_FUNC inline bool isinf_impl(const double& x) { return isinf_msvc_helper(x); }
  675. EIGEN_DEVICE_FUNC inline bool isinf_impl(const float& x) { return isinf_msvc_helper(x); }
  676. #elif (defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ && EIGEN_COMP_GNUC)
  677. #if EIGEN_GNUC_AT_LEAST(5,0)
  678. #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC inline __attribute__((optimize("no-finite-math-only")))
  679. #else
  680. // NOTE the inline qualifier and noinline attribute are both needed: the former is to avoid linking issue (duplicate symbol),
  681. // while the second prevent too aggressive optimizations in fast-math mode:
  682. #define EIGEN_TMP_NOOPT_ATTRIB EIGEN_DEVICE_FUNC inline __attribute__((noinline,optimize("no-finite-math-only")))
  683. #endif
  684. template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const long double& x) { return __builtin_isnan(x); }
  685. template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const double& x) { return __builtin_isnan(x); }
  686. template<> EIGEN_TMP_NOOPT_ATTRIB bool isnan_impl(const float& x) { return __builtin_isnan(x); }
  687. template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const double& x) { return __builtin_isinf(x); }
  688. template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const float& x) { return __builtin_isinf(x); }
  689. template<> EIGEN_TMP_NOOPT_ATTRIB bool isinf_impl(const long double& x) { return __builtin_isinf(x); }
  690. #undef EIGEN_TMP_NOOPT_ATTRIB
  691. #endif
  692. #endif
  693. // The following overload are defined at the end of this file
  694. template<typename T> EIGEN_DEVICE_FUNC bool isfinite_impl(const std::complex<T>& x);
  695. template<typename T> EIGEN_DEVICE_FUNC bool isnan_impl(const std::complex<T>& x);
  696. template<typename T> EIGEN_DEVICE_FUNC bool isinf_impl(const std::complex<T>& x);
  697. template<typename T> T generic_fast_tanh_float(const T& a_x);
  698. } // end namespace internal
  699. /****************************************************************************
  700. * Generic math functions *
  701. ****************************************************************************/
  702. namespace numext {
  703. #ifndef __CUDA_ARCH__
  704. template<typename T>
  705. EIGEN_DEVICE_FUNC
  706. EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
  707. {
  708. EIGEN_USING_STD_MATH(min);
  709. return min EIGEN_NOT_A_MACRO (x,y);
  710. }
  711. template<typename T>
  712. EIGEN_DEVICE_FUNC
  713. EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
  714. {
  715. EIGEN_USING_STD_MATH(max);
  716. return max EIGEN_NOT_A_MACRO (x,y);
  717. }
  718. #else
  719. template<typename T>
  720. EIGEN_DEVICE_FUNC
  721. EIGEN_ALWAYS_INLINE T mini(const T& x, const T& y)
  722. {
  723. return y < x ? y : x;
  724. }
  725. template<>
  726. EIGEN_DEVICE_FUNC
  727. EIGEN_ALWAYS_INLINE float mini(const float& x, const float& y)
  728. {
  729. return fminf(x, y);
  730. }
  731. template<typename T>
  732. EIGEN_DEVICE_FUNC
  733. EIGEN_ALWAYS_INLINE T maxi(const T& x, const T& y)
  734. {
  735. return x < y ? y : x;
  736. }
  737. template<>
  738. EIGEN_DEVICE_FUNC
  739. EIGEN_ALWAYS_INLINE float maxi(const float& x, const float& y)
  740. {
  741. return fmaxf(x, y);
  742. }
  743. #endif
  744. template<typename Scalar>
  745. EIGEN_DEVICE_FUNC
  746. inline EIGEN_MATHFUNC_RETVAL(real, Scalar) real(const Scalar& x)
  747. {
  748. return EIGEN_MATHFUNC_IMPL(real, Scalar)::run(x);
  749. }
  750. template<typename Scalar>
  751. EIGEN_DEVICE_FUNC
  752. inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) >::type real_ref(const Scalar& x)
  753. {
  754. return internal::real_ref_impl<Scalar>::run(x);
  755. }
  756. template<typename Scalar>
  757. EIGEN_DEVICE_FUNC
  758. inline EIGEN_MATHFUNC_RETVAL(real_ref, Scalar) real_ref(Scalar& x)
  759. {
  760. return EIGEN_MATHFUNC_IMPL(real_ref, Scalar)::run(x);
  761. }
  762. template<typename Scalar>
  763. EIGEN_DEVICE_FUNC
  764. inline EIGEN_MATHFUNC_RETVAL(imag, Scalar) imag(const Scalar& x)
  765. {
  766. return EIGEN_MATHFUNC_IMPL(imag, Scalar)::run(x);
  767. }
  768. template<typename Scalar>
  769. EIGEN_DEVICE_FUNC
  770. inline EIGEN_MATHFUNC_RETVAL(arg, Scalar) arg(const Scalar& x)
  771. {
  772. return EIGEN_MATHFUNC_IMPL(arg, Scalar)::run(x);
  773. }
  774. template<typename Scalar>
  775. EIGEN_DEVICE_FUNC
  776. inline typename internal::add_const_on_value_type< EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) >::type imag_ref(const Scalar& x)
  777. {
  778. return internal::imag_ref_impl<Scalar>::run(x);
  779. }
  780. template<typename Scalar>
  781. EIGEN_DEVICE_FUNC
  782. inline EIGEN_MATHFUNC_RETVAL(imag_ref, Scalar) imag_ref(Scalar& x)
  783. {
  784. return EIGEN_MATHFUNC_IMPL(imag_ref, Scalar)::run(x);
  785. }
  786. template<typename Scalar>
  787. EIGEN_DEVICE_FUNC
  788. inline EIGEN_MATHFUNC_RETVAL(conj, Scalar) conj(const Scalar& x)
  789. {
  790. return EIGEN_MATHFUNC_IMPL(conj, Scalar)::run(x);
  791. }
  792. template<typename Scalar>
  793. EIGEN_DEVICE_FUNC
  794. inline EIGEN_MATHFUNC_RETVAL(abs2, Scalar) abs2(const Scalar& x)
  795. {
  796. return EIGEN_MATHFUNC_IMPL(abs2, Scalar)::run(x);
  797. }
  798. EIGEN_DEVICE_FUNC
  799. inline bool abs2(bool x) { return x; }
  800. template<typename Scalar>
  801. EIGEN_DEVICE_FUNC
  802. inline EIGEN_MATHFUNC_RETVAL(norm1, Scalar) norm1(const Scalar& x)
  803. {
  804. return EIGEN_MATHFUNC_IMPL(norm1, Scalar)::run(x);
  805. }
  806. template<typename Scalar>
  807. EIGEN_DEVICE_FUNC
  808. inline EIGEN_MATHFUNC_RETVAL(hypot, Scalar) hypot(const Scalar& x, const Scalar& y)
  809. {
  810. return EIGEN_MATHFUNC_IMPL(hypot, Scalar)::run(x, y);
  811. }
  812. template<typename Scalar>
  813. EIGEN_DEVICE_FUNC
  814. inline EIGEN_MATHFUNC_RETVAL(log1p, Scalar) log1p(const Scalar& x)
  815. {
  816. return EIGEN_MATHFUNC_IMPL(log1p, Scalar)::run(x);
  817. }
  818. #ifdef __CUDACC__
  819. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  820. float log1p(const float &x) { return ::log1pf(x); }
  821. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  822. double log1p(const double &x) { return ::log1p(x); }
  823. #endif
  824. template<typename ScalarX,typename ScalarY>
  825. EIGEN_DEVICE_FUNC
  826. inline typename internal::pow_impl<ScalarX,ScalarY>::result_type pow(const ScalarX& x, const ScalarY& y)
  827. {
  828. return internal::pow_impl<ScalarX,ScalarY>::run(x, y);
  829. }
  830. template<typename T> EIGEN_DEVICE_FUNC bool (isnan) (const T &x) { return internal::isnan_impl(x); }
  831. template<typename T> EIGEN_DEVICE_FUNC bool (isinf) (const T &x) { return internal::isinf_impl(x); }
  832. template<typename T> EIGEN_DEVICE_FUNC bool (isfinite)(const T &x) { return internal::isfinite_impl(x); }
  833. template<typename Scalar>
  834. EIGEN_DEVICE_FUNC
  835. inline EIGEN_MATHFUNC_RETVAL(round, Scalar) round(const Scalar& x)
  836. {
  837. return EIGEN_MATHFUNC_IMPL(round, Scalar)::run(x);
  838. }
  839. template<typename T>
  840. EIGEN_DEVICE_FUNC
  841. T (floor)(const T& x)
  842. {
  843. EIGEN_USING_STD_MATH(floor);
  844. return floor(x);
  845. }
  846. #ifdef __CUDACC__
  847. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  848. float floor(const float &x) { return ::floorf(x); }
  849. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  850. double floor(const double &x) { return ::floor(x); }
  851. #endif
  852. template<typename T>
  853. EIGEN_DEVICE_FUNC
  854. T (ceil)(const T& x)
  855. {
  856. EIGEN_USING_STD_MATH(ceil);
  857. return ceil(x);
  858. }
  859. #ifdef __CUDACC__
  860. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  861. float ceil(const float &x) { return ::ceilf(x); }
  862. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  863. double ceil(const double &x) { return ::ceil(x); }
  864. #endif
  865. /** Log base 2 for 32 bits positive integers.
  866. * Conveniently returns 0 for x==0. */
  867. inline int log2(int x)
  868. {
  869. eigen_assert(x>=0);
  870. unsigned int v(x);
  871. static const int table[32] = { 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 };
  872. v |= v >> 1;
  873. v |= v >> 2;
  874. v |= v >> 4;
  875. v |= v >> 8;
  876. v |= v >> 16;
  877. return table[(v * 0x07C4ACDDU) >> 27];
  878. }
  879. /** \returns the square root of \a x.
  880. *
  881. * It is essentially equivalent to
  882. * \code using std::sqrt; return sqrt(x); \endcode
  883. * but slightly faster for float/double and some compilers (e.g., gcc), thanks to
  884. * specializations when SSE is enabled.
  885. *
  886. * It's usage is justified in performance critical functions, like norm/normalize.
  887. */
  888. template<typename T>
  889. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  890. T sqrt(const T &x)
  891. {
  892. EIGEN_USING_STD_MATH(sqrt);
  893. return sqrt(x);
  894. }
  895. template<typename T>
  896. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  897. T log(const T &x) {
  898. EIGEN_USING_STD_MATH(log);
  899. return log(x);
  900. }
  901. #ifdef __CUDACC__
  902. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  903. float log(const float &x) { return ::logf(x); }
  904. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  905. double log(const double &x) { return ::log(x); }
  906. #endif
  907. template<typename T>
  908. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  909. typename internal::enable_if<NumTraits<T>::IsSigned || NumTraits<T>::IsComplex,typename NumTraits<T>::Real>::type
  910. abs(const T &x) {
  911. EIGEN_USING_STD_MATH(abs);
  912. return abs(x);
  913. }
  914. template<typename T>
  915. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  916. typename internal::enable_if<!(NumTraits<T>::IsSigned || NumTraits<T>::IsComplex),typename NumTraits<T>::Real>::type
  917. abs(const T &x) {
  918. return x;
  919. }
  920. #if defined(__SYCL_DEVICE_ONLY__)
  921. EIGEN_ALWAYS_INLINE float abs(float x) { return cl::sycl::fabs(x); }
  922. EIGEN_ALWAYS_INLINE double abs(double x) { return cl::sycl::fabs(x); }
  923. #endif // defined(__SYCL_DEVICE_ONLY__)
  924. #ifdef __CUDACC__
  925. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  926. float abs(const float &x) { return ::fabsf(x); }
  927. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  928. double abs(const double &x) { return ::fabs(x); }
  929. template <> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  930. float abs(const std::complex<float>& x) {
  931. return ::hypotf(x.real(), x.imag());
  932. }
  933. template <> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  934. double abs(const std::complex<double>& x) {
  935. return ::hypot(x.real(), x.imag());
  936. }
  937. #endif
  938. template<typename T>
  939. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  940. T exp(const T &x) {
  941. EIGEN_USING_STD_MATH(exp);
  942. return exp(x);
  943. }
  944. #ifdef __CUDACC__
  945. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  946. float exp(const float &x) { return ::expf(x); }
  947. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  948. double exp(const double &x) { return ::exp(x); }
  949. #endif
  950. template<typename T>
  951. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  952. T cos(const T &x) {
  953. EIGEN_USING_STD_MATH(cos);
  954. return cos(x);
  955. }
  956. #ifdef __CUDACC__
  957. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  958. float cos(const float &x) { return ::cosf(x); }
  959. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  960. double cos(const double &x) { return ::cos(x); }
  961. #endif
  962. template<typename T>
  963. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  964. T sin(const T &x) {
  965. EIGEN_USING_STD_MATH(sin);
  966. return sin(x);
  967. }
  968. #ifdef __CUDACC__
  969. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  970. float sin(const float &x) { return ::sinf(x); }
  971. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  972. double sin(const double &x) { return ::sin(x); }
  973. #endif
  974. template<typename T>
  975. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  976. T tan(const T &x) {
  977. EIGEN_USING_STD_MATH(tan);
  978. return tan(x);
  979. }
  980. #ifdef __CUDACC__
  981. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  982. float tan(const float &x) { return ::tanf(x); }
  983. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  984. double tan(const double &x) { return ::tan(x); }
  985. #endif
  986. template<typename T>
  987. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  988. T acos(const T &x) {
  989. EIGEN_USING_STD_MATH(acos);
  990. return acos(x);
  991. }
  992. #ifdef __CUDACC__
  993. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  994. float acos(const float &x) { return ::acosf(x); }
  995. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  996. double acos(const double &x) { return ::acos(x); }
  997. #endif
  998. template<typename T>
  999. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1000. T asin(const T &x) {
  1001. EIGEN_USING_STD_MATH(asin);
  1002. return asin(x);
  1003. }
  1004. #ifdef __CUDACC__
  1005. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1006. float asin(const float &x) { return ::asinf(x); }
  1007. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1008. double asin(const double &x) { return ::asin(x); }
  1009. #endif
  1010. template<typename T>
  1011. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1012. T atan(const T &x) {
  1013. EIGEN_USING_STD_MATH(atan);
  1014. return atan(x);
  1015. }
  1016. #ifdef __CUDACC__
  1017. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1018. float atan(const float &x) { return ::atanf(x); }
  1019. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1020. double atan(const double &x) { return ::atan(x); }
  1021. #endif
  1022. template<typename T>
  1023. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1024. T cosh(const T &x) {
  1025. EIGEN_USING_STD_MATH(cosh);
  1026. return cosh(x);
  1027. }
  1028. #ifdef __CUDACC__
  1029. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1030. float cosh(const float &x) { return ::coshf(x); }
  1031. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1032. double cosh(const double &x) { return ::cosh(x); }
  1033. #endif
  1034. template<typename T>
  1035. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1036. T sinh(const T &x) {
  1037. EIGEN_USING_STD_MATH(sinh);
  1038. return sinh(x);
  1039. }
  1040. #ifdef __CUDACC__
  1041. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1042. float sinh(const float &x) { return ::sinhf(x); }
  1043. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1044. double sinh(const double &x) { return ::sinh(x); }
  1045. #endif
  1046. template<typename T>
  1047. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1048. T tanh(const T &x) {
  1049. EIGEN_USING_STD_MATH(tanh);
  1050. return tanh(x);
  1051. }
  1052. #if (!defined(__CUDACC__)) && EIGEN_FAST_MATH
  1053. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1054. float tanh(float x) { return internal::generic_fast_tanh_float(x); }
  1055. #endif
  1056. #ifdef __CUDACC__
  1057. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1058. float tanh(const float &x) { return ::tanhf(x); }
  1059. template<> EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1060. double tanh(const double &x) { return ::tanh(x); }
  1061. #endif
  1062. template <typename T>
  1063. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1064. T fmod(const T& a, const T& b) {
  1065. EIGEN_USING_STD_MATH(fmod);
  1066. return fmod(a, b);
  1067. }
  1068. #ifdef __CUDACC__
  1069. template <>
  1070. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1071. float fmod(const float& a, const float& b) {
  1072. return ::fmodf(a, b);
  1073. }
  1074. template <>
  1075. EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE
  1076. double fmod(const double& a, const double& b) {
  1077. return ::fmod(a, b);
  1078. }
  1079. #endif
  1080. } // end namespace numext
  1081. namespace internal {
  1082. template<typename T>
  1083. EIGEN_DEVICE_FUNC bool isfinite_impl(const std::complex<T>& x)
  1084. {
  1085. return (numext::isfinite)(numext::real(x)) && (numext::isfinite)(numext::imag(x));
  1086. }
  1087. template<typename T>
  1088. EIGEN_DEVICE_FUNC bool isnan_impl(const std::complex<T>& x)
  1089. {
  1090. return (numext::isnan)(numext::real(x)) || (numext::isnan)(numext::imag(x));
  1091. }
  1092. template<typename T>
  1093. EIGEN_DEVICE_FUNC bool isinf_impl(const std::complex<T>& x)
  1094. {
  1095. return ((numext::isinf)(numext::real(x)) || (numext::isinf)(numext::imag(x))) && (!(numext::isnan)(x));
  1096. }
  1097. /****************************************************************************
  1098. * Implementation of fuzzy comparisons *
  1099. ****************************************************************************/
  1100. template<typename Scalar,
  1101. bool IsComplex,
  1102. bool IsInteger>
  1103. struct scalar_fuzzy_default_impl {};
  1104. template<typename Scalar>
  1105. struct scalar_fuzzy_default_impl<Scalar, false, false>
  1106. {
  1107. typedef typename NumTraits<Scalar>::Real RealScalar;
  1108. template<typename OtherScalar> EIGEN_DEVICE_FUNC
  1109. static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
  1110. {
  1111. return numext::abs(x) <= numext::abs(y) * prec;
  1112. }
  1113. EIGEN_DEVICE_FUNC
  1114. static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
  1115. {
  1116. return numext::abs(x - y) <= numext::mini(numext::abs(x), numext::abs(y)) * prec;
  1117. }
  1118. EIGEN_DEVICE_FUNC
  1119. static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar& prec)
  1120. {
  1121. return x <= y || isApprox(x, y, prec);
  1122. }
  1123. };
  1124. template<typename Scalar>
  1125. struct scalar_fuzzy_default_impl<Scalar, false, true>
  1126. {
  1127. typedef typename NumTraits<Scalar>::Real RealScalar;
  1128. template<typename OtherScalar> EIGEN_DEVICE_FUNC
  1129. static inline bool isMuchSmallerThan(const Scalar& x, const Scalar&, const RealScalar&)
  1130. {
  1131. return x == Scalar(0);
  1132. }
  1133. EIGEN_DEVICE_FUNC
  1134. static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar&)
  1135. {
  1136. return x == y;
  1137. }
  1138. EIGEN_DEVICE_FUNC
  1139. static inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y, const RealScalar&)
  1140. {
  1141. return x <= y;
  1142. }
  1143. };
  1144. template<typename Scalar>
  1145. struct scalar_fuzzy_default_impl<Scalar, true, false>
  1146. {
  1147. typedef typename NumTraits<Scalar>::Real RealScalar;
  1148. template<typename OtherScalar> EIGEN_DEVICE_FUNC
  1149. static inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y, const RealScalar& prec)
  1150. {
  1151. return numext::abs2(x) <= numext::abs2(y) * prec * prec;
  1152. }
  1153. EIGEN_DEVICE_FUNC
  1154. static inline bool isApprox(const Scalar& x, const Scalar& y, const RealScalar& prec)
  1155. {
  1156. return numext::abs2(x - y) <= numext::mini(numext::abs2(x), numext::abs2(y)) * prec * prec;
  1157. }
  1158. };
  1159. template<typename Scalar>
  1160. struct scalar_fuzzy_impl : scalar_fuzzy_default_impl<Scalar, NumTraits<Scalar>::IsComplex, NumTraits<Scalar>::IsInteger> {};
  1161. template<typename Scalar, typename OtherScalar> EIGEN_DEVICE_FUNC
  1162. inline bool isMuchSmallerThan(const Scalar& x, const OtherScalar& y,
  1163. const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
  1164. {
  1165. return scalar_fuzzy_impl<Scalar>::template isMuchSmallerThan<OtherScalar>(x, y, precision);
  1166. }
  1167. template<typename Scalar> EIGEN_DEVICE_FUNC
  1168. inline bool isApprox(const Scalar& x, const Scalar& y,
  1169. const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
  1170. {
  1171. return scalar_fuzzy_impl<Scalar>::isApprox(x, y, precision);
  1172. }
  1173. template<typename Scalar> EIGEN_DEVICE_FUNC
  1174. inline bool isApproxOrLessThan(const Scalar& x, const Scalar& y,
  1175. const typename NumTraits<Scalar>::Real &precision = NumTraits<Scalar>::dummy_precision())
  1176. {
  1177. return scalar_fuzzy_impl<Scalar>::isApproxOrLessThan(x, y, precision);
  1178. }
  1179. /******************************************
  1180. *** The special case of the bool type ***
  1181. ******************************************/
  1182. template<> struct random_impl<bool>
  1183. {
  1184. static inline bool run()
  1185. {
  1186. return random<int>(0,1)==0 ? false : true;
  1187. }
  1188. };
  1189. template<> struct scalar_fuzzy_impl<bool>
  1190. {
  1191. typedef bool RealScalar;
  1192. template<typename OtherScalar> EIGEN_DEVICE_FUNC
  1193. static inline bool isMuchSmallerThan(const bool& x, const bool&, const bool&)
  1194. {
  1195. return !x;
  1196. }
  1197. EIGEN_DEVICE_FUNC
  1198. static inline bool isApprox(bool x, bool y, bool)
  1199. {
  1200. return x == y;
  1201. }
  1202. EIGEN_DEVICE_FUNC
  1203. static inline bool isApproxOrLessThan(const bool& x, const bool& y, const bool&)
  1204. {
  1205. return (!x) || y;
  1206. }
  1207. };
  1208. } // end namespace internal
  1209. } // end namespace Eigen
  1210. #endif // EIGEN_MATHFUNCTIONS_H