1 package org.djutils.polynomialroots;
2
3 import static org.junit.jupiter.api.Assertions.assertArrayEquals;
4 import static org.junit.jupiter.api.Assertions.assertEquals;
5
6 import org.djutils.complex.Complex;
7 import org.junit.jupiter.api.Test;
8
9
10
11
12
13
14
15
16
17
18 public class TestPolynomialRoots
19 {
20
21
22
23
24
25 @Test
26 public void quadraticTest()
27 {
28 double[] paramValues = new double[] { 0, 1, 2, 3, 4, Math.PI, -Math.E, 0.0001, 10000 };
29 for (double a : paramValues)
30 {
31 for (double b : paramValues)
32 {
33 for (double c : paramValues)
34 {
35
36 Complex[] roots = PolynomialRoots.quadraticRoots(a, b, c);
37 int expectedNumber = a != 0 ? 2 : b != 0 ? 1 : 0;
38 assertEquals(expectedNumber, roots.length, "number of roots");
39
40
41 for (Complex root : roots)
42 {
43
44 Complex result = root.times(root).times(a).plus(root.times(b)).plus(c);
45 double margin = root.norm() / 1e6;
46 assertEquals(0, result.re, margin, "root is a root of the equation; re");
47 assertEquals(0, result.im, margin, "root is a root of the equation; im");
48 }
49
50 Complex[] alternate = PolynomialRoots.cubicRoots(0, a, b, c);
51 assertArrayEquals(roots, alternate, "cubic solver returns same results as quadratic solver if a is 0");
52 }
53 }
54 }
55 double q1 = 3 * Math.sqrt(Double.MAX_VALUE);
56 Complex[] roots = PolynomialRoots.quadraticRoots(q1, 1);
57 assertEquals(2, roots.length, "two roots");
58 assertEquals(0, roots[0].re, 0.0001, "first root is 0: re");
59 assertEquals(0, roots[0].im, 0.0001, "first root is 0: im");
60
61 assertEquals(-q1, roots[1].re, q1 / 1e7, "second root is 0: re");
62 assertEquals(0, roots[1].im, 0.0001, "second root is 0: im");
63 }
64
65
66
67
68 @Test
69 public void cubicTest()
70 {
71 double[] paramValues = new double[] { 0, 1, 2, 3, 4, Math.PI, -Math.E, 0.001, 1000 };
72 for (double a : paramValues)
73 {
74 for (double b : paramValues)
75 {
76 for (double c : paramValues)
77 {
78 for (double d : paramValues)
79 {
80
81 Complex[] roots = PolynomialRoots.cubicRoots(a, b, c, d);
82 int expectedNumber = a != 0 ? 3 : b != 0 ? 2 : c != 0 ? 1 : 0;
83 assertEquals(expectedNumber, roots.length, "number of roots");
84
85
86 for (Complex root : roots)
87 {
88
89 Complex result = root.times(root).times(root).times(a).plus(root.times(root).times(b))
90 .plus(root.times(c)).plus(d);
91 double margin = root.norm() / 1e6;
92 assertEquals(0, result.re, margin, "root is a root of the equation; re");
93 assertEquals(0, result.im, margin, "root is a root of the equation; im");
94 }
95
96 }
97 }
98 }
99 }
100 }
101
102
103
104
105 @Test
106 public void quarticTest()
107 {
108 double[] paramValues = new double[] { 0, 1, 2, 3, 4, Math.PI, -Math.E, 0.01, 100 };
109 for (double a : paramValues)
110 {
111 for (double b : paramValues)
112 {
113 for (double c : paramValues)
114 {
115 for (double d : paramValues)
116 {
117 for (double e : paramValues)
118 {
119
120 Complex[] roots = PolynomialRoots.quarticRoots(a, b, c, d, e);
121 int expectedNumber = a != 0 ? 4 : b != 0 ? 3 : c != 0 ? 2 : d != 0 ? 1 : 0;
122 assertEquals(expectedNumber, roots.length, "number of roots");
123
124
125 for (Complex root : roots)
126 {
127
128
129 Complex result = root.times(root).times(root).times(root).times(a)
130 .plus(root.times(root).times(root).times(b)).plus(root.times(root).times(c))
131 .plus(root.times(d)).plus(e);
132 double margin = root.norm() / 2e5;
133 assertEquals(0, result.re, margin, "root is a root of the equation; re");
134 assertEquals(0, result.im, margin, "root is a root of the equation; im");
135 }
136
137 }
138 }
139 }
140 }
141 }
142 }
143 }