libpappsomspp
Library for mass spectrometry
Toggle main menu visibility
Loading...
Searching...
No Matches
cardano.cpp
Go to the documentation of this file.
1
/**
2
* \file pappsomspp/vendors/tims/mzcalibration/cardano.cpp
3
* \date 17/12/2022
4
* \brief cubic solver adapted from
5
* https://www.codeproject.com/articles/798474/to-solve-a-cubic-equation
6
thanks
7
* to "Sergey Bochkanov" <sergey.bochkanov@alglib.net> for his advise
8
*/
9
10
/*******************************************************************************
11
* Copyright (c) 2022 Olivier Langella <Olivier.Langella@u-psud.fr>.
12
*
13
* This file is part of the PAPPSOms++ library.
14
*
15
* PAPPSOms++ is free software: you can redistribute it and/or modify
16
* it under the terms of the GNU General Public License as published by
17
* the Free Software Foundation, either version 3 of the License, or
18
* (at your option) any later version.
19
*
20
* PAPPSOms++ is distributed in the hope that it will be useful,
21
* but WITHOUT ANY WARRANTY; without even the implied warranty of
22
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23
* GNU General Public License for more details.
24
*
25
* You should have received a copy of the GNU General Public License
26
* along with PAPPSOms++. If not, see <http://www.gnu.org/licenses/>.
27
*
28
******************************************************************************/
29
30
#include "
cardano.h
"
31
32
33
#include <cmath>
34
#include <QDebug>
35
36
37
const
double
BUFFER_SQRT3
{std::sqrt(3.0)};
38
const
double
BUFFER_inv27
{1.0 / 27.0};
39
const
double
BUFFER_pow11
{std::pow(10.0, -11.0)};
40
41
void
42
cubic_solver
(
InHousePolynomialSolverResult
&res,
double
a1,
double
b,
double
c,
double
d)
43
{
44
45
/**
46
* @todo Cardaono cubic solver
47
*
48
* adapted in c++ from
49
* https://www.codeproject.com/articles/798474/to-solve-a-cubic-equation
50
thanks
51
* to "Sergey Bochkanov" <sergey.bochkanov@alglib.net> for his advise
52
*
53
* Cubic Equation
54
https://github.com/harveytriana/CubicEquation
55
Quartic Equation
56
https://github.com/harveytriana/QuarticEcuation
57
*/
58
double
a, p, q, u, v;
59
double
r, alpha;
60
a = b / a1;
61
b = c / a1;
62
c = d / a1;
63
64
double
aover3(a / 3.0);
65
p = -(a * aover3) + b;
66
q = (2.0 *
BUFFER_inv27
* a * a * a) - (b * aover3) + c;
67
d = q * q / 4.0 + p * p * p *
BUFFER_inv27
;
68
if
(std::abs(d) <
BUFFER_pow11
)
69
d = 0;
70
// 3 cases D > 0, D == 0 and D < 0
71
if
(d > 1e-20)
72
{
73
double
dsqrt = std::sqrt(d);
74
u = std::cbrt(-q / 2.0 + dsqrt);
75
v = std::cbrt(-q / 2.0 - dsqrt);
76
res.x1 = u + v - aover3;
77
/*
78
res.x2.real(-(u + v) / 2.0 - aover3);
79
res.x2.imag(BUFFER_SQRT3 / 2.0 * (u - v));
80
res.x3.real(res.x2.real());
81
res.x3.imag(-res.x2.imag());
82
*/
83
res.type =
CardanoResultCase::positived
;
84
}
85
if
(std::abs(d) <= 1e-20)
86
{
87
u = std::cbrt(-q / 2.0);
88
v = u;
89
res.x1 = u + v - aover3;
90
// res.x2.real(-(u + v) / 2.0 - aover3);
91
res.type =
CardanoResultCase::zerod
;
92
}
93
if
(d < -1e-20)
94
{
95
r = std::cbrt(std::sqrt(-p * p * p *
BUFFER_inv27
));
96
alpha = std::atan(std::sqrt(-d) / -q * 2.0);
97
if
(q > 0)
// if q > 0 the angle becomes 2 * PI - alpha
98
alpha = 2.0 * M_PI - alpha;
99
100
res.x1 = r * (std::cos((6.0 * M_PI - alpha) / 3.0) + std::cos(alpha / 3.0)) - aover3;
101
/*
102
res.x2.real(r * (std::cos((2.0 * M_PI + alpha) / 3.0) +
103
std::cos((4.0 * M_PI - alpha) / 3.0)) -
104
aover3);
105
res.x3.real(r * (std::cos((4.0 * M_PI + alpha) / 3.0) +
106
std::cos((2.0 * M_PI - alpha) / 3.0)) -
107
aover3);
108
*/
109
res.type =
CardanoResultCase::negatived
;
110
}
111
}
112
113
114
InHousePolynomialSolverResult
115
inHousePolynomialSolve
(
const
std::vector<double> &polynome)
116
{
117
InHousePolynomialSolverResult
res;
118
res.type =
CardanoResultCase::notvalid
;
119
std::size_t polynome_size = polynome.size();
120
121
double
a, b, c, delta;
122
123
switch
(polynome_size)
124
{
125
case
0:
126
break
;
127
case
1:
128
break
;
129
case
2:
// linear// equation ax + b = 0
130
a = polynome[1];
131
b = polynome[0];
132
if
(a != 0)
133
{
134
res.x1 = -b / a;
135
res.type =
CardanoResultCase::line
;
136
}
137
break
;
138
case
3:
139
// quadratic equation ax**2 + bx + c = 0
140
a = polynome[2];
141
if
(a == 0)
142
return
res;
143
b = polynome[1];
144
c = polynome[0];
145
146
if
(a == 0)
147
return
res;
148
// calculate the discriminant
149
delta = (b * b) - (a * c * 4);
150
// qDebug() << delta;
151
if
(delta < 0)
152
{
153
}
154
else
if
(std::abs(delta) <= 1e-20)
155
{
156
res.x1 = -b / (a * 2);
157
// qDebug() << x1.real() << " " << x2.real();
158
res.type =
CardanoResultCase::quadratic
;
159
}
160
else
161
{
162
// find two solutions
163
delta = std::sqrt(delta);
164
res.x1 = (-b + delta) / (a * 2);
165
res.x2 = (-b - delta) / (a * 2);
166
167
// qDebug() << x1.real() << " " << x2.real();
168
res.type =
CardanoResultCase::quadratic
;
169
}
170
break
;
171
case
4:
172
cubic_solver
(res, polynome[3], polynome[2], polynome[1], polynome[0]);
173
}
174
return
res;
175
}
BUFFER_SQRT3
const double BUFFER_SQRT3
Definition
cardano.cpp:37
cubic_solver
void cubic_solver(InHousePolynomialSolverResult &res, double a1, double b, double c, double d)
Definition
cardano.cpp:42
BUFFER_inv27
const double BUFFER_inv27
Definition
cardano.cpp:38
BUFFER_pow11
const double BUFFER_pow11
Definition
cardano.cpp:39
inHousePolynomialSolve
InHousePolynomialSolverResult inHousePolynomialSolve(const std::vector< double > &polynome)
Definition
cardano.cpp:115
cardano.h
CardanoResultCase::positived
@ positived
Definition
cardano.h:40
CardanoResultCase::line
@ line
Definition
cardano.h:42
CardanoResultCase::notvalid
@ notvalid
Definition
cardano.h:37
CardanoResultCase::zerod
@ zerod
Definition
cardano.h:38
CardanoResultCase::quadratic
@ quadratic
Definition
cardano.h:41
CardanoResultCase::negatived
@ negatived
Definition
cardano.h:39
InHousePolynomialSolverResult
Definition
cardano.h:47
pappsomspp
core
vendors
tims
mzcalibration
cardano.cpp
Generated on
for libpappsomspp by
1.17.0