import java.awt.*;
import java.lang.*;
import DField;
import MGraph;
import XFile;
import java.util.Date;
import PrintFormat;
public class SimParam extends Object{
static SimParam theParams[]; // array of params
static String theNames[]; // names for params
static int nParams=0; // how many params
static MGraph simGraph=null;
public static XFile theXFile=null;
static int theTick=0; // which time reference
is this
static PrintFormat xf=null;
static Date Xdate=null;
public static int logInterval=1;
public static boolean dumpMeans=false;
public static int numCycle=0;
int thisParam=0; // what is my index
boolean inited=false; // flag to indicate
that intialisation has happened once before;
private double value; // the value
public DField myField=null; // optional
field on screen or panel
String label=null;
double sumx=0;
double sumx2=0;
double min=1000000000.0;
double max = -1000000000.0;
int n=0;
static void sInit(int p) { // initialise
static variables
theParams = new SimParam[p];
theNames = new String[p];
simGraph = new MGraph("");
simGraph.init();
simGraph.run();
xf = new PrintFormat();
}
static void sInit() { // initialise static variables
theParams = new SimParam[50];
theNames = new String[50];
simGraph = new MGraph("");
simGraph.init();
simGraph.run();
xf = new PrintFormat();
}
public void reset() { // default reset ... override
setValue(0); // default value .. override for each
parameter
}
public static void sReset() { // reset
static stuff. should be done once
// this is a soft reset, leaves paramters defined,
but reset
theTick = 0; // reset time..
for(int i=0;i<nParams;i++) {
theParams[i].resetStats();
theParams[i].reset();
}
if (simGraph != null) simGraph.sReset();
}
void init() { // Override in subclasses
}
void gInit() { // Set up parameters etc.
init(); // do local init. overridden by subcalsses
inited = true;
}
public void registerGraph() {
if (simGraph != null) simGraph.register(this);
}
void initThis(String name) { // set set initial
stuff at creation.
if (nParams == 0) {
sInit(); // initialize static variables;
}
theParams[nParams] = this;
thisParam = nParams;
theNames[nParams++] = name;
resetStats();
}
void initThis(int p, String name) { //
set set initial stuff at creation.
if (nParams == 0) {
sInit(p); // initialize static variables;
}
theParams[nParams] = this;
thisParam = nParams;
theNames[nParams++] = name;
resetStats();
}
public void resetStats() {
sumx=0;
sumx2=0;
value=0;
min = 1000000000.0;
max = -1000000000.0;
n=0;
}
SimParam() { // new Simparam. must either use setname or initialize
name here.
initThis("");
}
SimParam(int p) { // new Simparam. must either use
setname or initialize name here.
initThis(p,"");
}
SimParam(int p, String name) { // new SimParam
with name;
initThis(p, name);
}
SimParam(String name) { // new SimParam with name;
initThis(name);
}
SimParam(DField aField) { // new SimParam with name;
setField(aField);
initThis(aField.getLabel());
}
SimParam(int p, DField aField) { // new SimParam with
name;
setField(aField);
initThis(p,aField.getLabel());
}
SimParam(DField aField, String name) { // new SimParam
with name;
setField(aField);
initThis(name);
aField.setLabel(name);
}
SimParam(int p, DField aField, String name) { //
new SimParam with name;
setField(aField);
initThis(p,name);
aField.setLabel(name);
}
public void setName(String name) { //
set name
theNames[thisParam] = name;
}
public void setField(DField x) { // set the
DField (optional)
myField = x;
}
public DoubleField getDoubleField() { // get the doublefield
if (myField != null) return(this.myField.value);
else return null;
}
public double getValue() { // get synchronised
value
if (myField != null) return(value = this.myField.value.getValue());
else return value;
}
public Object getValueObject() {
return (new Double(getValue()));
}
public double getStaticValue() { // get the
static value of field (if any).
// will not necessarily represent any new
typing
// done by users
if (myField != null) return(value = this.myField.value.getStaticVal());
else return value;
}
public void setValue(double v) { // sets
synchronised value. Slow if done often
value = v;
if(myField != null) this.myField.value.setValue(v);
}
public void setStaticValue(double v) { //
will not update the field on screen.
// Call sync() when ready to update display
value = v;
if(myField != null) this.myField.value.setStaticVal(v);
}
public double get() { // will not update the
field on screen.
return this.getStaticValue();
}
public double set(double v) { // will
not update the field on screen.
this.setStaticValue(v);
return this.value;
}
public double inc(double v) {
return this.set(this.get() + v);
}
public double inc() {
return this.set(this.get() + 1);
}
public double dec(double v) {
return this.set(this.get() - v);
}
public double dec() {
return this.set(this.get() - 1);
}
public void sync() { // make sure the field
(if any) is synchronised with the value
if(myField != null) this.myField.sync();
}
public double calc() {// override in subclasses,
One tick in the simulation
return value=getStaticValue();
}
public double calcResult() {
// value = getStaticValue(); // gets synchronised result
setStaticValue(calc()); // calls calc() routine that
subclasses are expected to override
n++; // increment n;
sumx += value; // sum x
sumx2 += value*value; // sum x2
if (value > max) max = value;
if (value < min) min = value;
reportStats(); // post calc -- better mechanism than this
!!!!!!!!!!!!!!!
return value; // default is passive. Some other
agent setting value;
}
public static void tick(int timeRef) {
theTick = timeRef;
}
public static void tick() {
theTick++;
}
public static int getTick() {
return (theTick);
}
public double getMean() {
if (n > 1)
return sumx/n;
else if (n == 1)
return (sumx);
else return(0);
}
public int getN() {
return n;
}
public double getMax() {
return max;
}
public double getMin() {
return min;
}
public double getSD() {
if (n > 1)
return Math.sqrt(((n*sumx2)-(sumx*sumx))/(n*(n-1)));
else return 0;
}
public void reportStats() { // override
}
static SimParam getParam(String x) { // get
param from name
// it is intended that this class is
// overridden for each variable that
// is derived from computation. init and
calc
// should be overridden. Part of initialization
// is looking up params by name, and the
new class
// should have appropriate new parameter
names whose
// value is derived from this routine. This
is why initAll
// should not be called until all params
are set.
int i = getParamIndex(x);
if (i >= 0) return theParams[i];
else return null;
}
public static SimParam getParam(int x) { //
get a SimParam object with index x
return theParams[x]; // STATIC
}
static int getParamIndex(String x) { //
look up param by name. return index
for (int i=0;i<nParams;i++) {
if (theNames[i].equals(x)) return i;
}
return -1;
}
public static void postCycle() { // override
to do processing at end of each cycle;
// really needs some kind of callback mechanism
}
public static void cycleParams() { //
runs a cycle of the simulation. STATIC
tick();
for(int i=0;i<nParams;i++) theParams[i].calcResult();
postCycle();
if (simGraph != null) {
simGraph.initParams();
if (nParams > 0 && !simGraph.isVisible()) simGraph.show();
}
if (theXFile != null) logData();
}
public static void cycleParams(double x[]) { //
runs a cycle of the simulation. STATIC
for(int i=0;i<nParams;i++) x[i] = theParams[i].calcResult();
postCycle();
if (simGraph != null) {
simGraph.initParams();
if (nParams > 0 && !simGraph.isVisible()) simGraph.show();
// simGraph.repaint();
}
if (theXFile != null) logData();
// this routine gets the values in order. later params might
change values
}
public static void multiCycle(int k) { //
main entry to run simulation
for (int i=0;i<k;i++) cycleParams();
syncAll();
if (simGraph != null) simGraph.repaint();
}
public static void collectData(double x[]) { //
collects the current state of all
// values. STATIC
for(int i=0;i<nParams;i++) {
theParams[i].sync();
x[i] = theParams[i].value;
}
}
public static void collectDataObjects(Object x[]) { //
collects the current state of all
// values as objects. This permits
for(int i=0;i<nParams;i++) { //
routines to gnerate their own
theParams[i].sync(); // arbitray return value
types. STATIC
x[i] = theParams[i].getValueObject();
}
}
public static void syncAll() { // must
be done after all definitions. STATIC
for(int i=0;i<nParams;i++) theParams[i].sync();
}
public static void initAll() { // must
be done after all definitions. STATIC
for(int i=0;i<nParams;i++) theParams[i].gInit();
theTick = 0;
}
double chartScale=0;
public void setChartScale(double chartScale) {
this.chartScale = chartScale;
}
public double getChartScale() {
return chartScale;
}
public void setLabel(String l) {
this.label = l;
}
public String getLabel() {
if (label != null)
return this.label;
else return this.myField.getLabel();
}
int style=0; // solid
public void setStyle(int style) {
this.style = style;
}
public int getStyle() {
return style;
}
public static void setGraphTitle(String t) {
if (simGraph != null) simGraph.setTitle(t);
}
double chartMin=-10;
public void setChartMin(int chartMin) {
this.chartMin = (double) chartMin;
}
public void setChartMin(double chartMin) {
this.chartMin = chartMin;
}
public double getChartMin() {
return chartMin;
}
double chartMax=10;
public void setChartMax(int chartMax) {
this.chartMax = (double) chartMax;
}
public void setChartMax(double chartMax) {
this.chartMax = chartMax;
}
public double getChartMax() {
return chartMax;
}
public static void startLog(){
if (theXFile == null) {
theXFile = new XFile();
Xdate = new Date(); // sets time to current offset
from 1970 in UTC
theXFile.Choose(1);
// System.out.println(theXfile.aFile.getPath());
theXFile.Open();
if (theXFile.errMessage != null) System.out.println(theXFile.errMessage);
xf.printf("Session %d-%d-%d %d:%d:%d %d\r",Xdate.getDate());
xf.printF(Xdate.getMonth());
xf.printF(Xdate.getYear());
xf.printF(Xdate.getHours());
xf.printF(Xdate.getMinutes());
xf.printF(Xdate.getSeconds());
xf.printF(System.currentTimeMillis());
theXFile.WriteLine(xf.printOut());
if (theXFile.errMessage != null) System.out.println(theXFile.errMessage);
// Logger("// labels");
writeLabels(theXFile);
}
}
public static void writeLabels(XFile theFile) {
xf.printf("%8s ","
");
theFile.WriteString(xf.printOut());
xf.printf("%-12s ","Trial");
for(int i=0;i<nParams;i++) {
// theParams[i].sync();
xf.printF(theParams[i].getLabel());
}
theFile.WriteLine(xf.printOut());
}
public static void stopLog() {
if (theXFile != null) {
if (logInterval != 1) logData(); // do last line
if logInterval != 1
writeStatTable(theXFile);
writeStatList(theXFile); // write out table of Means etc
theXFile.Close();
theXFile = null;
}
}
public static void breakLog() {
if (theXFile != null) {
if (logInterval != 1) logData(); // do last line
if logInterval != 1
writeStatTable(theXFile);
writeStatList(theXFile); // write out table of Means etc
}
}
public static void writeStatTable(XFile theFile) {
xf.printf("\r// mins, maxs, means, stds ");
theFile.WriteLine(xf.printOut());
xf.printf("%10.2f ",theParams[0].getN());
for(int i=0;i<nParams;i++) {
// theParams[i].sync();
xf.printF(theParams[i].getMin());
}
theFile.WriteLine(xf.printOut());
xf.printf("%10.2f ",theParams[0].getN());
for(int i=0;i<nParams;i++) {
// theParams[i].sync();
xf.printF(theParams[i].getMax());
}
theFile.WriteLine(xf.printOut());
xf.printf("%10.2f ",theParams[0].getN());
for(int i=0;i<nParams;i++) {
// theParams[i].sync();
xf.printF(theParams[i].getMean());
}
theFile.WriteLine(xf.printOut());
xf.printf("%10.2f ",theParams[0].getN());
for(int i=0;i<nParams;i++) {
// theParams[i].sync();
xf.printF(theParams[i].getSD());
}
theFile.WriteLine(xf.printOut());
}
public static void writeStatList(XFile theFile) {
xf.printf("\r\rTrial %d\r",theParams[0].getN());
theFile.WriteLine(xf.printOut());
theFile.WriteLine("Label Min
Max Mean STD\r ");
for(int i=0;i<nParams;i++) {
xf.printf("%10s %10.2f %10.2f %10.2f %10.2f ",theParams[i].getLabel());
xf.printF(theParams[i].getMin());
xf.printF(theParams[i].getMax());
xf.printF(theParams[i].getMean());
xf.printF(theParams[i].getSD());
theFile.WriteLine(xf.printOut());
}
theXFile.WriteLine("\r---\r");
}
public static void Logger(String s) {
if (theXFile != null) {
theXFile.WriteLine(new Integer(getTick()).toString()+"
"+s);
} else {
System.out.println(new Integer(getTick()).toString()+"
"+s);
}
}
public static void Logger() {
Logger(xf.printOut());
}
public static void logData() { // collects
the current state of all
if (theXFile != null) {
if (theTick == 1 || theTick % logInterval == 0) {
xf.printf("%10.2f ",theTick);
for(int i=0;i<nParams;i++) {
// theParams[i].sync();
xf.printF(theParams[i].getStaticValue());
}
theXFile.WriteLine(xf.printOut());
if (dumpMeans) writeStatList(theXFile);
}
}
}
public static void superCycle(int m, int n) {
// m = cycles, n = ticks
for (numCycle = 0; numCycle < m;numCycle++) {
sReset();
multiCycle(n);
breakLog();
if (theXFile != null) {
xf.printf("... Run %d \r\r",numCycle+1);
theXFile.WriteLine(SimParam.xf.printOut());
writeLabels(theXFile);
}
}
}
} // STATIC things can be called from the Type rather than
an instance