Class Functions
Math
as function objects, as
well as a few more basic functions.
Function objects conveniently allow to express arbitrary functions in a generic manner. Essentially, a function object is an object that can perform a function on some arguments. It has a minimal interface: a method apply that takes the arguments, computes something and returns some result value. Function objects are comparable to function pointers in C used for call-backs.
Unary functions are of type DoubleFunction
, binary functions
of type DoubleDoubleFunction
. All can be retrieved via public
static final variables named after the function.
Unary predicates are of type DoubleProcedure
, binary predicates
of type DoubleDoubleProcedure
. All can be retrieved via public
static final variables named isXXX.
Binary functions and predicates also exist as unary functions with the second argument being fixed to a constant. These are generated and retrieved via factory methods (again with the same name as the function). Example:
- Functions.pow gives the function ab.
- Functions.pow.apply(2,3)==8.
- Functions.pow(3) gives the function a3.
- Functions.pow(3).apply(2)==8.
bindArg1(DoubleDoubleFunction,double)
and bindArg2(DoubleDoubleFunction,double)
. The order of arguments
can be swapped so that the first argument becomes the second and vice-versa. See
method swapArgs(DoubleDoubleFunction)
. Example:
- Functions.pow gives the function ab.
- Functions.bindArg2(Functions.pow,3) gives the function x3.
- Functions.bindArg1(Functions.pow,3) gives the function 3x.
- Functions.swapArgs(Functions.pow) gives the function ba.
Even more general, functions can be chained (composed, assembled). Assume we have two unary
functions g and h. The unary function g(h(a)) applying
both in sequence can be generated via chain(DoubleFunction,DoubleFunction)
:
- Functions.chain(g,h);
chain(DoubleFunction,DoubleDoubleFunction)
:
- Functions.chain(g,f);
chain(DoubleDoubleFunction,DoubleFunction,DoubleFunction)
:
- Functions.chain(f,g,h);
- chain(plus,sin,chain(square,cos));
new DoubleDoubleFunction() { public final double apply(double a, double b) { return Math.sin(a) + Math.pow(Math.cos(b),2); } }
For aliasing see functions
.
Try this
// should yield 1.4399560356056456 in all cases double a = 0.5; double b = 0.2; double v = Math.sin(a) + Math.pow(Math.cos(b),2); System.out.println(v); Functions F = Functions.functions; DoubleDoubleFunction f = F.chain(F.plus,F.sin,F.chain(F.square,F.cos)); System.out.println(f.apply(a,b)); DoubleDoubleFunction g = new DoubleDoubleFunction() { public double apply(double a, double b) { return Math.sin(a) + Math.pow(Math.cos(b),2); } }; System.out.println(g.apply(a,b)); |
Performance
Surprise. Using modern non-adaptive JITs such as SunJDK 1.2.2 (java -classic) there seems to be no or only moderate performance penalty in using function objects in a loop over traditional code in a loop. For complex nested function objects (e.g. F.chain(F.abs,F.chain(F.plus,F.sin,F.chain(F.square,F.cos)))) the penalty is zero, for trivial functions (e.g. F.plus) the penalty is often acceptable. Iteration Performance [million function
evaluations per second] Pentium Pro 200 Mhz, SunJDK 1.2.2, NT, java -classic, |
||||||
30000000 iterations |
3000000 iterations (10 times less) | |||||
F.plus | a+b | F.chain(F.abs,F.chain(F.plus,F.sin,F.chain(F.square,F.cos))) | Math.abs(Math.sin(a) + Math.pow(Math.cos(b),2)) | |||
10.8 | 29.6 | 0.43 | 0.35 |
- Version:
- 1.0, 09/24/99
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final DoubleFunction
Function that returns Math.abs(a).static final DoubleFunction
Function that returns Math.acos(a).static final DoubleFunction
Function that returns Math.asin(a).static final DoubleFunction
Function that returns Math.atan(a).static final DoubleDoubleFunction
Function that returns Math.atan2(a,b).static final DoubleFunction
Function that returns Math.ceil(a).static final DoubleDoubleFunction
Function that returns a invalid input: '<' b ? -1 : a > b ? 1 : 0.static final DoubleFunction
Function that returns Math.cos(a).static final DoubleDoubleFunction
Function that returns a / b.static final DoubleDoubleFunction
Function that returns a == b ? 1 : 0.static final DoubleFunction
Function that returns Math.exp(a).static final DoubleFunction
Function that returns Math.floor(a).static final Functions
Little trick to allow for "aliasing", that is, renaming this class.static final DoubleDoubleFunction
Function that returns a > b ? 1 : 0.static final DoubleFunction
Function that returns its argument.static final DoubleDoubleFunction
Function that returns Math.IEEEremainder(a,b).static final DoubleFunction
Function that returns 1.0 / a.static final DoubleDoubleProcedure
Function that returns a == b.static final DoubleDoubleProcedure
Function that returns a > b.static final DoubleDoubleProcedure
Function that returns a invalid input: '<' b.static final DoubleDoubleFunction
Function that returns a invalid input: '<' b ? 1 : 0.static final DoubleDoubleFunction
Function that returns Math.log(a) / Math.log(b).static final DoubleFunction
Function that returns Math.log(a).static final DoubleFunction
Function that returns Math.log(a) / Math.log(2).static final DoubleDoubleFunction
Function that returns Math.max(a,b).static final DoubleDoubleFunction
Function that returns Math.min(a,b).static final DoubleDoubleFunction
Function that returns a - b.static final DoubleDoubleFunction
Function that returns a % b.static final DoubleDoubleFunction
Function that returns a * b.static final DoubleFunction
Function that returns -a.static final DoubleDoubleFunction
Function that returns a + b.static final DoubleDoubleFunction
Function that returns Math.abs(a) + Math.abs(b).static final DoubleDoubleFunction
Function that returns Math.pow(a,b).static final DoubleFunction
Function that returns Math.rint(a).static final DoubleFunction
Function that returns a invalid input: '<' 0 ? -1 : a > 0 ? 1 : 0.static final DoubleFunction
Function that returns Math.sin(a).static final DoubleFunction
Function that returns Math.sqrt(a).static final DoubleFunction
Function that returns a * a.static final DoubleFunction
Function that returns Math.tan(a). -
Constructor Summary
ConstructorsModifierConstructorDescriptionprotected
Makes this class non instantiable, but still let's others inherit from it. -
Method Summary
Modifier and TypeMethodDescriptionstatic DoubleFunction
between
(double from, double to) Constructs a function that returns (frominvalid input: '<'=a invalid input: '&'invalid input: '&' ainvalid input: '<'=to) ? 1 : 0.static DoubleFunction
bindArg1
(DoubleDoubleFunction function, double c) Constructs a unary function from a binary function with the first operand (argument) fixed to the given constant c.static DoubleFunction
bindArg2
(DoubleDoubleFunction function, double c) Constructs a unary function from a binary function with the second operand (argument) fixed to the given constant c.static DoubleDoubleFunction
Constructs the function f( g(a), h(b) ).static DoubleDoubleFunction
Constructs the function g( h(a,b) ).static DoubleFunction
Constructs the function g( h(a) ).static DoubleFunction
compare
(double b) Constructs a function that returns a invalid input: '<' b ? -1 : a > b ? 1 : 0.static DoubleFunction
constant
(double c) Constructs a function that returns the constant c.static void
demo1()
Demonstrates usage of this class.static void
demo2
(int size) Benchmarks and demonstrates usage of trivial and complex functions.static DoubleFunction
div
(double b) Constructs a function that returns a / b.static DoubleFunction
equals
(double b) Constructs a function that returns a == b ? 1 : 0.static DoubleFunction
greater
(double b) Constructs a function that returns a > b ? 1 : 0.static DoubleFunction
IEEEremainder
(double b) Constructs a function that returns Math.IEEEremainder(a,b).static DoubleProcedure
isBetween
(double from, double to) Constructs a function that returns frominvalid input: '<'=a invalid input: '&'invalid input: '&' ainvalid input: '<'=to.static DoubleProcedure
isEqual
(double b) Constructs a function that returns a == b.static DoubleProcedure
isGreater
(double b) Constructs a function that returns a > b.static DoubleProcedure
isLess
(double b) Constructs a function that returns a invalid input: '<' b.static DoubleFunction
less
(double b) Constructs a function that returns a invalid input: '<' b ? 1 : 0.static DoubleFunction
lg
(double b) Constructs a function that returns Math.log(a) / Math.log(b).protected static void
Tests various methods of this class.static DoubleFunction
max
(double b) Constructs a function that returns Math.max(a,b).static DoubleFunction
min
(double b) Constructs a function that returns Math.min(a,b).static DoubleFunction
minus
(double b) Constructs a function that returns a - b.static DoubleDoubleFunction
minusMult
(double constant) Constructs a function that returns a - b*constant.static DoubleFunction
mod
(double b) Constructs a function that returns a % b.static DoubleFunction
mult
(double b) Constructs a function that returns a * b.static DoubleFunction
plus
(double b) Constructs a function that returns a + b.static DoubleDoubleFunction
plusMult
(double constant) Constructs a function that returns a + b*constant.static DoubleFunction
pow
(double b) Constructs a function that returns Math.pow(a,b).static DoubleFunction
random()
Constructs a function that returns a new uniform random number in the open unit interval(0.0,1.0)
(excluding 0.0 and 1.0).static DoubleFunction
round
(double precision) Constructs a function that returns the number rounded to the given precision; Math.rint(a/precision)*precision.static DoubleDoubleFunction
swapArgs
(DoubleDoubleFunction function) Constructs a function that returns function.apply(b,a), i.e.
-
Field Details
-
functions
Little trick to allow for "aliasing", that is, renaming this class. Writing code likeFunctions.chain(Functions.plus,Functions.sin,Functions.chain(Functions.square,Functions.cos));
is a bit awkward, to say the least. Using the aliasing you can instead write
Functions F = Functions.functions;
F.chain(F.plus,F.sin,F.chain(F.square,F.cos)); -
abs
Function that returns Math.abs(a). -
acos
Function that returns Math.acos(a). -
asin
Function that returns Math.asin(a). -
atan
Function that returns Math.atan(a). -
ceil
Function that returns Math.ceil(a). -
cos
Function that returns Math.cos(a). -
exp
Function that returns Math.exp(a). -
floor
Function that returns Math.floor(a). -
identity
Function that returns its argument. -
inv
Function that returns 1.0 / a. -
log
Function that returns Math.log(a). -
log2
Function that returns Math.log(a) / Math.log(2). -
neg
Function that returns -a. -
rint
Function that returns Math.rint(a). -
sign
Function that returns a invalid input: '<' 0 ? -1 : a > 0 ? 1 : 0. -
sin
Function that returns Math.sin(a). -
sqrt
Function that returns Math.sqrt(a). -
square
Function that returns a * a. -
tan
Function that returns Math.tan(a). -
atan2
Function that returns Math.atan2(a,b). -
compare
Function that returns a invalid input: '<' b ? -1 : a > b ? 1 : 0. -
div
Function that returns a / b. -
equals
Function that returns a == b ? 1 : 0. -
greater
Function that returns a > b ? 1 : 0. -
IEEEremainder
Function that returns Math.IEEEremainder(a,b). -
isEqual
Function that returns a == b. -
isLess
Function that returns a invalid input: '<' b. -
isGreater
Function that returns a > b. -
less
Function that returns a invalid input: '<' b ? 1 : 0. -
lg
Function that returns Math.log(a) / Math.log(b). -
max
Function that returns Math.max(a,b). -
min
Function that returns Math.min(a,b). -
minus
Function that returns a - b. -
mod
Function that returns a % b. -
mult
Function that returns a * b. -
plus
Function that returns a + b. -
plusAbs
Function that returns Math.abs(a) + Math.abs(b). -
pow
Function that returns Math.pow(a,b).
-
-
Constructor Details
-
Functions
protected Functions()Makes this class non instantiable, but still let's others inherit from it.
-
-
Method Details
-
between
Constructs a function that returns (frominvalid input: '<'=a invalid input: '&'invalid input: '&' ainvalid input: '<'=to) ? 1 : 0. a is a variable, from and to are fixed. -
bindArg1
Constructs a unary function from a binary function with the first operand (argument) fixed to the given constant c. The second operand is variable (free).- Parameters:
function
- a binary function taking operands in the form function.apply(c,var).- Returns:
- the unary function function(c,var).
-
bindArg2
Constructs a unary function from a binary function with the second operand (argument) fixed to the given constant c. The first operand is variable (free).- Parameters:
function
- a binary function taking operands in the form function.apply(var,c).- Returns:
- the unary function function(var,c).
-
chain
public static DoubleDoubleFunction chain(DoubleDoubleFunction f, DoubleFunction g, DoubleFunction h) Constructs the function f( g(a), h(b) ).- Parameters:
f
- a binary function.g
- a unary function.h
- a unary function.- Returns:
- the binary function f( g(a), h(b) ).
-
chain
Constructs the function g( h(a,b) ).- Parameters:
g
- a unary function.h
- a binary function.- Returns:
- the unary function g( h(a,b) ).
-
chain
Constructs the function g( h(a) ).- Parameters:
g
- a unary function.h
- a unary function.- Returns:
- the unary function g( h(a) ).
-
compare
Constructs a function that returns a invalid input: '<' b ? -1 : a > b ? 1 : 0. a is a variable, b is fixed. -
constant
Constructs a function that returns the constant c. -
demo1
public static void demo1()Demonstrates usage of this class. -
demo2
public static void demo2(int size) Benchmarks and demonstrates usage of trivial and complex functions. -
div
Constructs a function that returns a / b. a is a variable, b is fixed. -
equals
Constructs a function that returns a == b ? 1 : 0. a is a variable, b is fixed. -
greater
Constructs a function that returns a > b ? 1 : 0. a is a variable, b is fixed. -
IEEEremainder
Constructs a function that returns Math.IEEEremainder(a,b). a is a variable, b is fixed. -
isBetween
Constructs a function that returns frominvalid input: '<'=a invalid input: '&'invalid input: '&' ainvalid input: '<'=to. a is a variable, from and to are fixed. -
isEqual
Constructs a function that returns a == b. a is a variable, b is fixed. -
isGreater
Constructs a function that returns a > b. a is a variable, b is fixed. -
isLess
Constructs a function that returns a invalid input: '<' b. a is a variable, b is fixed. -
less
Constructs a function that returns a invalid input: '<' b ? 1 : 0. a is a variable, b is fixed. -
lg
Constructs a function that returns Math.log(a) / Math.log(b). a is a variable, b is fixed. -
main
Tests various methods of this class. -
max
Constructs a function that returns Math.max(a,b). a is a variable, b is fixed. -
min
Constructs a function that returns Math.min(a,b). a is a variable, b is fixed. -
minus
Constructs a function that returns a - b. a is a variable, b is fixed. -
minusMult
Constructs a function that returns a - b*constant. a and b are variables, constant is fixed. -
mod
Constructs a function that returns a % b. a is a variable, b is fixed. -
mult
Constructs a function that returns a * b. a is a variable, b is fixed. -
plus
Constructs a function that returns a + b. a is a variable, b is fixed. -
plusMult
Constructs a function that returns a + b*constant. a and b are variables, constant is fixed. -
pow
Constructs a function that returns Math.pow(a,b). a is a variable, b is fixed. -
random
Constructs a function that returns a new uniform random number in the open unit interval(0.0,1.0)
(excluding 0.0 and 1.0). Currently the engine isMersenneTwister
and is seeded with the current time.Note that any random engine derived from
RandomEngine
and any random distribution derived fromAbstractDistribution
are function objects, because they implement the proper interfaces. Thus, if you are not happy with the default, just pass your favourite random generator to function evaluating methods. -
round
Constructs a function that returns the number rounded to the given precision; Math.rint(a/precision)*precision. Examples:precision = 0.01 rounds 0.012 --> 0.01, 0.018 --> 0.02 precision = 10 rounds 123 --> 120 , 127 --> 130
-
swapArgs
Constructs a function that returns function.apply(b,a), i.e. applies the function with the first operand as second operand and the second operand as first operand.- Parameters:
function
- a function taking operands in the form function.apply(a,b).- Returns:
- the binary function function(b,a).
-