// ART1MASPAR.cpp
// (c) Indra's Net Farm - 2002
// trans(c) Tim McFadden
// This code is released to be used entirely at the user's own risk
// for any consequences what so ever.
// Please keep the Indra's Net Farm name on copied code.
#include <iostream>
#include "ART1MASPAR.h"
#include "Up.h"
void ART1_Interfac(char* filenam);
//
// ART1MASPAR() - main class for application.
// reads in parameters, creates objects, and runs
// the main processing loop.
//
ART1MASPAR::ART1MASPAR(char* filenam)
{
int i,j,k;
int traceIndx; // index thru traces.
int reset = 0; // 1 => a F1 calls for a reset of F2.
int wini; // the index of the winning node in F2.
int loopCnt; // count of loops thru a resonance.
// dummy values for compiler.
M = 30;
N = 30;
L = 0;
B1 = 0;
D1 = 0;
rho = 0;
BotupFact = 0;
if (DebugFlag >= 1)
cout << "ART1MASPAR\n";
// create array for input patterns.
inPuts = new int [maxInputs] [maxM] ;
// read in ART1 params.
Parse.parse(this, filenam);
if (DebugFlag >= 1)
{
cout << "parser read " << rowCnt << " traces \n";
cout << "create the objects\n";\
}
// create the objects.
// F1 and F2 layers.
F1L = Fact.Make1(N, A1, B1, C1, D1, DebugFlag);
F2L = Fact.Make2(M, DebugFlag);
// shared registers.
F2L->VReg = F1L->VReg = new FloatReg(N);
F2L->TReg = F1L->TReg = new FloatReg(M);
F1L->IReg = new IntReg(N);
// LTM.
F1L->LTMBU = new LTMBottomUp(N, M, L, BotupFact, DebugFlag);
F2L->LTMTD = new LTMTopDown(N, M, B1, D1, DebugFlag);
// orienting subsystem, used by F1.
F1L->Ori = new Orienting(rho, N);
if (DebugFlag >= 1)
{
// dump LTM.
cout << "Initial LTM\nZbu " "\n";
F1L->LTMBU->dump();
cout << "Ztd " "\n";
F2L->LTMTD->dump();
}
}
//
// ART1MASPAR::run() - run resonance.
void ART1MASPAR::run() {
int i,j,k;
int traceIndx; // index thru traces.
int reset = 0; // 1 => a F1 calls for a reset of F2.
int wini; // the index of the winning node in F2.
int loopCnt; // count of loops thru a resonance.
// main loop.
// for each input trace.
for (traceIndx = 0; traceIndx < rowCnt; traceIndx++)
{
if (DebugFlag >= 1)
cout << "\n\ntrace " << traceIndx << "\n";
// set up a new I.
F1L->setI(inPuts[traceIndx]);
// clear V.
for (i = 0; i < N; i++)
F1L->VReg->Reg[i] = 0;
// init F2.
F2L->init();
cout << "ART1MASPAR::run F2L->nodeNum = " << F2L->nodeNum << endl;
loopCnt = 0; // start guard counter.
try {
// run until resonance or loop bound is reached.
// F1 returns 1 when there is a reset.
// if there's no reset, a resonance has
// occurred.
while(F1L->run() == 1)
{
// there was a reset.
F2L->reset(); // reset.
wini = F2L->run(); // run F2.
// check loop.
if (loopCnt++ > 20)
{
throw Up("***** loopCnt > 20 \n");
}
}
}
catch(const Up& uppity)
{
cout << "*** " << uppity.getUp() << "\n";
terminate();
}
// got a resonance.
cout << "Resonance on unit " << wini << " for pattern " <<
traceIndx << "\n";
// update LTM weights.
try {
F1L->LTMBU->learn(wini, F1L->getS());
F2L->LTMTD->learn(wini, F1L->getS());
}
catch(const Up& uppity)
{
cout << "*** " << uppity.getUp() << "\n";
terminate();
}
} // for all traces.
// dump LTM.
cout << "Zbu " "\n";
F1L->LTMBU->dump();
cout << "Ztd " "\n";
F2L->LTMTD->dump();
}
//
// main()
//
void main(int argc, char** argv)
{
int i,m,n;
ART1MASPAR* Mas;
cout << "ART1 V3.0\n";
if (argc < 2)
{
cout << "Usage: art1 <filename>\n";
return;
}
Mas = new ART1MASPAR(argv[1]);
Mas->run();
}
//
// ART1_Interfac() - use file name, calling interface for a DLL
// packaging.
// Not in use yet.
void ART1MASPAR::ART1_Interfac(char* filenam) {
ART1MASPAR* Mas;
cout << "ART1 .dll V3.0\n";
Mas = new ART1MASPAR(filenam); // put on heap.
}
//
// ART1_Interfac() - use new trace, calling interface for a DLL
// packaging.
// Not in use yet.
//
void ART1MASPAR::ART1_Interfac(int tri, char* filenam) {
ART1MASPAR* Mas;
cout << "ART1 new trace .dll V3.0\n";
Mas = new ART1MASPAR(filenam);
}
--------------------------------
// F1Layer.cpp
// (c) Indra's Net Farm - 2002
// trans(c) Tim McFadden
// This code is released to be used entirely at the user's own risk
// for any consequences what so ever.
// Please keep the Indra's Net Farm name on copied code.
#include <iostream>
#include <math.h>
#include "F1Layer.h"
#include "Up.h"
#include "Dumpster.h"
//
// F1Layer::F1Layer() - constructor.
//
F1Layer::F1Layer (int _n, float _A1, float _B1, float _C1, float _D1,
int _debug) : Layer (_n),
A1(_A1), B1(_B1), C1(_C1), D1(_D1), DebugFlag(_debug)
{
// create registers.
X = new float[nodeNum];
S = new float[nodeNum];
TReg = new FloatReg(nodeNum);
}
//
// F1Layer::run() - run the F1 layer.
// returns:
// 0 => no reset.
// 1 => reset.
// throws Up.
//
int F1Layer::run() throw(Up)
{
int i,j,k;
int reset = 0;
int* hist = new int[HISTNUM];
if (DebugFlag >= 1)
cout << "run F1\n";
// is F2 active?
if (magItF(VReg->Reg, nodeNum) <= 0)
{
// nope - don't look at V.
for (i = 0; i < nodeNum; i++)
{
float Ii;
Ii = (float)IReg->Reg[i];
X[i] = (Ii / (1.0 + A1 * Ii));
}
reset = 1; // by default.
}
else // yup.
{
// use V and I.
// update X[i].
for (i = 0; i < nodeNum; i++)
{
float Ii;
float Vi;
float divisor;
Ii = (float)IReg->Reg[i];
Vi = VReg->Reg[i];
// Xi = (Ii + D1 * Vi - B1) /
// (1 + A1 * (Ii + D1 * Vi) + C1)
if ((divisor = 1.0 + A1 * (Ii + D1 * Vi) + C1) < .0001)
throw (Up("********* F1 run < 0"));
X[i] = (Ii + D1 * Vi - B1) / divisor;
}
reset = 0;
}
if (DebugFlag >= 2)
{
cout << "reset = " << reset << "\n";
cout << "X = \n";
Dumpster().dumpVecF(X, nodeNum);
cout << "XOR I,V = \n";
Dumpster().dumpXOR(IReg->Reg, VReg->Reg, nodeNum);
cout << "V = \n";
Dumpster().dumpVecF(VReg->Reg, nodeNum);
}
// make all Xi >= 0.
// is used for the histogram technique below.
float Xmin = 100.0;
for (i = 0; i < nodeNum; i++)
if (Xmin > X[i])
Xmin = X[i];
if (Xmin <= 0)
for (i = 0; i < nodeNum; i++)
X[i] += -Xmin + HIST_DIF;
// sample S from h(Xi).
// get histogram of X.
for (i = 0; i < HISTNUM; i++)
hist[i] = 0;
for (i = 0; i < nodeNum; i++)
for (j = 1; j < HISTNUM + 1; j++)
if ( (X[i] <= HIST_DIF * j + HIST_MIN) &&
(X[i] > HIST_DIF * (j - 1) + HIST_MIN)
)
hist[j - 1]++;
// use histogram to find max and estimate next peak.
// The histogram peak method is from "Algorithms for Image
// Processing and Computer Vision", J. R. Parker.
// We use (k - j) ^ 4 instead of (k - j) ^ 2.
int histMaxi;
float peakMax2 = -4.0;
float peakWrk;
float peakAmp;
// find 1st peak.
for (j = 0; j < HISTNUM; j++)
if (hist[HISTNUM - 1 - j] > 0)
break;
if (j == HISTNUM)
throw (Up("********* bad histogram"));
j = HISTNUM - 1 - j;
if (DebugFlag >= 2)
{
cout << "X[] max = " << HIST_DIF * j + HIST_MIN << "\n";
}
histMaxi = j;
// find next peak.
// we want to make Xi <= second peak zero.
// for each X[i], see where it fits in histogram.
// compare to a working maximum, but multiply
// by (k - j) ^ 4 to give it a chance to be max.
for (i = 0; i < nodeNum; i++)
{
// find this X[i] in histogram.
for (j = 1; j < HISTNUM + 1; j++)
if ( (X[i] <= HIST_DIF * j + HIST_MIN) &&
(X[i] > HIST_DIF * (j - 1) + HIST_MIN)
)
break;
int histFact = (j - 1) - histMaxi;
peakAmp = histFact * histFact* histFact * histFact;
if (peakAmp * X[i] > peakMax2)
peakMax2 = X[i];
}
if (DebugFlag >= 2)
{
cout << "second peak max = " << peakMax2 << "\n";
}
// map X onto {1, 0} in S using second peak as the threshold.
for (i = 0; i < nodeNum; i++)
if (X[i] > peakMax2 + HIST_DIF)
S[i] = 1.0;
else
S[i] = 0;
if (DebugFlag >= 2)
{
cout << "S = \n";
Dumpster().dumpVecF(S, nodeNum);
}
// check reset.
if (reset == 0)
reset = Ori->doReset(IReg->Reg, S);
// T = S . Zbu.
// this is the output to F2.
TReg->Reg = LTMBU->dot(S);
if (DebugFlag >= 2)
{
cout << "T = S . Zbu =\n";
Dumpster().dumpVecF(TReg->Reg, TReg->length);
}
return reset;
}
//
// F1Layer::getS() - return S[].
//
float* F1Layer::getS()
{
return S;
}
//
// F1Layer::setI() - put the values into I[].
//
void F1Layer::setI(int* _I)
{
for (int i = 0; i < nodeNum; i++)
IReg->Reg[i] = _I[i];
}
--------------------------------
// F2Layer.cpp
// (c) Indra's Net Farm - 2002
// trans(c) Tim McFadden
// This code is released to be used entirely at the user's own risk
// for any consequences what so ever.
// Please keep the Indra's Net Farm name on copied code.
#include <iostream>
#include "F2Layer.h"
#include "Up.h"
#include "Dumpster.h"
//
// F2Layer::F2Layer() - constructor.
//
F2Layer::F2Layer (int _m, int _debug) : Layer(_m), DebugFlag(_debug)
{
// create registers.
U = new float[nodeNum];
Y = new float[nodeNum];
// and droplist.
droplist = new int[nodeNum];
wini = -1; // signal that compete hasn't been run.
}
//
// F2Layer::run () - run the F2 layer.
// returns the index of the winning F2 node.
// side effect - also sets this index in F2Layer.wini.
// throws Up.
//
int
F2Layer::run () throw(Up)
{
int i,j,k;
if (DebugFlag >= 1)
cout << "run F2\n";
// turn off inhibited units.
for (i = 0; i < nodeNum; i++)
TReg->Reg[i] = (droplist[i] == 1? TReg->Reg[i] : 0);
// compete to find a critical feature pattern.
compete();
// sample to U and find the winning node, wini.
wini = -1; // mark not found.
for (i = 0; i < nodeNum; i++)
{
U[i] = TReg->Reg[i] > 0 ? 1 : 0;
if (U[i] == 1)
wini = i;
}
if (wini == -1)
throw (Up("********* wini not found"));
// V = U . Ztd .
// output to F1.
VReg->Reg = LTMTD->dot(U);
return wini;
}
//
// F2Layer::init() - init F2.
//
void
F2Layer::init()
{
int i,j,k;
// init drop list.
for (i = 0; i < nodeNum; i++)
droplist[i] = 1;
}
//
// F2Layer::compete() - find the winning node in F2 = max(T[i]).
//
void F2Layer::compete()
{
int i,j,k;
int maxi = -1;
float max = -1;
// compete to get Y, just the max() of T.
for (i = 0; i < nodeNum; i++)
{
if (max < TReg->Reg[i])
{
max = TReg->Reg[i];
maxi = i;
}
}
if (maxi == -1)
{
cout << "*** compete() maxi = -1, no winner." << endl;
}
if (DebugFlag >= 2)
{
cout << "compete() maxi = " << maxi << endl;
cout << "compete() max = " << max << endl;
}
// clear out every one but the winner.
for (i = 0; i < nodeNum; i++)
{
if (maxi != i)
TReg->Reg[i] = 0;
}
if (DebugFlag >= 2)
{
cout << "compete() T =\n";
Dumpster().dumpVecF(TReg->Reg, TReg->length);
}
}
//
// F2Layer::reset() - set the last used node to 0 in the drop list.
//
void
F2Layer::reset()
{
// if F2 has been run, drop the last used F2 node from the active list.
if (wini >= 0)
droplist[wini] = 0;
}
--------------------------------
// Layer.cpp
// (c) Indra's Net Farm - 2002
// trans(c) Tim McFadden
// This code is released to be used entirely at the user's own risk
// for any consequences what so ever.
// Please keep the Indra's Net Farm name on copied code.
#include "Layer.h"
//
// Layer::magIt() - int magnitude.
//
int
Layer::magIt(int* _I, int _n)
{
int mag = 0;
for (int i = 0; i < _n; i++)
mag += _I[i];
return mag;
}
//
// Layer::magItF() - float magnitude.
//
float
Layer::magItF(float* _I, int _n)
{
float mag = 0;
for (int i = 0; i < _n; i++)
{
if (_I[i] < 0)
mag += -_I[i];
else
mag += _I[i];
}
return mag;
}
--------------------------------
// LayerFactory.cpp
// (c) Indra's Net Farm - 2002
// trans(c) Tim McFadden
// This code is released to be used entirely at the user's own risk
// for any consequences what so ever.
// Please keep the Indra's Net Farm name on copied code.
#include "LayerFactory.h"
#include "F1Layer.h"
#include "F2Layer.h"
//
// LayerFactory::Make1() -
//
F1Layer*
LayerFactory::Make1(int _m, float _A1, float _B1, float _C1,
float _D1, int _debug)
{
return new F1Layer(_m, _A1, _B1, _C1, _D1, _debug);
}
//
// LayerFactory::Make2()
//
F2Layer*
LayerFactory::Make2(int _m, int _debug)
{
return new F2Layer(_m, _debug);
}
--------------------------------
// LTMBottomUp.cpp
// (c) Indra's Net Farm - 2002
// trans(c) Tim McFadden
// This code is released to be used entirely at the user's own risk
// for any consequences what so ever.
// Please keep the Indra's Net Farm name on copied code.
#include <iostream>
#include "LTMBottomUp.h"
#include "Layer.h"
#include "Dumpster.h"
//
// LTMBottomUp::LTMBottomUp () - constructor.
//
LTMBottomUp::LTMBottomUp (int _n, int _m, float _L, float _BotupFact,
int _debug) : LTM(_n, _m)
{
int i,j,k;
Z = new float[maxN][maxM];
L = _L;
DebugFlag = _debug;
BotupFact = _BotupFact;
// initialize Zbu(0).
for (i = 0; i < n; i++)
{
for (j = 0; j < m; j++)
Z[i][j] = L / (L - 1 + m);
}
}
//
// LTMBottomUp::dot() - dot vector into bottom up LTM.
float*
LTMBottomUp::dot(float* x)
{
int i,j,k;
float* ret = new float[maxM];
// dot over i.
for (j = 0; j < m; j++)
{
ret[j] = 0;
for (i = 0; i < n; i++)
{
ret[j] += x[i] * Z[i][j];
}
}
if (DebugFlag >= 1)
{
cout << "x . LTMBU\n";
Dumpster().dumpVecF(ret, m);
}
return ret;
}
//
// LTMBottomUp::learn() - run fast learning rule.
void
LTMBottomUp::learn(int _wini, float* _S) throw(Up)
{
int i,j,k;
float mag = 0;
mag = Layer().magItF(_S, n);
// change from Carpenter and Grossberg.
// In the case of input patterns that have successively more
// ones set, the values in T of uncommitted F2 nodes in
// LTM may have larger values than the committed - hence
// the committed nodes will not be tried. To overcome this,
// the values for non-zero S are multiplied by a factor
// BotupFact > 1. This makes the committed nodes larger
// in LTM.
for (i = 0; i < n; i++)
if (_S[i] >= 1)
Z[i][_wini] = BotupFact * L / (L - 1 + mag);
else
Z[i][_wini] = 0;
}
//
// LTMBottomUp::dump() - dump BU LTM.
//
void LTMBottomUp::dump()
{
float *momo;
momo = *Z;
Dumpster().dumpMatrix(momo, n, m);
}
--------------------------------
// LTMTopDown.cpp
// (c) Indra's Net Farm - 2002
// trans(c) Tim McFadden
// This code is released to be used entirely at the user's own risk
// for any consequences what so ever.
// Please keep the Indra's Net Farm name on copied code.
#include "LTMTopDown.h"
#include "Dumpster.h"
//
// LTMTopDown::LTMTopDown () - constructor
LTMTopDown::LTMTopDown (int _n, int _m, float _b1, float _d1,
int _debug) : LTM(_n, _m), B1(_b1), D1(_d1), DebugFlag(_debug)
{
int i, j, k;
// allocate top down LTM.
Z = new float[maxM][maxN];
// initialize Ztd(0).
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
Z[i][j] = (B1 - 1) / D1;
}
}
///
// LTMTopDown::dot() - dot vector into top down LTM.
float*
LTMTopDown::dot(float* x)
{
int i,j,k;
float* ret = new float[maxN];
// dot over i.
for (j = 0; j < n; j++)
{
ret[j] = 0;
for (i = 0; i < m; i++)
ret[j] += x[i] * Z[i][j];
}
return ret;
}
//
// LTMTopDown::learn() - use fast learning.
void
LTMTopDown::learn(int _wini, float* _S) throw(Up)
{
int i,j,k;
for (i = 0; i < n; i++)
Z[_wini][i] = _S[i];
}
//
// LTMTopDown::dump() - dump the TD LTM.
//
void
LTMTopDown::dump()
{
float *momo;
momo = *Z;
if (DebugFlag >= 1)
Dumpster().dumpMatrix(momo, m, n);
cout << "critical feature patterns\n";
for (int i = 0; i < m; i++)
{
cout << "patt " << i << "\n";
for (int j = 0; j < 25; j++)
{
if ((j > 0) && (j % 5) == 0)
cout << "\n";
cout << Z[i][j] << " ";
}
cout << "\n";
}
}
--------------------------------
// Orienting.cpp
// Orienting.h
// (c) Indra's Net Farm - 2002
// trans(c) Tim McFadden
// This code is released to be used entirely at the user's own risk
// for any consequences what so ever.
// Please keep the Indra's Net Farm name on copied code.
#include "Orienting.h"
//
// Orienting::Orienting() - constructor.
//
Orienting::Orienting(float _rho, int _N) : Layer(_N)
{
rho = _rho;
nodeNum = _N;
}
//
// Orienting::doReset( -
// returns:
// 0 => no reset.
// 1 => reset.
//
int Orienting::doReset(int* _I, float* _X)
{
// reset when rho > |X| / |I|.
if (rho > (magItF(_X, nodeNum) / magIt(_I, nodeNum)))
return 1;
else
return 0;
}
--------------------------------
// TraceParse.cpp
// (c) Indra's Net Farm - 2002
// trans(c) Tim McFadden
// This code is released to be used entirely at the user's own risk
// for any consequences what so ever.
// Please keep the Indra's Net Farm name on copied code.
// Changes
// 10/20/04 - use file input.
#include <iostream>
#include <fstream>
#include <string.h>
#include "ART1MASPAR.h"
#include "TraceParse.h"
#include "Up.h"
// structure to hold operands.
struct nameVal
{
char name[20];
int intNum;
} ;
// map name to code.
struct nameVal namez[] = { {"M", TraceParse::NAME_M},
{"N", TraceParse::NAME_N},
{"A1", TraceParse::NAME_A1},
{"B1", TraceParse::NAME_B1},
{"C1", TraceParse::NAME_C1},
{"Epsilon", TraceParse::NAME_EPSILON},
{"A2", TraceParse::NAME_A2},
{"B2", TraceParse::NAME_B2},
{"C2", TraceParse::NAME_C2},
{"Rho", TraceParse::NAME_RHO},
{"L", TraceParse::NAME_L},
{"D1", TraceParse::NAME_D1},
{"Debug", TraceParse::NAME_DEBUG},
{"BotupFact", TraceParse::NAME_BUPF},
};
//
// TraceParse::parse() - parse an input set of a header and a set of traces.
// TraceParse is a friend of ART1MASPAR and the input values are placed there.
//
void
TraceParse::parse(ART1MASPAR* z, char* fnam)
{
char wrkStr[300];
MASp = z;
rowCnt = 0;
// open up.
Ins.open(fnam);
if (!Ins)
{
cout << "TraceParse bad open " << fnam << endl;
terminate();
}
// start with header.
Ins >> wrkStr;
if (wrkStr[0] == '(')
{
Ins >> wrkStr; // header.
if (strncmp(wrkStr, "header", 6) == 0)
{
try
{
header();
}
catch(const Up& uppity)
{
cout << "TraceParse " << uppity.getUp() << "\n";
terminate();
}
}
Ins >> wrkStr; // trace.
cout << wrkStr << "\n";
// there may now follow a number of input traces.
while (strncmp(wrkStr, "trace", 5) == 0)
{
trace();
rowCnt++;
if (Ins.eof())
break;
Ins >> wrkStr; // trace?.
cout << wrkStr << "\n";
}
}
MASp->rowCnt = rowCnt;
}
//
// TraceParse::header() - parse the header.
// throws Up.
//
void
TraceParse::header() throw(Up)
{
char wrkStr[300];
int wrkInt;
float wrkFloat;
keyNames keyId;
int i,j,k;
Ins >> wrkStr;
if (wrkStr[0] == '(')
{
while (!Ins.eof())
{
Ins >> wrkStr; // operand.
if(wrkStr[0] == ')')
break;
cout << wrkStr << " = ";
// try for a keyword.
keyId = TraceParse::NAME_NOT_HERE;
for (i = 0; i < sizeof(namez) / sizeof(struct nameVal); i++)
{
if (strcmp(wrkStr, namez[i].name) == 0)
keyId = keyNames(namez[i].intNum);
}
if (keyId == TraceParse::NAME_NOT_HERE)
throw Up("*** header operand not found\n", wrkStr);
// parse each keyword value.
switch(keyId)
{
case NAME_M :
lexChar(PARSE_LOOK_DIGIT);
Ins >> wrkInt;
cout << wrkInt << "\n";
MASp->M = wrkInt;
break;
case NAME_N :
lexChar(PARSE_LOOK_DIGIT);
Ins >> wrkInt;
cout << wrkInt << "\n";
MASp->N = wrkInt;
break;
case NAME_A1 :
lexChar(PARSE_LOOK_FLOAT);
Ins >> wrkFloat;
cout << wrkFloat << "\n";
MASp->A1= wrkFloat;
break;
case NAME_B1 :
lexChar(PARSE_LOOK_FLOAT);
Ins >> wrkFloat;
cout << wrkFloat << "\n";
MASp->B1= wrkFloat;
break;
case NAME_C1 :
lexChar(PARSE_LOOK_FLOAT);
Ins >> wrkFloat;
cout << wrkFloat << "\n";
MASp->C1= wrkFloat;
break;
case NAME_D1 :
lexChar(PARSE_LOOK_FLOAT);
Ins >> wrkFloat;
cout << wrkFloat << "\n";
MASp->D1= wrkFloat;
break;
case NAME_D2 :
lexChar(PARSE_LOOK_FLOAT);
Ins >> wrkFloat;
cout << wrkFloat << "\n";
MASp->D2= wrkFloat;
break;
case NAME_L :
lexChar(PARSE_LOOK_FLOAT);
Ins >> wrkFloat;
cout << wrkFloat << "\n";
MASp->L= wrkFloat;
break;
case NAME_EPSILON :
lexChar(PARSE_LOOK_FLOAT);
Ins >> wrkFloat;
cout << wrkFloat << "\n";
MASp->Epsilon = wrkFloat;
break;
case NAME_RHO :
lexChar(PARSE_LOOK_FLOAT);
Ins >> wrkFloat;
cout << wrkFloat << "\n";
MASp->rho = wrkFloat;
break;
case NAME_BUPF :
lexChar(PARSE_LOOK_FLOAT);
Ins >> wrkFloat;
cout << wrkFloat << "\n";
MASp->BotupFact = wrkFloat;
break;
case NAME_DEBUG :
lexChar(PARSE_LOOK_DIGIT);
Ins >> wrkInt;
cout << wrkInt << "\n";
MASp->DebugFlag = wrkInt;
break;
} // switch.
if (Ins.bad())
throw Up("*** header bad input\n");
} // while.
} // if '('
}
//
// TraceParse::trace() - parse a trace.
//
void
TraceParse::trace()
{
char wrkStr[300];
int wrkInt;
int i,j,k;
Ins >> wrkStr;
cout << wrkStr << " ";
if (wrkStr[0] == '(')
{
// read in a trace.
// this is a list of int's
for (i = 0; i < MASp->N; i++)
{
Ins >> wrkInt;
cout << wrkInt << " ";
MASp->inPuts[rowCnt][i] = wrkInt;
}
if (Ins.eof())
return;
Ins >> wrkStr; // dump ')'
cout << wrkStr << ")\n";
cout << "rowCnt = " << rowCnt << "\n";
}
}
//
// TraceParse::lexChar() - check for the correct lexical type.
// throws Up if not happy with type.
//
void
TraceParse::lexChar(unsigned int flags) throw (Up)
{
unsigned int init;
char charz = ' ';
while (!Ins.eof())
{
charz = init = Ins.peek();
if (isspace(charz) )
Ins.get();
else
break;
}
if ((flags & PARSE_LOOK_LETTER) != 0)
{
if (isalpha(charz) == 0)
throw Up("*** expecting name \n");
}
else
if ((flags & PARSE_LOOK_PAREN) != 0)
{
if ( (init!= '(') && (init!= '(') )
throw Up("*** expecting parentheses \n");
}
else
if ((flags & PARSE_LOOK_DIGIT) != 0)
{
if (isdigit(charz) == 0)
throw Up("*** expecting digit \n");
}
else
if ((flags & PARSE_LOOK_FLOAT) != 0)
{
if (init == (int)'.')
return;
if (isdigit(charz) == 0)
throw Up("*** expecting float \n");
}
}