Reputation: 5
Let's say I have 3 functions, something like y_1(x) = x^2
, y_2(x) = x+1
and y_3(x) = x/5
.
How do I apply these functions to any multidimensional float array in an element wise fashion?
Now given that I have the functions y_1
, y_2
and y_3
, what is a function that applies an arbitrary function to a float array of any size and shape?
I tried creating a function applier that takes in any function and then applying it to every element in a double loop for the 2 dimensional case but I cannot even get the function applier to take another function as input.
I tried doing the following
public float[][] elemen_wise_function( float[][] x,
int Size_axis_0,
int Size_axis_1,
Callable<> myFunc) {
float[][] Constructed_array = new float[Size_axis_0][Size_axis_1];
for (int i=0; i<Size_axis_0; i++) {
for (int j = 0; j < Size_axis_1; j++) {
Constructed_array[i][j] = (float) myFunc(x[i][j]) ;
}
}
return Constructed_array;
}
But this fails because I cannot find a way to pass myFunc
to elemen_wise_function
.
Upvotes: 0
Views: 4719
Reputation: 58
If you are trying to do this with Java 6, you can do something like.
import java.util.Arrays;
import java.util.function.Function;
public interface MapFunction {
public float map(float value);
}
public static float[][] map2DArray(float[][] floatArrays, MapFunction mapper) {
final float[][] retval = new float[floatArrays.length][];
for (int i = 0; i < floatArrays.length; i++) {
float [] floats = floatArrays[i];
retval[i] = new float[floats.length];
for (int j = 0; j < floats.length; j++) {
retval[i][j] = mapper.map(floats[j]);
}
}
return retval;
}
Or in Java 8 and you don't mind using Float
import java.util.Arrays;
import java.util.function.Function;
public static Float[][] map2DArray(Float[][] floatArrays, Function<Float, Float> mapper) {
return Arrays.stream(floatArrays).map((Float[] floats) ->
Arrays.stream(floats).map(mapper).toArray(Float[]::new)
).toArray(Float[][]::new);
}
Upvotes: 0
Reputation: 26056
Quite cool, you can pass a lambda (since java 8):
public float[][] elemen_wise_function(float[][] x,
Function<Float, Float> f) {
float[][] Constructed_array = new float[x.length][x[0].length];
for (int i=0; i<x.length; i++) {
for (int j = 0; j < x[0].length; j++) {
Constructed_array[i][j] = f.apply(x[i][j]);
}
}
return Constructed_array;
}
Then you can pass any function defined as lambda, for example:
Function<Float, Float> fun = x -> 2 * x;
Also one note - use camelCase in java for method names;)
Upvotes: 0
Reputation: 85452
One solution would be to declare myFunc as UnaryOperator<Float>
.
public float[][] elemen_wise_function(float[][] x, int Size_axis_0, int Size_axis_1,
UnaryOperator<Float> myFunc) {
Unfortunately that will autobox the float
back and forth.
If performance is a concern you can define a custom interface that is hard-coded to operate on primitive float
s:
interface FloatOperator {
float apply(float x);
}
public float[][] elemen_wise_function(float[][] x, int Size_axis_0, int Size_axis_1,
FloatOperator myFunc) {
In both cases use as:
for (int i = 0; i < Size_axis_0; i++) {
for (int j = 0; j < Size_axis_1; j++) {
Constructed_array[i][j] = myFunc.apply(x[i][j]);
}
}
Invoke as (example):
elemen_wise_function(array, size0, size1, a -> 1/a);
Upvotes: 2