// Matt Streeter
// 2/27/00
// NVIS.CPP
// Implementation of class TNVisWindow; window class for visualization of a
// single neural network.
// Copyright Matt Streeter, 2000. All rights reserved
#include "nvis.h"
#include "ids.h"
#include <math.h>
#include <stdio.h>
#include "eswin.rh"
DEFINE_RESPONSE_TABLE1(TNVisWindow, TESWindow)
EV_WM_SIZE,
EV_CHILD_NOTIFY_ALL_CODES(ID_SAMPLE_SCROLL,EvSampleScroll),
EV_CHILD_NOTIFY_ALL_CODES(ID_SAMPLE_EDIT,EvSampleEdit),
EV_WM_LBUTTONDOWN,
EV_WM_LBUTTONUP,
EV_WM_MOUSEMOVE,
EV_COMMAND(CM_FILE_LOAD,CmFileLoad),
EV_COMMAND(CM_FILE_SAVE,CmFileSave),
EV_COMMAND(CM_FILE_SAVE_AS,CmFileSaveAs),
EV_COMMAND(CM_FILE_LOADTESTSET,CmFileLoadTestSet),
EV_COMMAND_ENABLE(CM_FILE_SAVE,CeFileSave),
EV_COMMAND(CM_NETWORK_EVAL,CmNetworkEval),
EV_COMMAND(CM_NETWORK_VIEW_ACTIVATIONS,CmNetworkViewActivations),
EV_COMMAND(CM_NETWORK_BACKPROP,CmNetworkBackProp),
EV_COMMAND(CM_VIEW_VOLATILITY,CmViewVolatility),
EV_COMMAND_ENABLE(CM_VIEW_VOLATILITY,CeViewVolatility),
END_RESPONSE_TABLE;
// The following four #defines determine, in pixels, the left, right, top,
// and bottom borders, respectively, between window contents and the window
// edge.
#define WINDOW_LBORDER 20
#define WINDOW_RBORDER 20
#define WINDOW_TBORDER 5
#define WINDOW_BBORDER 0
// Height in pixels of horizontal scroll bar used to scroll through samples.
#define SCROLLBAR_HEIGHT 25
// Height and width of sample edit control.
#define SAMPLE_EDIT_HEIGHT 25
#define SAMPLE_EDIT_WIDTH 50
// Height and width of "Sample" text static.
#define SAMPLE_STATIC_HEIGHT 25
#define SAMPLE_STATIC_WIDTH 75
// Horizontal space (in pixels) between "Sample" text static and edit control.
#define SAMPLE_STATIC_SPACING 25
// Font face and height for node information.
#define NODE_FONT_FACE "Times New Roman"
#define NODE_FONT_HEIGHT 20
// Activations are multiplied by 'SIGMOID_SCALE_FACTOR' before being passed
// through a sigmoid function to determine the diameter of the circle used
// to display the activation.
#define SIGMOID_SCALE_FACTOR 10.0f
// thickness of weight lines
#define WEIGHT_THICKNESS 2
// thickness of sigma lines
#define SIGMA_THICKNESS 2
// Set to 1 to show sigma (volatility) information by default, 0 otherwise.
#define SHOW_SIGMAS_DEFAULT 1
TColor TNVisWindow::mGrayLineColor(64,64,64);
TColor TNVisWindow::mRingColor(0,0,0);
TColor TNVisWindow::mActivityColor(255,255,255);
TNVisWindow::TNVisWindow(TWindow *pParent,Network *pNetwork,
Chromosome *pChromosome,Parameter *pParam)
:TESWindow(pParent,0)
{
Attr.Style|=WS_VISIBLE|WS_OVERLAPPEDWINDOW;
// tbd: account correctly for parent coords
Attr.X=475+(pParent?pParent->Attr.X+3:0);
Attr.Y=200+(pParent?pParent->Attr.Y+25:0);
Attr.W=275;
Attr.H=325;
mParam=*(pParam->Copy());
mChromosome.InitChromosome(pChromosome->GetLength());
mChromosome=*pChromosome;
miWeights=mParam.GetNParams();
Decode(mChromosome,mParam);
mpWeights=new double[miWeights];
memcpy(mpWeights,mParam.GetParams(),miWeights*sizeof(double));
mdMaxWeight=mParam.GetUpper(0);
mNetwork=*(pNetwork->Copy());
miSample=0;
miSelectedNode=-1;
miSelectedWeight=-1;
miSelectedWeightSign=0;
mpFilename=0;
mbShowSigmas=SHOW_SIGMAS_DEFAULT;
mpBackpropWin=0;
mpNodeCenterPoints=new TPoint[mNetwork.GetNumNodes()];
mpWeightEndPoints=new TDrawnWeight[miWeights];
mpSampleStatic=new TESStatic(this,ID_SAMPLE_STATIC,"Sample:",0,0,
SAMPLE_STATIC_WIDTH,SAMPLE_STATIC_HEIGHT);
mpSampleEdit=new TEdit(this,ID_SAMPLE_EDIT,"0",
SAMPLE_STATIC_WIDTH+SAMPLE_STATIC_SPACING,0,
SAMPLE_EDIT_WIDTH,SAMPLE_EDIT_HEIGHT);
// correct dimensions will be set up by EvSize()
mpHScroll=new TScrollBar(this,ID_SAMPLE_SCROLL,0,0,0,0,TRUE);
mNetwork.RunSample(mpWeights,miWeights,miSample);
UpdateCaption();
AssignMenu(NETWORK_FILE_MENU);
}
TNVisWindow::~TNVisWindow()
{
delete(mpWeights);
}
void TNVisWindow::SetupWindow()
{
TFrameWindow::SetupWindow();
mpHScroll->SetRange(0,mNetwork.GetNumSamples()-1);
}
bool TNVisWindow::IdleAction(long lIdleCount)
{
ChildrenIdleAction(lIdleCount);
return(true);
}
void TNVisWindow::BackProp()
{
mNetwork.BackProp(mpWeights,miWeights);
// enforce parameter bounds
for(int m=0;m<miWeights;m++)
{
if(mpWeights[m]>mParam.GetUpper(m))
mpWeights[m]=mParam.GetUpper(m);
if(mpWeights[m]<mParam.GetLower(m))
mpWeights[m]=mParam.GetLower(m);
}
// calculate activity levels for this sample
mNetwork.RunSample(mpWeights,miWeights,miSample);
// redraw window
Invalidate(TRUE);
}
double TNVisWindow::GetFitness()
{
#if(!ATTRIBUTE_EVAL)
double dFitness=sqrt(mNetwork.NetEval(mpWeights,miWeights));
#else
double dFitness=100.0f-100.0f*mNetwork.NetEval(mpWeights,miWeights);
#endif
// we must run the sample we're on for the activity levels to still be right
mNetwork.RunSample(mpWeights,miWeights,miSample);
return(dFitness);
}
// the ratio of vertical space between circles to the diameter of the circles
#define VSPACE_RATIO 2.0
// the same for horizontal space
#define HSPACE_RATIO 2.0
#define RING_THICKNESS 2.0
void TNVisWindow::Paint(TDC& dc, bool, TRect&)
{
int n;
TRect DrawRect;
GetClientRect(DrawRect);
DrawRect.bottom-=SCROLLBAR_HEIGHT;
if(DrawRect.bottom<DrawRect.top)
return;
DrawRect.top+=SAMPLE_EDIT_HEIGHT>SAMPLE_STATIC_HEIGHT?
SAMPLE_EDIT_HEIGHT:SAMPLE_STATIC_HEIGHT;
DrawRect.bottom-=NODE_FONT_HEIGHT*2;
if(DrawRect.bottom<DrawRect.top)
return;
if(miWeights!=mNetwork.NumWeights())
return;
if(miSample==mNetwork.GetNumSamples())
miSample=0;
DrawRect.left+=WINDOW_LBORDER;
DrawRect.top+=WINDOW_TBORDER;
DrawRect.right-=WINDOW_RBORDER;
DrawRect.bottom-=WINDOW_BBORDER;
// find maximum sigma -- we will scale relative to this
double dMaxSigma=0.0f;
for(n=0;n<miWeights;n++)
{
double dSigma=fabs(mChromosome.GetGene(n+miWeights));
if(dSigma>dMaxSigma)
dMaxSigma=dSigma;
}
// for now let link height be 2*(circle height)
float fCircleHeight=(float)DrawRect.Height()/
(mNetwork.GetLayers()+VSPACE_RATIO*(mNetwork.GetLayers()-1));
// find maximum layer size
int iMaxLayerSize=0;
for(n=0;n<mNetwork.GetLayers();n++)
{
if(mNetwork.GetLayerSize(n)>iMaxLayerSize)
iMaxLayerSize=mNetwork.GetLayerSize(n);
}
// we also let the horizontal space between the the circles be 2 times
// the circles' width
float fCircleWidth=(float)DrawRect.Width()/
(iMaxLayerSize+HSPACE_RATIO*(iMaxLayerSize-1));
float fCircleDiameter=fCircleHeight<fCircleWidth?
fCircleHeight:fCircleWidth;
mfNodeRadius=fCircleDiameter/2.0;
float VSpacing=((float)DrawRect.Height()-fCircleDiameter)/
(float)(mNetwork.GetLayers()-1);
float HSpacing=(iMaxLayerSize!=1?((float)DrawRect.Width()-fCircleDiameter)/
(float)(iMaxLayerSize-1):0);
float XCursor,YCursor=(float)DrawRect.top+mfNodeRadius;
float XCenter=(float)DrawRect.left+(float)DrawRect.Width()/2.0;
int iWeightOffset=0;
TPen RingPen(mRingColor,RING_THICKNESS);
TPen ActivityPen(mActivityColor,1);
TBrush ActivityBrush(mActivityColor);
int iNodesDrawn=0;
for(int iLayer=0;iLayer<mNetwork.GetLayers();iLayer++)
{
XCursor=XCenter-HSpacing*(float)(mNetwork.GetLayerSize(iLayer)-1)/2.0;
for(int iNode=0;iNode<mNetwork.GetLayerSize(iLayer);iNode++)
{
// draw weights from this circle to circles in next layer
if(iLayer<mNetwork.GetLayers()-1)
{
float WXCursor=XCenter-HSpacing*
(float)(mNetwork.GetLayerSize(iLayer+1)-1)/2.0;
TPoint Center(XCursor,YCursor);
for(int m=0;m<mNetwork.GetLayerSize(iLayer+1);m++)
{
// weight indexing is kind of tricky
int iWeight=iWeightOffset+m*(mNetwork.GetLayerSize(iLayer))
+iNode;
float fHypotenuse=sqrt(pow(XCursor-WXCursor,2)+pow(VSpacing,2));
float fXRadius=mfNodeRadius*(WXCursor-XCursor)/fHypotenuse;
float fYRadius=mfNodeRadius*VSpacing/fHypotenuse;
TPoint P1(XCursor+fXRadius,YCursor+fYRadius);
TPoint P2(WXCursor-fXRadius,YCursor+VSpacing-fYRadius);
TPoint PCenter=DrawWeight(dc,P1,P2,
mdMaxWeight?mpWeights[iWeight]/mdMaxWeight:0,
dMaxSigma?
fabs(mChromosome.GetGene(iWeight+miWeights))/dMaxSigma:0,
WEIGHT_THICKNESS,mfNodeRadius*2.0);
// record weight end-point for future use
mpWeightEndPoints[iWeight].P1=P1;
mpWeightEndPoints[iWeight].P2=P2;
mpWeightEndPoints[iWeight].PCenter=PCenter;
WXCursor+=HSpacing;
}
}
// draw black ring
dc.SelectObject(mBackgroundFillBrush);
dc.SelectObject(RingPen);
TPoint OuterX1Y1(XCursor-mfNodeRadius,YCursor-mfNodeRadius);
TPoint OuterX2Y2(XCursor+mfNodeRadius,YCursor+mfNodeRadius);
dc.Ellipse(OuterX1Y1,OuterX2Y2);
// draw inner white circle
dc.SelectObject(ActivityBrush);
dc.SelectObject(ActivityPen);
double dActiv=mNetwork.GetActivation(iLayer,iNode);
float fThisCircleRadius=(mfNodeRadius-RING_THICKNESS)
*Sigmoid(dActiv*SIGMOID_SCALE_FACTOR);
TPoint InnerX1Y1(XCursor-fThisCircleRadius,YCursor-fThisCircleRadius);
TPoint InnerX2Y2(XCursor+fThisCircleRadius,YCursor+fThisCircleRadius);
dc.Ellipse(InnerX1Y1,InnerX2Y2);
// record center point for future use
mpNodeCenterPoints[iNodesDrawn].x=XCursor;
mpNodeCenterPoints[iNodesDrawn].y=YCursor;
iNodesDrawn++;
XCursor+=HSpacing;
}
if(iLayer<mNetwork.GetLayers()-1)
{
iWeightOffset+=mNetwork.GetLayerSize(iLayer)
*(mNetwork.GetLayerSize(iLayer+1));
}
YCursor+=VSpacing;
}
if(miSelectedNode!=-1)
{
DrawHighlight(miSelectedNode,1);
DrawNodeInfo();
}
}
int TNVisWindow::FindNode(TPoint& point)
{
int n,iNodes;
iNodes=mNetwork.GetNumNodes();
for(n=0;n<iNodes;n++)
{
if(pow(point.x-mpNodeCenterPoints[n].x,2)
+pow(point.y-mpNodeCenterPoints[n].y,2)<pow(mfNodeRadius,2))
{
return(n);
}
}
return(-1);
}
int TNVisWindow::FindWeight(TPoint& point)
{
for(int n=0;n<miWeights;n++)
{
if(pow(point.x-mpWeightEndPoints[n].PCenter.x,2)
+pow(point.y-mpWeightEndPoints[n].PCenter.y,2)
<pow(mfNodeRadius*2.0,2))
{
return(n);
}
}
return(-1);
}
void TNVisWindow::DrawHighlight(int iNode,byte bHighlight)
{
int iRGB=bHighlight?255:0;
LOGBRUSH HollowLogBrush={BS_HOLLOW,0,0};
TPen HighlightPen(TColor(iRGB,iRGB,iRGB),1);
TClientDC dc(*this);
dc.SelectObject(HighlightPen);
TPoint OuterX1Y1(mpNodeCenterPoints[iNode].x-mfNodeRadius,
mpNodeCenterPoints[iNode].y-mfNodeRadius);
TPoint OuterX2Y2(mpNodeCenterPoints[iNode].x+mfNodeRadius,
mpNodeCenterPoints[iNode].y+mfNodeRadius);
TBrush HollowBrush(&HollowLogBrush);
dc.SelectObject(HollowBrush);
dc.Ellipse(OuterX1Y1,OuterX2Y2);
}
void TNVisWindow::DrawNodeInfo()
{
if(miSelectedNode==-1)
return;
TClientDC dc(*this);
TRect ClientRect;
GetClientRect(ClientRect);
TRect DrawRect=ClientRect;
DrawRect.bottom-=SCROLLBAR_HEIGHT;
DrawRect.top=DrawRect.bottom-NODE_FONT_HEIGHT*2;
dc.FillRect(DrawRect,mBackgroundFillBrush);
TFont NodeFont(NODE_FONT_FACE,NODE_FONT_HEIGHT);
dc.SelectObject(NodeFont);
dc.SetBkColor(mBackgroundColor);
dc.SetTextColor(mTextColor);
TPoint TextPos(0,ClientRect.bottom-SCROLLBAR_HEIGHT-NODE_FONT_HEIGHT*2);
dc.TextOut(TextPos,"Input:",6);
TSize Size;
dc.GetTextExtent("Input: ",7,Size);
TextPos.x+=Size.cx;
char temp[200];
sprintf(temp,"%f",mNetwork.GetInput(miSelectedNode,miSample,mpWeights));
dc.TextOut(TextPos,temp,strlen(temp));
TextPos.x=0;
TextPos.y+=NODE_FONT_HEIGHT;
dc.TextOut(TextPos,"Activation:",11);
dc.GetTextExtent("Activation: ",12,Size);
TextPos.x+=Size.cx;
sprintf(temp,"%f",mNetwork.GetActivation(miSelectedNode));
dc.TextOut(TextPos,temp,strlen(temp));
}
TPoint TNVisWindow::DrawWeight(TDC& dc,TPoint& P1,TPoint& P2,
double dNormWeight,double dNormSigma,double dMinSigmaLen,
double dMaxSigmaLen)
{
if(dNormWeight<-1.0)
dNormWeight=-1.0;
if(dNormWeight>1.0)
dNormWeight=1.0;
if(dNormSigma<-1.0)
dNormSigma=-1.0;
if(dNormSigma>1.0)
dNormSigma=1.0;
TPen WeightPen(WeightToColor(dNormWeight),WEIGHT_THICKNESS);
dc.SelectObject(WeightPen);
dc.MoveTo(P1);
TPoint PC(P1.x+fabs(dNormWeight)*(P2.x-P1.x),
P1.y+fabs(dNormWeight)*(P2.y-P1.y));
dc.LineTo(PC);
TPen GrayPen(mGrayLineColor,WEIGHT_THICKNESS);
dc.SelectObject(GrayPen);
dc.MoveTo(PC);
dc.LineTo(P2);
if(!mbShowSigmas)
return(PC);
double dMaxDeltaLen=double(dMaxSigmaLen-dMinSigmaLen);
double dSigmaLen=dNormSigma*dMaxDeltaLen;
// tbd: pass in
double dHypotenuse=sqrt(pow(P1.x-P2.x,2)+pow(P1.y-P2.y,2));
double dXRatio=double(P2.y-P1.y)/dHypotenuse;
double dYRatio=double(P1.x-P2.x)/dHypotenuse;
double dDeltaX=dSigmaLen*dXRatio/2.0;
double dDeltaY=dSigmaLen*dYRatio/2.0;
double dMaxDeltaX=dMaxDeltaLen*dXRatio/2.0;
double dMaxDeltaY=dMaxDeltaLen*dYRatio/2.0;
// draw gray line in back
TPoint PG1(PC.x-dMaxDeltaX,PC.y-dMaxDeltaY);
TPoint PG2(PC.x+dMaxDeltaX,PC.y+dMaxDeltaY);
dc.MoveTo(PG1);
dc.LineTo(PG2);
TPoint PS1(PC.x-dDeltaX,PC.y-dDeltaY);
TPoint PS2(PC.x+dDeltaX,PC.y+dDeltaY);
TPen SigmaPen(SigmaToColor(dNormSigma),SIGMA_THICKNESS);
dc.SelectObject(SigmaPen);
dc.MoveTo(PS1);
dc.LineTo(PS2);
return(PC);
}
void TNVisWindow::EvLButtonDown(uint, TPoint& point)
{
int iNode;
iNode=FindNode(point);
if(iNode!=-1)
{
if(iNode==miSelectedNode)
{
DrawHighlight(iNode,0);
miSelectedNode=-1;
return;
}
if(miSelectedNode!=-1)
DrawHighlight(miSelectedNode,0);
DrawHighlight(iNode,1);
miSelectedNode=iNode;
DrawNodeInfo();
return;
}
miSelectedWeight=FindWeight(point);
if(miSelectedWeight!=-1)
{
if(mpWeights[miSelectedWeight]>0)
miSelectedWeightSign=1;
else
miSelectedWeightSign=-1;
}
}
void TNVisWindow::EvLButtonUp(uint, TPoint&)
{
miSelectedWeight=-1;
}
void TNVisWindow::EvMouseMove(uint modKeys, TPoint& point)
{
if(miSelectedWeight!=-1)
{
int iEffectiveY=point.y;
if(iEffectiveY<mpWeightEndPoints[miSelectedWeight].P1.y)
iEffectiveY=mpWeightEndPoints[miSelectedWeight].P1.y;
if(iEffectiveY>mpWeightEndPoints[miSelectedWeight].P2.y)
iEffectiveY=mpWeightEndPoints[miSelectedWeight].P2.y;
mpWeights[miSelectedWeight]=float(iEffectiveY
-mpWeightEndPoints[miSelectedWeight].P1.y)*mdMaxWeight/
(mpWeightEndPoints[miSelectedWeight].P2.y
-mpWeightEndPoints[miSelectedWeight].P1.y)
*float(miSelectedWeightSign);
double dFitness=GetFitness();
char temp[200];
sprintf(temp,"%lf",dFitness);
#if(ATTRIBUTE_EVAL)
strcat(temp,"%");
#endif
SetCaption(temp);
// tbd: just redraw network
Invalidate(TRUE);
}
TESWindow::EvMouseMove(modKeys,point);
}
void TNVisWindow::EvSampleEdit(UINT /*code*/)
{
char temp[200];
mpSampleEdit->GetText(temp,200);
miSample=atoi(temp);
if(miSample<0||miSample>=mNetwork.GetNumSamples())
{
miSample=miSample<0?0:mNetwork.GetNumSamples()-1;
UpdateSampleEdit();
}
mNetwork.RunSample(mpWeights,miWeights,miSample);
mpHScroll->SetPosition(miSample);
Invalidate(FALSE);
}
void TNVisWindow::EvSampleScroll(UINT /*code*/)
{
miSample=mpHScroll->GetPosition();
mNetwork.RunSample(mpWeights,miWeights,miSample);
UpdateSampleEdit();
Invalidate(FALSE);
}
void TNVisWindow::EvSize(UINT SizeType, TSize& Size)
{
TWindow::EvSize(SizeType, Size);
if(SizeType != SIZEICONIC)
{
// reposition scroll bar
TRect ClientRect;
GetClientRect(ClientRect);
mpHScroll->MoveWindow(0,
ClientRect.bottom-SCROLLBAR_HEIGHT-ClientRect.top,
ClientRect.Width(),SCROLLBAR_HEIGHT);
Invalidate(TRUE);
}
}
void TNVisWindow::CmFileLoad()
{
TOpenSaveDialog::TData FilenameData(OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST,
"Networks (*.net)|*.net|All Files (*.*)|*.*|",0,"","*");
if(TFileOpenDialog(this, FilenameData, 0, "Load Network").Execute()
== IDOK)
{
if(Load(FilenameData.FileName)<0)
MessageBox("File load failed!","Error!");
}
}
void TNVisWindow::CmFileSave()
{
if(mpFilename)
SaveAs(mpFilename);
}
void TNVisWindow::CmFileSaveAs()
{
TOpenSaveDialog::TData FilenameData(OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST,
"Networks (*.net)|*.net|All Files (*.*)|*.*|",0,"","*");
if(TFileSaveDialog(this, FilenameData, 0, "Save Network").Execute()
== IDOK)
{
SaveAs(FilenameData.FileName);
}
}
void TNVisWindow::CmFileLoadTestSet()
{
TOpenSaveDialog::TData FilenameData(OFN_FILEMUSTEXIST|OFN_PATHMUSTEXIST,
"Training Sets (*.ts)|*.ts|All Files (*.*)|*.*|",0,"","*");
if(TFileOpenDialog(this, FilenameData, 0, "Open Training File").Execute()
== IDOK)
{
// tbd: check for incompatible training set
if(mNetwork.LoadTrainingSet(FilenameData.FileName)<0)
{
MessageBox("File load failed!","Error!");
}
}
}
void TNVisWindow::CeFileSave(TCommandEnabler& ce)
{
ce.Enable(mpFilename?1:0);
}
void TNVisWindow::CeViewVolatility(TCommandEnabler& ce)
{
ce.SetCheck(mbShowSigmas);
}
void TNVisWindow::CmNetworkEval()
{
char pMessage[200];
sprintf(pMessage,"Fitness: %lf",GetFitness());
#if(ATTRIBUTE_EVAL)
strcat(pMessage,"%");
#endif
MessageBox(pMessage,"Fitness");
}
void TNVisWindow::CmNetworkViewActivations()
{
char pMessage[500];
int n;
pMessage[0]='\0';
for(n=0;n<mNetwork.GetLayers();n++)
{
strcat(pMessage,mNetwork.GetActivationName(n));
strcat(pMessage,"\n");
}
MessageBox(pMessage,"Activations");
}
void TNVisWindow::CmNetworkBackProp()
{
if(!mpBackpropWin)
{
mpBackpropWin=new TBackpropWindow(this,this,&mpBackpropWin);
if(mpBackpropWin)
mpBackpropWin->Create();
}
}
void TNVisWindow::CmViewVolatility()
{
mbShowSigmas=!mbShowSigmas;
Invalidate(TRUE);
}
int TNVisWindow::SaveAs(char *pFile)
{
ofstream outfile(pFile);
outfile << mNetwork;
outfile << "#Chromosome#\n";
outfile << mChromosome;
outfile << (*((ParamInfo*)(&mParam)));
mpFilename=pFile;
UpdateCaption();
return(0);
}
int TNVisWindow::Load(char *pFile)
{
char line[256];
mpFilename=pFile;
ifstream infile(pFile);
infile >> mNetwork;
if(!mNetwork.GetLoadStatus())
return(-1);
infile >> line;
infile >> mChromosome;
infile >> (*((ParamInfo*)(&mParam)));
mParam.SetNumParameters(mParam.GetNParams());
Decode(mChromosome,mParam);
miWeights=mNetwork.NumWeights();
delete(mpWeights);
mpWeights=new double[miWeights];
memcpy(mpWeights,mParam.GetParams(),miWeights*sizeof(double));
delete(mpNodeCenterPoints);
delete(mpWeightEndPoints);
mpNodeCenterPoints=new TPoint[mNetwork.GetNumNodes()];
mpWeightEndPoints=new TDrawnWeight[miWeights];
mNetwork.RunSample(mpWeights,miWeights,miSample);
UpdateCaption();
Invalidate(TRUE);
return(0);
}
void TNVisWindow::UpdateSampleEdit()
{
char temp[200];
itoa(miSample,temp,10);
mpSampleEdit->SetText(temp);
}
void TNVisWindow::UpdateCaption()
{
char pTitle[200];
strcpy(pTitle,"Network Editor - ");
if(mpFilename)
{
char *pFilename=&(mpFilename[strlen(mpFilename)]);
while(pFilename>=mpFilename && pFilename[0]!='/' && pFilename[0]!='\\')
pFilename--;
pFilename++;
int iStrlen=strlen(pTitle);
strcat(pTitle,pFilename);
strlwr(&(pTitle[iStrlen]));
}
else
{
mChromosome.GetName(&(pTitle[strlen(pTitle)]));
}
SetCaption(pTitle);
}
TColor WeightToColor(double dNormWeight)
{
float fIntensity=96.0+159.0*fabs(dNormWeight);
if(dNormWeight<0)
return(TColor(fIntensity,0,0));
else
return(TColor(0,fIntensity,fIntensity));
}
TColor SigmaToColor(double dNormSigma)
{
float fIntensity=96.0+159.0*dNormSigma;
return(TColor(0,fIntensity,0));
}