SDDSlib
Loading...
Searching...
No Matches
poly.c
Go to the documentation of this file.
1/**
2 * @file poly.c
3 * @brief Functions for evaluating polynomials and their derivatives, as well as solving quadratic equations.
4 *
5 * @copyright
6 * - (c) 2002 The University of Chicago, as Operator of Argonne National Laboratory.
7 * - (c) 2002 The Regents of the University of California, as Operator of Los Alamos National Laboratory.
8 *
9 * @license
10 * This file is distributed under the terms of the Software License Agreement
11 * found in the file LICENSE included with this distribution.
12 *
13 * @author M. Borland, C. Saunders, R. Soliday
14 */
15
16#include "mdb.h"
17
18/**
19 * @brief Evaluate a polynomial at a given point.
20 *
21 * Given an array of coefficients a and the number of terms n, this function returns the value of
22 * the polynomial at x. The polynomial is assumed to be of the form:
23 * a[0] + a[1]*x + a[2]*x^2 + ... + a[n-1]*x^(n-1).
24 *
25 * @param[in] a Pointer to the array of polynomial coefficients.
26 * @param[in] n Number of coefficients (degree+1 of the polynomial).
27 * @param[in] x The point at which to evaluate the polynomial.
28 * @return The value of the polynomial at x.
29 */
30double poly(double *a, long n, double x)
31{
32 register long i;
33 register double sum, xp;
34
35 sum = 0;
36 xp = 1;
37 for (i = 0; i < n; i++) {
38 sum += xp * a[i];
39 xp *= x;
40 }
41 return (sum);
42}
43
44/**
45 * @brief Evaluate the derivative of a polynomial at a given point.
46 *
47 * Given an array of coefficients a and the number of terms n, this function returns the value
48 * of the derivative of the polynomial at x. The polynomial is assumed to be:
49 * a[0] + a[1]*x + a[2]*x^2 + ...
50 * Its derivative is:
51 * a[1] + 2*a[2]*x + 3*a[3]*x^2 + ...
52 *
53 * @param[in] a Pointer to the array of polynomial coefficients.
54 * @param[in] n Number of coefficients (degree+1 of the polynomial).
55 * @param[in] x The point at which to evaluate the derivative.
56 * @return The value of the derivative at x.
57 */
58double dpoly(double *a, long n, double x) {
59 register long i;
60 register double sum, xp;
61
62 sum = 0;
63 xp = 1;
64 for (i = 1; i < n; i++) {
65 sum += i * xp * a[i];
66 xp *= x;
67 }
68 return (sum);
69}
70
71/**
72 * @brief Evaluate a polynomial with arbitrary powers at a given point.
73 *
74 * This function computes the value of a polynomial at x, where each term may have an arbitrary power.
75 * Given arrays a and power, the polynomial is:
76 * a[0]*x^(power[0]) + a[1]*x^(power[1]) + ... + a[n-1]*x^(power[n-1]).
77 *
78 * @param[in] a Pointer to the array of polynomial coefficients.
79 * @param[in] power Pointer to the array of powers for each term.
80 * @param[in] n Number of terms.
81 * @param[in] x The point at which to evaluate the polynomial.
82 * @return The value of the polynomial at x.
83 */
84double polyp(double *a, long *power, long n, double x) {
85 register long i;
86 register double sum, xp;
87
88 xp = ipow(x, power[0]);
89 sum = xp * a[0];
90 for (i = 1; i < n; i++) {
91 xp *= ipow(x, power[i] - power[i - 1]);
92 sum += xp * a[i];
93 }
94 return (sum);
95}
96
97/**
98 * @brief Evaluate the derivative of a polynomial with arbitrary powers at a given point.
99 *
100 * Given arrays a and power that define a polynomial
101 * a[0]*x^(power[0]) + a[1]*x^(power[1]) + ... + a[n-1]*x^(power[n-1]),
102 * this function returns the derivative of that polynomial at x:
103 * power[0]*a[0]*x^(power[0]-1) + power[1]*a[1]*x^(power[1]-1) + ...
104 *
105 * @param[in] a Pointer to the array of polynomial coefficients.
106 * @param[in] power Pointer to the array of powers for each term.
107 * @param[in] n Number of terms.
108 * @param[in] x The point at which to evaluate the derivative.
109 * @return The value of the derivative at x.
110 */
111double dpolyp(double *a, long *power, long n, double x) {
112 register long i;
113 register double sum, xp;
114
115 xp = ipow(x, power[0] - 1);
116 sum = power[0] * xp * a[0];
117 for (i = 1; i < n; i++) {
118 xp *= ipow(x, power[i] - power[i - 1]);
119 sum += power[i] * xp * a[i];
120 }
121 return (sum);
122}
123
124/**
125 * @brief Solve a quadratic equation for real solutions.
126 *
127 * Given a quadratic equation of the form a*x^2 + b*x + c = 0, this function finds its real solutions, if any.
128 * The solutions are returned in the array solution. The function returns the number of real solutions found:
129 * - 0 if no real solutions,
130 * - 1 if one real solution (repeated root),
131 * - 2 if two real solutions.
132 *
133 * @param[in] a Quadratic coefficient (for x^2).
134 * @param[in] b Linear coefficient (for x).
135 * @param[in] c Constant term.
136 * @param[out] solution Array of size 2 for storing the found solutions.
137 * @return The number of real solutions (0, 1, or 2).
138 */
139int solveQuadratic(double a, double b, double c, double *solution) {
140 double det;
141 if (a == 0) {
142 if (b == 0)
143 return 0;
144 solution[0] = -c / b;
145 return 1;
146 }
147 if ((det = b * b - 4 * a * c) < 0)
148 return 0;
149 if (det == 0) {
150 solution[0] = -b / a;
151 return 1;
152 }
153 solution[0] = (-b - sqrt(det)) / (2 * a);
154 solution[1] = (-b + sqrt(det)) / (2 * a);
155 return 2;
156}
double ipow(const double x, const int64_t p)
Compute x raised to the power p (x^p).
Definition ipow.c:33
double poly(double *a, long n, double x)
Evaluate a polynomial at a given point.
Definition poly.c:30
double dpoly(double *a, long n, double x)
Evaluate the derivative of a polynomial at a given point.
Definition poly.c:58
double dpolyp(double *a, long *power, long n, double x)
Evaluate the derivative of a polynomial with arbitrary powers at a given point.
Definition poly.c:111
double polyp(double *a, long *power, long n, double x)
Evaluate a polynomial with arbitrary powers at a given point.
Definition poly.c:84
int solveQuadratic(double a, double b, double c, double *solution)
Solve a quadratic equation for real solutions.
Definition poly.c:139