Main MRPT website > C++ reference for MRPT 1.5.6
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-2017, 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 
11 #include <mrpt/math/poly_roots.h>
12 #include <mrpt/system/os.h>
13 #include <gtest/gtest.h>
14 #include <cmath>
15 
16 using namespace std;
17 
18 const double eps = 1e-9;
19 
20 TEST(poly_roots,solve_poly2)
21 {
22  // `a*x^2 + b*x + c = 0`
23  // Table:
24  // coefs (a,b,c) num_real_roots root1 root2
25  double coefs_roots[][6] = {
26  { 1 ,-2 , 1 , 2, 1.0, 1.0 },
27  { 1 , 0 ,-1 , 2, -1.0, 1.0 },
28  { 1 ,-1 ,-56 , 2, -7.0, 8.0 },
29  { 5.0 , 0 , 1 , 0, 0, 0 },
30  { 2.0 , 0 , 0 , 2, 0, 0 }
31  };
32 
33  const unsigned int nTests = sizeof(coefs_roots)/sizeof(coefs_roots[0]);
34 
35  for (unsigned int i=0;i<nTests;i++)
36  {
37  const double a = coefs_roots[i][0], b = coefs_roots[i][1], c = coefs_roots[i][2];
38  const int num_roots_good = static_cast<int>( coefs_roots[i][3] );
39  const double r1_good = coefs_roots[i][4], r2_good = coefs_roots[i][5];
40 
41  double r1,r2;
42  int num_roots = mrpt::math::solve_poly2(a,b,c, r1,r2);
43 
44  const std::string sTestStr = mrpt::format("\nSolving: %.02f * x^2 + %.02f * x + %.02f = 0\n", a,b,c);
45 
46  EXPECT_EQ(num_roots,num_roots_good);
47  if (num_roots>=1) {
48  EXPECT_NEAR(r1,r1_good, eps) << sTestStr;
49  }
50  if (num_roots>=2) {
51  EXPECT_NEAR(r2,r2_good, eps) << sTestStr;
52  }
53  }
54 }
55 
56 TEST(poly_roots,solve_poly3)
57 {
58  // `x^3+ a*x^2 + b*x + c = 0`
59  // Table:
60  // coefs (a,b,c) num_real_roots root1 root2
61  double coefs_roots[][7] = {
62  { -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 
67  const unsigned int nTests = sizeof(coefs_roots)/sizeof(coefs_roots[0]);
68 
69  for (unsigned int i=0;i<nTests;i++)
70  {
71  const double a = coefs_roots[i][0], b = coefs_roots[i][1], 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], coefs_roots[i][6] };
74 
75  double roots[3];
76  int num_roots = mrpt::math::solve_poly3(roots,a,b,c);
77 
78  const std::string sTestStr = mrpt::format("\nSolving: x^3 + %.02f * x^2 + %.02f * x + %.02f = 0\n", a,b,c);
79 
80  EXPECT_EQ(num_roots,num_roots_good);
81  for (int k=0;k<num_roots;k++) {
82  bool match = false;
83  for (int j=0;j<num_roots;j++)
84  if (std::abs(roots[k]-roots_good[j])<eps)
85  match=true;
86 
87  EXPECT_TRUE(match) << sTestStr << "k: " << k << std::endl;
88  }
89  }
90 }
91 
92 TEST(poly_roots,solve_poly4)
93 {
94  // `x^4 * a*x^3+ b*x^2 + c*x + d = 0`
95  // Table:
96  // coefs (a,b,c) num_real_roots roots
97  double coefs_roots[][9] = {
98  {-10 , 35 , -50 , 24 , 4, 1.0, 2.0, 3.0, 4.0 },
99  {-14 , 35 , 50 , 0 , 4, -1, 0, 5, 10 }
100  };
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], c = coefs_roots[i][2], d = coefs_roots[i][3];
107  const int num_roots_good = static_cast<int>( coefs_roots[i][4] );
108  const double roots_good[4] = { coefs_roots[i][5], coefs_roots[i][6], coefs_roots[i][7], coefs_roots[i][8] };
109 
110  double roots[4];
111  int num_roots = mrpt::math::solve_poly4(roots,a,b,c,d);
112 
113  const std::string sTestStr = mrpt::format("\nSolving: x^4 + %.02f * x^3 + %.02f * x^2 + %.02f * x + %.02f = 0\n", a,b,c,d);
114 
115  EXPECT_EQ(num_roots,num_roots_good);
116  for (int k=0;k<num_roots;k++) {
117  bool match = false;
118  for (int j=0;j<num_roots;j++)
119  if (std::abs(roots[k]-roots_good[j])<eps)
120  match=true;
121 
122  EXPECT_TRUE(match) << sTestStr << "k: " << k << std::endl;
123  }
124  }
125 }
int BASE_IMPEXP solve_poly3(double *x, double a, double b, double c) MRPT_NO_THROWS
Solves cubic equation x^3 + a*x^2 + b*x + c = 0.
Definition: poly_roots.cpp:29
int BASE_IMPEXP solve_poly4(double *x, double a, double b, double c, double d) MRPT_NO_THROWS
Solves quartic equation x^4 + a*x^3 + b*x^2 + c*x + d = 0 by Dekart-Euler method. ...
Definition: poly_roots.cpp:215
STL namespace.
TEST(poly_roots, solve_poly2)
const GLubyte * c
Definition: glext.h:5590
std::string BASE_IMPEXP format(const char *fmt,...) MRPT_printf_format_check(1
A std::string version of C sprintf.
Definition: format.cpp:21
GLubyte GLubyte b
Definition: glext.h:5575
const double eps
GLsizei const GLchar ** string
Definition: glext.h:3919
int BASE_IMPEXP solve_poly2(double a, double b, double c, double &r1, double &r2) MRPT_NO_THROWS
Solves equation a*x^2 + b*x + c = 0.
Definition: poly_roots.cpp:302
GLubyte GLubyte GLubyte a
Definition: glext.h:5575



Page generated by Doxygen 1.8.14 for MRPT 1.5.6 Git: 4c65e8431 Tue Apr 24 08:18:17 2018 +0200 at lun oct 28 01:35:26 CET 2019