
import math.*;
import numbers.floats.*;
import math.native.approxmath.(private sqrtCoeff);

import math.native.sqrt_std.(sqrt_std);
import math.native.exp_std.(exp_std);
import math.native.expm1_std.(expm1_std);
import math.native.log_std.(log_std,log2_std,log10_std);
import math.native.trig_std.(sin_std,cos_std,tan_std);
import math.native.atan_std.(atan_std, atanpi_std);
import math.native.pow_std.(pow_std);

import math.native.exp_fast.(exp_fast);
public import math.native.gamma_std.*;
public import math.native.beta_std.*;
public import math.native.erf_std.*;
public import math.native.bessel_std.*;


//
//  STANDARD  - best precision, correct rounding, default
//

[T | Float?(T)] inline overload sqrt(x:T) = sqrt_std(x);
[T | Float?(T)] inline overload rsqrt(x:T) = recip(sqrt_std(x));
[T | Float?(T)] inline overload log(x:T) = log_std(x);
[T | Float?(T)] inline overload log2(x:T) = log2_std(x);
[T | Float?(T)] inline overload log10(x:T) = log10_std(x);
[T | Float?(T)] inline overload exp(x:T) = exp_std(x);
[T | Float?(T)] inline overload expm1(x:T) = expm1_std(x);
[T | Float?(T)] inline overload sin(x:T) = sin_std(x);
[T | Float?(T)] inline overload cos(x:T) = cos_std(x);
[T | Float?(T)] inline overload tan(x:T) = tan_std(x);
[T,U | Float?(T,U)] inline overload pow(x:T,y:U) = pow_std(x,y);
[T,U | Float?(T) and Integer?(U)] inline overload pow(x:T,y:U) = pow_std(x,T(y));
[T | Float?(T)] inline overload atan(x:T) = atan_std(x);
[T | Float?(T)] inline overload atanpi(x:T) = atanpi_std(x);


//
//  FAST - high precision approximations
//  Use -Dmath.Mode=fast
//

[T | Float?(T) and MathMode?(FAST)]
inline overload rsqrt(x:T) --> y:T{
    alias ONEHALF = T(1.5);
    alias tmp = T(0.5)*x;
    y <-- floatFromBits(sqrtCoeff(T) - bitshr(floatBits(x),1));
    y *= ONEHALF - tmp * y * y;
    y *= ONEHALF - tmp * y * y;
    y *= ONEHALF - tmp * y * y;
    y *= ONEHALF - tmp * y * y;
}

[T | Float?(T) and MathMode?(FAST)]
inline overload sqrt(x:T) = T(1)/rsqrt(x);

[T | Float?(T) and MathMode?(FAST)]
inline overload exp(x:T) = exp_fast(x);

[T | Float?(T)] inline overload sigmoid (x:T) = T(1) / (T(1) + exp (-x));

