org.apache.commons.rng.simple.internal.ProviderBuilder Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.commons.rng.simple.internal;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import org.apache.commons.rng.UniformRandomProvider;
import org.apache.commons.rng.RestorableUniformRandomProvider;
import org.apache.commons.rng.core.source32.JDKRandom;
import org.apache.commons.rng.core.source32.Well512a;
import org.apache.commons.rng.core.source32.Well1024a;
import org.apache.commons.rng.core.source32.Well19937a;
import org.apache.commons.rng.core.source32.Well19937c;
import org.apache.commons.rng.core.source32.Well44497a;
import org.apache.commons.rng.core.source32.Well44497b;
import org.apache.commons.rng.core.source32.ISAACRandom;
import org.apache.commons.rng.core.source32.MersenneTwister;
import org.apache.commons.rng.core.source32.MultiplyWithCarry256;
import org.apache.commons.rng.core.source32.KISSRandom;
import org.apache.commons.rng.core.source64.SplitMix64;
import org.apache.commons.rng.core.source64.XorShift1024Star;
import org.apache.commons.rng.core.source64.TwoCmres;
import org.apache.commons.rng.core.source64.MersenneTwister64;
/**
* RNG builder.
*
* It uses reflection to find the factory method of the RNG implementation,
* and performs seed type conversions.
*
*/
public final class ProviderBuilder {
/** Error message. */
private static final String INTERNAL_ERROR_MSG = "Internal error: Please file a bug report";
/** Length of the seed array (for random seed). */
private static final int RANDOM_SEED_ARRAY_SIZE = 128;
/** Seed converter. */
private static final Long2Int LONG_TO_INT = new Long2Int();
/** Seed converter. */
private static final Int2Long INT_TO_LONG = new Int2Long();
/** Seed converter. */
private static final Long2IntArray LONG_TO_INT_ARRAY = new Long2IntArray(RANDOM_SEED_ARRAY_SIZE);
/** Seed converter. */
private static final Long2LongArray LONG_TO_LONG_ARRAY = new Long2LongArray(RANDOM_SEED_ARRAY_SIZE);
/** Seed converter. */
private static final LongArray2Long LONG_ARRAY_TO_LONG = new LongArray2Long();
/** Seed converter. */
private static final IntArray2Int INT_ARRAY_TO_INT = new IntArray2Int();
/** Seed converter. */
private static final LongArray2IntArray LONG_ARRAY_TO_INT_ARRAY = new LongArray2IntArray();
/** Seed converter. */
private static final IntArray2LongArray INT_ARRAY_TO_LONG_ARRAY = new IntArray2LongArray();
/** Seed converter. */
private static final ByteArray2IntArray BYTE_ARRAY_TO_INT_ARRAY = new ByteArray2IntArray();
/** Seed converter. */
private static final ByteArray2LongArray BYTE_ARRAY_TO_LONG_ARRAY = new ByteArray2LongArray();
/** Map to convert "Integer" seeds. */
private static final Map, SeedConverter> CONV_INT =
new ConcurrentHashMap, SeedConverter>();
/** Map to convert "int[]" seeds. */
private static final Map, SeedConverter> CONV_INT_ARRAY =
new ConcurrentHashMap, SeedConverter>();
/** Map to convert "Long" seeds. */
private static final Map, SeedConverter> CONV_LONG =
new ConcurrentHashMap, SeedConverter>();
/** Map to convert "long[]" seeds. */
private static final Map, SeedConverter> CONV_LONG_ARRAY =
new ConcurrentHashMap, SeedConverter>();
/** Map to convert "byte[]" seeds. */
private static final Map, SeedConverter> CONV_BYTE_ARRAY =
new ConcurrentHashMap, SeedConverter>();
static {
// Input seed type is "Long".
// Key is the implementation's "native" seed type.
CONV_LONG.put(Integer.class, LONG_TO_INT);
CONV_LONG.put(Long.class, new NoOpConverter());
CONV_LONG.put(int[].class, LONG_TO_INT_ARRAY);
CONV_LONG.put(long[].class, LONG_TO_LONG_ARRAY);
// Input seed type is "Integer".
// Key is the implementation's "native" seed type.
CONV_INT.put(Integer.class, new NoOpConverter());
CONV_INT.put(Long.class, INT_TO_LONG);
CONV_INT.put(int[].class, new SeedConverterComposer(INT_TO_LONG, LONG_TO_INT_ARRAY));
CONV_INT.put(long[].class, new SeedConverterComposer(INT_TO_LONG, LONG_TO_LONG_ARRAY));
// Input seed type is "int[]".
// Key is the implementation's "native" seed type.
CONV_INT_ARRAY.put(Integer.class, INT_ARRAY_TO_INT);
CONV_INT_ARRAY.put(Long.class, new SeedConverterComposer(INT_ARRAY_TO_INT, INT_TO_LONG));
CONV_INT_ARRAY.put(int[].class, new NoOpConverter());
CONV_INT_ARRAY.put(long[].class, INT_ARRAY_TO_LONG_ARRAY);
// Input seed type is "long[]".
// Key is the implementation's "native" seed type.
CONV_LONG_ARRAY.put(Integer.class, new SeedConverterComposer(LONG_ARRAY_TO_LONG, LONG_TO_INT));
CONV_LONG_ARRAY.put(Long.class, LONG_ARRAY_TO_LONG);
CONV_LONG_ARRAY.put(int[].class, LONG_ARRAY_TO_INT_ARRAY);
CONV_LONG_ARRAY.put(long[].class, new NoOpConverter());
// Input seed type is "byte[]".
// Key is the implementation's "native" seed type.
CONV_BYTE_ARRAY.put(Integer.class, new SeedConverterComposer(BYTE_ARRAY_TO_INT_ARRAY, INT_ARRAY_TO_INT));
CONV_BYTE_ARRAY.put(Long.class, new SeedConverterComposer(BYTE_ARRAY_TO_LONG_ARRAY, LONG_ARRAY_TO_LONG));
CONV_BYTE_ARRAY.put(int[].class, BYTE_ARRAY_TO_INT_ARRAY);
CONV_BYTE_ARRAY.put(long[].class, BYTE_ARRAY_TO_LONG_ARRAY);
}
/**
* Class only contains static method.
*/
private ProviderBuilder() {}
/**
* Creates a RNG instance.
*
* @param source RNG specification.
* @param seed Seed value. It can be {@code null} (in which case a
* random value will be used).
* @param args Additional arguments to the implementation's constructor.
* @return a new RNG instance.
* @throws UnsupportedOperationException if the seed type is invalid.
*/
public static RestorableUniformRandomProvider create(RandomSourceInternal source,
Object seed,
Object[] args) {
// Convert seed to native type.
final Object nativeSeed = createSeed(source, seed);
// Build a single array with all the arguments to be passed
// (in the right order) to the constructor.
final List