📄 edgedlexperiment.java
字号:
package jaga.pj.circuits.experiment;
import jaga.*;
import jaga.experiment.*;
import java.util.Random;
import java.util.HashSet;
/**
*
* @author Michael Garvie
* @version
*/
public class EdgeDLExperiment implements ConfigurableSequentialCircuitExperiment {
private Random rnd = new Random();
protected Object rndSeed = new Integer( -1 );
private boolean refreshTestV = true;
private SampleData[] lastInput;
private int lastInputSampleSeparation = -1;
protected int[] stateEnterPos = new int[ 6 ];
protected MealyFSMNode[] nodesInEnterOrder = new MealyFSMNode[ 6 ];
protected int rndStatePos;
/** Fitness computed by calculating what the output be and if output is this
* then adding a fitness point.
* We may have to be meaner for this to work though...
* @param out outputs assumed to be with sampleSeparation = 1
*/
public double getFitness(SampleData[] in,SampleData[] out)
{
// calculate what output should be, and then add points for correct ones
int inputSampleSeparation = in[ 0 ].getSampleSeparation();
int inputSamples = in[ 0 ].length();
int numInputs = getNumOfInputs();
BitSet C = ( BitSet ) in[ 0 ];
BitSet D = ( BitSet ) in[ 1 ];
BitSet Q = ( BitSet ) out[ 0 ];
BitSet desQ = new BitSet( Q.length() );
//boolean[] currentInputs = new boolean[ numInputs ]; DEBUG
// for first bits assume they`re OK
for( int odl = 0; odl < inputSampleSeparation; odl++ )
{
desQ.setTo( odl, Q.get( odl ) );
}
// calculate what Q should have been - standard D-Latch
for( int idl = 1; idl < inputSamples; idl++ )
{
for( int odl = 0; odl < inputSampleSeparation; odl++ )
{
int currIdx = idl * inputSampleSeparation + odl;
boolean riseEdge = C.get( idl ) && !C.get( idl - 1 );
boolean desiredQ = riseEdge && D.get( idl -1 ); //** -1
desiredQ |= !riseEdge && desQ.get( currIdx - inputSampleSeparation ); // or Q - inputSampleSeparation?
desQ.setTo( currIdx, desiredQ );
}
}
return Math.abs( ExperimentLib.getCorrelationFitness( 0, inputSamples, inputSampleSeparation, desQ, Q ) );
/*
// ignore the first cycle because there was no previous state.
for( int idl = 1; idl < D.length(); idl++ )
{
// boolean allgood = true; could be used at some point to give extra bonus for keeping output steady and correct
// or better count how many and have minimum required to give points..
int odlCycleStart = idl * inputSampleSeparation;
odlCycleStart += (int)( inputSampleSeparation * tsetup ); // compensate for tsetup
// calculate what Q should be at this point - standard D-Latch logic
boolean desiredQ = ( !C.get( idl ) && Q.get( odlCycleStart - inputSampleSeparation ) ) || ( C.get( idl ) && D.get( idl ) );
// check how many times during the cycle it was the same
for( int odl = odlCycleStart; odl < ( idl + 1 ) * inputSampleSeparation; odl++ )
{
debug( idl + " " + C.get( idl ) + " " + D.get( idl ) + " " + desiredQ + " " + Q.get( odl ) + " " + score );
if( Q.get( odl ) == desiredQ )
{
score++;
// reward change
if( Q.get( odl ) != Q.get( odl - inputSampleSeparation ) )
{
//score += 100;
}
}else
{
score -= 3;
}
perfectScore++;
}
}
score = Math.max( 0, score ); // never negative!
return score * 1.0 / perfectScore;
*/
}
/** generates an array of inputs suitable for this experiment.
* @param inputSampleSeparation relative frequency of input to output samples. If this is n, then n outputs will be sampled for every change in inputs.
*/
public SampleData[] generateInput( )
{
final int INPUT_SAMPLE_SEPARATION = 10;
return generateInput( INPUT_SAMPLE_SEPARATION );
}
public SampleData[] generateInput( int inputSampleSeparation )
{
final double NON_RANDOM_TEST_PROPORTION = 1;
if( inputSampleSeparation != lastInputSampleSeparation )
{
refreshTestV = true;
lastInputSampleSeparation = inputSampleSeparation;
}
if( refreshTestV )
{
// Build D-Latch FSM
FSMNode n0u = new FSMNode( rnd );
FSMNode n0t0 = new FSMNode( rnd );
FSMNode n0t1 = new FSMNode( rnd );
FSMNode n1u = new FSMNode( rnd );
FSMNode n1t0 = new FSMNode( rnd );
FSMNode n1t1 = new FSMNode( rnd );
FSMEdge e0u_00 = new FSMEdge( false, false, n0t0 );
FSMEdge e0u_01 = new FSMEdge( false, true, n0t1 );
FSMEdge e0u_10 = new FSMEdge( true, false, n0u );
FSMEdge e0u_11 = new FSMEdge( true, true, n0u );
n0u.connectTo( e0u_00, e0u_01, e0u_10, e0u_11 );
FSMEdge e0t0_01 = new FSMEdge( false, true, n0t1 );
FSMEdge e0t0_10 = new FSMEdge( true, false, n0u );
n0t0.connectTo( e0t0_01, e0t0_10 );
FSMEdge e0t1_00 = new FSMEdge( false, false, n0t0 );
FSMEdge e0t1_11 = new FSMEdge( true, true, n1u );
n0t1.connectTo( e0t1_11, e0t1_00);
FSMEdge e1u_00 = new FSMEdge( false, false, n1t0 );
FSMEdge e1u_01 = new FSMEdge( false, true, n1t1 );
FSMEdge e1u_10 = new FSMEdge( true, false, n1u );
FSMEdge e1u_11 = new FSMEdge( true, true, n1u );
n1u.connectTo( e1u_01, e1u_00, e1u_10, e1u_11 );
FSMEdge e1t0_01 = new FSMEdge( false, true, n1t1 );
FSMEdge e1t0_10 = new FSMEdge( true, false, n0u );
n1t0.connectTo( e1t0_10, e1t0_01);
FSMEdge e1t1_00 = new FSMEdge( false, false, n1t0 );
FSMEdge e1t1_11 = new FSMEdge( true, true, n1u );
n1t1.connectTo( e1t1_00, e1t1_11 );
// Start at node n0u or n1u, make sure by adding initial input vectors.
int testLen = 0;
BitSet C = new BitSet();
BitSet D = new BitSet();
FSMNode currentNode = null;
boolean startN1 = rnd.nextBoolean();
C.setTo( 0, false );
D.setTo( 0, false );
C.setTo( 1, true );
D.setTo( 1, startN1 );
testLen = 2;
if( startN1 )
{
currentNode = n1u;
}else
{
currentNode = n0u;
}
// Enter state pos stuff
HashSet visitedNodes = new HashSet();
int visitIndex = 0;
visitedNodes.add( currentNode );
//nodesInEnterOrder[ visitIndex ] = currentNode;
stateEnterPos[ visitIndex++ ] = testLen;
// Walk around all edges at least once and then stop
int paths = 16;
FSMEdge currentEdge = null;
while( paths > 0 )
{
currentEdge = currentNode.pick();
if( currentNode.remove( currentEdge ) )
{
paths--;
}
C.setTo( testLen, currentEdge.i0 );
D.setTo( testLen++, currentEdge.i1 );
currentNode = currentEdge.dest;
if( !visitedNodes.contains( currentNode ) )
{
visitedNodes.add( currentNode );
stateEnterPos[ visitIndex++ ] = testLen;
}
}
// Clean Up
C.setLength( testLen );
D.setLength( testLen );
BitSet[] testVector = { C, D };
refreshTestV = false;
lastInput = ExperimentLib.generateInputFromTest( testVector , NON_RANDOM_TEST_PROPORTION, testLen, inputSampleSeparation );
rndStatePos = stateEnterPos[ rnd.nextInt( stateEnterPos.length ) ];
}
return lastInput;
}
public int getNumOfInputs()
{
return 2;
}
public int getNumOfOutputs()
{
return 1;
}
public String toString()
{
String rv = "Edge triggered D-Latch";
return rv;
}
public void set( Object rndSeed )
{
this.rndSeed = rndSeed;
rnd.setSeed( ( ( Long ) rndSeed ).longValue() );
refreshTestV = true;
}
public Object get(Object param) {
return rndSeed;
}
/** @return Array of positions in last test pattern generated of when the tested FSM - if perfect -
* would enter each state. So State N is entered at input data position rv[ N ]. The order of states
* is not important as long as rv[ i ] != rv[ j ] for i != j
*/
public int[] getStateEnterPos() {
return stateEnterPos;
}
public int rndStatePos() {
return rndStatePos;
}
/** @return Array of Mealy Finite State Machine Nodes. The nth node in the array represents the state
* for which the nth int in the array returned by getStateEnterPos() represents the position in the TP at which
* this state is entered.
*/
public MealyFSMNode[] getStateGraphNodes() {
return null; // nodesInEnterOrder; incompatible, this is Moore
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -