/* ========================
* JSynoptic : a free Synoptic editor
* ========================
*
* Project Info: http://jsynoptic.sourceforge.net/index.html
*
* This program is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* (C) Copyright 2001-2003, by :
* Corporate:
* Astrium SAS
* EADS CRC
* Individual:
* Nicolas Brodu
*
* $Id: RandomSource.java,v 1.4 2007/01/23 17:10:38 ogor Exp $
*
* Changes
* -------
* 21-Jan-2004 : Creation date (NB);
*
*/
package jsynoptic.builtin;
import java.awt.CardLayout;
import java.awt.event.ActionEvent;
import java.util.Random;
import java.util.ResourceBundle;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import simtools.data.DataException;
import simtools.data.DataInfo;
import simtools.data.DataSource;
import simtools.data.NoSuchIndex;
import simtools.data.UnsupportedOperation;
import simtools.ui.ActionCheckBox;
import simtools.ui.NumberField;
import simtools.ui.ResourceFinder;
/**
* Base class for the uniform and gaussian random sources
*/
public abstract class RandomSource extends DataSource {
public static ResourceBundle resources = ResourceFinder.get(RandomSource.class);
protected long maxIndex;
protected Long seed = null ; // when using a seed, keep it for later reference, including serialization
protected Random generator;
// params are mean and standard deviation in gaussian case
// interval boundaries in random distribution
protected double param1, param2;
protected double minValue, maxValue;
// This is a sample of a distribution, not a random variable
// So keep the values, for each index
protected double values[];
protected DataInfo info;
/* (non-Javadoc)
* @see simtools.data.DataSource#getInformation()
*/
public DataInfo getInformation() {
return info;
}
protected void fillValues() {
if (maxIndex>=0) {
values = new double[(int)maxIndex+1];
minValue = Double.POSITIVE_INFINITY;
maxValue = Double.NEGATIVE_INFINITY;
for (int i=0; i<=maxIndex; ++i) {
values[i] = nextRandomValue();
minValue = Math.min(minValue, values[i]);
maxValue = Math.max(maxValue, values[i]);
}
}
// Keep only the last value
else {
values = new double[1];
values[0] = Double.NaN; // unititialized
}
}
public RandomSource(String name, double param1, double param2) {
this(name, param1, param2, 0);
}
public RandomSource(String name, double param1, double param2, long nSamples) {
this.param1 = param1;
this.param2 = param2;
maxIndex = nSamples-1;
generator = new Random();
this.seed = null;
minValue = Double.NaN;
maxValue = Double.NaN;
info = new DataInfo(name);
fillValues();
}
public RandomSource(String name, long seed, double param1, double param2) {
this(name, seed, param1, param2, 0);
}
public RandomSource(String name, long seed, double param1, double param2, long nSamples) {
this.param1 = param1;
this.param2 = param2;
maxIndex = nSamples-1;
generator = new Random(seed);
this.seed = new Long(seed);
minValue = Double.NaN;
maxValue = Double.NaN;
info = new DataInfo(name);
fillValues();
}
/** For subclasses to implement according to their distribution */
protected abstract double nextRandomValue();
public Object getValue(long index) throws DataException {
// Optimize the code by not wrapping into an object when calling the Double function
return new Double(getDoubleValue(index));
}
/* (non-Javadoc)
* @see simtools.data.ValueProvider#getDoubleValue(long)
*/
public double getDoubleValue(long index) throws DataException {
// Optimize the code by not wrapping into an object
if (maxIndex==-1) {
values[0] = nextRandomValue();
minValue = values[0];
maxValue = values[0];
return values[0];
}
if (index>maxIndex) throw new NoSuchIndex(index);
return values[(int)index];
}
/* (non-Javadoc)
* @see simtools.data.DataSource#computeLastIndex()
*/
public long computeLastIndex() throws UnsupportedOperation {
if (maxIndex==-1) throw new UnsupportedOperation();
return maxIndex;
}
/* (non-Javadoc)
* @see simtools.data.DataSource#computeStartIndex()
*/
public long computeStartIndex() throws UnsupportedOperation {
return 0;
}
/* (non-Javadoc)
* @see simtools.data.DataSource#getLastIndex()
*/
public long getLastIndex() throws UnsupportedOperation {
return maxIndex;
}
/* (non-Javadoc)
* @see simtools.data.DataSource#getStartIndex()
*/
public long getStartIndex() throws UnsupportedOperation {
return 0;
}
/* (non-Javadoc)
* @see simtools.data.DataSource#computeMax()
*/
public Object computeMax() {
return getMax();
}
/* (non-Javadoc)
* @see simtools.data.DataSource#computeMin()
*/
public Object computeMin() {
return getMin();
}
/* (non-Javadoc)
* @see simtools.data.DataSource#getDoubleMax()
*/
public double getDoubleMax() {
return maxValue;
}
/* (non-Javadoc)
* @see simtools.data.DataSource#getDoubleMin()
*/
public double getDoubleMin() {
return minValue;
}
/* (non-Javadoc)
* @see simtools.data.DataSource#getMax()
*/
public Object getMax() {
return new Double(getDoubleMax());
}
/* (non-Javadoc)
* @see simtools.data.DataSource#getMin()
*/
public Object getMin() {
return new Double(getDoubleMin());
}
/**
* @return Returns the maxIndex.
*/
public long getMaxIndex() {
return maxIndex;
}
public static abstract class OptionPanel extends JPanel {
protected JRadioButton rbStatic, rbDynamic;
protected NumberField nfParam1, nfParam2, nfSize;
protected JLabel bufferLabel;
protected NumberField nfDynamicSize;
protected JTextField tfPeriod;
protected ActionCheckBox cbSeed;
protected JTextField tfSeed;
public OptionPanel() {
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
Box box = Box.createHorizontalBox();
box.add(new JLabel(param1Name()));
box.add(Box.createHorizontalGlue());
box.add(nfParam1 = new NumberField(0.0));
add(box);
box = Box.createHorizontalBox();
box.add(new JLabel(param2Name()));
box.add(Box.createHorizontalGlue());
box.add(nfParam2 = new NumberField(1.0));
add(box);
box = Box.createHorizontalBox();
box.add(rbStatic = new JRadioButton(resources.getString("static"),true));
box.add(Box.createHorizontalGlue());
add(box);
box = Box.createHorizontalBox();
box.add(rbDynamic = new JRadioButton(resources.getString("dynamic"),false));
box.add(Box.createHorizontalGlue());
add(box);
ButtonGroup bg = new ButtonGroup();
bg.add(rbStatic);
bg.add(rbDynamic);
final JPanel cardPane = new JPanel(new CardLayout());
box = Box.createHorizontalBox();
box.add(bufferLabel = new JLabel(resources.getString("staticBufferLabel")));
box.add(Box.createHorizontalGlue());
box.add(nfSize = new NumberField(100,5));
cardPane.add(box,"s");
Box vbox = Box.createVerticalBox();
box = Box.createHorizontalBox();
box.add(bufferLabel = new JLabel(resources.getString("dynamicBufferLabel")));
box.add(Box.createHorizontalGlue());
box.add(nfDynamicSize = new NumberField(100,5));
vbox.add(box);
box = Box.createHorizontalBox();
box.add(bufferLabel = new JLabel(resources.getString("period")));
box.add(Box.createHorizontalGlue());
box.add(tfPeriod = new JTextField("1000"));
vbox.add(box);
cardPane.add(vbox,"d");
add(cardPane);
rbDynamic.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
((CardLayout)cardPane.getLayout()).show(cardPane,rbDynamic.isSelected()?"d":"s");
}
});
box = Box.createHorizontalBox();
box.add(cbSeed = new ActionCheckBox(resources.getString("seed"),false) {
public void actionPerformed(ActionEvent e) {
tfSeed.setEditable(cbSeed.isSelected());
tfSeed.setEnabled(cbSeed.isSelected());
}
});
box.add(Box.createHorizontalGlue());
box.add(tfSeed = new JTextField());
add(box);
cbSeed.apply();
}
/**
* @return the name of parameter 1 for the user
*/
protected abstract String param1Name();
protected abstract String param2Name();
public abstract DataSource createSource(String name);
}
}