1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.complex;
23
24 import java.io.Serializable;
25
26 import org.hipparchus.exception.LocalizedCoreFormats;
27 import org.hipparchus.exception.MathIllegalArgumentException;
28 import org.hipparchus.exception.MathIllegalStateException;
29 import org.hipparchus.util.FastMath;
30 import org.hipparchus.util.SinCos;
31
32
33
34
35
36 public class RootsOfUnity implements Serializable {
37
38
39 private static final long serialVersionUID = 20120201L;
40
41
42 private int omegaCount;
43
44
45 private double[] omegaReal;
46
47
48
49
50
51
52 private double[] omegaImaginaryCounterClockwise;
53
54
55
56
57
58 private double[] omegaImaginaryClockwise;
59
60
61
62
63
64
65 private boolean isCounterClockWise;
66
67
68
69
70 public RootsOfUnity() {
71 omegaCount = 0;
72 omegaReal = null;
73 omegaImaginaryCounterClockwise = null;
74 omegaImaginaryClockwise = null;
75 isCounterClockWise = true;
76 }
77
78
79
80
81
82
83
84
85
86 public boolean isCounterClockWise()
87 throws MathIllegalStateException {
88 synchronized (this) {
89 if (omegaCount == 0) {
90 throw new MathIllegalStateException(
91 LocalizedCoreFormats.ROOTS_OF_UNITY_NOT_COMPUTED_YET);
92 }
93 return isCounterClockWise;
94 }
95 }
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114 public void computeRoots(int n) throws MathIllegalArgumentException {
115
116 if (n == 0) {
117 throw new MathIllegalArgumentException(
118 LocalizedCoreFormats.CANNOT_COMPUTE_0TH_ROOT_OF_UNITY);
119 }
120
121 synchronized (this) {
122 isCounterClockWise = n > 0;
123
124
125 final int absN = FastMath.abs(n);
126
127 if (absN == omegaCount) {
128 return;
129 }
130
131
132 final double t = 2.0 * FastMath.PI / absN;
133 final SinCos sc = FastMath.sinCos(t);
134 omegaReal = new double[absN];
135 omegaImaginaryCounterClockwise = new double[absN];
136 omegaImaginaryClockwise = new double[absN];
137 omegaReal[0] = 1.0;
138 omegaImaginaryCounterClockwise[0] = 0.0;
139 omegaImaginaryClockwise[0] = 0.0;
140 for (int i = 1; i < absN; i++) {
141 omegaReal[i] = omegaReal[i - 1] * sc.cos() -
142 omegaImaginaryCounterClockwise[i - 1] * sc.sin();
143 omegaImaginaryCounterClockwise[i] = omegaReal[i - 1] * sc.sin() +
144 omegaImaginaryCounterClockwise[i - 1] * sc.cos();
145 omegaImaginaryClockwise[i] = -omegaImaginaryCounterClockwise[i];
146 }
147 omegaCount = absN;
148 }
149 }
150
151
152
153
154
155
156
157
158
159 public double getReal(int k)
160 throws MathIllegalArgumentException, MathIllegalStateException {
161
162 synchronized (this) {
163 if (omegaCount == 0) {
164 throw new MathIllegalStateException(
165 LocalizedCoreFormats.ROOTS_OF_UNITY_NOT_COMPUTED_YET);
166 }
167 if ((k < 0) || (k >= omegaCount)) {
168 throw new MathIllegalArgumentException(
169 LocalizedCoreFormats.OUT_OF_RANGE_ROOT_OF_UNITY_INDEX,
170 Integer.valueOf(k),
171 Integer.valueOf(0),
172 Integer.valueOf(omegaCount - 1));
173 }
174
175 return omegaReal[k];
176 }
177 }
178
179
180
181
182
183
184
185
186
187 public double getImaginary(int k)
188 throws MathIllegalArgumentException, MathIllegalStateException {
189
190 synchronized (this) {
191 if (omegaCount == 0) {
192 throw new MathIllegalStateException(
193 LocalizedCoreFormats.ROOTS_OF_UNITY_NOT_COMPUTED_YET);
194 }
195 if ((k < 0) || (k >= omegaCount)) {
196 throw new MathIllegalArgumentException(
197 LocalizedCoreFormats.OUT_OF_RANGE_ROOT_OF_UNITY_INDEX,
198 Integer.valueOf(k),
199 Integer.valueOf(0),
200 Integer.valueOf(omegaCount - 1));
201 }
202
203 return isCounterClockWise ? omegaImaginaryCounterClockwise[k] :
204 omegaImaginaryClockwise[k];
205 }
206 }
207
208
209
210
211
212
213
214
215
216
217 public int getNumberOfRoots() {
218 synchronized (this) {
219 return omegaCount;
220 }
221 }
222 }