/*
* Encog(tm) Core v2.5 - Java Version
* http://www.heatonresearch.com/encog/
* http://code.google.com/p/encog-java/
* Copyright 2008-2010 Heaton Research, Inc.
*
* 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.
*
* For more information on Heaton Research copyrights, licenses
* and trademarks visit:
* http://www.heatonresearch.com/copyright
*/
package org.encog.mathutil.randomize;
import java.util.Random;
import org.encog.mathutil.matrices.Matrix;
import org.encog.neural.networks.BasicNetwork;
import org.encog.neural.networks.layers.Layer;
import org.encog.neural.networks.structure.FlatUpdateNeeded;
import org.encog.neural.networks.synapse.Synapse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Provides basic functionality that most randomizers will need.
*
* @author jheaton
*
*/
public abstract class BasicRandomizer implements Randomizer {
/**
* The logging object.
*/
@SuppressWarnings("unused")
private final Logger logger = LoggerFactory.getLogger(this.getClass());
/**
* The random number generator.
*/
private Random random;
/**
* Construct a random number generator with a random(current time) seed.
* If you want to set your own seed, just call "getRandom().setSeed".
*/
public BasicRandomizer() {
this.random = new Random(System.nanoTime());
}
/**
* Randomize the synapses and biases in the basic network based on an array,
* modify the array. Previous values may be used, or they may be discarded,
* depending on the randomizer.
*
* @param network
* A network to randomize.
*/
public void randomize(final BasicNetwork network) {
network.getStructure().updateFlatNetwork();
// randomize the weight matrix
for (final Synapse synapse : network.getStructure().getSynapses()) {
if (synapse.getMatrix() != null) {
randomize(network, synapse);
}
}
// randomize the bias
for (final Layer layer : network.getStructure().getLayers()) {
if (layer.hasBias()) {
randomize(layer.getBiasWeights());
}
}
network.getStructure().setFlatUpdate(FlatUpdateNeeded.Flatten);
network.getStructure().flattenWeights();
}
/**
* Randomize a synapse, only randomize those connections that are actually
* connected.
*
* @param network
* The network the synapse belongs to.
* @param synapse
* The synapse to randomize.
*/
public void randomize(final BasicNetwork network, final Synapse synapse) {
if (synapse.getMatrix() != null) {
boolean limited = network.getStructure().isConnectionLimited();
final double[][] d = synapse.getMatrix().getData();
for (int fromNeuron = 0; fromNeuron
< synapse.getMatrix().getRows(); fromNeuron++) {
for (int toNeuron = 0; toNeuron
< synapse.getMatrix().getCols(); toNeuron++) {
if (!limited
|| network.isConnected(synapse, fromNeuron,
toNeuron)) {
d[fromNeuron][toNeuron] =
randomize(d[fromNeuron][toNeuron]);
}
}
}
}
}
/**
* Randomize the array based on an array, modify the array. Previous values
* may be used, or they may be discarded, depending on the randomizer.
*
* @param d
* An array to randomize.
*/
public void randomize(final double[] d) {
for (int i = 0; i < d.length; i++) {
d[i] = randomize(d[i]);
}
}
/**
* Randomize the array based on an array, modify the array. Previous values
* may be used, or they may be discarded, depending on the randomizer.
*
* @param d
* An array to randomize.
*/
public void randomize(final Double[] d) {
for (int i = 0; i < d.length; i++) {
d[i] = randomize(d[i]);
}
}
/**
* Randomize the 2d array based on an array, modify the array. Previous
* values may be used, or they may be discarded, depending on the
* randomizer.
*
* @param d
* An array to randomize.
*/
public void randomize(final double[][] d) {
for (int r = 0; r < d.length; r++) {
for (int c = 0; c < d[0].length; c++) {
d[r][c] = randomize(d[r][c]);
}
}
}
/**
* Randomize the 2d array based on an array, modify the array. Previous
* values may be used, or they may be discarded, depending on the
* randomizer.
*
* @param d
* An array to randomize.
*/
public void randomize(final Double[][] d) {
for (int r = 0; r < d.length; r++) {
for (int c = 0; c < d[0].length; c++) {
d[r][c] = randomize(d[r][c]);
}
}
}
/**
* Randomize the matrix based on an array, modify the array. Previous values
* may be used, or they may be discarded, depending on the randomizer.
*
* @param m
* A matrix to randomize.
*/
public void randomize(final Matrix m) {
final double[][] d = m.getData();
for (int r = 0; r < m.getRows(); r++) {
for (int c = 0; c < m.getCols(); c++) {
d[r][c] = randomize(d[r][c]);
}
}
}
/**
* @return The random number generator in use. Use this to set the seed, if
* desired.
*/
public Random getRandom() {
return random;
}
/**
* @return The next double.
*/
public double nextDouble() {
return this.random.nextDouble();
}
/**
* @param random the random to set
*/
public void setRandom(final Random random) {
this.random = random;
}
/**
* Generate a random number in the specified range.
*
* @param min
* The minimum value.
* @param max
* The maximum value.
* @return A random number.
*/
public double nextDouble(final double min, final double max) {
final double range = max - min;
return (range * this.random.nextDouble()) + min;
}
}