/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.commons.math3.util;
/**
* <p>
* FastMath is slower in GWT than java.lang.Math so has been stripped down to
* just asinh, acosh, atanh which are not in java.lang.Math and FastMath
* references in math3 have been changed to Math
*
* Also nextAfter() which isn't emulated by GWT as of 2.8
*
* <ul>
* <li>{@link #asinh(double)}</li>
* <li>{@link #acosh(double)}</li>
* <li>{@link #atanh(double)}</li>
* </ul>
* </p>
*
* @since 2.2
*/
public class FastMath {
/** Constant: {@value}. */
private static final double F_1_3 = 1d / 3d;
/** Constant: {@value}. */
private static final double F_1_5 = 1d / 5d;
/** Constant: {@value}. */
private static final double F_1_7 = 1d / 7d;
/** Constant: {@value}. */
private static final double F_1_9 = 1d / 9d;
/** Constant: {@value}. */
private static final double F_1_11 = 1d / 11d;
/** Constant: {@value}. */
private static final double F_1_13 = 1d / 13d;
/** Constant: {@value}. */
private static final double F_1_15 = 1d / 15d;
/** Constant: {@value}. */
private static final double F_1_17 = 1d / 17d;
/** Constant: {@value}. */
private static final double F_3_4 = 3d / 4d;
/** Constant: {@value}. */
private static final double F_15_16 = 15d / 16d;
/** Constant: {@value}. */
private static final double F_13_14 = 13d / 14d;
/** Constant: {@value}. */
private static final double F_11_12 = 11d / 12d;
/** Constant: {@value}. */
private static final double F_9_10 = 9d / 10d;
/** Constant: {@value}. */
private static final double F_7_8 = 7d / 8d;
/** Constant: {@value}. */
private static final double F_5_6 = 5d / 6d;
/** Constant: {@value}. */
private static final double F_1_2 = 1d / 2d;
/**
* Private Constructor
*/
private FastMath() {}
/** Compute the inverse hyperbolic cosine of a number.
* @param a number on which evaluation is done
* @return inverse hyperbolic cosine of a
*/
public static double acosh(final double a) {
return Math.log(a + Math.sqrt(a * a - 1));
}
/** Compute the inverse hyperbolic sine of a number.
* @param a number on which evaluation is done
* @return inverse hyperbolic sine of a
*/
public static double asinh(double a) {
boolean negative = false;
if (a < 0) {
negative = true;
a = -a;
}
double absAsinh;
if (a > 0.167) {
absAsinh = Math.log(Math.sqrt(a * a + 1) + a);
} else {
final double a2 = a * a;
if (a > 0.097) {
absAsinh = a * (1 - a2 * (F_1_3 - a2 * (F_1_5 - a2 * (F_1_7 - a2 * (F_1_9 - a2 * (F_1_11 - a2 * (F_1_13 - a2 * (F_1_15 - a2 * F_1_17 * F_15_16) * F_13_14) * F_11_12) * F_9_10) * F_7_8) * F_5_6) * F_3_4) * F_1_2);
} else if (a > 0.036) {
absAsinh = a * (1 - a2 * (F_1_3 - a2 * (F_1_5 - a2 * (F_1_7 - a2 * (F_1_9 - a2 * (F_1_11 - a2 * F_1_13 * F_11_12) * F_9_10) * F_7_8) * F_5_6) * F_3_4) * F_1_2);
} else if (a > 0.0036) {
absAsinh = a * (1 - a2 * (F_1_3 - a2 * (F_1_5 - a2 * (F_1_7 - a2 * F_1_9 * F_7_8) * F_5_6) * F_3_4) * F_1_2);
} else {
absAsinh = a * (1 - a2 * (F_1_3 - a2 * F_1_5 * F_3_4) * F_1_2);
}
}
return negative ? -absAsinh : absAsinh;
}
/** Compute the inverse hyperbolic tangent of a number.
* @param a number on which evaluation is done
* @return inverse hyperbolic tangent of a
*/
public static double atanh(double a) {
boolean negative = false;
if (a < 0) {
negative = true;
a = -a;
}
double absAtanh;
if (a > 0.15) {
absAtanh = 0.5 * Math.log((1 + a) / (1 - a));
} else {
final double a2 = a * a;
if (a > 0.087) {
absAtanh = a * (1 + a2 * (F_1_3 + a2 * (F_1_5 + a2 * (F_1_7 + a2 * (F_1_9 + a2 * (F_1_11 + a2 * (F_1_13 + a2 * (F_1_15 + a2 * F_1_17))))))));
} else if (a > 0.031) {
absAtanh = a * (1 + a2 * (F_1_3 + a2 * (F_1_5 + a2 * (F_1_7 + a2 * (F_1_9 + a2 * (F_1_11 + a2 * F_1_13))))));
} else if (a > 0.003) {
absAtanh = a * (1 + a2 * (F_1_3 + a2 * (F_1_5 + a2 * (F_1_7 + a2 * F_1_9))));
} else {
absAtanh = a * (1 + a2 * (F_1_3 + a2 * F_1_5));
}
}
return negative ? -absAtanh : absAtanh;
}
}