jet_test.cc 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361
  1. // Ceres Solver - A fast non-linear least squares minimizer
  2. // Copyright 2023 Google Inc. All rights reserved.
  3. // http://ceres-solver.org/
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions are met:
  7. //
  8. // * Redistributions of source code must retain the above copyright notice,
  9. // this list of conditions and the following disclaimer.
  10. // * Redistributions in binary form must reproduce the above copyright notice,
  11. // this list of conditions and the following disclaimer in the documentation
  12. // and/or other materials provided with the distribution.
  13. // * Neither the name of Google Inc. nor the names of its contributors may be
  14. // used to endorse or promote products derived from this software without
  15. // specific prior written permission.
  16. //
  17. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  18. // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  19. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  20. // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
  21. // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  22. // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  23. // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  24. // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  25. // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  26. // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  27. // POSSIBILITY OF SUCH DAMAGE.
  28. //
  29. // Author: keir@google.com (Keir Mierle)
  30. #include "ceres/jet.h"
  31. #include <Eigen/Dense>
  32. #include <algorithm>
  33. #include <cfenv>
  34. #include <cmath>
  35. #include "ceres/stringprintf.h"
  36. #include "ceres/test_util.h"
  37. #include "glog/logging.h"
  38. #include "gmock/gmock.h"
  39. #include "gtest/gtest.h"
  40. // The floating-point environment access and modification is only meaningful
  41. // with the following pragma.
  42. #ifdef _MSC_VER
  43. #pragma float_control(precise, on, push)
  44. #pragma fenv_access(on)
  45. #elif !(defined(__ARM_ARCH) && __ARM_ARCH >= 8) && !defined(__MINGW32__)
  46. // NOTE: FENV_ACCESS cannot be set to ON when targeting arm(v8) and MinGW
  47. #pragma STDC FENV_ACCESS ON
  48. #else
  49. #define CERES_NO_FENV_ACCESS
  50. #endif
  51. namespace ceres::internal {
  52. namespace {
  53. constexpr double kE = 2.71828182845904523536;
  54. using J = Jet<double, 2>;
  55. // Don't care about the dual part for scalar part categorization and comparison
  56. // tests
  57. template <typename T>
  58. using J0 = Jet<T, 0>;
  59. using J0d = J0<double>;
  60. // Convenient shorthand for making a jet.
  61. J MakeJet(double a, double v0, double v1) {
  62. J z;
  63. z.a = a;
  64. z.v[0] = v0;
  65. z.v[1] = v1;
  66. return z;
  67. }
  68. double const kTolerance = 1e-13;
  69. // Stores the floating-point environment containing active floating-point
  70. // exceptions, rounding mode, etc., and restores it upon destruction.
  71. //
  72. // Useful for avoiding side-effects.
  73. class Fenv {
  74. public:
  75. Fenv() { std::fegetenv(&e); }
  76. ~Fenv() { std::fesetenv(&e); }
  77. Fenv(const Fenv&) = delete;
  78. Fenv& operator=(const Fenv&) = delete;
  79. private:
  80. std::fenv_t e;
  81. };
  82. bool AreAlmostEqual(double x, double y, double max_abs_relative_difference) {
  83. if (std::isnan(x) && std::isnan(y)) {
  84. return true;
  85. }
  86. if (std::isinf(x) && std::isinf(y)) {
  87. return (std::signbit(x) == std::signbit(y));
  88. }
  89. Fenv env; // Do not leak floating-point exceptions to the caller
  90. double absolute_difference = std::abs(x - y);
  91. double relative_difference =
  92. absolute_difference / std::max(std::abs(x), std::abs(y));
  93. if (std::fpclassify(x) == FP_ZERO || std::fpclassify(y) == FP_ZERO) {
  94. // If x or y is exactly zero, then relative difference doesn't have any
  95. // meaning. Take the absolute difference instead.
  96. relative_difference = absolute_difference;
  97. }
  98. return std::islessequal(relative_difference, max_abs_relative_difference);
  99. }
  100. MATCHER_P(IsAlmostEqualTo, y, "") {
  101. const bool result = (AreAlmostEqual(arg.a, y.a, kTolerance) &&
  102. AreAlmostEqual(arg.v[0], y.v[0], kTolerance) &&
  103. AreAlmostEqual(arg.v[1], y.v[1], kTolerance));
  104. if (!result) {
  105. *result_listener << "\nexpected - actual : " << y - arg;
  106. }
  107. return result;
  108. }
  109. const double kStep = 1e-8;
  110. const double kNumericalTolerance = 1e-6; // Numeric derivation is quite inexact
  111. // Differentiate using Jet and confirm results with numerical derivation.
  112. template <typename Function>
  113. void NumericalTest(const char* name, const Function& f, const double x) {
  114. const double exact_dx = f(MakeJet(x, 1.0, 0.0)).v[0];
  115. const double estimated_dx =
  116. (f(J(x + kStep)).a - f(J(x - kStep)).a) / (2.0 * kStep);
  117. VLOG(1) << name << "(" << x << "), exact dx: " << exact_dx
  118. << ", estimated dx: " << estimated_dx;
  119. ExpectClose(exact_dx, estimated_dx, kNumericalTolerance);
  120. }
  121. // Same as NumericalTest, but given a function taking two arguments.
  122. template <typename Function>
  123. void NumericalTest2(const char* name,
  124. const Function& f,
  125. const double x,
  126. const double y) {
  127. const J exact_delta = f(MakeJet(x, 1.0, 0.0), MakeJet(y, 0.0, 1.0));
  128. const double exact_dx = exact_delta.v[0];
  129. const double exact_dy = exact_delta.v[1];
  130. // Sanity check - these should be equivalent:
  131. EXPECT_EQ(exact_dx, f(MakeJet(x, 1.0, 0.0), MakeJet(y, 0.0, 0.0)).v[0]);
  132. EXPECT_EQ(exact_dx, f(MakeJet(x, 0.0, 1.0), MakeJet(y, 0.0, 0.0)).v[1]);
  133. EXPECT_EQ(exact_dy, f(MakeJet(x, 0.0, 0.0), MakeJet(y, 1.0, 0.0)).v[0]);
  134. EXPECT_EQ(exact_dy, f(MakeJet(x, 0.0, 0.0), MakeJet(y, 0.0, 1.0)).v[1]);
  135. const double estimated_dx =
  136. (f(J(x + kStep), J(y)).a - f(J(x - kStep), J(y)).a) / (2.0 * kStep);
  137. const double estimated_dy =
  138. (f(J(x), J(y + kStep)).a - f(J(x), J(y - kStep)).a) / (2.0 * kStep);
  139. VLOG(1) << name << "(" << x << ", " << y << "), exact dx: " << exact_dx
  140. << ", estimated dx: " << estimated_dx;
  141. ExpectClose(exact_dx, estimated_dx, kNumericalTolerance);
  142. VLOG(1) << name << "(" << x << ", " << y << "), exact dy: " << exact_dy
  143. << ", estimated dy: " << estimated_dy;
  144. ExpectClose(exact_dy, estimated_dy, kNumericalTolerance);
  145. }
  146. } // namespace
  147. // Pick arbitrary values for x and y.
  148. const J x = MakeJet(2.3, -2.7, 1e-3);
  149. const J y = MakeJet(1.7, 0.5, 1e+2);
  150. const J z = MakeJet(1e-6, 1e-4, 1e-2);
  151. TEST(Jet, Elementary) {
  152. EXPECT_THAT((x * y) / x, IsAlmostEqualTo(y));
  153. EXPECT_THAT(sqrt(x * x), IsAlmostEqualTo(x));
  154. EXPECT_THAT(sqrt(y) * sqrt(y), IsAlmostEqualTo(y));
  155. NumericalTest("sqrt", sqrt<double, 2>, 0.00001);
  156. NumericalTest("sqrt", sqrt<double, 2>, 1.0);
  157. EXPECT_THAT(x + 1.0, IsAlmostEqualTo(1.0 + x));
  158. {
  159. J c = x;
  160. c += 1.0;
  161. EXPECT_THAT(c, IsAlmostEqualTo(1.0 + x));
  162. }
  163. EXPECT_THAT(-(x - 1.0), IsAlmostEqualTo(1.0 - x));
  164. {
  165. J c = x;
  166. c -= 1.0;
  167. EXPECT_THAT(c, IsAlmostEqualTo(x - 1.0));
  168. }
  169. EXPECT_THAT((x * 5.0) / 5.0, IsAlmostEqualTo((x / 5.0) * 5.0));
  170. EXPECT_THAT((x * 5.0) / 5.0, IsAlmostEqualTo(x));
  171. EXPECT_THAT((x / 5.0) * 5.0, IsAlmostEqualTo(x));
  172. {
  173. J c = x;
  174. c /= 5.0;
  175. J d = x;
  176. d *= 5.0;
  177. EXPECT_THAT(c, IsAlmostEqualTo(x / 5.0));
  178. EXPECT_THAT(d, IsAlmostEqualTo(5.0 * x));
  179. }
  180. EXPECT_THAT(1.0 / (y / x), IsAlmostEqualTo(x / y));
  181. }
  182. TEST(Jet, Trigonometric) {
  183. EXPECT_THAT(cos(2.0 * x), IsAlmostEqualTo(cos(x) * cos(x) - sin(x) * sin(x)));
  184. EXPECT_THAT(sin(2.0 * x), IsAlmostEqualTo(2.0 * sin(x) * cos(x)));
  185. EXPECT_THAT(sin(x) * sin(x) + cos(x) * cos(x), IsAlmostEqualTo(J(1.0)));
  186. {
  187. J t = MakeJet(0.7, -0.3, +1.5);
  188. J r = MakeJet(2.3, 0.13, -2.4);
  189. EXPECT_THAT(atan2(r * sin(t), r * cos(t)), IsAlmostEqualTo(t));
  190. }
  191. EXPECT_THAT(sin(x) / cos(x), IsAlmostEqualTo(tan(x)));
  192. EXPECT_THAT(tan(atan(x)), IsAlmostEqualTo(x));
  193. {
  194. J a = MakeJet(0.1, -2.7, 1e-3);
  195. EXPECT_THAT(cos(acos(a)), IsAlmostEqualTo(a));
  196. EXPECT_THAT(acos(cos(a)), IsAlmostEqualTo(a));
  197. J b = MakeJet(0.6, 0.5, 1e+2);
  198. EXPECT_THAT(cos(acos(b)), IsAlmostEqualTo(b));
  199. EXPECT_THAT(acos(cos(b)), IsAlmostEqualTo(b));
  200. }
  201. {
  202. J a = MakeJet(0.1, -2.7, 1e-3);
  203. EXPECT_THAT(sin(asin(a)), IsAlmostEqualTo(a));
  204. EXPECT_THAT(asin(sin(a)), IsAlmostEqualTo(a));
  205. J b = MakeJet(0.4, 0.5, 1e+2);
  206. EXPECT_THAT(sin(asin(b)), IsAlmostEqualTo(b));
  207. EXPECT_THAT(asin(sin(b)), IsAlmostEqualTo(b));
  208. }
  209. }
  210. TEST(Jet, Hyperbolic) {
  211. // cosh(x)*cosh(x) - sinh(x)*sinh(x) = 1
  212. EXPECT_THAT(cosh(x) * cosh(x) - sinh(x) * sinh(x), IsAlmostEqualTo(J(1.0)));
  213. // tanh(x + y) = (tanh(x) + tanh(y)) / (1 + tanh(x) tanh(y))
  214. EXPECT_THAT(
  215. tanh(x + y),
  216. IsAlmostEqualTo((tanh(x) + tanh(y)) / (J(1.0) + tanh(x) * tanh(y))));
  217. }
  218. TEST(Jet, Abs) {
  219. EXPECT_THAT(abs(-x * x), IsAlmostEqualTo(x * x));
  220. EXPECT_THAT(abs(-x), IsAlmostEqualTo(sqrt(x * x)));
  221. {
  222. J a = MakeJet(-std::numeric_limits<double>::quiet_NaN(), 2.0, 4.0);
  223. J b = abs(a);
  224. EXPECT_TRUE(std::signbit(b.v[0]));
  225. EXPECT_TRUE(std::signbit(b.v[1]));
  226. }
  227. }
  228. TEST(Jet, Bessel) {
  229. J zero = J(0.0);
  230. EXPECT_THAT(BesselJ0(zero), IsAlmostEqualTo(J(1.0)));
  231. EXPECT_THAT(BesselJ1(zero), IsAlmostEqualTo(zero));
  232. EXPECT_THAT(BesselJn(2, zero), IsAlmostEqualTo(zero));
  233. EXPECT_THAT(BesselJn(3, zero), IsAlmostEqualTo(zero));
  234. J z = MakeJet(0.1, -2.7, 1e-3);
  235. EXPECT_THAT(BesselJ0(z), IsAlmostEqualTo(BesselJn(0, z)));
  236. EXPECT_THAT(BesselJ1(z), IsAlmostEqualTo(BesselJn(1, z)));
  237. // See formula http://dlmf.nist.gov/10.6.E1
  238. EXPECT_THAT(BesselJ0(z) + BesselJn(2, z),
  239. IsAlmostEqualTo((2.0 / z) * BesselJ1(z)));
  240. }
  241. TEST(Jet, Floor) {
  242. { // floor of a positive number works.
  243. J a = MakeJet(0.1, -2.7, 1e-3);
  244. J b = floor(a);
  245. J expected = MakeJet(floor(a.a), 0.0, 0.0);
  246. EXPECT_EQ(expected, b);
  247. }
  248. { // floor of a negative number works.
  249. J a = MakeJet(-1.1, -2.7, 1e-3);
  250. J b = floor(a);
  251. J expected = MakeJet(floor(a.a), 0.0, 0.0);
  252. EXPECT_EQ(expected, b);
  253. }
  254. { // floor of a positive number works.
  255. J a = MakeJet(10.123, -2.7, 1e-3);
  256. J b = floor(a);
  257. J expected = MakeJet(floor(a.a), 0.0, 0.0);
  258. EXPECT_EQ(expected, b);
  259. }
  260. }
  261. TEST(Jet, Ceil) {
  262. { // ceil of a positive number works.
  263. J a = MakeJet(0.1, -2.7, 1e-3);
  264. J b = ceil(a);
  265. J expected = MakeJet(ceil(a.a), 0.0, 0.0);
  266. EXPECT_EQ(expected, b);
  267. }
  268. { // ceil of a negative number works.
  269. J a = MakeJet(-1.1, -2.7, 1e-3);
  270. J b = ceil(a);
  271. J expected = MakeJet(ceil(a.a), 0.0, 0.0);
  272. EXPECT_EQ(expected, b);
  273. }
  274. { // ceil of a positive number works.
  275. J a = MakeJet(10.123, -2.7, 1e-3);
  276. J b = ceil(a);
  277. J expected = MakeJet(ceil(a.a), 0.0, 0.0);
  278. EXPECT_EQ(expected, b);
  279. }
  280. }
  281. TEST(Jet, Erf) {
  282. { // erf works.
  283. J a = MakeJet(10.123, -2.7, 1e-3);
  284. J b = erf(a);
  285. J expected = MakeJet(erf(a.a), 0.0, 0.0);
  286. EXPECT_EQ(expected, b);
  287. }
  288. NumericalTest("erf", erf<double, 2>, -1.0);
  289. NumericalTest("erf", erf<double, 2>, 1e-5);
  290. NumericalTest("erf", erf<double, 2>, 0.5);
  291. NumericalTest("erf", erf<double, 2>, 100.0);
  292. }
  293. TEST(Jet, Erfc) {
  294. { // erfc works.
  295. J a = MakeJet(10.123, -2.7, 1e-3);
  296. J b = erfc(a);
  297. J expected = MakeJet(erfc(a.a), 0.0, 0.0);
  298. EXPECT_EQ(expected, b);
  299. }
  300. NumericalTest("erfc", erfc<double, 2>, -1.0);
  301. NumericalTest("erfc", erfc<double, 2>, 1e-5);
  302. NumericalTest("erfc", erfc<double, 2>, 0.5);
  303. NumericalTest("erfc", erfc<double, 2>, 100.0);
  304. }
  305. TEST(Jet, Cbrt) {
  306. EXPECT_THAT(cbrt(x * x * x), IsAlmostEqualTo(x));
  307. EXPECT_THAT(cbrt(y) * cbrt(y) * cbrt(y), IsAlmostEqualTo(y));
  308. EXPECT_THAT(cbrt(x), IsAlmostEqualTo(pow(x, 1.0 / 3.0)));
  309. NumericalTest("cbrt", cbrt<double, 2>, -1.0);
  310. NumericalTest("cbrt", cbrt<double, 2>, -1e-5);
  311. NumericalTest("cbrt", cbrt<double, 2>, 1e-5);
  312. NumericalTest("cbrt", cbrt<double, 2>, 1.0);
  313. }
  314. TEST(Jet, Log1p) {
  315. EXPECT_THAT(log1p(expm1(x)), IsAlmostEqualTo(x));
  316. EXPECT_THAT(log1p(x), IsAlmostEqualTo(log(J{1} + x)));
  317. { // log1p(x) does not loose precision for small x
  318. J x = MakeJet(1e-16, 1e-8, 1e-4);
  319. EXPECT_THAT(log1p(x),
  320. IsAlmostEqualTo(MakeJet(9.9999999999999998e-17, 1e-8, 1e-4)));
  321. // log(1 + x) collapses to 0
  322. J v = log(J{1} + x);
  323. EXPECT_TRUE(v.a == 0);
  324. }
  325. }
  326. TEST(Jet, Expm1) {
  327. EXPECT_THAT(expm1(log1p(x)), IsAlmostEqualTo(x));
  328. EXPECT_THAT(expm1(x), IsAlmostEqualTo(exp(x) - 1.0));
  329. { // expm1(x) does not loose precision for small x
  330. J x = MakeJet(9.9999999999999998e-17, 1e-8, 1e-4);
  331. EXPECT_THAT(expm1(x), IsAlmostEqualTo(MakeJet(1e-16, 1e-8, 1e-4)));
  332. // exp(x) - 1 collapses to 0
  333. J v = exp(x) - J{1};
  334. EXPECT_TRUE(v.a == 0);
  335. }
  336. }
  337. TEST(Jet, Exp2) {
  338. EXPECT_THAT(exp2(x), IsAlmostEqualTo(exp(x * log(2.0))));
  339. NumericalTest("exp2", exp2<double, 2>, -1.0);
  340. NumericalTest("exp2", exp2<double, 2>, -1e-5);
  341. NumericalTest("exp2", exp2<double, 2>, -1e-200);
  342. NumericalTest("exp2", exp2<double, 2>, 0.0);
  343. NumericalTest("exp2", exp2<double, 2>, 1e-200);
  344. NumericalTest("exp2", exp2<double, 2>, 1e-5);
  345. NumericalTest("exp2", exp2<double, 2>, 1.0);
  346. }
  347. TEST(Jet, Log) { EXPECT_THAT(log(exp(x)), IsAlmostEqualTo(x)); }
  348. TEST(Jet, Log10) {
  349. EXPECT_THAT(log10(x), IsAlmostEqualTo(log(x) / log(10)));
  350. NumericalTest("log10", log10<double, 2>, 1e-5);
  351. NumericalTest("log10", log10<double, 2>, 1.0);
  352. NumericalTest("log10", log10<double, 2>, 98.76);
  353. }
  354. TEST(Jet, Log2) {
  355. EXPECT_THAT(log2(x), IsAlmostEqualTo(log(x) / log(2)));
  356. NumericalTest("log2", log2<double, 2>, 1e-5);
  357. NumericalTest("log2", log2<double, 2>, 1.0);
  358. NumericalTest("log2", log2<double, 2>, 100.0);
  359. }
  360. TEST(Jet, Norm) {
  361. EXPECT_THAT(norm(x), IsAlmostEqualTo(x * x));
  362. EXPECT_THAT(norm(-x), IsAlmostEqualTo(x * x));
  363. }
  364. TEST(Jet, Pow) {
  365. EXPECT_THAT(pow(x, 1.0), IsAlmostEqualTo(x));
  366. EXPECT_THAT(pow(x, MakeJet(1.0, 0.0, 0.0)), IsAlmostEqualTo(x));
  367. EXPECT_THAT(pow(kE, log(x)), IsAlmostEqualTo(x));
  368. EXPECT_THAT(pow(MakeJet(kE, 0., 0.), log(x)), IsAlmostEqualTo(x));
  369. EXPECT_THAT(pow(x, y),
  370. IsAlmostEqualTo(pow(MakeJet(kE, 0.0, 0.0), y * log(x))));
  371. // Specially cases
  372. // pow(0, y) == 0 for y > 1, with both arguments Jets.
  373. EXPECT_THAT(pow(MakeJet(0, 1, 2), MakeJet(2, 3, 4)),
  374. IsAlmostEqualTo(MakeJet(0, 0, 0)));
  375. // pow(0, y) == 0 for y == 1, with both arguments Jets.
  376. EXPECT_THAT(pow(MakeJet(0, 1, 2), MakeJet(1, 3, 4)),
  377. IsAlmostEqualTo(MakeJet(0, 1, 2)));
  378. // pow(0, <1) is not finite, with both arguments Jets.
  379. {
  380. for (int i = 1; i < 10; i++) {
  381. J a = MakeJet(0, 1, 2);
  382. J b = MakeJet(i * 0.1, 3, 4); // b = 0.1 ... 0.9
  383. J c = pow(a, b);
  384. EXPECT_EQ(c.a, 0.0) << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  385. EXPECT_FALSE(isfinite(c.v[0]))
  386. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  387. EXPECT_FALSE(isfinite(c.v[1]))
  388. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  389. }
  390. for (int i = -10; i < 0; i++) {
  391. J a = MakeJet(0, 1, 2);
  392. J b = MakeJet(i * 0.1, 3, 4); // b = -1,-0.9 ... -0.1
  393. J c = pow(a, b);
  394. EXPECT_FALSE(isfinite(c.a))
  395. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  396. EXPECT_FALSE(isfinite(c.v[0]))
  397. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  398. EXPECT_FALSE(isfinite(c.v[1]))
  399. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  400. }
  401. // The special case of 0^0 = 1 defined by the C standard.
  402. {
  403. J a = MakeJet(0, 1, 2);
  404. J b = MakeJet(0, 3, 4);
  405. J c = pow(a, b);
  406. EXPECT_EQ(c.a, 1.0) << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  407. EXPECT_FALSE(isfinite(c.v[0]))
  408. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  409. EXPECT_FALSE(isfinite(c.v[1]))
  410. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  411. }
  412. }
  413. // pow(<0, b) is correct for integer b.
  414. {
  415. J a = MakeJet(-1.5, 3, 4);
  416. // b integer:
  417. for (int i = -10; i <= 10; i++) {
  418. J b = MakeJet(i, 0, 5);
  419. J c = pow(a, b);
  420. EXPECT_TRUE(AreAlmostEqual(c.a, pow(-1.5, i), kTolerance))
  421. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  422. EXPECT_TRUE(isfinite(c.v[0]))
  423. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  424. EXPECT_FALSE(isfinite(c.v[1]))
  425. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  426. EXPECT_TRUE(
  427. AreAlmostEqual(c.v[0], i * pow(-1.5, i - 1) * 3.0, kTolerance))
  428. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  429. }
  430. }
  431. // pow(<0, b) is correct for noninteger b.
  432. {
  433. J a = MakeJet(-1.5, 3, 4);
  434. J b = MakeJet(-2.5, 0, 5);
  435. J c = pow(a, b);
  436. EXPECT_FALSE(isfinite(c.a))
  437. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  438. EXPECT_FALSE(isfinite(c.v[0]))
  439. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  440. EXPECT_FALSE(isfinite(c.v[1]))
  441. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  442. }
  443. // pow(0,y) == 0 for y == 2, with the second argument a Jet.
  444. EXPECT_THAT(pow(0.0, MakeJet(2, 3, 4)), IsAlmostEqualTo(MakeJet(0, 0, 0)));
  445. // pow(<0,y) is correct for integer y.
  446. {
  447. double a = -1.5;
  448. for (int i = -10; i <= 10; i++) {
  449. J b = MakeJet(i, 3, 0);
  450. J c = pow(a, b);
  451. ExpectClose(c.a, pow(-1.5, i), kTolerance);
  452. EXPECT_FALSE(isfinite(c.v[0]))
  453. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  454. EXPECT_TRUE(isfinite(c.v[1]))
  455. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  456. ExpectClose(c.v[1], 0, kTolerance);
  457. }
  458. }
  459. // pow(<0,y) is correct for noninteger y.
  460. {
  461. double a = -1.5;
  462. J b = MakeJet(-3.14, 3, 0);
  463. J c = pow(a, b);
  464. EXPECT_FALSE(isfinite(c.a))
  465. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  466. EXPECT_FALSE(isfinite(c.v[0]))
  467. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  468. EXPECT_FALSE(isfinite(c.v[1]))
  469. << "\na: " << a << "\nb: " << b << "\na^b: " << c;
  470. }
  471. }
  472. TEST(Jet, Hypot2) {
  473. // Resolve the ambiguity between two and three argument hypot overloads
  474. using Hypot2 = J(const J&, const J&);
  475. auto* const hypot2 = static_cast<Hypot2*>(&hypot<double, 2>);
  476. // clang-format off
  477. NumericalTest2("hypot2", hypot2, 0.0, 1e-5);
  478. NumericalTest2("hypot2", hypot2, -1e-5, 0.0);
  479. NumericalTest2("hypot2", hypot2, 1e-5, 1e-5);
  480. NumericalTest2("hypot2", hypot2, 0.0, 1.0);
  481. NumericalTest2("hypot2", hypot2, 1e-3, 1.0);
  482. NumericalTest2("hypot2", hypot2, 1e-3, -1.0);
  483. NumericalTest2("hypot2", hypot2, -1e-3, 1.0);
  484. NumericalTest2("hypot2", hypot2, -1e-3, -1.0);
  485. NumericalTest2("hypot2", hypot2, 1.0, 2.0);
  486. // clang-format on
  487. J zero = MakeJet(0.0, 2.0, 3.14);
  488. EXPECT_THAT(hypot(x, y), IsAlmostEqualTo(sqrt(x * x + y * y)));
  489. EXPECT_THAT(hypot(x, x), IsAlmostEqualTo(sqrt(2.0) * abs(x)));
  490. // The derivative is zero tangentially to the circle:
  491. EXPECT_THAT(hypot(MakeJet(2.0, 1.0, 1.0), MakeJet(2.0, 1.0, -1.0)),
  492. IsAlmostEqualTo(MakeJet(sqrt(8.0), std::sqrt(2.0), 0.0)));
  493. EXPECT_THAT(hypot(zero, x), IsAlmostEqualTo(x));
  494. EXPECT_THAT(hypot(y, zero), IsAlmostEqualTo(y));
  495. // hypot(x, 0, 0) == x, even when x * x underflows:
  496. EXPECT_EQ(
  497. std::numeric_limits<double>::min() * std::numeric_limits<double>::min(),
  498. 0.0); // Make sure it underflows
  499. J tiny = MakeJet(std::numeric_limits<double>::min(), 2.0, 3.14);
  500. EXPECT_THAT(hypot(tiny, J{0}), IsAlmostEqualTo(tiny));
  501. // hypot(x, 0, 0) == x, even when x * x overflows:
  502. EXPECT_EQ(
  503. std::numeric_limits<double>::max() * std::numeric_limits<double>::max(),
  504. std::numeric_limits<double>::infinity());
  505. J huge = MakeJet(std::numeric_limits<double>::max(), 2.0, 3.14);
  506. EXPECT_THAT(hypot(huge, J{0}), IsAlmostEqualTo(huge));
  507. }
  508. TEST(Jet, Hypot3) {
  509. J zero = MakeJet(0.0, 2.0, 3.14);
  510. // hypot(x, y, z) == sqrt(x^2 + y^2 + z^2)
  511. EXPECT_THAT(hypot(x, y, z), IsAlmostEqualTo(sqrt(x * x + y * y + z * z)));
  512. // hypot(x, x) == sqrt(3) * abs(x)
  513. EXPECT_THAT(hypot(x, x, x), IsAlmostEqualTo(sqrt(3.0) * abs(x)));
  514. // The derivative is zero tangentially to the circle:
  515. EXPECT_THAT(hypot(MakeJet(2.0, 1.0, 1.0),
  516. MakeJet(2.0, 1.0, -1.0),
  517. MakeJet(2.0, -1.0, 0.0)),
  518. IsAlmostEqualTo(MakeJet(sqrt(12.0), 1.0 / std::sqrt(3.0), 0.0)));
  519. EXPECT_THAT(hypot(x, zero, zero), IsAlmostEqualTo(x));
  520. EXPECT_THAT(hypot(zero, y, zero), IsAlmostEqualTo(y));
  521. EXPECT_THAT(hypot(zero, zero, z), IsAlmostEqualTo(z));
  522. EXPECT_THAT(hypot(x, y, z), IsAlmostEqualTo(hypot(hypot(x, y), z)));
  523. EXPECT_THAT(hypot(x, y, z), IsAlmostEqualTo(hypot(x, hypot(y, z))));
  524. // The following two tests are disabled because the three argument hypot is
  525. // broken in the libc++ shipped with CLANG as of January 2022.
  526. #if !defined(_LIBCPP_VERSION)
  527. // hypot(x, 0, 0) == x, even when x * x underflows:
  528. EXPECT_EQ(
  529. std::numeric_limits<double>::min() * std::numeric_limits<double>::min(),
  530. 0.0); // Make sure it underflows
  531. J tiny = MakeJet(std::numeric_limits<double>::min(), 2.0, 3.14);
  532. EXPECT_THAT(hypot(tiny, J{0}, J{0}), IsAlmostEqualTo(tiny));
  533. // hypot(x, 0, 0) == x, even when x * x overflows:
  534. EXPECT_EQ(
  535. std::numeric_limits<double>::max() * std::numeric_limits<double>::max(),
  536. std::numeric_limits<double>::infinity());
  537. J huge = MakeJet(std::numeric_limits<double>::max(), 2.0, 3.14);
  538. EXPECT_THAT(hypot(huge, J{0}, J{0}), IsAlmostEqualTo(huge));
  539. #endif
  540. }
  541. #ifdef CERES_HAS_CPP20
  542. TEST(Jet, Lerp) {
  543. EXPECT_THAT(lerp(x, y, J{0}), IsAlmostEqualTo(x));
  544. EXPECT_THAT(lerp(x, y, J{1}), IsAlmostEqualTo(y));
  545. EXPECT_THAT(lerp(x, x, J{1}), IsAlmostEqualTo(x));
  546. EXPECT_THAT(lerp(y, y, J{0}), IsAlmostEqualTo(y));
  547. EXPECT_THAT(lerp(x, y, J{0.5}), IsAlmostEqualTo((x + y) / J{2.0}));
  548. EXPECT_THAT(lerp(x, y, J{2}), IsAlmostEqualTo(J{2.0} * y - x));
  549. EXPECT_THAT(lerp(x, y, J{-2}), IsAlmostEqualTo(J{3.0} * x - J{2} * y));
  550. }
  551. TEST(Jet, Midpoint) {
  552. EXPECT_THAT(midpoint(x, y), IsAlmostEqualTo((x + y) / J{2}));
  553. EXPECT_THAT(midpoint(x, x), IsAlmostEqualTo(x));
  554. {
  555. // midpoint(x, y) = (x + y) / 2 while avoiding overflow
  556. J x = MakeJet(std::numeric_limits<double>::min(), 1, 2);
  557. J y = MakeJet(std::numeric_limits<double>::max(), 3, 4);
  558. EXPECT_THAT(midpoint(x, y), IsAlmostEqualTo(x + (y - x) / J{2}));
  559. }
  560. {
  561. // midpoint(x, x) = x while avoiding overflow
  562. J x = MakeJet(std::numeric_limits<double>::max(),
  563. std::numeric_limits<double>::max(),
  564. std::numeric_limits<double>::max());
  565. EXPECT_THAT(midpoint(x, x), IsAlmostEqualTo(x));
  566. }
  567. { // midpoint does not overflow for very large values
  568. constexpr double a = 0.75 * std::numeric_limits<double>::max();
  569. J x = MakeJet(a, a, -a);
  570. J y = MakeJet(a, a, a);
  571. EXPECT_THAT(midpoint(x, y), IsAlmostEqualTo(MakeJet(a, a, 0)));
  572. }
  573. }
  574. #endif // defined(CERES_HAS_CPP20)
  575. TEST(Jet, Fma) {
  576. J v = fma(x, y, z);
  577. J w = x * y + z;
  578. EXPECT_THAT(v, IsAlmostEqualTo(w));
  579. }
  580. TEST(Jet, FmaxJetWithJet) {
  581. Fenv env;
  582. // Clear all exceptions to ensure none are set by the following function
  583. // calls.
  584. std::feclearexcept(FE_ALL_EXCEPT);
  585. EXPECT_THAT(fmax(x, y), IsAlmostEqualTo(x));
  586. EXPECT_THAT(fmax(y, x), IsAlmostEqualTo(x));
  587. // Average the Jets on equality (of scalar parts).
  588. const J scalar_part_only_equal_to_x = J(x.a, 2 * x.v);
  589. const J average = (x + scalar_part_only_equal_to_x) * 0.5;
  590. EXPECT_THAT(fmax(x, scalar_part_only_equal_to_x), IsAlmostEqualTo(average));
  591. EXPECT_THAT(fmax(scalar_part_only_equal_to_x, x), IsAlmostEqualTo(average));
  592. // Follow convention of fmax(): treat NANs as missing values.
  593. const J nan_scalar_part(std::numeric_limits<double>::quiet_NaN(), 2 * x.v);
  594. EXPECT_THAT(fmax(x, nan_scalar_part), IsAlmostEqualTo(x));
  595. EXPECT_THAT(fmax(nan_scalar_part, x), IsAlmostEqualTo(x));
  596. #ifndef CERES_NO_FENV_ACCESS
  597. EXPECT_EQ(std::fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT), 0);
  598. #endif
  599. }
  600. TEST(Jet, FmaxJetWithScalar) {
  601. Fenv env;
  602. // Clear all exceptions to ensure none are set by the following function
  603. // calls.
  604. std::feclearexcept(FE_ALL_EXCEPT);
  605. EXPECT_THAT(fmax(x, y.a), IsAlmostEqualTo(x));
  606. EXPECT_THAT(fmax(y.a, x), IsAlmostEqualTo(x));
  607. EXPECT_THAT(fmax(y, x.a), IsAlmostEqualTo(J{x.a}));
  608. EXPECT_THAT(fmax(x.a, y), IsAlmostEqualTo(J{x.a}));
  609. // Average the Jet and scalar cast to a Jet on equality (of scalar parts).
  610. const J average = (x + J{x.a}) * 0.5;
  611. EXPECT_THAT(fmax(x, x.a), IsAlmostEqualTo(average));
  612. EXPECT_THAT(fmax(x.a, x), IsAlmostEqualTo(average));
  613. // Follow convention of fmax(): treat NANs as missing values.
  614. EXPECT_THAT(fmax(x, std::numeric_limits<double>::quiet_NaN()),
  615. IsAlmostEqualTo(x));
  616. EXPECT_THAT(fmax(std::numeric_limits<double>::quiet_NaN(), x),
  617. IsAlmostEqualTo(x));
  618. const J nan_scalar_part(std::numeric_limits<double>::quiet_NaN(), 2 * x.v);
  619. EXPECT_THAT(fmax(nan_scalar_part, x.a), IsAlmostEqualTo(J{x.a}));
  620. EXPECT_THAT(fmax(x.a, nan_scalar_part), IsAlmostEqualTo(J{x.a}));
  621. #ifndef CERES_NO_FENV_ACCESS
  622. EXPECT_EQ(std::fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT), 0);
  623. #endif
  624. }
  625. TEST(Jet, FminJetWithJet) {
  626. Fenv env;
  627. // Clear all exceptions to ensure none are set by the following function
  628. // calls.
  629. std::feclearexcept(FE_ALL_EXCEPT);
  630. EXPECT_THAT(fmin(x, y), IsAlmostEqualTo(y));
  631. EXPECT_THAT(fmin(y, x), IsAlmostEqualTo(y));
  632. // Average the Jets on equality (of scalar parts).
  633. const J scalar_part_only_equal_to_x = J(x.a, 2 * x.v);
  634. const J average = (x + scalar_part_only_equal_to_x) * 0.5;
  635. EXPECT_THAT(fmin(x, scalar_part_only_equal_to_x), IsAlmostEqualTo(average));
  636. EXPECT_THAT(fmin(scalar_part_only_equal_to_x, x), IsAlmostEqualTo(average));
  637. // Follow convention of fmin(): treat NANs as missing values.
  638. const J nan_scalar_part(std::numeric_limits<double>::quiet_NaN(), 2 * x.v);
  639. EXPECT_THAT(fmin(x, nan_scalar_part), IsAlmostEqualTo(x));
  640. EXPECT_THAT(fmin(nan_scalar_part, x), IsAlmostEqualTo(x));
  641. #ifndef CERES_NO_FENV_ACCESS
  642. EXPECT_EQ(std::fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT), 0);
  643. #endif
  644. }
  645. TEST(Jet, FminJetWithScalar) {
  646. Fenv env;
  647. // Clear all exceptions to ensure none are set by the following function
  648. // calls.
  649. std::feclearexcept(FE_ALL_EXCEPT);
  650. EXPECT_THAT(fmin(x, y.a), IsAlmostEqualTo(J{y.a}));
  651. EXPECT_THAT(fmin(y.a, x), IsAlmostEqualTo(J{y.a}));
  652. EXPECT_THAT(fmin(y, x.a), IsAlmostEqualTo(y));
  653. EXPECT_THAT(fmin(x.a, y), IsAlmostEqualTo(y));
  654. // Average the Jet and scalar cast to a Jet on equality (of scalar parts).
  655. const J average = (x + J{x.a}) * 0.5;
  656. EXPECT_THAT(fmin(x, x.a), IsAlmostEqualTo(average));
  657. EXPECT_THAT(fmin(x.a, x), IsAlmostEqualTo(average));
  658. // Follow convention of fmin(): treat NANs as missing values.
  659. EXPECT_THAT(fmin(x, std::numeric_limits<double>::quiet_NaN()),
  660. IsAlmostEqualTo(x));
  661. EXPECT_THAT(fmin(std::numeric_limits<double>::quiet_NaN(), x),
  662. IsAlmostEqualTo(x));
  663. const J nan_scalar_part(std::numeric_limits<double>::quiet_NaN(), 2 * x.v);
  664. EXPECT_THAT(fmin(nan_scalar_part, x.a), IsAlmostEqualTo(J{x.a}));
  665. EXPECT_THAT(fmin(x.a, nan_scalar_part), IsAlmostEqualTo(J{x.a}));
  666. #ifndef CERES_NO_FENV_ACCESS
  667. EXPECT_EQ(std::fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT), 0);
  668. #endif
  669. }
  670. TEST(Jet, Fdim) {
  671. Fenv env;
  672. // Clear all exceptions to ensure none are set by the following function
  673. // calls.
  674. std::feclearexcept(FE_ALL_EXCEPT);
  675. const J zero{};
  676. const J diff = x - y;
  677. const J diffx = x - J{y.a};
  678. const J diffy = J{x.a} - y;
  679. EXPECT_THAT(fdim(x, y), IsAlmostEqualTo(diff));
  680. EXPECT_THAT(fdim(y, x), IsAlmostEqualTo(zero));
  681. EXPECT_THAT(fdim(x, y.a), IsAlmostEqualTo(diffx));
  682. EXPECT_THAT(fdim(y.a, x), IsAlmostEqualTo(J{zero.a}));
  683. EXPECT_THAT(fdim(x.a, y), IsAlmostEqualTo(diffy));
  684. EXPECT_THAT(fdim(y, x.a), IsAlmostEqualTo(zero));
  685. EXPECT_TRUE(isnan(fdim(x, std::numeric_limits<J>::quiet_NaN())));
  686. EXPECT_TRUE(isnan(fdim(std::numeric_limits<J>::quiet_NaN(), x)));
  687. EXPECT_TRUE(isnan(fdim(x, std::numeric_limits<double>::quiet_NaN())));
  688. EXPECT_TRUE(isnan(fdim(std::numeric_limits<double>::quiet_NaN(), x)));
  689. #ifndef CERES_NO_FENV_ACCESS
  690. EXPECT_EQ(std::fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT), 0);
  691. #endif
  692. }
  693. TEST(Jet, CopySign) {
  694. { // copysign(x, +1)
  695. J z = copysign(x, J{+1});
  696. EXPECT_THAT(z, IsAlmostEqualTo(x));
  697. EXPECT_TRUE(isfinite(z.v[0])) << z;
  698. EXPECT_TRUE(isfinite(z.v[1])) << z;
  699. }
  700. { // copysign(x, -1)
  701. J z = copysign(x, J{-1});
  702. EXPECT_THAT(z, IsAlmostEqualTo(-x));
  703. EXPECT_TRUE(isfinite(z.v[0])) << z;
  704. EXPECT_TRUE(isfinite(z.v[1])) << z;
  705. }
  706. { // copysign(-x, +1)
  707. J z = copysign(-x, J{+1});
  708. EXPECT_THAT(z, IsAlmostEqualTo(x));
  709. EXPECT_TRUE(isfinite(z.v[0])) << z;
  710. EXPECT_TRUE(isfinite(z.v[1])) << z;
  711. }
  712. { // copysign(-x, -1)
  713. J z = copysign(-x, J{-1});
  714. EXPECT_THAT(z, IsAlmostEqualTo(-x));
  715. EXPECT_TRUE(isfinite(z.v[0])) << z;
  716. EXPECT_TRUE(isfinite(z.v[1])) << z;
  717. }
  718. { // copysign(-0, +1)
  719. J z = copysign(MakeJet(-0, 1, 2), J{+1});
  720. EXPECT_THAT(z, IsAlmostEqualTo(MakeJet(+0, 1, 2)));
  721. EXPECT_FALSE(std::signbit(z.a)) << z;
  722. EXPECT_TRUE(isfinite(z.v[0])) << z;
  723. EXPECT_TRUE(isfinite(z.v[1])) << z;
  724. }
  725. { // copysign(-0, -1)
  726. J z = copysign(MakeJet(-0, 1, 2), J{-1});
  727. EXPECT_THAT(z, IsAlmostEqualTo(MakeJet(-0, -1, -2)));
  728. EXPECT_TRUE(std::signbit(z.a)) << z;
  729. EXPECT_TRUE(isfinite(z.v[0])) << z;
  730. EXPECT_TRUE(isfinite(z.v[1])) << z;
  731. }
  732. { // copysign(+0, -1)
  733. J z = copysign(MakeJet(+0, 1, 2), J{-1});
  734. EXPECT_THAT(z, IsAlmostEqualTo(MakeJet(-0, -1, -2)));
  735. EXPECT_TRUE(std::signbit(z.a)) << z;
  736. EXPECT_TRUE(isfinite(z.v[0])) << z;
  737. EXPECT_TRUE(isfinite(z.v[1])) << z;
  738. }
  739. { // copysign(+0, +1)
  740. J z = copysign(MakeJet(+0, 1, 2), J{+1});
  741. EXPECT_THAT(z, IsAlmostEqualTo(MakeJet(+0, 1, 2)));
  742. EXPECT_FALSE(std::signbit(z.a)) << z;
  743. EXPECT_TRUE(isfinite(z.v[0])) << z;
  744. EXPECT_TRUE(isfinite(z.v[1])) << z;
  745. }
  746. { // copysign(+0, +0)
  747. J z = copysign(MakeJet(+0, 1, 2), J{+0});
  748. EXPECT_FALSE(std::signbit(z.a)) << z;
  749. EXPECT_TRUE(isnan(z.v[0])) << z;
  750. EXPECT_TRUE(isnan(z.v[1])) << z;
  751. }
  752. { // copysign(+0, -0)
  753. J z = copysign(MakeJet(+0, 1, 2), J{-0});
  754. EXPECT_FALSE(std::signbit(z.a)) << z;
  755. EXPECT_TRUE(isnan(z.v[0])) << z;
  756. EXPECT_TRUE(isnan(z.v[1])) << z;
  757. }
  758. { // copysign(-0, +0)
  759. J z = copysign(MakeJet(-0, 1, 2), J{+0});
  760. EXPECT_FALSE(std::signbit(z.a)) << z;
  761. EXPECT_TRUE(isnan(z.v[0])) << z;
  762. EXPECT_TRUE(isnan(z.v[1])) << z;
  763. }
  764. { // copysign(-0, -0)
  765. J z = copysign(MakeJet(-0, 1, 2), J{-0});
  766. EXPECT_FALSE(std::signbit(z.a)) << z;
  767. EXPECT_TRUE(isnan(z.v[0])) << z;
  768. EXPECT_TRUE(isnan(z.v[1])) << z;
  769. }
  770. { // copysign(1, -nan)
  771. J z = copysign(MakeJet(1, 2, 3),
  772. -J{std::numeric_limits<double>::quiet_NaN()});
  773. EXPECT_TRUE(std::signbit(z.a)) << z;
  774. EXPECT_TRUE(std::signbit(z.v[0])) << z;
  775. EXPECT_TRUE(std::signbit(z.v[1])) << z;
  776. EXPECT_FALSE(isnan(z.v[0])) << z;
  777. EXPECT_FALSE(isnan(z.v[1])) << z;
  778. }
  779. { // copysign(1, +nan)
  780. J z = copysign(MakeJet(1, 2, 3),
  781. +J{std::numeric_limits<double>::quiet_NaN()});
  782. EXPECT_FALSE(std::signbit(z.a)) << z;
  783. EXPECT_FALSE(std::signbit(z.v[0])) << z;
  784. EXPECT_FALSE(std::signbit(z.v[1])) << z;
  785. EXPECT_FALSE(isnan(z.v[0])) << z;
  786. EXPECT_FALSE(isnan(z.v[1])) << z;
  787. }
  788. }
  789. TEST(Jet, JetsInEigenMatrices) {
  790. J x = MakeJet(2.3, -2.7, 1e-3);
  791. J y = MakeJet(1.7, 0.5, 1e+2);
  792. J z = MakeJet(5.3, -4.7, 1e-3);
  793. J w = MakeJet(9.7, 1.5, 10.1);
  794. Eigen::Matrix<J, 2, 2> M;
  795. Eigen::Matrix<J, 2, 1> v, r1, r2;
  796. M << x, y, z, w;
  797. v << x, z;
  798. // M * v == (v^T * M^T)^T
  799. r1 = M * v;
  800. r2 = (v.transpose() * M.transpose()).transpose();
  801. EXPECT_THAT(r1(0), IsAlmostEqualTo(r2(0)));
  802. EXPECT_THAT(r1(1), IsAlmostEqualTo(r2(1)));
  803. }
  804. TEST(Jet, ScalarComparison) {
  805. Jet<double, 1> zero{0.0};
  806. zero.v << std::numeric_limits<double>::infinity();
  807. Jet<double, 1> one{1.0};
  808. one.v << std::numeric_limits<double>::quiet_NaN();
  809. Jet<double, 1> two{2.0};
  810. two.v << std::numeric_limits<double>::min() / 2;
  811. Jet<double, 1> three{3.0};
  812. auto inf = std::numeric_limits<Jet<double, 1>>::infinity();
  813. auto nan = std::numeric_limits<Jet<double, 1>>::quiet_NaN();
  814. inf.v << 1.2;
  815. nan.v << 3.4;
  816. std::feclearexcept(FE_ALL_EXCEPT);
  817. EXPECT_FALSE(islessgreater(zero, zero));
  818. EXPECT_FALSE(islessgreater(zero, zero.a));
  819. EXPECT_FALSE(islessgreater(zero.a, zero));
  820. EXPECT_TRUE(isgreaterequal(three, three));
  821. EXPECT_TRUE(isgreaterequal(three, three.a));
  822. EXPECT_TRUE(isgreaterequal(three.a, three));
  823. EXPECT_TRUE(isgreater(three, two));
  824. EXPECT_TRUE(isgreater(three, two.a));
  825. EXPECT_TRUE(isgreater(three.a, two));
  826. EXPECT_TRUE(islessequal(one, one));
  827. EXPECT_TRUE(islessequal(one, one.a));
  828. EXPECT_TRUE(islessequal(one.a, one));
  829. EXPECT_TRUE(isless(one, two));
  830. EXPECT_TRUE(isless(one, two.a));
  831. EXPECT_TRUE(isless(one.a, two));
  832. EXPECT_FALSE(isunordered(inf, one));
  833. EXPECT_FALSE(isunordered(inf, one.a));
  834. EXPECT_FALSE(isunordered(inf.a, one));
  835. EXPECT_TRUE(isunordered(nan, two));
  836. EXPECT_TRUE(isunordered(nan, two.a));
  837. EXPECT_TRUE(isunordered(nan.a, two));
  838. EXPECT_TRUE(isunordered(inf, nan));
  839. EXPECT_TRUE(isunordered(inf, nan.a));
  840. EXPECT_TRUE(isunordered(inf.a, nan.a));
  841. EXPECT_EQ(std::fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT), 0);
  842. }
  843. TEST(Jet, Nested2XScalarComparison) {
  844. Jet<J0d, 1> zero{J0d{0.0}};
  845. zero.v << std::numeric_limits<J0d>::infinity();
  846. Jet<J0d, 1> one{J0d{1.0}};
  847. one.v << std::numeric_limits<J0d>::quiet_NaN();
  848. Jet<J0d, 1> two{J0d{2.0}};
  849. two.v << std::numeric_limits<J0d>::min() / J0d{2};
  850. Jet<J0d, 1> three{J0d{3.0}};
  851. auto inf = std::numeric_limits<Jet<J0d, 1>>::infinity();
  852. auto nan = std::numeric_limits<Jet<J0d, 1>>::quiet_NaN();
  853. inf.v << J0d{1.2};
  854. nan.v << J0d{3.4};
  855. std::feclearexcept(FE_ALL_EXCEPT);
  856. EXPECT_FALSE(islessgreater(zero, zero));
  857. EXPECT_FALSE(islessgreater(zero, zero.a));
  858. EXPECT_FALSE(islessgreater(zero.a, zero));
  859. EXPECT_FALSE(islessgreater(zero, zero.a.a));
  860. EXPECT_FALSE(islessgreater(zero.a.a, zero));
  861. EXPECT_TRUE(isgreaterequal(three, three));
  862. EXPECT_TRUE(isgreaterequal(three, three.a));
  863. EXPECT_TRUE(isgreaterequal(three.a, three));
  864. EXPECT_TRUE(isgreaterequal(three, three.a.a));
  865. EXPECT_TRUE(isgreaterequal(three.a.a, three));
  866. EXPECT_TRUE(isgreater(three, two));
  867. EXPECT_TRUE(isgreater(three, two.a));
  868. EXPECT_TRUE(isgreater(three.a, two));
  869. EXPECT_TRUE(isgreater(three, two.a.a));
  870. EXPECT_TRUE(isgreater(three.a.a, two));
  871. EXPECT_TRUE(islessequal(one, one));
  872. EXPECT_TRUE(islessequal(one, one.a));
  873. EXPECT_TRUE(islessequal(one.a, one));
  874. EXPECT_TRUE(islessequal(one, one.a.a));
  875. EXPECT_TRUE(islessequal(one.a.a, one));
  876. EXPECT_TRUE(isless(one, two));
  877. EXPECT_TRUE(isless(one, two.a));
  878. EXPECT_TRUE(isless(one.a, two));
  879. EXPECT_TRUE(isless(one, two.a.a));
  880. EXPECT_TRUE(isless(one.a.a, two));
  881. EXPECT_FALSE(isunordered(inf, one));
  882. EXPECT_FALSE(isunordered(inf, one.a));
  883. EXPECT_FALSE(isunordered(inf.a, one));
  884. EXPECT_FALSE(isunordered(inf, one.a.a));
  885. EXPECT_FALSE(isunordered(inf.a.a, one));
  886. EXPECT_TRUE(isunordered(nan, two));
  887. EXPECT_TRUE(isunordered(nan, two.a));
  888. EXPECT_TRUE(isunordered(nan.a, two));
  889. EXPECT_TRUE(isunordered(nan, two.a.a));
  890. EXPECT_TRUE(isunordered(nan.a.a, two));
  891. EXPECT_TRUE(isunordered(inf, nan));
  892. EXPECT_TRUE(isunordered(inf, nan.a));
  893. EXPECT_TRUE(isunordered(inf.a, nan));
  894. EXPECT_TRUE(isunordered(inf, nan.a.a));
  895. EXPECT_TRUE(isunordered(inf.a.a, nan));
  896. EXPECT_EQ(std::fetestexcept(FE_ALL_EXCEPT & ~FE_INEXACT), 0);
  897. }
  898. TEST(JetTraitsTest, ClassificationNaN) {
  899. Jet<double, 1> a(std::numeric_limits<double>::quiet_NaN());
  900. a.v << std::numeric_limits<double>::infinity();
  901. EXPECT_EQ(fpclassify(a), FP_NAN);
  902. EXPECT_FALSE(isfinite(a));
  903. EXPECT_FALSE(isinf(a));
  904. EXPECT_FALSE(isnormal(a));
  905. EXPECT_FALSE(signbit(a));
  906. EXPECT_TRUE(isnan(a));
  907. }
  908. TEST(JetTraitsTest, ClassificationInf) {
  909. Jet<double, 1> a(-std::numeric_limits<double>::infinity());
  910. a.v << std::numeric_limits<double>::quiet_NaN();
  911. EXPECT_EQ(fpclassify(a), FP_INFINITE);
  912. EXPECT_FALSE(isfinite(a));
  913. EXPECT_FALSE(isnan(a));
  914. EXPECT_FALSE(isnormal(a));
  915. EXPECT_TRUE(signbit(a));
  916. EXPECT_TRUE(isinf(a));
  917. }
  918. TEST(JetTraitsTest, ClassificationFinite) {
  919. Jet<double, 1> a(-5.5);
  920. a.v << std::numeric_limits<double>::quiet_NaN();
  921. EXPECT_EQ(fpclassify(a), FP_NORMAL);
  922. EXPECT_FALSE(isinf(a));
  923. EXPECT_FALSE(isnan(a));
  924. EXPECT_TRUE(signbit(a));
  925. EXPECT_TRUE(isfinite(a));
  926. EXPECT_TRUE(isnormal(a));
  927. }
  928. TEST(JetTraitsTest, ClassificationScalar) {
  929. EXPECT_EQ(fpclassify(J0d{+0.0}), FP_ZERO);
  930. EXPECT_EQ(fpclassify(J0d{-0.0}), FP_ZERO);
  931. EXPECT_EQ(fpclassify(J0d{1.234}), FP_NORMAL);
  932. EXPECT_EQ(fpclassify(J0d{std::numeric_limits<double>::min() / 2}),
  933. FP_SUBNORMAL);
  934. EXPECT_EQ(fpclassify(J0d{std::numeric_limits<double>::quiet_NaN()}), FP_NAN);
  935. }
  936. TEST(JetTraitsTest, Nested2XClassificationScalar) {
  937. EXPECT_EQ(fpclassify(J0<J0d>{J0d{+0.0}}), FP_ZERO);
  938. EXPECT_EQ(fpclassify(J0<J0d>{J0d{-0.0}}), FP_ZERO);
  939. EXPECT_EQ(fpclassify(J0<J0d>{J0d{1.234}}), FP_NORMAL);
  940. EXPECT_EQ(fpclassify(J0<J0d>{J0d{std::numeric_limits<double>::min() / 2}}),
  941. FP_SUBNORMAL);
  942. EXPECT_EQ(fpclassify(J0<J0d>{J0d{std::numeric_limits<double>::quiet_NaN()}}),
  943. FP_NAN);
  944. }
  945. // The following test ensures that Jets have all the appropriate Eigen
  946. // related traits so that they can be used as part of matrix
  947. // decompositions.
  948. TEST(Jet, FullRankEigenLLTSolve) {
  949. Eigen::Matrix<J, 3, 3> A;
  950. Eigen::Matrix<J, 3, 1> b, x;
  951. for (int i = 0; i < 3; ++i) {
  952. for (int j = 0; j < 3; ++j) {
  953. A(i, j) = MakeJet(0.0, i, j * j);
  954. }
  955. b(i) = MakeJet(i, i, i);
  956. x(i) = MakeJet(0.0, 0.0, 0.0);
  957. A(i, i) = MakeJet(1.0, i, i * i);
  958. }
  959. x = A.llt().solve(b);
  960. for (int i = 0; i < 3; ++i) {
  961. EXPECT_EQ(x(i).a, b(i).a);
  962. }
  963. }
  964. TEST(Jet, FullRankEigenLDLTSolve) {
  965. Eigen::Matrix<J, 3, 3> A;
  966. Eigen::Matrix<J, 3, 1> b, x;
  967. for (int i = 0; i < 3; ++i) {
  968. for (int j = 0; j < 3; ++j) {
  969. A(i, j) = MakeJet(0.0, i, j * j);
  970. }
  971. b(i) = MakeJet(i, i, i);
  972. x(i) = MakeJet(0.0, 0.0, 0.0);
  973. A(i, i) = MakeJet(1.0, i, i * i);
  974. }
  975. x = A.ldlt().solve(b);
  976. for (int i = 0; i < 3; ++i) {
  977. EXPECT_EQ(x(i).a, b(i).a);
  978. }
  979. }
  980. TEST(Jet, FullRankEigenLUSolve) {
  981. Eigen::Matrix<J, 3, 3> A;
  982. Eigen::Matrix<J, 3, 1> b, x;
  983. for (int i = 0; i < 3; ++i) {
  984. for (int j = 0; j < 3; ++j) {
  985. A(i, j) = MakeJet(0.0, i, j * j);
  986. }
  987. b(i) = MakeJet(i, i, i);
  988. x(i) = MakeJet(0.0, 0.0, 0.0);
  989. A(i, i) = MakeJet(1.0, i, i * i);
  990. }
  991. x = A.lu().solve(b);
  992. for (int i = 0; i < 3; ++i) {
  993. EXPECT_EQ(x(i).a, b(i).a);
  994. }
  995. }
  996. // ScalarBinaryOpTraits is only supported on Eigen versions >= 3.3
  997. TEST(JetTraitsTest, MatrixScalarUnaryOps) {
  998. const J x = MakeJet(2.3, -2.7, 1e-3);
  999. const J y = MakeJet(1.7, 0.5, 1e+2);
  1000. Eigen::Matrix<J, 2, 1> a;
  1001. a << x, y;
  1002. const J sum = a.sum();
  1003. const J sum2 = a(0) + a(1);
  1004. EXPECT_THAT(sum, IsAlmostEqualTo(sum2));
  1005. }
  1006. TEST(JetTraitsTest, MatrixScalarBinaryOps) {
  1007. const J x = MakeJet(2.3, -2.7, 1e-3);
  1008. const J y = MakeJet(1.7, 0.5, 1e+2);
  1009. const J z = MakeJet(5.3, -4.7, 1e-3);
  1010. const J w = MakeJet(9.7, 1.5, 10.1);
  1011. Eigen::Matrix<J, 2, 2> M;
  1012. Eigen::Vector2d v;
  1013. M << x, y, z, w;
  1014. v << 0.6, -2.1;
  1015. // M * v == M * v.cast<J>().
  1016. const Eigen::Matrix<J, 2, 1> r1 = M * v;
  1017. const Eigen::Matrix<J, 2, 1> r2 = M * v.cast<J>();
  1018. EXPECT_THAT(r1(0), IsAlmostEqualTo(r2(0)));
  1019. EXPECT_THAT(r1(1), IsAlmostEqualTo(r2(1)));
  1020. // M * a == M * T(a).
  1021. const double a = 3.1;
  1022. const Eigen::Matrix<J, 2, 2> r3 = M * a;
  1023. const Eigen::Matrix<J, 2, 2> r4 = M * J(a);
  1024. EXPECT_THAT(r3(0, 0), IsAlmostEqualTo(r4(0, 0)));
  1025. EXPECT_THAT(r3(0, 1), IsAlmostEqualTo(r4(0, 1)));
  1026. EXPECT_THAT(r3(1, 0), IsAlmostEqualTo(r4(1, 0)));
  1027. EXPECT_THAT(r3(1, 1), IsAlmostEqualTo(r4(1, 1)));
  1028. }
  1029. TEST(JetTraitsTest, ArrayScalarUnaryOps) {
  1030. const J x = MakeJet(2.3, -2.7, 1e-3);
  1031. const J y = MakeJet(1.7, 0.5, 1e+2);
  1032. Eigen::Array<J, 2, 1> a;
  1033. a << x, y;
  1034. const J sum = a.sum();
  1035. const J sum2 = a(0) + a(1);
  1036. EXPECT_THAT(sum, sum2);
  1037. }
  1038. TEST(JetTraitsTest, ArrayScalarBinaryOps) {
  1039. const J x = MakeJet(2.3, -2.7, 1e-3);
  1040. const J y = MakeJet(1.7, 0.5, 1e+2);
  1041. Eigen::Array<J, 2, 1> a;
  1042. Eigen::Array2d b;
  1043. a << x, y;
  1044. b << 0.6, -2.1;
  1045. // a * b == a * b.cast<T>()
  1046. const Eigen::Array<J, 2, 1> r1 = a * b;
  1047. const Eigen::Array<J, 2, 1> r2 = a * b.cast<J>();
  1048. EXPECT_THAT(r1(0), r2(0));
  1049. EXPECT_THAT(r1(1), r2(1));
  1050. // a * c == a * T(c).
  1051. const double c = 3.1;
  1052. const Eigen::Array<J, 2, 1> r3 = a * c;
  1053. const Eigen::Array<J, 2, 1> r4 = a * J(c);
  1054. EXPECT_THAT(r3(0), r3(0));
  1055. EXPECT_THAT(r4(1), r4(1));
  1056. }
  1057. TEST(Jet, Nested3X) {
  1058. using JJ = Jet<J, 2>;
  1059. using JJJ = Jet<JJ, 2>;
  1060. JJJ x;
  1061. x.a = JJ(J(1, 0), 0);
  1062. x.v[0] = JJ(J(1));
  1063. JJJ y = x * x * x;
  1064. ExpectClose(y.a.a.a, 1, kTolerance);
  1065. ExpectClose(y.v[0].a.a, 3., kTolerance);
  1066. ExpectClose(y.v[0].v[0].a, 6., kTolerance);
  1067. ExpectClose(y.v[0].v[0].v[0], 6., kTolerance);
  1068. JJJ e = exp(x);
  1069. ExpectClose(e.a.a.a, kE, kTolerance);
  1070. ExpectClose(e.v[0].a.a, kE, kTolerance);
  1071. ExpectClose(e.v[0].v[0].a, kE, kTolerance);
  1072. ExpectClose(e.v[0].v[0].v[0], kE, kTolerance);
  1073. }
  1074. #if GTEST_HAS_TYPED_TEST
  1075. using Types = testing::Types<std::int16_t,
  1076. std::uint16_t,
  1077. std::int32_t,
  1078. std::uint32_t,
  1079. std::int64_t,
  1080. std::uint64_t,
  1081. float,
  1082. double,
  1083. long double>;
  1084. template <typename T>
  1085. class JetTest : public testing::Test {};
  1086. TYPED_TEST_SUITE(JetTest, Types);
  1087. TYPED_TEST(JetTest, Comparison) {
  1088. using Scalar = TypeParam;
  1089. EXPECT_EQ(J0<Scalar>{0}, J0<Scalar>{0});
  1090. EXPECT_GE(J0<Scalar>{3}, J0<Scalar>{3});
  1091. EXPECT_GT(J0<Scalar>{3}, J0<Scalar>{2});
  1092. EXPECT_LE(J0<Scalar>{1}, J0<Scalar>{1});
  1093. EXPECT_LT(J0<Scalar>{1}, J0<Scalar>{2});
  1094. EXPECT_NE(J0<Scalar>{1}, J0<Scalar>{2});
  1095. }
  1096. TYPED_TEST(JetTest, ScalarComparison) {
  1097. using Scalar = TypeParam;
  1098. EXPECT_EQ(J0d{0.0}, Scalar{0});
  1099. EXPECT_GE(J0d{3.0}, Scalar{3});
  1100. EXPECT_GT(J0d{3.0}, Scalar{2});
  1101. EXPECT_LE(J0d{1.0}, Scalar{1});
  1102. EXPECT_LT(J0d{1.0}, Scalar{2});
  1103. EXPECT_NE(J0d{1.0}, Scalar{2});
  1104. EXPECT_EQ(Scalar{0}, J0d{0.0});
  1105. EXPECT_GE(Scalar{1}, J0d{1.0});
  1106. EXPECT_GT(Scalar{2}, J0d{1.0});
  1107. EXPECT_LE(Scalar{3}, J0d{3.0});
  1108. EXPECT_LT(Scalar{2}, J0d{3.0});
  1109. EXPECT_NE(Scalar{2}, J0d{1.0});
  1110. }
  1111. TYPED_TEST(JetTest, Nested2XComparison) {
  1112. using Scalar = TypeParam;
  1113. EXPECT_EQ(J0<J0d>{J0d{0.0}}, Scalar{0});
  1114. EXPECT_GE(J0<J0d>{J0d{3.0}}, Scalar{3});
  1115. EXPECT_GT(J0<J0d>{J0d{3.0}}, Scalar{2});
  1116. EXPECT_LE(J0<J0d>{J0d{1.0}}, Scalar{1});
  1117. EXPECT_LT(J0<J0d>{J0d{1.0}}, Scalar{2});
  1118. EXPECT_NE(J0<J0d>{J0d{1.0}}, Scalar{2});
  1119. EXPECT_EQ(Scalar{0}, J0<J0d>{J0d{0.0}});
  1120. EXPECT_GE(Scalar{1}, J0<J0d>{J0d{1.0}});
  1121. EXPECT_GT(Scalar{2}, J0<J0d>{J0d{1.0}});
  1122. EXPECT_LE(Scalar{3}, J0<J0d>{J0d{3.0}});
  1123. EXPECT_LT(Scalar{2}, J0<J0d>{J0d{3.0}});
  1124. EXPECT_NE(Scalar{2}, J0<J0d>{J0d{1.0}});
  1125. }
  1126. TYPED_TEST(JetTest, Nested3XComparison) {
  1127. using Scalar = TypeParam;
  1128. EXPECT_EQ(J0<J0<J0d>>{J0<J0d>{J0d{0.0}}}, Scalar{0});
  1129. EXPECT_GE(J0<J0<J0d>>{J0<J0d>{J0d{3.0}}}, Scalar{3});
  1130. EXPECT_GT(J0<J0<J0d>>{J0<J0d>{J0d{3.0}}}, Scalar{2});
  1131. EXPECT_LE(J0<J0<J0d>>{J0<J0d>{J0d{1.0}}}, Scalar{1});
  1132. EXPECT_LT(J0<J0<J0d>>{J0<J0d>{J0d{1.0}}}, Scalar{2});
  1133. EXPECT_NE(J0<J0<J0d>>{J0<J0d>{J0d{1.0}}}, Scalar{2});
  1134. EXPECT_EQ(Scalar{0}, J0<J0<J0d>>{J0<J0d>{J0d{0.0}}});
  1135. EXPECT_GE(Scalar{1}, J0<J0<J0d>>{J0<J0d>{J0d{1.0}}});
  1136. EXPECT_GT(Scalar{2}, J0<J0<J0d>>{J0<J0d>{J0d{1.0}}});
  1137. EXPECT_LE(Scalar{3}, J0<J0<J0d>>{J0<J0d>{J0d{3.0}}});
  1138. EXPECT_LT(Scalar{2}, J0<J0<J0d>>{J0<J0d>{J0d{3.0}}});
  1139. EXPECT_NE(Scalar{2}, J0<J0<J0d>>{J0<J0d>{J0d{1.0}}});
  1140. }
  1141. #endif // GTEST_HAS_TYPED_TEST
  1142. } // namespace ceres::internal
  1143. #ifdef _MSC_VER
  1144. #pragma float_control(pop)
  1145. #endif