MRPT  1.9.9
poly_roots_unittest.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2018, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include <mrpt/math/poly_roots.h>
11 #include <mrpt/core/format.h>
12 #include <gtest/gtest.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  const unsigned int nTests = sizeof(coefs_roots) / sizeof(coefs_roots[0]);
31 
32  for (unsigned int i = 0; i < nTests; i++)
33  {
34  const double a = coefs_roots[i][0], b = coefs_roots[i][1],
35  c = coefs_roots[i][2];
36  const int num_roots_good = static_cast<int>(coefs_roots[i][3]);
37  const double r1_good = coefs_roots[i][4], r2_good = coefs_roots[i][5];
38 
39  double r1, r2;
40  int num_roots = mrpt::math::solve_poly2(a, b, c, r1, r2);
41 
42  const std::string sTestStr = mrpt::format(
43  "\nSolving: %.02f * x^2 + %.02f * x + %.02f = 0\n", a, b, c);
44 
45  EXPECT_EQ(num_roots, num_roots_good);
46  if (num_roots >= 1)
47  {
48  EXPECT_NEAR(r1, r1_good, eps) << sTestStr;
49  }
50  if (num_roots >= 2)
51  {
52  EXPECT_NEAR(r2, r2_good, eps) << sTestStr;
53  }
54  }
55 }
56 
57 TEST(poly_roots, solve_poly3)
58 {
59  // `x^3+ a*x^2 + b*x + c = 0`
60  // Table:
61  // coefs (a,b,c) num_real_roots root1 root2
62  double coefs_roots[][7] = {{-6, 11, -6, 3, 1.0, 2.0, 3.0},
63  {2, 3, 4, 1, -1.650629191439386, 0, 0},
64  {0, -91, -90, 3, -1.0, -9.0, 10.0}};
65 
66  const unsigned int nTests = sizeof(coefs_roots) / sizeof(coefs_roots[0]);
67 
68  for (unsigned int i = 0; i < nTests; i++)
69  {
70  const double a = coefs_roots[i][0], b = coefs_roots[i][1],
71  c = coefs_roots[i][2];
72  const int num_roots_good = static_cast<int>(coefs_roots[i][3]);
73  const double roots_good[3] = {coefs_roots[i][4], coefs_roots[i][5],
74  coefs_roots[i][6]};
75 
76  double roots[3];
77  int num_roots = mrpt::math::solve_poly3(roots, a, b, c);
78 
79  const std::string sTestStr = mrpt::format(
80  "\nSolving: x^3 + %.02f * x^2 + %.02f * x + %.02f = 0\n", a, b, c);
81 
82  EXPECT_EQ(num_roots, num_roots_good);
83  for (int k = 0; k < num_roots; k++)
84  {
85  bool match = false;
86  for (int j = 0; j < num_roots; j++)
87  if (std::abs(roots[k] - roots_good[j]) < eps) match = true;
88 
89  EXPECT_TRUE(match) << sTestStr << "k: " << k << std::endl;
90  }
91  }
92 }
93 
94 TEST(poly_roots, solve_poly4)
95 {
96  // `x^4 * a*x^3+ b*x^2 + c*x + d = 0`
97  // Table:
98  // coefs (a,b,c) num_real_roots roots
99  double coefs_roots[][9] = {{-10, 35, -50, 24, 4, 1.0, 2.0, 3.0, 4.0},
100  {-14, 35, 50, 0, 4, -1, 0, 5, 10}};
101 
102  const unsigned int nTests = sizeof(coefs_roots) / sizeof(coefs_roots[0]);
103 
104  for (unsigned int i = 0; i < nTests; i++)
105  {
106  const double a = coefs_roots[i][0], b = coefs_roots[i][1],
107  c = coefs_roots[i][2], d = coefs_roots[i][3];
108  const int num_roots_good = static_cast<int>(coefs_roots[i][4]);
109  const double roots_good[4] = {coefs_roots[i][5], coefs_roots[i][6],
110  coefs_roots[i][7], coefs_roots[i][8]};
111 
112  double roots[4];
113  int num_roots = mrpt::math::solve_poly4(roots, a, b, c, d);
114 
115  const std::string sTestStr = mrpt::format(
116  "\nSolving: x^4 + %.02f * x^3 + %.02f * x^2 + %.02f * x + %.02f = "
117  "0\n",
118  a, b, c, d);
119 
120  EXPECT_EQ(num_roots, num_roots_good);
121  for (int k = 0; k < num_roots; k++)
122  {
123  bool match = false;
124  for (int j = 0; j < num_roots; j++)
125  if (std::abs(roots[k] - roots_good[j]) < eps) match = true;
126 
127  EXPECT_TRUE(match) << sTestStr << "k: " << k << std::endl;
128  }
129  }
130 }
STL namespace.
TEST(poly_roots, solve_poly2)
const GLubyte * c
Definition: glext.h:6313
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:6279
const double eps
GLsizei const GLchar ** string
Definition: glext.h:4101
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:6279
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: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020