Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||||||
ComplexUtils |
|
| 2.8666666666666667;2.867 |
1 | /* |
|
2 | * Copyright 2003-2004 The Apache Software Foundation. |
|
3 | * |
|
4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
|
5 | * you may not use this file except in compliance with the License. |
|
6 | * You may obtain a copy of the License at |
|
7 | * |
|
8 | * http://www.apache.org/licenses/LICENSE-2.0 |
|
9 | * |
|
10 | * Unless required by applicable law or agreed to in writing, software |
|
11 | * distributed under the License is distributed on an "AS IS" BASIS, |
|
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
13 | * See the License for the specific language governing permissions and |
|
14 | * limitations under the License. |
|
15 | */ |
|
16 | ||
17 | package org.apache.commons.math.complex; |
|
18 | ||
19 | import org.apache.commons.math.util.MathUtils; |
|
20 | ||
21 | /** |
|
22 | * Implementations of various transcendental functions for |
|
23 | * {@link org.apache.commons.math.complex.Complex} arguments. |
|
24 | * |
|
25 | * Reference: |
|
26 | * <ul> |
|
27 | * <li><a href="http://myweb.lmu.edu/dmsmith/ZMLIB.pdf"> |
|
28 | * Multiple Precision Complex Arithmetic and Functions</a></li> |
|
29 | * </ul> |
|
30 | * |
|
31 | * @version $Revision$ $Date: 2005-08-24 15:06:52 -0700 (Wed, 24 Aug 2005) $ |
|
32 | */ |
|
33 | public class ComplexUtils { |
|
34 | ||
35 | /** |
|
36 | * Default constructor. |
|
37 | */ |
|
38 | private ComplexUtils() { |
|
39 | 0 | super(); |
40 | 0 | } |
41 | ||
42 | /** |
|
43 | * Compute the <a href="http://mathworld.wolfram.com/InverseCosine.html"> |
|
44 | * inverse cosine</a> for the given complex argument. |
|
45 | * @param z the value whose inverse cosine is to be returned. |
|
46 | * @return the inverse cosine of <code>z</code>. |
|
47 | */ |
|
48 | public static Complex acos(Complex z) { |
|
49 | 4 | if (z.isNaN()) { |
50 | 2 | return Complex.NaN; |
51 | } |
|
52 | ||
53 | 2 | return Complex.I.negate().multiply(log(z.add( |
54 | Complex.I.multiply(sqrt1z(z))))); |
|
55 | } |
|
56 | ||
57 | /** |
|
58 | * Compute the <a href="http://mathworld.wolfram.com/InverseSine.html"> |
|
59 | * inverse sine</a> for the given complex argument. |
|
60 | * @param z the value whose inverse sine is to be returned. |
|
61 | * @return the inverse sine of <code>z</code>. |
|
62 | */ |
|
63 | public static Complex asin(Complex z) { |
|
64 | 4 | if (z.isNaN()) { |
65 | 2 | return Complex.NaN; |
66 | } |
|
67 | ||
68 | 2 | return Complex.I.negate().multiply(log(sqrt1z(z).add( |
69 | Complex.I.multiply(z)))); |
|
70 | } |
|
71 | ||
72 | /** |
|
73 | * Compute the <a href="http://mathworld.wolfram.com/InverseTangent.html"> |
|
74 | * inverse tangent</a> for the given complex argument. |
|
75 | * @param z the value whose inverse tangent is to be returned. |
|
76 | * @return the inverse tangent of <code>z</code>. |
|
77 | */ |
|
78 | public static Complex atan(Complex z) { |
|
79 | 4 | if (z.isNaN()) { |
80 | 2 | return Complex.NaN; |
81 | } |
|
82 | ||
83 | ||
84 | 2 | return Complex.I.multiply( |
85 | log(Complex.I.add(z).divide(Complex.I.subtract(z)))) |
|
86 | .divide(new Complex(2.0, 0.0)); |
|
87 | } |
|
88 | ||
89 | /** |
|
90 | * Compute the <a href="http://mathworld.wolfram.com/Cosine.html">cosine</a> |
|
91 | * for the given complex argument. |
|
92 | * @param z the value whose cosine is to be returned. |
|
93 | * @return the cosine of <code>z</code>. |
|
94 | */ |
|
95 | public static Complex cos(Complex z) { |
|
96 | 4 | if (z.isNaN()) { |
97 | 2 | return Complex.NaN; |
98 | } |
|
99 | ||
100 | 2 | double a = z.getReal(); |
101 | 2 | double b = z.getImaginary(); |
102 | ||
103 | 2 | return new Complex(Math.cos(a) * MathUtils.cosh(b), |
104 | -Math.sin(a) * MathUtils.sinh(b)); |
|
105 | } |
|
106 | ||
107 | /** |
|
108 | * Compute the <a href="http://mathworld.wolfram.com/HyperbolicCosine.html"> |
|
109 | * hyperbolic cosine</a> for the given complex argument. |
|
110 | * @param z the value whose hyperbolic cosine is to be returned. |
|
111 | * @return the hyperbolic cosine of <code>z</code>. |
|
112 | */ |
|
113 | public static Complex cosh(Complex z) { |
|
114 | 4 | if (z.isNaN()) { |
115 | 2 | return Complex.NaN; |
116 | } |
|
117 | ||
118 | 2 | double a = z.getReal(); |
119 | 2 | double b = z.getImaginary(); |
120 | ||
121 | 2 | return new Complex(MathUtils.cosh(a) * Math.cos(b), |
122 | MathUtils.sinh(a) * Math.sin(b)); |
|
123 | } |
|
124 | ||
125 | /** |
|
126 | * Compute the |
|
127 | * <a href="http://mathworld.wolfram.com/ExponentialFunction.html"> |
|
128 | * exponential function</a> for the given complex argument. |
|
129 | * @param z the value. |
|
130 | * @return <i>e</i><sup><code>z</code></sup>. |
|
131 | */ |
|
132 | public static Complex exp(Complex z) { |
|
133 | 10 | if (z.isNaN()) { |
134 | 6 | return Complex.NaN; |
135 | } |
|
136 | ||
137 | 4 | double b = z.getImaginary(); |
138 | 4 | double expA = Math.exp(z.getReal()); |
139 | 4 | double sinB = Math.sin(b); |
140 | 4 | double cosB = Math.cos(b); |
141 | 4 | return new Complex(expA * cosB, expA * sinB); |
142 | } |
|
143 | ||
144 | /** |
|
145 | * Compute the <a href="http://mathworld.wolfram.com/NaturalLogarithm.html"> |
|
146 | * natural logarithm</a> for the given complex argument. |
|
147 | * @param z the value. |
|
148 | * @return ln <code>z</code>. |
|
149 | */ |
|
150 | public static Complex log(Complex z) { |
|
151 | 16 | if (z.isNaN()) { |
152 | 4 | return Complex.NaN; |
153 | } |
|
154 | ||
155 | 12 | return new Complex(Math.log(z.abs()), |
156 | Math.atan2(z.getImaginary(), z.getReal())); |
|
157 | } |
|
158 | ||
159 | ||
160 | /** |
|
161 | * Returns of value of <code>y</code> raised to the power of <code>x</code>. |
|
162 | * @param y the base. |
|
163 | * @param x the exponent. |
|
164 | * @return <code>y</code><sup><code>z</code></sup>. |
|
165 | */ |
|
166 | public static Complex pow(Complex y, Complex x) { |
|
167 | 6 | return exp(x.multiply(log(y))); |
168 | } |
|
169 | ||
170 | /** |
|
171 | * Compute the <a href="http://mathworld.wolfram.com/Sine.html">sine</a> |
|
172 | * for the given complex argument. |
|
173 | * @param z the value whose sine is to be returned. |
|
174 | * @return the sine of <code>z</code>. |
|
175 | */ |
|
176 | public static Complex sin(Complex z) { |
|
177 | 4 | if (z.isNaN()) { |
178 | 2 | return Complex.NaN; |
179 | } |
|
180 | ||
181 | 2 | double a = z.getReal(); |
182 | 2 | double b = z.getImaginary(); |
183 | ||
184 | 2 | return new Complex(Math.sin(a) * MathUtils.cosh(b), |
185 | Math.cos(a) * MathUtils.sinh(b)); |
|
186 | } |
|
187 | ||
188 | /** |
|
189 | * Compute the <a href="http://mathworld.wolfram.com/HyperbolicSine.html"> |
|
190 | * hyperbolic sine</a> for the given complex argument. |
|
191 | * @param z the value whose hyperbolic sine is to be returned. |
|
192 | * @return the hyperbolic sine of <code>z</code>. |
|
193 | */ |
|
194 | public static Complex sinh(Complex z) { |
|
195 | 4 | if (z.isNaN()) { |
196 | 2 | return Complex.NaN; |
197 | } |
|
198 | ||
199 | 2 | double a = z.getReal(); |
200 | 2 | double b = z.getImaginary(); |
201 | ||
202 | 2 | return new Complex(MathUtils.sinh(a) * Math.cos(b), |
203 | MathUtils.cosh(a) * Math.sin(b)); |
|
204 | } |
|
205 | ||
206 | /** |
|
207 | * Compute the <a href="http://mathworld.wolfram.com/SquareRoot.html">squre |
|
208 | * root</a> for the given complex argument. |
|
209 | * @param z the value whose square root is to be returned. |
|
210 | * @return the square root of <code>z</code>. |
|
211 | */ |
|
212 | public static Complex sqrt(Complex z) { |
|
213 | 180 | if (z.isNaN()) { |
214 | 4 | return Complex.NaN; |
215 | } |
|
216 | ||
217 | 176 | double a = z.getReal(); |
218 | 176 | double b = z.getImaginary(); |
219 | 176 | if (a == 0.0 && b == 0.0) { |
220 | 16 | return new Complex(0.0, 0.0); |
221 | } |
|
222 | ||
223 | 160 | double t = Math.sqrt((Math.abs(a) + z.abs()) / 2.0); |
224 | 160 | if (a >= 0.0) { |
225 | 102 | return new Complex(t, b / (2.0 * t)); |
226 | } else { |
|
227 | 58 | return new Complex(Math.abs(b) / (2.0 * t), |
228 | MathUtils.indicator(b) * t); |
|
229 | } |
|
230 | } |
|
231 | ||
232 | /** |
|
233 | * Compute the <a href="http://mathworld.wolfram.com/SquareRoot.html">squre |
|
234 | * root of 1 - <code>z</code><sup>2</sup> for the given complex argument. |
|
235 | * @param z the value. |
|
236 | * @return the square root of 1 - <code>z</code><sup>2</sup>. |
|
237 | */ |
|
238 | public static Complex sqrt1z(Complex z) { |
|
239 | 8 | return sqrt(Complex.ONE.subtract(z.multiply(z))); |
240 | } |
|
241 | ||
242 | /** |
|
243 | * Compute the <a href="http://mathworld.wolfram.com/Tangent.html"> |
|
244 | * tangent</a> for the given complex argument. |
|
245 | * @param z the value whose tangent is to be returned. |
|
246 | * @return the tangent of <code>z</code>. |
|
247 | */ |
|
248 | public static Complex tan(Complex z) { |
|
249 | 4 | if (z.isNaN()) { |
250 | 2 | return Complex.NaN; |
251 | } |
|
252 | ||
253 | 2 | double a2 = 2.0 * z.getReal(); |
254 | 2 | double b2 = 2.0 * z.getImaginary(); |
255 | 2 | double d = Math.cos(a2) + MathUtils.cosh(b2); |
256 | ||
257 | 2 | return new Complex(Math.sin(a2) / d, MathUtils.sinh(b2) / d); |
258 | } |
|
259 | ||
260 | /** |
|
261 | * Compute the |
|
262 | * <a href="http://mathworld.wolfram.com/HyperbolicTangent.html"> |
|
263 | * hyperbolic tangent</a> for the given complex argument. |
|
264 | * @param z the value whose hyperbolic tangent is to be returned. |
|
265 | * @return the hyperbolic tangent of <code>z</code>. |
|
266 | */ |
|
267 | public static Complex tanh(Complex z) { |
|
268 | 4 | if (z.isNaN()) { |
269 | 2 | return Complex.NaN; |
270 | } |
|
271 | ||
272 | 2 | double a2 = 2.0 * z.getReal(); |
273 | 2 | double b2 = 2.0 * z.getImaginary(); |
274 | 2 | double d = MathUtils.cosh(a2) + Math.cos(b2); |
275 | ||
276 | 2 | return new Complex(MathUtils.sinh(a2) / d, Math.sin(b2) / d); |
277 | } |
|
278 | } |