# AVSLib :: 'numeric' package :: 'functions' module
# Copyright (c) 2005 George Zarkadas (gzarkadas@users.sourceforge.net)

# This program is free software; you can redistribute it and/or modify it under the terms of 
# the GNU General Public License as published by the Free Software Foundation; either 
# version 2 of the License, or (at your option) any later version.
# This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
# PURPOSE.  See the GNU General Public License for more details.
# You should have received a copy of the GNU General Public License along with this program; 
# if not, write to the "Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, 
# MA  02111-1307  USA"

DefineModule("avslib", "numeric", "functions")

global __load__ = Eval("""
	LoadModule("avslib", "numeric", "core")
	""")

# Exponential and trigonometric functions

# Expontentials
Function ExpBs(float x, float base) { return Exp(x * Log(base)) }
Function Exp10(float x) { return Exp(x * Log(10.0)) }

# Logarithms
Function LogBs(float x, float base) { return Log(x) / Log(base) }
Function Log10(float x) { return Log(x) / Log(10.0) }

# Trigonometric functions
Function Tan(float x) { return Sin(x) / Cos(x) }
Function Cot(float x) { return Cos(x) / Sin(x) }

# Hyperbolic trigonometric functions
Function Sinh(float x) { return (Exp(x) - Exp(-x)) / 2.0 }
Function Cosh(float x) { return (Exp(x) + Exp(-x)) / 2.0 }
Function Tanh(float x) { return Sinh(x) / Cosh(x) }
Function Coth(float x) { return Cosh(x) / Sinh(x) }

# Inverse trigonometric functions

# ArcSin: inner function ensures private arguments cannot be called by user

	Function __arc_sin(float x, float "__prev", int "__step", float "__pterm")
	{
		__prev  = Default(__prev, x)
		__pterm = Default(__pterm, x)
		__step  = Default(__step, 1) # step 0 is introduced by defaults
		st2 = 2 * __step
		t = st2 - 1
		term = __pterm * (Float(t * t) / Float(st2 * (st2 + 1))) * (x * x)
		return Abs(term) > 0.00001 \
			? __arc_sin(x, __prev + term, __step + 1, term) \
			: __prev + term
	}

Function ArcSin(float x) { return __arc_sin(x) }

Function ArcCos(float x) { return (Pi/2) - ArcSin(x) }

# ArcTan: inner function ensures private arguments cannot be called by user

	Function __arc_tan(float x, float "__prev", int "__step")
	{
		__prev = Default(__prev, (Abs(x) < 1 ? x : Sign(x) * Pi / 2))
		__step = Default(__step, 1) # step 0 is introduced by __prev defaults
		term = Abs(x) < 1 \
			? (IsEven(__step) ? 1 : -1) * Pow(x, 2 * __step + 1) / (2 * __step + 1) \
			: (IsEven(__step) ? 1 : -1) * 1 / ((2 * __step - 1) * Pow(x, 2 * __step - 1))
		return Abs(term) > 0.00001 \
			? __arc_tan(x, __prev + term, __step + 1) \
			: __prev + term
	}

Function ArcTan(float x) { return __arc_tan(x) }

Function ArcCot(float x) { return (Pi/2) - ArcTan(x) }

# Inverse hyperbolic trigonometric functions
Function ArcSinh(float x) { return Log(x + Sqrt(x * x + 1.0)) }
Function ArcCosh(float x) { return Log(x + Sqrt(x * x - 1.0)) }
Function ArcTanh(float x) { return Log((1.0 + x)/(1.0 - x)) / 2.0 }
Function ArcCoth(float x) { return Log((x + 1.0)/(x - 1.0)) / 2.0 }
