/*
 * 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.lucene.util;


/* some code derived from jodk: http://code.google.com/p/jodk/ (apache 2.0)
 * asin() derived from fdlibm: http://www.netlib.org/fdlibm/e_asin.c (public domain):
 * =============================================================================
 * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
 *
 * Developed at SunSoft, a Sun Microsystems, Inc. business.
 * Permission to use, copy, modify, and distribute this
 * software is freely granted, provided that this notice 
 * is preserved.
 * =============================================================================
 */

/** Math functions that trade off accuracy for speed. */
public class SloppyMath {
  
  /**
   * Returns the Haversine distance in kilometers between two points
   * specified in decimal degrees (latitude/longitude).  This works correctly
   * even if the dateline is between the two points.
   *
   * @param lat1 Latitude of the first point.
   * @param lon1 Longitude of the first point.
   * @param lat2 Latitude of the second point.
   * @param lon2 Longitude of the second point.
   * @return distance in kilometers.
   */
  public static double haversin(double lat1, double lon1, double lat2, double lon2) {
    double x1 = lat1 * TO_RADIANS;
    double x2 = lat2 * TO_RADIANS;
    double h1 = 1 - cos(x1 - x2);
    double h2 = 1 - cos((lon1 - lon2) * TO_RADIANS);
    double h = (h1 + cos(x1) * cos(x2) * h2) / 2;

    double avgLat = (x1 + x2) / 2d;
    double diameter = earthDiameter(avgLat);

    return diameter * asin(Math.min(1, Math.sqrt(h)));
    
  }

  /**
   * Returns the trigonometric cosine of an angle.
   * <p>
   * Error is around 1E-15.
   * <p>
   * Special cases:
   * <ul>
   *  <li>If the argument is {@code NaN} or an infinity, then the result is {@code NaN}.
   * </ul>
   * @param a an angle, in radians.
   * @return the cosine of the argument.
   * @see Math#cos(double)
   */
  public static double cos(double a) {
    if (a < 0.0) {
      a = -a;
    }
    if (a > SIN_COS_MAX_VALUE_FOR_INT_MODULO) {
      return Math.cos(a);
    }
    // index: possibly outside tables range.
    int index = (int)(a * SIN_COS_INDEXER + 0.5);
    double delta = (a - index * SIN_COS_DELTA_HI) - index * SIN_COS_DELTA_LO;
    // Making sure index is within tables range.
    // Last value of each table is the same than first, so we ignore it (tabs size minus one) for modulo.
    index &= (SIN_COS_TABS_SIZE-2); // index % (SIN_COS_TABS_SIZE-1)
    double indexCos = cosTab[index];
    double indexSin = sinTab[index];
    return indexCos + delta * (-indexSin + delta * (-indexCos * ONE_DIV_F2 + delta * (indexSin * ONE_DIV_F3 + delta * indexCos * ONE_DIV_F4)));
  }

  /**
   * Returns the trigonometric sine of an angle converted as a cos operation.
   * <p>
   * Error is around 1E-15.
   * <p>
   * Special cases:
   * <ul>
   *  <li>If the argument is {@code NaN} or an infinity, then the result is {@code NaN}.
   * </ul>
   * @param a an angle, in radians.
   * @return the sine of the argument.
   * @see Math#cos(double)
   */
  public static double sin(double a) {
    return cos(a - PIO2);
  }

  /**
   * Returns the trigonometric tangent of an angle converted in terms of a sin/cos operation.
   * <p>
   * Error is around 1E-15.
   * <p>
   * Special cases:
   * <ul>
   *  <li>If the argument is {@code NaN} or an infinity, then the result is {@code NaN}.
   * </ul>
   * @param a an angle, in radians.
   * @return the tangent of the argument.
   * @see Math#sin(double) aand Math#cos(double)
   */
  public static double tan(double a) {
    return sin(a) / cos(a);
  }

  /**
   * Returns the arc sine of a value.
   * <p>
   * The returned angle is in the range <i>-pi</i>/2 through <i>pi</i>/2. 
   * Error is around 1E-7.
   * <p>
   * Special cases:
   * <ul>
   *  <li>If the argument is {@code NaN} or its absolute value is greater than 1, then the result is {@code NaN}.
   * </ul>
   * @param a the value whose arc sine is to be returned.
   * @return arc sine of the argument
   * @see Math#asin(double)
   */
  // because asin(-x) = -asin(x), asin(x) only needs to be computed on [0,1].
  // ---> we only have to compute asin(x) on [0,1].
  // For values not close to +-1, we use look-up tables;
  // for values near +-1, we use code derived from fdlibm.
  public static double asin(double a) { 
    boolean negateResult;
    if (a < 0.0) {
      a = -a;
      negateResult = true;
    } else {
      negateResult = false;
    }
    if (a <= ASIN_MAX_VALUE_FOR_TABS) {
      int index = (int)(a * ASIN_INDEXER + 0.5);
      double delta = a - index * ASIN_DELTA;
      double result = asinTab[index] + delta * (asinDer1DivF1Tab[index] + delta * (asinDer2DivF2Tab[index] + delta * (asinDer3DivF3Tab[index] + delta * asinDer4DivF4Tab[index])));
      return negateResult ? -result : result;
    } else { // value > ASIN_MAX_VALUE_FOR_TABS, or value is NaN
      // This part is derived from fdlibm.
      if (a < 1.0) {
        double t = (1.0 - a)*0.5;
        double p = t*(ASIN_PS0+t*(ASIN_PS1+t*(ASIN_PS2+t*(ASIN_PS3+t*(ASIN_PS4+t*ASIN_PS5)))));
        double q = 1.0+t*(ASIN_QS1+t*(ASIN_QS2+t*(ASIN_QS3+t*ASIN_QS4)));
        double s = Math.sqrt(t);
        double z = s+s*(p/q);
        double result = ASIN_PIO2_HI-((z+z)-ASIN_PIO2_LO);
        return negateResult ? -result : result;
      } else { // value >= 1.0, or value is NaN
        if (a == 1.0) {
          return negateResult ? -Math.PI/2 : Math.PI/2;
        } else {
          return Double.NaN;
        }
      }
    }
  }

  /** Return an approximate value of the diameter of the earth at the given latitude, in kilometers. */
  public static double earthDiameter(double latitude) {
    final int index = (int)(Math.abs(latitude) * RADIUS_INDEXER + 0.5) % earthDiameterPerLatitude.length;
    return earthDiameterPerLatitude[index];
  }

  // haversin
  public static final double TO_RADIANS = Math.PI / 180D;
  public static final double TO_DEGREES = 180D / Math.PI;
  
  // cos/asin
  private static final double ONE_DIV_F2 = 1/2.0;
  private static final double ONE_DIV_F3 = 1/6.0;
  private static final double ONE_DIV_F4 = 1/24.0;

  public static final double PIO2 = Math.PI / 2D;
  private static final double PIO2_HI = Double.longBitsToDouble(0x3FF921FB54400000L); // 1.57079632673412561417e+00 first 33 bits of pi/2
  private static final double PIO2_LO = Double.longBitsToDouble(0x3DD0B4611A626331L); // 6.07710050650619224932e-11 pi/2 - PIO2_HI
  private static final double TWOPI_HI = 4*PIO2_HI;
  private static final double TWOPI_LO = 4*PIO2_LO;
  private static final int SIN_COS_TABS_SIZE = (1<<11) + 1;
  private static final double SIN_COS_DELTA_HI = TWOPI_HI/(SIN_COS_TABS_SIZE-1);
  private static final double SIN_COS_DELTA_LO = TWOPI_LO/(SIN_COS_TABS_SIZE-1);
  private static final double SIN_COS_INDEXER = 1/(SIN_COS_DELTA_HI+SIN_COS_DELTA_LO);
  private static final double[] sinTab = new double[SIN_COS_TABS_SIZE];
  private static final double[] cosTab = new double[SIN_COS_TABS_SIZE];
  
  // Max abs value for fast modulo, above which we use regular angle normalization.
  // This value must be < (Integer.MAX_VALUE / SIN_COS_INDEXER), to stay in range of int type.
  // The higher it is, the higher the error, but also the faster it is for lower values.
  // If you set it to ((Integer.MAX_VALUE / SIN_COS_INDEXER) * 0.99), worse accuracy on double range is about 1e-10.
  static final double SIN_COS_MAX_VALUE_FOR_INT_MODULO = ((Integer.MAX_VALUE>>9) / SIN_COS_INDEXER) * 0.99;
    
  // Supposed to be >= sin(77.2deg), as fdlibm code is supposed to work with values > 0.975,
  // but seems to work well enough as long as value >= sin(25deg).
  private static final double ASIN_MAX_VALUE_FOR_TABS = StrictMath.sin(Math.toRadians(73.0));
  
  private static final int ASIN_TABS_SIZE = (1<<13) + 1;
  private static final double ASIN_DELTA = ASIN_MAX_VALUE_FOR_TABS/(ASIN_TABS_SIZE - 1);
  private static final double ASIN_INDEXER = 1/ASIN_DELTA;
  private static final double[] asinTab = new double[ASIN_TABS_SIZE];
  private static final double[] asinDer1DivF1Tab = new double[ASIN_TABS_SIZE];
  private static final double[] asinDer2DivF2Tab = new double[ASIN_TABS_SIZE];
  private static final double[] asinDer3DivF3Tab = new double[ASIN_TABS_SIZE];
  private static final double[] asinDer4DivF4Tab = new double[ASIN_TABS_SIZE];
  
  private static final double ASIN_PIO2_HI = Double.longBitsToDouble(0x3FF921FB54442D18L); // 1.57079632679489655800e+00
  private static final double ASIN_PIO2_LO = Double.longBitsToDouble(0x3C91A62633145C07L); // 6.12323399573676603587e-17
  private static final double ASIN_PS0 = Double.longBitsToDouble(0x3fc5555555555555L); //  1.66666666666666657415e-01
  private static final double ASIN_PS1 = Double.longBitsToDouble(0xbfd4d61203eb6f7dL); // -3.25565818622400915405e-01
  private static final double ASIN_PS2 = Double.longBitsToDouble(0x3fc9c1550e884455L); //  2.01212532134862925881e-01
  private static final double ASIN_PS3 = Double.longBitsToDouble(0xbfa48228b5688f3bL); // -4.00555345006794114027e-02
  private static final double ASIN_PS4 = Double.longBitsToDouble(0x3f49efe07501b288L); //  7.91534994289814532176e-04
  private static final double ASIN_PS5 = Double.longBitsToDouble(0x3f023de10dfdf709L); //  3.47933107596021167570e-05
  private static final double ASIN_QS1 = Double.longBitsToDouble(0xc0033a271c8a2d4bL); // -2.40339491173441421878e+00
  private static final double ASIN_QS2 = Double.longBitsToDouble(0x40002ae59c598ac8L); //  2.02094576023350569471e+00
  private static final double ASIN_QS3 = Double.longBitsToDouble(0xbfe6066c1b8d0159L); // -6.88283971605453293030e-01
  private static final double ASIN_QS4 = Double.longBitsToDouble(0x3fb3b8c5b12e9282L); //  7.70381505559019352791e-02
  
  private static final int RADIUS_TABS_SIZE = (1<<10) + 1;
  private static final double RADIUS_DELTA = (StrictMath.PI/2d) / (RADIUS_TABS_SIZE - 1);
  private static final double RADIUS_INDEXER = 1d/RADIUS_DELTA;
  private static final double[] earthDiameterPerLatitude = new double[RADIUS_TABS_SIZE];
  
  /** Initializes look-up tables. */
  static {
    // sin and cos
    final int SIN_COS_PI_INDEX = (SIN_COS_TABS_SIZE-1)/2;
    final int SIN_COS_PI_MUL_2_INDEX = 2*SIN_COS_PI_INDEX;
    final int SIN_COS_PI_MUL_0_5_INDEX = SIN_COS_PI_INDEX/2;
    final int SIN_COS_PI_MUL_1_5_INDEX = 3*SIN_COS_PI_INDEX/2;
    for (int i=0;i<SIN_COS_TABS_SIZE;i++) {
      // angle: in [0,2*PI].
      double angle = i * SIN_COS_DELTA_HI + i * SIN_COS_DELTA_LO;
      double sinAngle = StrictMath.sin(angle);
      double cosAngle = StrictMath.cos(angle);
      // For indexes corresponding to null cosine or sine, we make sure the value is zero
      // and not an epsilon. This allows for a much better accuracy for results close to zero.
      if (i == SIN_COS_PI_INDEX) {
        sinAngle = 0.0;
      } else if (i == SIN_COS_PI_MUL_2_INDEX) {
        sinAngle = 0.0;
      } else if (i == SIN_COS_PI_MUL_0_5_INDEX) {
        cosAngle = 0.0;
      } else if (i == SIN_COS_PI_MUL_1_5_INDEX) {
        cosAngle = 0.0;
      }
      sinTab[i] = sinAngle;
      cosTab[i] = cosAngle;
    }
    
    // asin
    for (int i=0;i<ASIN_TABS_SIZE;i++) {
      // x: in [0,ASIN_MAX_VALUE_FOR_TABS].
      double x = i * ASIN_DELTA;
      asinTab[i] = StrictMath.asin(x);
      double oneMinusXSqInv = 1.0/(1-x*x);
      double oneMinusXSqInv0_5 = StrictMath.sqrt(oneMinusXSqInv);
      double oneMinusXSqInv1_5 = oneMinusXSqInv0_5*oneMinusXSqInv;
      double oneMinusXSqInv2_5 = oneMinusXSqInv1_5*oneMinusXSqInv;
      double oneMinusXSqInv3_5 = oneMinusXSqInv2_5*oneMinusXSqInv;
      asinDer1DivF1Tab[i] = oneMinusXSqInv0_5;
      asinDer2DivF2Tab[i] = (x*oneMinusXSqInv1_5) * ONE_DIV_F2;
      asinDer3DivF3Tab[i] = ((1+2*x*x)*oneMinusXSqInv2_5) * ONE_DIV_F3;
      asinDer4DivF4Tab[i] = ((5+2*x*(2+x*(5-2*x)))*oneMinusXSqInv3_5) * ONE_DIV_F4;
    }
    
    
    // WGS84 earth-ellipsoid major (a) and minor (b) radius
    final double a = 6_378_137; // [m]
    final double b = 6_356_752.31420; // [m]
    
    final double a2 = a*a;
    final double b2 = b*b;
    
    earthDiameterPerLatitude[0] = 2 * a / 1000d;
    earthDiameterPerLatitude[RADIUS_TABS_SIZE-1] = 2 * b / 1000d;
    // earth radius
    for (int i=1;i<RADIUS_TABS_SIZE-1;i++) {
      final double lat = Math.PI * i / (2d * RADIUS_TABS_SIZE-1);
      double one = StrictMath.pow(a2 * StrictMath.cos(lat), 2); 
      double two = StrictMath.pow(b2 * StrictMath.sin(lat), 2);
      double three = StrictMath.pow(a * StrictMath.cos(lat), 2);
      double four = StrictMath.pow(b * StrictMath.sin(lat), 2);
      
      double radius = StrictMath.sqrt((one+two)/(three+four));
      earthDiameterPerLatitude[i] = 2 * radius / 1000d;
    }
  }
}
