下面列出了怎么用java.util.function.DoubleFunction的API类实例代码及写法,或者点击链接到github查看源代码。
private static <T> void readNonNullDoubleColumn(Object[] vals, int fieldIdx, DoubleColumnVector vector,
int childCount, DoubleFunction<T> reader) {
if (vector.isRepeating) { // fill complete column with first value
T repeatingValue = reader.apply(vector.vector[0]);
fillColumnWithRepeatingValue(vals, fieldIdx, repeatingValue, childCount);
} else {
if (fieldIdx == -1) { // set as an object
for (int i = 0; i < childCount; i++) {
vals[i] = reader.apply(vector.vector[i]);
}
} else { // set as a field of Row
Row[] rows = (Row[]) vals;
for (int i = 0; i < childCount; i++) {
rows[i].setField(fieldIdx, reader.apply(vector.vector[i]));
}
}
}
}
@Override
public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedDouble<U>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.apply(t));
}
};
}
};
}
@Override
public final DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}
@Override
public void accept(double t) {
try (DoubleStream result = mapper.apply(t)) {
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if (result != null)
result.sequential().forEach(i -> downstream.accept(i));
}
}
};
}
};
}
protected JFreeChart doInBackground(double binShift, double binwidth) {
// create histogram
double[] dat = data.getData();
if (cbExcludeSmallerNoise.isSelected()) {
double noise = data.getRange().getLowerBound();
// get processed data from original image
dat = DoubleStream.of(dat).filter(d -> d > noise).toArray();
}
Range r = HistogramChartFactory.getBounds(dat);
DoubleFunction<Double> f =
cbThirdSQRT.isSelected() ? val -> Math.cbrt(val) : val -> val;
JFreeChart chart = HistogramChartFactory.createHistogram(dat, xLabel, binwidth,
r.getLowerBound() - binShift, r.getUpperBound(), f);
// add gaussian?
if (cbGaussianFit.isSelected()) {
addGaussianCurve(chart.getXYPlot());
}
return chart;
}
private static <T> void readNonNullDoubleColumn(Object[] vals, int fieldIdx, DoubleColumnVector vector,
int childCount, DoubleFunction<T> reader) {
if (vector.isRepeating) { // fill complete column with first value
T repeatingValue = reader.apply(vector.vector[0]);
fillColumnWithRepeatingValue(vals, fieldIdx, repeatingValue, childCount);
} else {
if (fieldIdx == -1) { // set as an object
for (int i = 0; i < childCount; i++) {
vals[i] = reader.apply(vector.vector[i]);
}
} else { // set as a field of Row
Row[] rows = (Row[]) vals;
for (int i = 0; i < childCount; i++) {
rows[i].setField(fieldIdx, reader.apply(vector.vector[i]));
}
}
}
}
@Override
public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedDouble<U>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.apply(t));
}
};
}
};
}
@Override
public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedDouble<U>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.apply(t));
}
};
}
};
}
public static double binarySearch(
double lo, double hi, double target, DoubleFunction<Double> function) {
if (hi <= lo) throw new IllegalArgumentException("hi should be greater than lo");
double mid;
do {
// Find the middle point
mid = (hi + lo) / 2.0;
// Compute the value of our function for the middle point
// Note that f can be any function not just the square root function
double value = function.apply(mid);
if (value > target) {
hi = mid;
} else {
lo = mid;
}
} while ((hi - lo) > EPS);
return mid;
}
@Override
public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedDouble<U>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.apply(t));
}
};
}
};
}
@Override
public final DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}
@Override
public void accept(double t) {
try (DoubleStream result = mapper.apply(t)) {
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if (result != null)
result.sequential().forEach(i -> downstream.accept(i));
}
}
};
}
};
}
@Override
public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedDouble<U>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.apply(t));
}
};
}
};
}
@Override
public final DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}
@Override
public void accept(double t) {
try (DoubleStream result = mapper.apply(t)) {
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if (result != null)
result.sequential().forEach(i -> downstream.accept(i));
}
}
};
}
};
}
@Test
public void testSlerp_simple() {
// arrange
QuaternionRotation q0 = QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Z, 0.0);
QuaternionRotation q1 = QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Z, PlaneAngleRadians.PI);
DoubleFunction<QuaternionRotation> fn = q0.slerp(q1);
Vector3D v = Vector3D.of(2, 0, 1);
double sqrt2 = Math.sqrt(2);
// act
checkVector(fn.apply(0).apply(v), 2, 0, 1);
checkVector(fn.apply(0.25).apply(v), sqrt2, sqrt2, 1);
checkVector(fn.apply(0.5).apply(v), 0, 2, 1);
checkVector(fn.apply(0.75).apply(v), -sqrt2, sqrt2, 1);
checkVector(fn.apply(1).apply(v), -2, 0, 1);
}
@Test
public void testSlerp_tOutsideOfZeroToOne_apply() {
// arrange
Vector3D vec = Vector3D.Unit.PLUS_X;
QuaternionRotation q1 = QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Z, 0.25 * PlaneAngleRadians.PI);
QuaternionRotation q2 = QuaternionRotation.fromAxisAngle(Vector3D.Unit.PLUS_Z, 0.75 * PlaneAngleRadians.PI);
// act/assert
DoubleFunction<QuaternionRotation> slerp12 = q1.slerp(q2);
EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.PLUS_X, slerp12.apply(-4.5).apply(vec), EPS);
EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.PLUS_X, slerp12.apply(-0.5).apply(vec), EPS);
EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.MINUS_X, slerp12.apply(1.5).apply(vec), EPS);
EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.MINUS_X, slerp12.apply(5.5).apply(vec), EPS);
DoubleFunction<QuaternionRotation> slerp21 = q2.slerp(q1);
EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.MINUS_X, slerp21.apply(-4.5).apply(vec), EPS);
EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.MINUS_X, slerp21.apply(-0.5).apply(vec), EPS);
EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.PLUS_X, slerp21.apply(1.5).apply(vec), EPS);
EuclideanTestUtils.assertCoordinatesEqual(Vector3D.Unit.PLUS_X, slerp21.apply(5.5).apply(vec), EPS);
}
@Override
public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedDouble<U>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.apply(t));
}
};
}
};
}
@Override
public final DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}
@Override
public void accept(double t) {
try (DoubleStream result = mapper.apply(t)) {
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if (result != null)
result.sequential().forEach(i -> downstream.accept(i));
}
}
};
}
};
}
@Override
public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedDouble<U>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.apply(t));
}
};
}
};
}
@Override
public final DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}
@Override
public void accept(double t) {
try (DoubleStream result = mapper.apply(t)) {
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if (result != null)
result.sequential().forEach(i -> downstream.accept(i));
}
}
};
}
};
}
@Override
public final DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
Objects.requireNonNull(mapper);
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}
@Override
public void accept(double t) {
try (DoubleStream result = mapper.apply(t)) {
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if (result != null)
result.sequential().forEach(i -> downstream.accept(i));
}
}
};
}
};
}
@Override
public final <U> Stream<U> mapToObj(DoubleFunction<? extends U> mapper) {
Objects.requireNonNull(mapper);
return new ReferencePipeline.StatelessOp<Double, U>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT) {
@Override
Sink<Double> opWrapSink(int flags, Sink<U> sink) {
return new Sink.ChainedDouble<U>(sink) {
@Override
public void accept(double t) {
downstream.accept(mapper.apply(t));
}
};
}
};
}
@Override
public final DoubleStream flatMap(DoubleFunction<? extends DoubleStream> mapper) {
return new StatelessOp<Double>(this, StreamShape.DOUBLE_VALUE,
StreamOpFlag.NOT_SORTED | StreamOpFlag.NOT_DISTINCT | StreamOpFlag.NOT_SIZED) {
@Override
Sink<Double> opWrapSink(int flags, Sink<Double> sink) {
return new Sink.ChainedDouble<Double>(sink) {
@Override
public void begin(long size) {
downstream.begin(-1);
}
@Override
public void accept(double t) {
try (DoubleStream result = mapper.apply(t)) {
// We can do better that this too; optimize for depth=0 case and just grab spliterator and forEach it
if (result != null)
result.sequential().forEach(i -> downstream.accept(i));
}
}
};
}
};
}
private static <T> void readDoubleColumn(Object[] vals, int fieldIdx, DoubleColumnVector vector,
int childCount, DoubleFunction<T> reader) {
if (vector.isRepeating) { // fill complete column with first value
if (vector.isNull[0]) {
// fill vals with null values
fillColumnWithRepeatingValue(vals, fieldIdx, null, childCount);
} else {
// read repeating non-null value by forwarding call
readNonNullDoubleColumn(vals, fieldIdx, vector, childCount, reader);
}
} else {
boolean[] isNullVector = vector.isNull;
if (fieldIdx == -1) { // set as an object
for (int i = 0; i < childCount; i++) {
if (isNullVector[i]) {
vals[i] = null;
} else {
vals[i] = reader.apply(vector.vector[i]);
}
}
} else { // set as a field of Row
Row[] rows = (Row[]) vals;
for (int i = 0; i < childCount; i++) {
if (isNullVector[i]) {
rows[i].setField(fieldIdx, null);
} else {
rows[i].setField(fieldIdx, reader.apply(vector.vector[i]));
}
}
}
}
}
public static JFreeChart createHistogram(double[] data, double binwidth, String yAxisLabel,
double min, double max, DoubleFunction<Double> function) {
if (data != null && data.length > 0) {
double datawidth = (max - min);
int cbin = (int) Math.ceil(datawidth / binwidth);
int[] bins = new int[cbin + 1];
XYSeries series = createHistoSeries(data, binwidth, min, max, function);
double barwidth = binwidth;
// calc new barwidth if a transformation function is defined
if (function != null) {
int sum = Arrays.stream(bins).sum();
// see when 98% of the data is displayed
int sum2 = 0;
for (int i = 0; i < bins.length; i++) {
if (bins[i] > 0) {
sum2 += bins[i];
if ((sum2 / (double) sum) >= 0.99) {
barwidth = function.apply(min + (binwidth / 2.0) + i * binwidth).doubleValue()
- function.apply(min + (binwidth / 2.0) + (i - 1) * binwidth).doubleValue();
}
}
}
}
return createHistogram(series, barwidth, yAxisLabel);
} else
return null;
}
/**
* Converts from double array to histogram array
*
* @param data
* @param binwidth
* @param min real minimum of data
* @param max real maximum of data
* @param function function to transform data axis
* @return A histogram array with length = datawidth/binwidth +1 (datawidth = max-min)
*/
public static XYSeries createHistoSeries(double[] data, double binwidth, double min, double max,
DoubleFunction<Double> function) {
double datawidth = (max - min);
int cbin = (int) Math.ceil(datawidth / binwidth);
int[] bins = new int[cbin + 1];
// count intensities in bins
// if value>bin.upper put in next
for (double v : data) {
int i = (int) Math.ceil((v - min) / binwidth) - 1;
if (i < 0) // does only happen if min>than minimum value of data
i = 0;
if (i >= bins.length)
i = bins.length - 1;
bins[i]++;
}
// add zeros around data
boolean peakStarted = false;
XYSeries series = new XYSeries("histo", true, true);
for (int i = 0; i < bins.length; i++) {
// start peak and add data if>0
if (bins[i] > 0) {
// add previous zero once
if (!peakStarted && i > 0)
addDPToSeries(series, bins, i - 1, binwidth, min, max, function);
// add data
addDPToSeries(series, bins, i, binwidth, min, max, function);
peakStarted = true;
} else {
// add trailing zero
addDPToSeries(series, bins, i, binwidth, min, max, function);
peakStarted = false;
}
}
return series;
}
/**
* Converts from double array to histogram array
*
* @param data
* @param binwidth
* @param min real minimum of data
* @param max real maximum of data
* @param function function to transform data axis
* @return A histogram array with length = datawidth/binwidth +1 (datawidth = max-min)
*/
public static XYSeries createHistoSeries(DoubleArrayList data, double binwidth, double min,
double max, DoubleFunction<Double> function) {
double datawidth = (max - min);
int cbin = (int) Math.ceil(datawidth / binwidth);
int[] bins = new int[cbin + 1];
// count intensities in bins
// if value>bin.upper put in next
for (double v : data) {
int i = (int) Math.ceil((v - min) / binwidth) - 1;
if (i < 0) // does only happen if min>than minimum value of data
i = 0;
if (i >= bins.length)
i = bins.length - 1;
bins[i]++;
}
// add zeros around data
boolean peakStarted = false;
XYSeries series = new XYSeries("histo", true, true);
for (int i = 0; i < bins.length; i++) {
// start peak and add data if>0
if (bins[i] > 0) {
// add previous zero once
if (!peakStarted && i > 0)
addDPToSeries(series, bins, i - 1, binwidth, min, max, function);
// add data
addDPToSeries(series, bins, i, binwidth, min, max, function);
peakStarted = true;
} else {
// add trailing zero
addDPToSeries(series, bins, i, binwidth, min, max, function);
peakStarted = false;
}
}
return series;
}
private static void addDPToSeries(XYSeries series, int[] bins, int i, double binwidth, double min,
double max, DoubleFunction<Double> function) {
// adds a data point to the series
double x = min + (binwidth / 2.0) + i * binwidth;
if (function != null)
x = function.apply(x);
series.add(x, bins[i]);
}
/**
* Converts from double array to histogram array
*
* @param data
* @param binwidth
* @param min real minimum of data
* @param max real maximum of data
* @param function function to transform data axis
* @return A histogram array with length = datawidth/binwidth +1 (datawidth = max-min)
*/
public static List<DataPoint> createHistoList(DoubleArrayList data, double binwidth, double min,
double max, DoubleFunction<Double> function) {
double datawidth = (max - min);
int cbin = (int) Math.ceil(datawidth / binwidth);
int[] bins = new int[cbin + 1];
// count intensities in bins
// if value>bin.upper put in next
for (double v : data) {
int i = (int) Math.ceil((v - min) / binwidth) - 1;
if (i < 0) // does only happen if min>than minimum value of data
i = 0;
if (i >= bins.length)
i = bins.length - 1;
bins[i]++;
}
// add zeros around data
List<DataPoint> result = new ArrayList<>();
boolean peakStarted = false;
for (int i = 0; i < bins.length; i++) {
// start peak and add data if>0
if (bins[i] > 0) {
// add previous zero once
if (!peakStarted && i > 0)
addDPToList(result, bins, i - 1, binwidth, min, max, function);
// add data
addDPToList(result, bins, i, binwidth, min, max, function);
peakStarted = true;
} else {
// add trailing zero
addDPToList(result, bins, i, binwidth, min, max, function);
peakStarted = false;
}
}
return result;
}
private static void addDPToList(List<DataPoint> list, int[] bins, int i, double binwidth,
double min, double max, DoubleFunction<Double> function) {
// adds a data point to the series
double x = min + (binwidth / 2.0) + i * binwidth;
if (function != null)
x = function.apply(x);
list.add(new SimpleDataPoint(x, bins[i]));
}
/**
*
* @param data
* @param yAxisLabel
* @param width automatic width if parameter is <=0
* @param function transform the data axis after binning
* @return
*/
public static JFreeChart createHistogram(double[] data, String yAxisLabel, double width,
double min, double max, DoubleFunction<Double> function) {
if (width <= 0)
return createHistogram(data, yAxisLabel, min, max, function);
else {
return createHistogram(data, width, yAxisLabel, min, max, function);
}
}
private static <T> void readDoubleColumn(Object[] vals, int fieldIdx, DoubleColumnVector vector,
int childCount, DoubleFunction<T> reader) {
if (vector.isRepeating) { // fill complete column with first value
if (vector.isNull[0]) {
// fill vals with null values
fillColumnWithRepeatingValue(vals, fieldIdx, null, childCount);
} else {
// read repeating non-null value by forwarding call
readNonNullDoubleColumn(vals, fieldIdx, vector, childCount, reader);
}
} else {
boolean[] isNullVector = vector.isNull;
if (fieldIdx == -1) { // set as an object
for (int i = 0; i < childCount; i++) {
if (isNullVector[i]) {
vals[i] = null;
} else {
vals[i] = reader.apply(vector.vector[i]);
}
}
} else { // set as a field of Row
Row[] rows = (Row[]) vals;
for (int i = 0; i < childCount; i++) {
if (isNullVector[i]) {
rows[i].setField(fieldIdx, null);
} else {
rows[i].setField(fieldIdx, reader.apply(vector.vector[i]));
}
}
}
}
}