| 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 | } |