MRPT  1.9.9
poly_roots_unittest.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2019, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include <gtest/gtest.h>
11 #include <mrpt/core/format.h>
12 #include <mrpt/math/poly_roots.h>
13 #include <cmath>
14 
15 using namespace std;
16 
17 const double eps = 1e-9;
18 
19 TEST(poly_roots, solve_poly2)
20 {
21  // `a*x^2 + b*x + c = 0`
22  // Table:
23  // coefs (a,b,c) num_real_roots root1 root2
24  double coefs_roots[][6] = {{1, -2, 1, 2, 1.0, 1.0},
25  {1, 0, -1, 2, -1.0, 1.0},
26  {1, -1, -56, 2, -7.0, 8.0},
27  {5.0, 0, 1, 0, 0, 0},
28  {2.0, 0, 0, 2, 0, 0}};
29 
30  for (auto& coefs_root : coefs_roots)
31  {
32  const double a = coefs_root[0], b = coefs_root[1], c = coefs_root[2];
33  const int num_roots_good = static_cast<int>(coefs_root[3]);
34  const double r1_good = coefs_root[4], r2_good = coefs_root[5];
35 
36  double r1, r2;
37  int num_roots = mrpt::math::solve_poly2(a, b, c, r1, r2);
38 
39  const std::string sTestStr = mrpt::format(
40  "\nSolving: %.02f * x^2 + %.02f * x + %.02f = 0\n", a, b, c);
41 
42  EXPECT_EQ(num_roots, num_roots_good);
43  if (num_roots >= 1)
44  {
45  EXPECT_NEAR(r1, r1_good, eps) << sTestStr;
46  }
47  if (num_roots >= 2)
48  {
49  EXPECT_NEAR(r2, r2_good, eps) << sTestStr;
50  }
51  }
52 }
53 
54 TEST(poly_roots, solve_poly3)
55 {
56  // `x^3+ a*x^2 + b*x + c = 0`
57  // Table:
58  // coefs (a,b,c) num_real_roots root1 root2
59  double coefs_roots[][7] = {{-6, 11, -6, 3, 1.0, 2.0, 3.0},
60  {2, 3, 4, 1, -1.650629191439386, 0, 0},
61  {0, -91, -90, 3, -1.0, -9.0, 10.0}};
62 
63  for (auto& coefs_root : coefs_roots)
64  {
65  const double a = coefs_root[0], b = coefs_root[1], c = coefs_root[2];
66  const int num_roots_good = static_cast<int>(coefs_root[3]);
67  const double roots_good[3] = {coefs_root[4], coefs_root[5],
68  coefs_root[6]};
69 
70  double roots[3];
71  int num_roots = mrpt::math::solve_poly3(roots, a, b, c);
72 
73  const std::string sTestStr = mrpt::format(
74  "\nSolving: x^3 + %.02f * x^2 + %.02f * x + %.02f = 0\n", a, b, c);
75 
76  EXPECT_EQ(num_roots, num_roots_good);
77  for (int k = 0; k < num_roots; k++)
78  {
79  bool match = false;
80  for (int j = 0; j < num_roots; j++)
81  if (std::abs(roots[k] - roots_good[j]) < eps) match = true;
82 
83  EXPECT_TRUE(match) << sTestStr << "k: " << k << std::endl;
84  }
85  }
86 }
87 
88 TEST(poly_roots, solve_poly4)
89 {
90  // `x^4 * a*x^3+ b*x^2 + c*x + d = 0`
91  // Table:
92  // coefs (a,b,c) num_real_roots roots
93  double coefs_roots[][9] = {{-10, 35, -50, 24, 4, 1.0, 2.0, 3.0, 4.0},
94  {-14, 35, 50, 0, 4, -1, 0, 5, 10}};
95 
96  for (auto& coefs_root : coefs_roots)
97  {
98  const double a = coefs_root[0], b = coefs_root[1], c = coefs_root[2],
99  d = coefs_root[3];
100  const int num_roots_good = static_cast<int>(coefs_root[4]);
101  const double roots_good[4] = {coefs_root[5], coefs_root[6],
102  coefs_root[7], coefs_root[8]};
103 
104  double roots[4];
105  int num_roots = mrpt::math::solve_poly4(roots, a, b, c, d);
106 
107  const std::string sTestStr = mrpt::format(
108  "\nSolving: x^4 + %.02f * x^3 + %.02f * x^2 + %.02f * x + %.02f = "
109  "0\n",
110  a, b, c, d);
111 
112  EXPECT_EQ(num_roots, num_roots_good);
113  for (int k = 0; k < num_roots; k++)
114  {
115  bool match = false;
116  for (int j = 0; j < num_roots; j++)
117  if (std::abs(roots[k] - roots_good[j]) < eps) match = true;
118 
119  EXPECT_TRUE(match) << sTestStr << "k: " << k << std::endl;
120  }
121  }
122 }
STL namespace.
TEST(poly_roots, solve_poly2)
const GLubyte * c
Definition: glext.h:6406
int solve_poly4(double *x, double a, double b, double c, double d) noexcept
Solves quartic equation x^4 + a*x^3 + b*x^2 + c*x + d = 0 by Dekart-Euler method. ...
Definition: poly_roots.cpp:254
GLubyte GLubyte b
Definition: glext.h:6372
const double eps
GLsizei const GLchar ** string
Definition: glext.h:4116
std::string format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:16
GLubyte GLubyte GLubyte a
Definition: glext.h:6372
int solve_poly3(double *x, double a, double b, double c) noexcept
Solves cubic equation x^3 + a*x^2 + b*x + c = 0.
Definition: poly_roots.cpp:29
int solve_poly2(double a, double b, double c, double &r1, double &r2) noexcept
Solves equation a*x^2 + b*x + c = 0.
Definition: poly_roots.cpp:401



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 8fe78517f Sun Jul 14 19:43:28 2019 +0200 at lun oct 28 02:10:00 CET 2019