-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generators: * Create LinearShortElement - add constructor with Random argument, implement generate method, store number of LinearStates as member variable * Create ShortElementInterface Tests: * Create LinearShortElementAnalysis - measure distributions of outcomes, combine length test cases into parameterized test * Create LinearShortElementPerformance - measure performance of different outcomes * Create LinearShortElementStaticTest - add test cases for the countLinearStates method * Create LinearShortElementTest * Update RandomProvider - update code style
- Loading branch information
Showing
7 changed files
with
411 additions
and
1 deletion.
There are no files selected for viewing
130 changes: 130 additions & 0 deletions
130
generators/src/main/java/mathtools/generators/elements/shorts/LinearShortElement.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
package mathtools.generators.elements.shorts; | ||
|
||
import java.security.SecureRandom; | ||
import java.util.Random; | ||
|
||
import javax.annotation.Nonnull; | ||
|
||
/** An element with a linearly changing probability. | ||
* Max Length (Number of outcomes) = 180 | ||
* Max Rate of Change (Linear Slope) = 200 | ||
* @author DK96-OS : 2022 */ | ||
public final class LinearShortElement | ||
implements ShortElementInterface { | ||
|
||
private short mLength; | ||
|
||
private int mLengthStates; | ||
|
||
private final Random mRNG; | ||
|
||
/** Create a new Linear Short Element with SecureRandom RNG | ||
* @param length The number of outcomes | ||
* @throws IllegalArgumentException if length is negative or zero, or rate is negative or zero | ||
*/ | ||
public LinearShortElement( | ||
final short length | ||
) throws IllegalArgumentException { | ||
// Validate arguments | ||
if (1 > length || 180 < length) | ||
throw new IllegalArgumentException("Invalid Length"); | ||
// | ||
mLength = length; | ||
mLengthStates = countLinearStates(length); | ||
mRNG = new SecureRandom(); | ||
} | ||
|
||
/** Create a new Linear Short Element with a given RNG instance | ||
* @param length The number of outcomes | ||
* @param rng The Random number generator to use | ||
* @throws IllegalArgumentException if length is negative or zero, or rate is negative or zero | ||
*/ | ||
public LinearShortElement( | ||
final short length, | ||
@Nonnull final Random rng | ||
) { // Validate arguments | ||
if (1 > length || 180 < length) | ||
throw new IllegalArgumentException("Invalid Length"); | ||
// | ||
mLength = length; | ||
mLengthStates = countLinearStates(length); | ||
mRNG = rng; | ||
} | ||
|
||
/** Obtain the Range Length, or the number of outcomes */ | ||
public short getLength() { | ||
return mLength; | ||
} | ||
|
||
/** Set the length of the Element, or the number of outcomes | ||
* @param length The new number of outcomes | ||
* @return Whether the new value is valid, and has been updated */ | ||
public boolean setLength( | ||
final short length | ||
) { | ||
if (1 > length || | ||
180 < length || | ||
mLength == length | ||
) return false; | ||
// | ||
mLength = length; | ||
mLengthStates = countLinearStates(length); | ||
return true; | ||
} | ||
|
||
@Override | ||
public short generate() { | ||
// Select one of the Element micro-states | ||
final int selectedState = mRNG.nextInt(mLengthStates); | ||
// | ||
int sCounter = mLength - 1; | ||
short tCounter = 1; | ||
for (; | ||
selectedState > sCounter && mLength > tCounter; | ||
++tCounter | ||
) { | ||
sCounter += mLength - tCounter; | ||
} | ||
return tCounter; | ||
} | ||
|
||
/** Calculate the minimum number of Microstates for a Linear element | ||
* @param length The number of Macrostates. Must be less than 181. | ||
* @return The minimum number of Microstates required */ | ||
public static int countLinearStates( | ||
short length | ||
) { | ||
// Zero or negative lengths are invalid | ||
if (1 > length) return 0; | ||
// Max length is 180 | ||
if (180 < length) return 16290; | ||
// Count the states | ||
int states; | ||
// Split the range of lengths in half | ||
if (80 <= length) { // 80+ | ||
if (150 <= length) { // 150+ | ||
for (states = 11325; // State count for 150 | ||
150 < length; | ||
--length | ||
) states += length; | ||
} else { // 80 -> 149 | ||
for (states = 3240;// State count for 80 | ||
80 < length; | ||
--length | ||
) states += length; | ||
} | ||
} else if (40 <= length) { // 40 -> 79 | ||
for (states = 820; // State count for 40 | ||
40 < length; | ||
--length | ||
) states += length; | ||
} else { // 1 -> 39 | ||
for (states = 1; | ||
1 < length; | ||
--length | ||
) states += length; | ||
} | ||
return states; | ||
} | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
generators/src/main/java/mathtools/generators/elements/shorts/ShortElementInterface.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package mathtools.generators.elements.shorts; | ||
|
||
/** An Element that produces 16-bit Short integers */ | ||
public interface ShortElementInterface { | ||
|
||
/** Generate a new short */ | ||
short generate(); | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
53 changes: 53 additions & 0 deletions
53
...rators/src/test/java/mathtools/generators/elements/shorts/LinearShortElementAnalysis.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package mathtools.generators.elements.shorts; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static org.junit.jupiter.api.Assertions.assertTrue; | ||
|
||
import org.junit.jupiter.api.AfterEach; | ||
import org.junit.jupiter.params.ParameterizedTest; | ||
import org.junit.jupiter.params.provider.ValueSource; | ||
|
||
import java.util.List; | ||
|
||
import mathtools.generators.counters.ints.IntCounter32000; | ||
|
||
/** Inspection of the generated values of [LinearShortElement] | ||
* @author DK96-OS : 2022 */ | ||
public final class LinearShortElementAnalysis { | ||
|
||
private LinearShortElement mElement; | ||
private IntCounter32000 mCounter; | ||
|
||
@AfterEach | ||
public void testCleanup() { | ||
mElement = null; | ||
mCounter = null; | ||
} | ||
|
||
@ParameterizedTest | ||
@ValueSource(shorts = { 9, 25, 100, 150 }) | ||
public void testLengths( | ||
final short length | ||
) { | ||
mElement = new LinearShortElement(length); | ||
mCounter = new IntCounter32000(1, length); | ||
// | ||
for (int i = 0; 160_000 > i; ++i) { | ||
assertTrue( | ||
mCounter.count(mElement.generate())); | ||
} | ||
final List<Integer> results = mCounter.toList(); | ||
// Print the results | ||
for (int i = 0; i < results.size(); ++i) { | ||
final int outcome = i + 1; | ||
System.out.printf( | ||
"%d : %d\n", outcome, results.get(i) | ||
); | ||
} | ||
assert 0 < mCounter.getCountOf(1); | ||
assert 0 < mCounter.getCountOf(length); | ||
assertEquals( | ||
length, results.size()); | ||
} | ||
|
||
} |
61 changes: 61 additions & 0 deletions
61
...ors/src/test/java/mathtools/generators/elements/shorts/LinearShortElementPerformance.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package mathtools.generators.elements.shorts; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static mathtools.generators.elements.shorts.LinearShortElement.countLinearStates; | ||
|
||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.util.Random; | ||
|
||
import mathtools.generators.RandomProvider; | ||
|
||
/** Compare the Performance of [LinearShortElement] scenarios */ | ||
public final class LinearShortElementPerformance { | ||
|
||
private LinearShortElement mElement1; | ||
private LinearShortElement mElementLarge; | ||
|
||
private static final short largeLength = 150; | ||
private static final int mStateCountLarge = countLinearStates(largeLength); | ||
|
||
private static final int trials = 1_000_000; | ||
|
||
private final Random mFixedRandom1 = RandomProvider.fixedValue(1); | ||
private final Random mFixedRandomLarge = RandomProvider.fixedValue(mStateCountLarge); | ||
|
||
@BeforeEach | ||
public void testSetup() { | ||
mElement1 = new LinearShortElement( | ||
largeLength, mFixedRandom1 | ||
); | ||
mElementLarge = new LinearShortElement( | ||
largeLength, mFixedRandomLarge | ||
); | ||
} | ||
|
||
@Test | ||
public void compareStateSelection() { | ||
for (int i = 0; trials > i; ++i) { | ||
mElement1.generate(); | ||
mElementLarge.generate(); | ||
} | ||
} | ||
|
||
@Test | ||
public void compareStateSelection1() { | ||
for (int i = 0; trials > i; ++i) { | ||
assertEquals( | ||
1, mElement1.generate()); | ||
} | ||
} | ||
|
||
@Test | ||
public void compareStateSelectionLarge() { | ||
for (int i = 0; trials > i; ++i) { | ||
assertEquals( | ||
largeLength, mElementLarge.generate()); | ||
} | ||
} | ||
|
||
} |
54 changes: 54 additions & 0 deletions
54
...tors/src/test/java/mathtools/generators/elements/shorts/LinearShortElementStaticTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package mathtools.generators.elements.shorts; | ||
|
||
import static org.junit.jupiter.api.Assertions.assertEquals; | ||
import static mathtools.generators.elements.shorts.LinearShortElement.countLinearStates; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
/** Testing [LinearShortElement] static methods | ||
* @author DK96-OS : 2022 */ | ||
public final class LinearShortElementStaticTest { | ||
|
||
@Test | ||
public void testCountLinearStatesNormal() { | ||
short i = 1; | ||
assertEquals( | ||
1, countLinearStates(i++)); | ||
assertEquals( | ||
3, countLinearStates(i++)); | ||
assertEquals( | ||
6, countLinearStates(i++)); | ||
// | ||
int previous = 6; | ||
for (; | ||
181 > i; | ||
++i | ||
) { | ||
final int next = countLinearStates(i); | ||
assertEquals( | ||
previous + i, next); | ||
previous = next; | ||
} | ||
} | ||
|
||
@Test | ||
public void testCountLinearStatesTooLarge() { | ||
assertEquals( | ||
16290, countLinearStates((short) 181)); | ||
assertEquals( | ||
16290, countLinearStates((short) 200)); | ||
assertEquals( | ||
16290, countLinearStates((short) 2000)); | ||
} | ||
|
||
@Test | ||
public void testCountLinearStatesNegative() { | ||
assertEquals( | ||
0, countLinearStates((short) -1)); | ||
assertEquals( | ||
0, countLinearStates((short) 0)); | ||
assertEquals( | ||
0, countLinearStates((short) -180)); | ||
} | ||
|
||
} |
Oops, something went wrong.