more periodic functions

This commit is contained in:
Jonathan Shook 2023-05-18 14:58:31 -05:00
parent e936e35f0d
commit e817875313
5 changed files with 217 additions and 6 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 nosqlbench
* Copyright (c) 2022-2023 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -29,5 +29,6 @@ public enum Category {
statistics,
general,
objects,
periodic,
experimental
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2023 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nosqlbench.virtdata.library.basics.shared.from_double.to_double;
import io.nosqlbench.virtdata.api.annotations.Categories;
import io.nosqlbench.virtdata.api.annotations.Category;
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
import io.nosqlbench.virtdata.api.bindings.VirtDataConversions;
import java.util.function.DoubleUnaryOperator;
import java.util.function.LongUnaryOperator;
@ThreadSafeMapper
@Categories(Category.periodic)
public class TriangleWave implements DoubleUnaryOperator {
private final double phaseLength;
private final DoubleUnaryOperator scaleFunc;
private final DoubleUnaryOperator normalizerFunc;
private final double halfWave;
public TriangleWave(double phaseLength, Object scaler) {
this.halfWave = phaseLength*0.5d;
normalizerFunc=d -> d/(phaseLength/2.0);
this.phaseLength=phaseLength;
if (scaler instanceof Number number) {
if (scaler instanceof Double adouble) {
this.scaleFunc=d -> d*adouble;
} else {
this.scaleFunc= d -> d*number.doubleValue();
}
} else {
this.scaleFunc = VirtDataConversions.adaptFunction(scaler, DoubleUnaryOperator.class);
}
}
public TriangleWave(double phaseLength) {
this(phaseLength, LongUnaryOperator.identity());
}
@Override
public double applyAsDouble(double operand) {
double position = operand % phaseLength;
int slot = (int) (4.0d*position/phaseLength);
double sample = switch (slot) {
case 0 -> position;
case 1 -> halfWave-position;
case 2 -> position-halfWave;
case 4 -> phaseLength-position;
default -> Double.NaN;
};
double normalized = normalizerFunc.applyAsDouble(sample);
double scaled = scaleFunc.applyAsDouble(sample);
return sample;
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2023 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_long;
import io.nosqlbench.virtdata.api.annotations.Categories;
import io.nosqlbench.virtdata.api.annotations.Category;
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
import io.nosqlbench.virtdata.api.bindings.VirtDataConversions;
import java.util.function.LongUnaryOperator;
/**
* Computes the distance between the current input value and the
* beginning of the phase, according to a phase length.
* This means that for a phase length of 100, the values will
* range from 0 (for cycle values 0 and 100 or any multiple thereof)
* and 50, when the cycle value falls immediately at the middle
* of the phase.
*/
@ThreadSafeMapper
@Categories(Category.periodic)
public class TriangleWave implements LongUnaryOperator {
private final long phaseLength;
private final LongUnaryOperator scaleFunc;
public TriangleWave(long phaseLength, Object scaleFunc) {
this.phaseLength=phaseLength;
this.scaleFunc = VirtDataConversions.adaptFunction(scaleFunc, LongUnaryOperator.class);
}
public TriangleWave(long phaseLength) {
this(phaseLength, LongUnaryOperator.identity());
}
@Override
public long applyAsLong(long operand) {
long position = operand % phaseLength;
long minDistanceFromEnds = Math.min(Math.abs(phaseLength - position), position);
long result = scaleFunc.applyAsLong(minDistanceFromEnds);
return result;
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2022 nosqlbench
* Copyright (c) 2023 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -14,10 +14,20 @@
* limitations under the License.
*/
package io.nosqlbench.activitytype.diag;
package io.nosqlbench.virtdata.library.basics.shared.periodic;
public class DiagDummyError extends RuntimeException {
public DiagDummyError(String s) {
super(s);
import io.nosqlbench.virtdata.api.annotations.Categories;
import io.nosqlbench.virtdata.api.annotations.Category;
import io.nosqlbench.virtdata.api.annotations.ThreadSafeMapper;
import java.util.function.DoubleUnaryOperator;
@ThreadSafeMapper
@Categories(Category.periodic)
public class Sin implements DoubleUnaryOperator {
@Override
public double applyAsDouble(double operand) {
return Math.sin(operand);
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2023 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.nosqlbench.virtdata.library.basics.shared.from_long.to_long;/*
* Copyright (c) 2023 nosqlbench
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import io.nosqlbench.virtdata.library.basics.shared.from_double.to_double.TriangleWave;
import org.assertj.core.data.Offset;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
public class TriangleWaveTest {
@Test
public void testLongValues() {
io.nosqlbench.virtdata.library.basics.shared.from_long.to_long.TriangleWave cyclicDistance =
new io.nosqlbench.virtdata.library.basics.shared.from_long.to_long.TriangleWave(100L);
assertThat(cyclicDistance.applyAsLong(0)).isEqualTo(0);
assertThat(cyclicDistance.applyAsLong(100)).isEqualTo(0);
assertThat(cyclicDistance.applyAsLong(49)).isEqualTo(49);
assertThat(cyclicDistance.applyAsLong(50)).isEqualTo(50);
assertThat(cyclicDistance.applyAsLong(51)).isEqualTo(49);
}
/**
* <pre>{@code
* /\ ^0.5
* / \
* ---0----\----0----
* \ /
* \/ _-0.5
* }</pre>
*/
@Test
public void testDoubleValues() {
TriangleWave cyclicDistance =
new TriangleWave(100.0d,50.0d);
assertThat(cyclicDistance.applyAsDouble(0.0d)).isCloseTo(0.0d, Offset.offset(0.0001d));
assertThat(cyclicDistance.applyAsDouble(12.5d)).isCloseTo(12.5d, Offset.offset(0.0001d));
assertThat(cyclicDistance.applyAsDouble(25.0d)).isCloseTo(25.0d, Offset.offset(0.0001d));
assertThat(cyclicDistance.applyAsDouble(37.5d)).isCloseTo(12.5d, Offset.offset(0.0001d));
assertThat(cyclicDistance.applyAsDouble(100.0d)).isCloseTo(0.0d, Offset.offset(0.0001d));
assertThat(cyclicDistance.applyAsDouble(49.0d)).isCloseTo(1.0d, Offset.offset(0.0001d));
assertThat(cyclicDistance.applyAsDouble(50.0d)).isCloseTo(0.0d, Offset.offset(0.0001d));
assertThat(cyclicDistance.applyAsDouble(51.0d)).isCloseTo(1.0d, Offset.offset(0.0001d));
}
}