/*----------------------------------------------------------------*/ #include "graph_exp.h" #include "net_exp.h" /******Function DrawTitle draws the network title in the "pix" widget */ DrawTitle(win) Window win; { Dimension pixwidth; Arg wargs[1]; int x, y; /* Title the drawing (centered text) */ XtSetArg(wargs[0], XtNwidth, &pixwidth); XtGetValues(pix, wargs, 1); y = (int) XTextWidth(textstruct, pixtitle, strlen(pixtitle)); x = (int)(((int)pixwidth - y ) / 2); XDrawString(dpy, win, textgc, x, 25, pixtitle, strlen(pixtitle)); } /******Function DrawNone general-purpose do-nothing routine (for now) */ void DrawNone(w, client_data, call_data) Widget w; XtPointer client_data, call_data; { } /******Function DrawNet draws a neural network in the "pix" widget */ void DrawNet(w, client_data, call_data) Widget w; XtPointer client_data, call_data; { int i, j, k, l, ncolor; int x, y, x2, y2; Window win = XtWindow(pix); int scr = DefaultScreen(dpy); XPoint dpoints[5]; /* Draw a network in the "pix" widget */ if(XtIsRealized(pix)) { DrawTitle(win); /* Draw inputs and outputs */ x = 10; x2 = 60; y = (40 - 60 * Network.taps[0]) + (NODSIZ / 2); for (k = 0; k < Network.nodes[0]; k++) { y += 60 * Network.taps[0]; XDrawLine(dpy, win, linegc, x, y, x2, y); if (Recurrent && (k == Network.nodes[Network.layers - 1] - 1)) XDrawLine(dpy, win, linegc, 10, y, 10, 32); } x = 60 + (Network.layers - 1) * (120 + (3 * NODSIZ / 2)) + NODSIZ / 2; x2 = x + 70; y = (40 - 60 * Network.taps[Network.layers - 1]) + (NODSIZ / 2); for (k = 0; k < Network.nodes[Network.layers - 1]; k++) { y += 60 * Network.taps[Network.layers - 1]; XDrawLine(dpy, win, linegc, x, y, x2, y); } if (Recurrent) { XDrawLine(dpy, win, linegc, x + 30, y, x + 30, 32); XDrawLine(dpy, win, linegc, x + 30, 32, 10, 32); } /* Draw weights in color */ x = -95 + (NODSIZ / 2); for (l = 0; l < Network.layers - 1; l++) { x += 155; y = -20 + (NODSIZ / 2); for (k = 0; k < Network.nodes[l]; k++) { for (j = 0; j < Network.taps[l]; j++) { y += 60; y2 = (40 - 60 * Network.taps[l+1]) + (NODSIZ / 2); for (i = 0; i < Network.nodes[l+1]; i++) { x2 = x + 120; y2 += 60 * Network.taps[l+1]; ncolor = 42 + (int) (Network.weight[l][j][k][i] * 8.0 * weightnorm); if (ncolor > 55) ncolor = 52; else if (ncolor > 50) ncolor = 50; if (ncolor < 29) ncolor = 51; else if (ncolor < 34) ncolor = 34; XSetForeground(XtDisplay(pix), gc, colorvals[ncolor]); XDrawLine(dpy, win, gc, x, y, x2, y2); } } } } /* Draw network nodes in color */ x = -95; for (l = 0; l < Network.layers; l++) { x += 155; y = -20; for (k = 0; k < Network.nodes[l]; k++) { x2 = x + NODSIZ/2; y2 = y + 60 * Network.taps[l]; XDrawLine(dpy, win, linegc, x2, y + 60, x2, y2); for (j = 0; j < Network.taps[l]; j++) { y += 60; ncolor = 8 + (int) (Network.state[l][j][k] * 8.9); XSetForeground(XtDisplay(pix), gc, colorvals[ncolor]); XFillArc(dpy, win, gc, x, y, NODSIZ, NODSIZ, 0, 64*360); XDrawArc(dpy, win, linegc, x, y, NODSIZ, NODSIZ, 0, 64*360); } } } /* Draw threshold units in color, plus summation nodes */ x = -95 - NODSIZ + 180; for (l = 1; l < Network.layers; l++) { x += 155; dpoints[1].x = dpoints[3].x = x - NODSIZ / 4; dpoints[0].x = dpoints[4].x = x; dpoints[2].x = x - NODSIZ / 2; y = (40 - 60 * Network.taps[l]) + (NODSIZ / 2); for (k = 0; k < Network.nodes[l]; k++) { y += 60 * Network.taps[l]; dpoints[0].y = dpoints[4].y = dpoints[2].y = y; dpoints[1].y = y - NODSIZ / 2; dpoints[3].y = y + NODSIZ / 2; ncolor = 25 + (int) (Network.threshold[l-1][k] * 8.0 * weightnorm); if (ncolor > 38) ncolor = 52; else if (ncolor > 33) ncolor = 33; if (ncolor < 12) ncolor = 51; else if (ncolor < 17) ncolor = 17; XSetForeground(XtDisplay(pix), gc, colorvals[ncolor]); XFillPolygon(dpy, win, gc, dpoints, 5, Convex, CoordModeOrigin); XDrawLines(dpy, win, linegc, dpoints, 5, CoordModeOrigin); x2 = dpoints[2].x - NODSIZ; y2 = dpoints[1].y; XFillArc(dpy, win, textgc, x2, y2, NODSIZ, NODSIZ, 0, 64*360); XDrawArc(dpy, win, linegc, x2, y2, NODSIZ, NODSIZ, 0, 64*360); x2 += (NODSIZ - SIGWIDTH)/2; y2 += (NODSIZ - SIGHEIGHT)/2 + SIGHEIGHT; XDrawString(dpy, win, linegc, x2, y2, "S", 1); } } /* Draw delay taps */ x = -95 + NODSIZ / 6; for (l = 0; l < Network.layers; l++) { x += 155; y = -80 + 30 + NODSIZ / 3; for (k = 0; k < Network.nodes[l]; k++) { y += 60; for (j = 0; j < Network.taps[l] - 1; j++) { y += 60; XFillRectangle(dpy, win, textgc, x, y, (int)2 * NODSIZ / 3, (int) 2 * NODSIZ / 3); XDrawRectangle(dpy, win, linegc, x, y, (int)2 * NODSIZ / 3, (int) 2 * NODSIZ / 3); x2 = x + ((int)(2 * NODSIZ / 3) - DELWIDTH)/2; y2 = y + ((int)(2 * NODSIZ / 3) - DELHEIGHT)/2 + DELHEIGHT; XDrawString(dpy, win, linegc, x2, y2, "D", 1); } } } } } /*******Function DrawActive draws the network activations in a series of matrices */ void DrawActive(w, client_data, call_data) Widget w; XtPointer client_data, call_data; { int i, j, k, l, ncolor; int x, y, x2, x3; Window win = XtWindow(pix); int scr = DefaultScreen(dpy), taps_accum; /* Draw a network in the "pix" widget */ if(XtIsRealized(pix)) { DrawTitle(win); /* Draw network activations (nodes + buffered taps) in color */ y = 30; taps_accum = 1; for (l = Network.layers - 1; l >= 0; l--) { for (k = Network.nodes[l] - 1; k >= 0; k--) { x = 60; x3 = (Recurrent && (k >= Network.nodes[Network.layers - 1])) ? 40 : 30; y += (NODSIZ + 2); if (l == 0) { /* Draw input arrows */ x2 = y + (NODSIZ / 2); XDrawLine(dpy, win, linegc, x3, x2, 60, x2); XDrawLine(dpy, win, linegc, 55, x2+5, 60, x2); XDrawLine(dpy, win, linegc, 55, x2-5, 60, x2); } for (j = 0; j < taps_accum; j++) { ncolor = 8 + (int) (Network.state[l][j][k] * 8.9); XSetForeground(XtDisplay(pix), gc, colorvals[ncolor]); XFillRectangle(dpy, win, gc, x, y, NODSIZ, NODSIZ); XDrawRectangle(dpy, win, linegc, x, y, NODSIZ, NODSIZ); x += (NODSIZ + 2); } } if (Recurrent) XDrawLine(dpy, win, linegc, 30, y + (NODSIZ / 2), 30, 35); if (l != 0) { taps_accum += Network.taps[l - 1] - 1; x2 = (l == Network.layers - 1) ? x2 = 60 + (NODSIZ + 2) : 60 + (NODSIZ + 2) * Network.taps [l]; x3 = 60 + (NODSIZ + 2) * Network.taps [l - 1]; XDrawLine(dpy, win, textgc, 60, y + NODSIZ, 60, y + 50 + NODSIZ); XDrawLine(dpy, win, textgc, x2, y + NODSIZ, x3, y + 50 + NODSIZ); } y += 50; } /* Draw output arrows */ y = 30 + (NODSIZ + 2) + (NODSIZ / 2); x2 = 60 + NODSIZ; for (k = Network.nodes[Network.layers - 1] - 1; k >= 0; k--) { XDrawLine(dpy, win, linegc, x2, y, x2 + 30, y); XDrawLine(dpy, win, linegc, x2 + 25, y+5, x2 + 30, y); XDrawLine(dpy, win, linegc, x2 + 25, y-5, x2 + 30, y); y += (NODSIZ + 2); } if (Recurrent) { XDrawLine(dpy, win, linegc, x2 + 15, y - (NODSIZ + 2), x2 + 15, 35); XDrawLine(dpy, win, linegc, x2 + 15, 35, 30, 35); } } } /********Function DrawGraph draws the input/output history of the network. */ void DrawGraph(w, client_data, call_data) Widget w; XtPointer client_data, call_data; { int i, o, j, p; int x, y, yscale, xscale; Window win = XtWindow(graph); int scr = DefaultScreen(dpy); XPoint ipoints[MAXPATTERNS * 2 + 2], opoints[MAXPATTERNS * 2 + 2]; Dimension gheight, gwidth; Arg wargs[2]; char gstring[20]; int patterns; float input; if(XtIsRealized(graph)) { patterns = trainsamp ? no_samples : no_patterns; /* Draw the i/o characteristics in the "graph" widget */ XtSetArg (wargs[0], XtNheight, &gheight); XtSetArg (wargs[1], XtNwidth, &gwidth); XtGetValues (graph, wargs, 2); /* Set x and y scaling values */ gheight -= 40; gwidth -= 40; yscale = (gheight / (Network.nodes[Network.layers - 1] + Network.nodes[0]) - 20) / 2; xscale = gwidth / (patterns + 1); y = 40 + yscale; XSetForeground(dpy, gc, colorvals[0]); for (i = 0; i < Network.nodes[0]; i++) { x = 30; sprintf(gstring, "Input %d", i); for (p = 0; p < patterns; p++) { input = trainsamp ? sampleinput[p][i] : traininput[p][i]; ipoints[p * 2].x = x; ipoints[p * 2].y = ipoints[p * 2 + 1].y = y - yscale * input; x += xscale; ipoints[p * 2 + 1].x = x; } if (trainsamp) XClearArea(dpy, win, 29, y - yscale - 1, gwidth + 1, y + yscale + 1, CoordModeOrigin); XDrawString(dpy, win, graphgc, 30, y - yscale - 5, gstring, strlen(gstring)); XDrawLine(dpy, win, graphgc, 30, y, gwidth, y); XDrawLines(dpy, win, textgc, ipoints, patterns * 2, CoordModeOrigin); y += 2 * yscale + 20; } for (o = 0; o < Network.nodes[Network.layers - 1]; o++) { x = 30; sprintf(gstring, "Output %d", o); for (p = 0; p < patterns; p++) { opoints[p * 2].x = x; opoints[p * 2].y = opoints[p * 2 + 1].y = y - yscale * traindesired[p][o]; ipoints[p * 2].y = ipoints[p * 2 + 1].y = y - yscale * outputhistory[p][o]; x += xscale; opoints[p * 2 + 1].x = x; } XClearArea(dpy, win, 29, y - yscale - 1, gwidth + 1, y + yscale + 1, CoordModeOrigin); XDrawString(dpy, win, graphgc, 30, y - yscale - 5, gstring, strlen(gstring)); XDrawLine(dpy, win, graphgc, 30, y, gwidth, y); if (!trainsamp) XDrawLines(dpy, win, textgc, opoints, patterns * 2, CoordModeOrigin); XDrawLines(dpy, win, gc, ipoints, patterns * 2, CoordModeOrigin); y += 2 * yscale + 20; } } }