Added script front-end for primer-design code
[htsworkflow.git] / htswanalysis / MACS / lib / gsl / gsl-1.11 / poly / zsolve_quadratic.c
1 /* poly/zsolve_quadratic.c
2  * 
3  * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or (at
8  * your option) any later version.
9  * 
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  * 
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19
20 /* complex_solve_quadratic.c - finds complex roots of a x^2 + b x + c = 0 */
21
22 #include <config.h>
23 #include <math.h>
24 #include <gsl/gsl_complex.h>
25 #include <gsl/gsl_poly.h>
26
27 int
28 gsl_poly_complex_solve_quadratic (double a, double b, double c,
29                                   gsl_complex *z0, gsl_complex *z1)
30 {
31   double disc = b * b - 4 * a * c;
32
33   if (a == 0) /* Handle linear case */
34     {
35       if (b == 0)
36         {
37           return 0;
38         }
39       else
40         {
41           GSL_REAL(*z0) = -c / b;
42           GSL_IMAG(*z0) = 0;
43           return 1;
44         };
45     }
46
47   if (disc > 0)
48     {
49       if (b == 0)
50         {
51           double s = fabs (0.5 * sqrt (disc) / a);
52           GSL_REAL (*z0) = -s;
53           GSL_IMAG (*z0) = 0;
54           GSL_REAL (*z1) = s;
55           GSL_IMAG (*z1) = 0;
56         }
57       else
58         {
59           double sgnb = (b > 0 ? 1 : -1);
60           double temp = -0.5 * (b + sgnb * sqrt (disc));
61           double r1 = temp / a;
62           double r2 = c / temp;
63
64           if (r1 < r2)
65             {
66               GSL_REAL (*z0) = r1;
67               GSL_IMAG (*z0) = 0;
68               GSL_REAL (*z1) = r2;
69               GSL_IMAG (*z1) = 0;
70             }
71           else
72             {
73               GSL_REAL (*z0) = r2;
74               GSL_IMAG (*z0) = 0;
75               GSL_REAL (*z1) = r1;
76               GSL_IMAG (*z1) = 0;
77             }
78         }
79       return 2;
80     }
81   else if (disc == 0)
82     {
83       GSL_REAL (*z0) = -0.5 * b / a;
84       GSL_IMAG (*z0) = 0;
85
86       GSL_REAL (*z1) = -0.5 * b / a;
87       GSL_IMAG (*z1) = 0;
88
89       return 2;
90     }
91   else
92     {
93       double s = fabs (0.5 * sqrt (-disc) / a);
94
95       GSL_REAL (*z0) = -0.5 * b / a;
96       GSL_IMAG (*z0) = -s;
97
98       GSL_REAL (*z1) = -0.5 * b / a;
99       GSL_IMAG (*z1) = s;
100
101       return 2;
102     }
103 }