org.jenetics.internal.util.DieHarder Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.jenetics Show documentation
Show all versions of org.jenetics Show documentation
Jenetics - Java Genetic Algorithm Library
/*
* Java Genetic Algorithm Library (jenetics-3.2.0).
* Copyright (c) 2007-2015 Franz Wilhelmstötter
*
* 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.
*
* Author:
* Franz Wilhelmstötter ([email protected])
*/
package org.jenetics.internal.util;
import static java.lang.String.format;
import static java.util.Objects.requireNonNull;
import static java.util.regex.Pattern.quote;
import static java.util.stream.Collectors.counting;
import static java.util.stream.Collectors.groupingBy;
import static org.jenetics.internal.util.Equality.eq;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.Random;
import org.jenetics.internal.util.DieHarder.Result.Assessment;
/**
* Class for testing a given random engine using the
* dieharder
* test application.
*
* @author Franz Wilhelmstötter
* @since 1.5
* @version 3.0
*/
public final class DieHarder {
/**
* Writes random numbers to an given data output stream.
*
* @author Franz Wilhelmstötter
* @since 1.5
* @version 3.0
*/
private static final class Randomizer implements Runnable {
private final Random _random;
private final CountingOutputStream _out;
Randomizer(final Random random, final OutputStream out) {
_random = requireNonNull(random);
_out = new CountingOutputStream(out);
}
@Override
public void run() {
try {
final byte[] data = new byte[4096];
while (!Thread.currentThread().isInterrupted()) {
_random.nextBytes(data);
_out.write(data);
}
} catch (IOException ignore) {
}
}
long getCount() {
return _out.getCount();
}
}
public static void main(final String[] args) throws Exception {
if ( args.length < 1) {
println("Usage: java org.jenetics.internal.util.DieHarder ");
return;
}
final String randomName = args[0];
Random random = null;
try {
random = (Random)Class.forName(randomName).newInstance();
printt(
"Testing: %s (%s)",
randomName,
new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date())
);
} catch (Exception e) {
System.out.println("Can't create random class " + randomName);
return;
}
final List dieharderArgs = new ArrayList<>();
dieharderArgs.add("dieharder");
for (int i = 1; i < args.length; ++i) {
dieharderArgs.add(args[i]);
}
dieharderArgs.add("-g");
dieharderArgs.add("200");
printv();
final long start = System.currentTimeMillis();
final ProcessBuilder builder = new ProcessBuilder(dieharderArgs);
final Process dieharder = builder.start();
final Randomizer randomizer = new Randomizer(
random,
dieharder.getOutputStream()
);
final Thread randomizerThread = new Thread(randomizer);
randomizerThread.start();
// The dieharder console output.
final BufferedReader stdout = new BufferedReader (
new InputStreamReader(dieharder.getInputStream())
);
final List results = new ArrayList<>();
for (String l = stdout.readLine(); l != null; l = stdout.readLine()) {
Result.parse(l).ifPresent(results::add);
System.out.println(l);
}
dieharder.waitFor();
randomizerThread.interrupt();
final long millis = System.currentTimeMillis() - start;
final long sec = (millis)/1000;
final double megaBytes = randomizer.getCount()/(1024.0*1024.0);
// Calculate statistics.
final Map grouped = results.stream()
.collect(groupingBy(r -> r.assessment, counting()));
final long passed = grouped.getOrDefault(Assessment.PASSED, 0L);
final long weak = grouped.getOrDefault(Assessment.WEAK, 0L);
final long failed = grouped.getOrDefault(Assessment.FAILED, 0L);
final NumberFormat formatter = NumberFormat.getIntegerInstance();
formatter.setMinimumFractionDigits(3);
formatter.setMaximumFractionDigits(3);
println("#=============================================================================#");
println(
"# %-76s#",
format("Summary: PASSED=%d, WEAK=%d, FAILED=%d", passed, weak, failed)
);
println(
"# %-76s#",
format(" %s MB of random data created with %s MB/sec",
formatter.format(megaBytes),
formatter.format(megaBytes/(millis/1000.0))
)
);
println("#=============================================================================#");
printt("Runtime: %d:%02d:%02d", sec/3600, (sec%3600)/60, (sec%60));
}
private static void printt(final String title, final Object... args) {
println("#=============================================================================#");
println("# %-76s#", format(title, args));
println("#=============================================================================#");
}
private static void printv() {
println("#=============================================================================#");
println(
"# %-76s#",
format("%s %s (%s) ", p("os.name"), p("os.version"), p("os.arch"))
);
println(
"# %-76s#",
format("java version \"%s\"", p("java.version"))
);
println(
"# %-76s#",
format("%s (build %s)", p("java.runtime.name"), p("java.runtime.version"))
);
println(
"# %-76s#",
format("%s (build %s)", p("java.vm.name"), p("java.vm.version"))
);
println("#=============================================================================#");
}
private static String p(final String name) {
return System.getProperty(name);
}
private static void println(final String pattern, final Object... args) {
System.out.println(format(pattern, args));
}
/**
* Represents one DieHarder test result.
*
* @author Franz Wilhelmstötter
* @since 3.0
* @version 3.0
*/
static final class Result {
static enum Assessment {
PASSED,
FAILED,
WEAK;
static Optional of(final String assessment) {
switch (assessment) {
case "PASSED": return Optional.of(PASSED);
case "FAILED": return Optional.of(FAILED);
case "WEAK": return Optional.of(WEAK);
default: return Optional.empty();
}
}
}
final String testName;
final int ntup;
final int tsamples;
final int psamples;
final double pvalue;
final Assessment assessment;
private Result(
final String testName,
final int ntup,
final int tsamples,
final int psamples,
final double pvalue,
final Assessment assessment
) {
this.testName = testName;
this.ntup = ntup;
this.tsamples = tsamples;
this.psamples = psamples;
this.pvalue = pvalue;
this.assessment = assessment;
}
static Optional parse(final String line) {
final String[] parts = line.split(quote("|"));
if (parts.length == 6) {
final String name = parts[0].trim();
final OptionalInt ntup = toOptionalInt(parts[1].trim());
final OptionalInt tsamples = toOptionalInt(parts[2].trim());
final OptionalInt psamples = toOptionalInt(parts[3].trim());
final OptionalDouble pvalue = toOptionalDouble(parts[4].trim());
final Optional assessment = Assessment.of(parts[5].trim());
if (ntup.isPresent() &&
tsamples.isPresent() &&
psamples.isPresent() &&
pvalue.isPresent() &&
assessment.isPresent())
{
return Optional.of(new Result(
name,
ntup.getAsInt(),
tsamples.getAsInt(),
psamples.getAsInt(),
pvalue.getAsDouble(),
assessment.get()
));
}
}
return Optional.empty();
}
private static OptionalInt toOptionalInt(final String value) {
try {
return OptionalInt.of(Integer.parseInt(value));
} catch (NumberFormatException e) {
return OptionalInt.empty();
}
}
private static OptionalDouble toOptionalDouble(final String value) {
try {
return OptionalDouble.of(Double.parseDouble(value));
} catch (NumberFormatException e) {
return OptionalDouble.empty();
}
}
@Override
public int hashCode() {
return Hash.of(getClass())
.and(testName)
.and(ntup)
.and(tsamples)
.and(psamples)
.and(pvalue)
.and(assessment).value();
}
@Override
public boolean equals(final Object obj) {
return Equality.of(this, obj).test(result ->
eq(testName, result.testName) &&
eq(ntup, result.ntup) &&
eq(tsamples, result.tsamples) &&
eq(psamples, result.psamples) &&
eq(pvalue, result.psamples) &&
eq(assessment, result.assessment)
);
}
@Override
public String toString() {
return format(
"%s[ntup=%d, tsamples=%d, psamples=%d, pvalue=%f, assessment=%s]",
testName, ntup, tsamples, psamples, pvalue, assessment
);
}
}
/**
* Counts the written bytes.
*
* @author Franz Wilhelmstötter
* @since 3.0
* @version 3.0
*/
private static final class CountingOutputStream extends OutputStream {
private final OutputStream _delegate;
private long _count;
CountingOutputStream(final OutputStream delegate) {
_delegate = requireNonNull(delegate);
}
@Override
public void write(final byte[] b) throws IOException {
_delegate.write(b);
_count += b.length;
}
@Override
public void write(final byte[] b, final int offset, final int length)
throws IOException
{
_delegate.write(b, offset, length);
_count += length;
}
@Override
public void write(final int b) throws IOException {
_delegate.write(b);
_count += 1;
}
long getCount() {
return _count;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy