2 Copyright 2005, 2006 Computer Vision Lab,
3 Ecole Polytechnique Federale de Lausanne (EPFL), Switzerland.
6 This file is part of BazAR.
8 BazAR is free software; you can redistribute it and/or modify it under the
9 terms of the GNU General Public License as published by the Free Software
10 Foundation; either version 2 of the License, or (at your option) any later
13 BazAR is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
15 PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License along with
18 BazAR; if not, write to the Free Software Foundation, Inc., 51 Franklin
19 Street, Fifth Floor, Boston, MA 02110-1301, USA
21 /// \file polynom_solver.cpp
22 /// \brief Functions to calculate roots of polynomials (Author: Mustafa Ozuysal, modified by Vincent Lepetit)
27 #include "polynom_solver.h"
28 #include <general/general.h>
32 int solve_deg2(double a
, double b
, double c
, double & x1
, double & x2
)
34 double delta
= b
* b
- 4 * a
* c
;
36 if (delta
< 0) return 0;
38 double inv_2a
= 0.5 / a
;
47 double sqrt_delta
= sqrt(delta
);
48 x1
= (-b
+ sqrt_delta
) * inv_2a
;
49 x2
= (-b
- sqrt_delta
) * inv_2a
;
54 /// Reference : Eric W. Weisstein. "Cubic Equation." From MathWorld--A Wolfram Web Resource.
55 /// http://mathworld.wolfram.com/CubicEquation.html
56 /// \return Number of real roots found.
57 int solve_deg3(double a
, double b
, double c
, double d
,
58 double & x0
, double & x1
, double & x2
)
62 // Solve second order sytem
65 // Solve first order system
74 return solve_deg2(b
, c
, d
, x0
, x1
);
77 // Calculate the normalized form x^3 + a2 * x^2 + a1 * x + a0 = 0
78 double inv_a
= 1. / a
;
79 double b_a
= inv_a
* b
, b_a2
= b_a
* b_a
;
80 double c_a
= inv_a
* c
;
81 double d_a
= inv_a
* d
;
83 // Solve the cubic equation
84 double Q
= (3 * c_a
- b_a2
) / 9;
85 double R
= (9 * b_a
* c_a
- 27 * d_a
- 2 * b_a
* b_a2
) / 54;
86 double Q3
= Q
* Q
* Q
;
87 double D
= Q3
+ R
* R
;
88 double b_a_3
= (1. / 3.) * b_a
;
92 x0
= x1
= x2
= - b_a_3
;
97 x0
= pow(2 * R
, 1 / 3.0) - b_a_3
;
105 double theta
= acos(R
/ sqrt(-Q3
));
106 double sqrt_Q
= sqrt(-Q
);
107 x0
= 2 * sqrt_Q
* cos(theta
/ 3.0) - b_a_3
;
108 x1
= 2 * sqrt_Q
* cos((theta
+ 2 * M_PI
)/ 3.0) - b_a_3
;
109 x2
= 2 * sqrt_Q
* cos((theta
+ 4 * M_PI
)/ 3.0) - b_a_3
;
114 // D > 0, only one real root
115 double AD
= pow(fabs(R
) + sqrt(D
), 1.0 / 3.0) * (R
> 0 ? 1 : (R
< 0 ? -1 : 0));
116 double BD
= (AD
== 0) ? 0 : -Q
/ AD
;
118 // Calculate the only real root
119 x0
= AD
+ BD
- b_a_3
;
124 /// Reference : Eric W. Weisstein. "Quartic Equation." From MathWorld--A Wolfram Web Resource.
125 /// http://mathworld.wolfram.com/QuarticEquation.html
126 /// \return Number of real roots found.
127 int solve_deg4(double a
, double b
, double c
, double d
, double e
,
128 double & x0
, double & x1
, double & x2
, double & x3
)
133 return solve_deg3(b
, c
, d
, e
, x0
, x1
, x2
);
136 // Normalize coefficients
137 double inv_a
= 1. / a
;
138 b
*= inv_a
; c
*= inv_a
; d
*= inv_a
; e
*= inv_a
;
139 double b2
= b
* b
, bc
= b
* c
, b3
= b2
* b
;
141 // Solve resultant cubic
143 int n
= solve_deg3(1, -c
, d
* b
- 4 * e
, 4 * c
* e
- d
* d
- b2
* e
, r0
, r1
, r2
);
144 if (n
== 0) return 0;
147 double R2
= 0.25 * b2
- c
+ r0
, R
;
152 double inv_R
= 1. / R
;
154 int nb_real_roots
= 0;
156 // Calculate D^2 and E^2
160 double temp
= r0
* r0
- 4 * e
;
165 double sqrt_temp
= sqrt(temp
);
166 D2
= 0.75 * b2
- 2 * c
+ 2 * sqrt_temp
;
167 E2
= D2
- 4 * sqrt_temp
;
172 double u
= 0.75 * b2
- 2 * c
- R2
, v
= 0.25 * inv_R
* (4 * bc
- 8 * d
- b3
);
177 double b_4
= 0.25 * b
, R_2
= 0.5 * R
;
181 double D_2
= 0.5 * D
;
182 x0
= R_2
+ D_2
- b_4
;
189 double E_2
= 0.5 * E
;
190 if (nb_real_roots
== 0)
192 x0
= - R_2
+ E_2
- b_4
;
198 x2
= - R_2
+ E_2
- b_4
;
204 return nb_real_roots
;