package jal.GENERIC; import jal.GENERIC.BinaryOperator; /** * A class that encapsulates generalized numeric algorithms on one * and two arrays. All methods are static and all variables are * static and final, so this class has no constructors. * *
* Most methods operate on a range of elements. A range is described
* by the index of its first element and an index that is
* one past its last element. So, for example,
* [n, n+1)
is a range that contains one element,
* [n, n)
is a range that contains zero elements,
* and [n, n-1)
is not a valid range.
*
*
* Unless otherwise specified, the test for equality uses
* the ==
operator by default. Any different notion of
* equality may be represented as a BinaryPredicate. You can use the
* predefined class Equals, which implements BinaryPredicate, if you want
* to use the Object.equals()
method.
*
*
Copyright © 1996
* Silicon Graphics, Inc.
*
*
Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Silicon Graphics makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or
* implied warranty.
*
*
* @see Inspection
* @see Modification
* @see Sorting
* @author Matthew Austern (austern@mti.sgi.com)
* @author Alexander Stepanov (stepanov@mti.sgi.com)
*/
public final class Numeric
{
/**
* Generalized accumulation. The result acc
is set to
* an initial value and, for each index i
in the range,
* it is set to op.apply(acc, array[i])
.
*
* @param array Array containing the range.
* @param first Beginning of the range.
* @param last Last element of the range.
* @param init Initial value of the accumulation.
* @param op Binary operation.
* @return The result of the accumulation.
*/
public static generic accumulate(generic[] array, int first, int last,
generic init,
BinaryOperator op)
{
generic acc = init;
while (first < last)
acc = op.apply(acc, array[first++]);
return acc;
}
/**
* Computes the generalized inner product of two ranges. This is
* identical to the ordinary inner product, except that addition and
* multiplication are replaced, respectively, by binary operations
* op1
and op2
. Specifically, the result
* acc
is set to an initial value, and, for each index
* i
in the range [first, last)
,
* acc
is set to
* op1.apply(acc, op2.apply(array1[i] * array2[first2 + (i - first1)]))
.
* @param array1 Array containing the first range.
* @param array2 Array containing the second range.
* @param first1 Beginning of the first range.
* @param last1 One past the end of the first range.
* @param first2 Beginning of the second range.
* @param init Initial value for the result.
* @param op1 Binary operation that plays the role of addition.
* @param op1 Binary operation that plays the role of multiplication.
*/
public static generic inner_product(generic[] array1, generic[] array2,
int first1, int last1, int first2,
generic init,
BinaryOperator op1, BinaryOperator op2)
{
generic acc = init;
while (first1 < last1)
acc = op1.apply(acc, op2.apply(array1[first1++], array2[first2++]));
return acc;
}
/**
* Computes the generalized partial sums of elements in an input range and
* assigns them to elements in an output range. Generalized partial sums
* are identical to partial sums except that addition is replaced by an
* arbitrary binary operation op
.
* dest[to]
= source[first]
,
* dest[to+1]
= op.apply(source[first], source[first+1])
,
* etc.
* There must be
* enough space in the destination array, and existing elements
* will be overwritten.
* @param source Array containing the input range.
* @param dest Array containing the output range.
* @param first Beginning of the input range.
* @param last One past the end of the input range.
* @param to Beginning of the output range.
* @param op Binary operation that plays the role of addition.
* @return One past the end of the output range, that is,
* to + (last - first)
.
*/
public static int partial_sum(generic[] source, generic[] dest,
int first, int last, int to,
BinaryOperator op)
{
if (first < last) {
dest[to] = source[first];
generic value = dest[to];
while (++first < last) {
value = op.apply(value, source[first]);
dest[++to] = value;
}
return to + 1;
}
else
return to;
}
/**
* Computes a binary operation op
for each pair of adjacent elements in
* the input range and assigns the results to an output range. Assigns
* dest[to] = source[first]
,
* dest[to+1] = op.apply(source[first+1], source[first])
,...,
* dest[to + (last-first)] = op.apply(source[last-1], source[last-2])
.
* There must be
* enough space in the destination array, and existing elements
* will be overwritten.
* @param source Array containing the input range.
* @param dest Array containing the output range.
* @param first Beginning of the input range.
* @param last One past the end of the input range.
* @param to Beginning of the output range.
* @param op Binary operation.
* @return One past the end of the output range, that is,
* to + (last - first)
.
*/
public static int adjacent_difference(generic[] source, generic[] dest,
int first, int last, int to,
BinaryOperator op)
{
if (first < last) {
dest[to] = source[first];
generic prev_value = source[first];
while (++first < last) {
generic cur_value = source[first];
dest[++to] = op.apply(cur_value, prev_value);
prev_value = cur_value;
}
return to + 1;
}
else
return to;
}
/* We don't need a constructor. */
private Numeric() {}
}