# AVSLib :: 'numeric' package :: 'core' 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", "core")

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

# Special functions corresponding to variable operations 
# Use them for constructing expressions for Eval 
# or as building blocks of multi-argument functions.

# Public variants, for library users; transfered from the 'base' package 
# to increase library's modularity
Function Dif2(val x1, val x2) { return x1 - x2 }
Function Div2(val x1, val x2) { return x1 / x2 }
Function Max2(val x1, val x2) { return (x1 >= x2) ? x1 : x2 }
Function Min2(val x1, val x2) { return (x1 <= x2) ? x1 : x2 }
Function Mod2(val x1, val x2) { return x1 % x2 }
Function Product2(val x1, val x2) { return x1 * x2 }
Function Sum2(val x1, val x2) { return x1 + x2 }

# Number of arguments to the function below has been reduced to 20 for performance.
# If you need more than that, use the tools provided by the array package.

# Returns the minimum of xi
#
Function Min(val x1, val "x2", val "x3", val "x4", val "x5", val "x6", val "x7", \
	val "x8", val "x9", val "x10",val "x11", val "x12", val "x13", val "x14", \
	val "x15", val "x16", val "x17", val "x18", val "x19", val "x20")
{
	_min = x1
	_min = Defined(x2) ? __min2(_min, x2) : _min
	_min = Defined(x3) ? __min2(_min, x3) : _min
	_min = Defined(x4) ? __min2(_min, x4) : _min
	_min = Defined(x5) ? __min2(_min, x5) : _min
	_min = Defined(x6) ? __min2(_min, x6) : _min
	_min = Defined(x7) ? __min2(_min, x7) : _min
	_min = Defined(x8) ? __min2(_min, x8) : _min
	_min = Defined(x9) ? __min2(_min, x9) : _min
	_min = Defined(x10) ? __min2(_min, x10) : _min
	_min = Defined(x11) ? __min2(_min, x11) : _min
	_min = Defined(x12) ? __min2(_min, x12) : _min
	_min = Defined(x13) ? __min2(_min, x13) : _min
	_min = Defined(x14) ? __min2(_min, x14) : _min
	_min = Defined(x15) ? __min2(_min, x15) : _min
	_min = Defined(x16) ? __min2(_min, x16) : _min
	_min = Defined(x17) ? __min2(_min, x17) : _min
	_min = Defined(x18) ? __min2(_min, x18) : _min
	_min = Defined(x19) ? __min2(_min, x19) : _min
	_min = Defined(x20) ? __min2(_min, x20) : _min
	return _min
}

# Returns the maximum of xi
#
Function Max(val x1, val "x2", val "x3", val "x4", val "x5", val "x6", val "x7", \
	val "x8", val "x9", val "x10",val "x11", val "x12", val "x13", val "x14", \
	val "x15", val "x16", val "x17", val "x18", val "x19", val "x20")
{
	_max = x1
	_max = Defined(x2) ? __max2(_max, x2) : _max
	_max = Defined(x3) ? __max2(_max, x3) : _max
	_max = Defined(x4) ? __max2(_max, x4) : _max
	_max = Defined(x5) ? __max2(_max, x5) : _max
	_max = Defined(x6) ? __max2(_max, x6) : _max
	_max = Defined(x7) ? __max2(_max, x7) : _max
	_max = Defined(x8) ? __max2(_max, x8) : _max
	_max = Defined(x9) ? __max2(_max, x9) : _max
	_max = Defined(x10) ? __max2(_max, x10) : _max
	_max = Defined(x11) ? __max2(_max, x11) : _max
	_max = Defined(x12) ? __max2(_max, x12) : _max
	_max = Defined(x13) ? __max2(_max, x13) : _max
	_max = Defined(x14) ? __max2(_max, x14) : _max
	_max = Defined(x15) ? __max2(_max, x15) : _max
	_max = Defined(x16) ? __max2(_max, x16) : _max
	_max = Defined(x17) ? __max2(_max, x17) : _max
	_max = Defined(x18) ? __max2(_max, x18) : _max
	_max = Defined(x19) ? __max2(_max, x19) : _max
	_max = Defined(x20) ? __max2(_max, x20) : _max
	return _max
}

# Clamps x within the [low_limit...high_limit] interval.
#
Function Clamp(val x, val low_limit, val high_limit)
{ 
	Assert (low_limit <= high_limit, \
		"Clamp: 'low_limit' must be less or equal to 'high_limit'.")
	return __max2(low_limit, __min2(x, high_limit)) 
}

# Returns the number of defined arguments passed in (ie the count of defined arguments)
#
Function Count(val "x1", val "x2", val "x3", val "x4", val "x5", val "x6", \
	val "x7", val "x8", val "x9", val "x10",val "x11", val "x12", val "x13", \
	val "x14", val "x15", val "x16", val "x17", val "x18", val "x19", val "x20")
{
	n = Defined(x1) ? 1 : 0
	n = Defined(x2) ? n + 1 : n
	n = Defined(x3) ? n + 1 : n
	n = Defined(x4) ? n + 1 : n
	n = Defined(x5) ? n + 1 : n
	n = Defined(x6) ? n + 1 : n
	n = Defined(x7) ? n + 1 : n
	n = Defined(x8) ? n + 1 : n
	n = Defined(x9) ? n + 1 : n
	n = Defined(x10) ? n + 1 : n
	n = Defined(x11) ? n + 1 : n
	n = Defined(x12) ? n + 1 : n
	n = Defined(x13) ? n + 1 : n
	n = Defined(x14) ? n + 1 : n
	n = Defined(x15) ? n + 1 : n
	n = Defined(x16) ? n + 1 : n
	n = Defined(x17) ? n + 1 : n
	n = Defined(x18) ? n + 1 : n
	n = Defined(x19) ? n + 1 : n
	n = Defined(x20) ? n + 1 : n
	return n
}

# Returns the sum of xi.
#
Function Sum(val x1, val "x2", val "x3", val "x4", val "x5", val "x6", val "x7", \
	val "x8", val "x9", val "x10",val "x11", val "x12", val "x13", val "x14", \
	val "x15", val "x16", val "x17", val "x18", val "x19", val "x20")
{
	_sum = x1
	_sum = Defined(x2) ? __sum2(_sum, x2) : _sum
	_sum = Defined(x3) ? __sum2(_sum, x3) : _sum
	_sum = Defined(x4) ? __sum2(_sum, x4) : _sum
	_sum = Defined(x5) ? __sum2(_sum, x5) : _sum
	_sum = Defined(x6) ? __sum2(_sum, x6) : _sum
	_sum = Defined(x7) ? __sum2(_sum, x7) : _sum
	_sum = Defined(x8) ? __sum2(_sum, x8) : _sum
	_sum = Defined(x9) ? __sum2(_sum, x9) : _sum
	_sum = Defined(x10) ? __sum2(_sum, x10) : _sum
	_sum = Defined(x11) ? __sum2(_sum, x11) : _sum
	_sum = Defined(x12) ? __sum2(_sum, x12) : _sum
	_sum = Defined(x13) ? __sum2(_sum, x13) : _sum
	_sum = Defined(x14) ? __sum2(_sum, x14) : _sum
	_sum = Defined(x15) ? __sum2(_sum, x15) : _sum
	_sum = Defined(x16) ? __sum2(_sum, x16) : _sum
	_sum = Defined(x17) ? __sum2(_sum, x17) : _sum
	_sum = Defined(x18) ? __sum2(_sum, x18) : _sum
	_sum = Defined(x19) ? __sum2(_sum, x19) : _sum
	_sum = Defined(x20) ? __sum2(_sum, x20) : _sum
	return _sum
}

# Returns the product of xi.
#
Function Product(val x1, val "x2", val "x3", val "x4", val "x5", val "x6", val "x7", \
	val "x8", val "x9", val "x10",val "x11", val "x12", val "x13", val "x14", \
	val "x15", val "x16", val "x17", val "x18", val "x19", val "x20")
{
	_prod = x1
	_prod = Defined(x2) ? __product2(_prod, x2) : _prod
	_prod = Defined(x3) ? __product2(_prod, x3) : _prod
	_prod = Defined(x4) ? __product2(_prod, x4) : _prod
	_prod = Defined(x5) ? __product2(_prod, x5) : _prod
	_prod = Defined(x6) ? __product2(_prod, x6) : _prod
	_prod = Defined(x7) ? __product2(_prod, x7) : _prod
	_prod = Defined(x8) ? __product2(_prod, x8) : _prod
	_prod = Defined(x9) ? __product2(_prod, x9) : _prod
	_prod = Defined(x10) ? __product2(_prod, x10) : _prod
	_prod = Defined(x11) ? __product2(_prod, x11) : _prod
	_prod = Defined(x12) ? __product2(_prod, x12) : _prod
	_prod = Defined(x13) ? __product2(_prod, x13) : _prod
	_prod = Defined(x14) ? __product2(_prod, x14) : _prod
	_prod = Defined(x15) ? __product2(_prod, x15) : _prod
	_prod = Defined(x16) ? __product2(_prod, x16) : _prod
	_prod = Defined(x17) ? __product2(_prod, x17) : _prod
	_prod = Defined(x18) ? __product2(_prod, x18) : _prod
	_prod = Defined(x19) ? __product2(_prod, x19) : _prod
	_prod = Defined(x20) ? __product2(_prod, x20) : _prod
	return _prod
}

# degrees <-> radians conversion functions
#
Function DegToRad(float degrees) { return Pi * (degrees / 180.0) }
Function RadToDeg(float radians) { return 180.0 * (radians / Pi) }

# Even, Odd test functions
#
Function IsEven(int x) { return x % 2 == 0 }
Function IsOdd(int x) { return x % 2 != 0 }
