# AVSLib :: 'array' 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", "array", "functions")

global __load__ = Eval("""
	LoadModule("avslib", "base", "core")
	LoadModule("avslib", "numeric", "core")
	""")
global __load__ = IsPackageLoaded("avslib", "array") ? NOP : Eval("""
	LoadModule("avslib", "array", "core")
	LoadModule("avslib", "array", "operators")
	""")

# Returns an array with the negative value 
# of each element of the initial array.
#
Function ArrayNegate(string array)
{
	return ArrayOpValue(array, -1, "*")
}

# Returns array clamped between [low_limit...high_limit]
#
Function ArrayClamp(string array, val low_limit, val high_limit)
{
	return array.ArrayOpFunc("Clamp", \
		Apply(ArraySetValueHandler, low_limit) + "," + \
		Apply(ArraySetValueHandler, high_limit))
}

# Returns an array with elements the spline of  x_array.
# 'point_curve' must be an array of x,y coodrinates, as in Spline function.
#
Function ArraySpline(string x_array, string point_curve, bool "cubic")
{
	cubic = Default(cubic, false)
	return ArrayOpFunc(x_array, "Spline", point_curve + "," + String(cubic))
}

# Returns the product of the values stored in array (ie array[0]*array[1]*...).
Function ArrayProduct(string array)
{
	return ArraySum(array, sum_func="__product2") 
}

# Returns the sum of the products of corresponding elements of array1 and array2
# (ie the internal product of the two arrays).
#
Function ArraySumProduct(string array1, string array2)
{
	return ArraySum(ArrayOpArray(array1, array2, "*")) 
}

# Returns the average of the values stored in array.
#
Function ArrayAverage(string array)
{ 
	arrlen = array.ArrayLen()
	Assert(arrlen > 0, \
		"ArrayAverage: 'array' argument had zero length.")
	return array.ArraySum() / arrlen
}

# Returns the standard deviation of the values stored in array.
#
Function ArrayStDev(string array)
{ 
	arrlen = array.ArrayLen()
	Assert(arrlen > 1, \
		"ArrayStDev: 'array' argument had length < 2.")
	sx = array.ArraySum()
	sx2 = array.ArraySum(elm_func="pow", elm_args="2")
	return Sqrt( (arrlen * sx2 - sx * sx) / (arrlen * (arrlen - 1)) )
}

# Returns (boolean) array with values inverted
#
Function ArrayNot(string array)
{
	return array.ArrayOpFunc("__not")
}

# Array comparison functions, for arrays of equal lengths. 
# Compare arrays element vs element, ie array1[i] <comparison> array2[i]
# for every i and sum the results with &&.
# The result is always a single bool value (true or false).

# Returns true if array1[i] == array2[i] for every i.
#
Function ArrayEqual(string array1, string array2)
{
	return ArrayOpArray(array1, array2, "==").ArraySum(sum_func="__and2") 
}

# Returns true if array1[i] != array2[i] for every i.
#
Function ArrayNotEqual(string array1, string array2)
{
	return ArrayOpArray(array1, array2, "!=").ArraySum(sum_func="__and2") 
}

# Returns true if array1[i] >= array2[i] for every i.
#
Function ArrayGreaterOrEqual(string array1, string array2)
{
	return ArrayOpArray(array1, array2, ">=").ArraySum(sum_func="__and2") 
}

# Returns true if array1[i] <= array2[i] for every i.
#
Function ArrayLessOrEqual(string array1, string array2)
{
	return ArrayOpArray(array1, array2, "<=").ArraySum(sum_func="__and2") 
}

# Returns true if array1[i] > array2[i] for every i.
#
Function ArrayGreater(string array1, string array2)
{
	return ArrayOpArray(array1, array2, ">").ArraySum(sum_func="__and2") 
}

# Returns true if array1[i] < array2[i] for every i.
#
Function ArrayLess(string array1, string array2)
{
	return ArrayOpArray(array1, array2, "<").ArraySum(sum_func="__and2") 
}
