#include void dprint( char *fmt, ...); void dputchar( int c); /* * plot() tabulates and plots n points of y vs. x * hplot() is like plot(), but histogram style * plot2d() plots without tabulating * * If x == NULL, 1..n is used for x */ #define SIZE 51 /* horizontal size for plot() and hplot() */ #define STAR '*' /* plotting characters */ #define SPACE ' ' #define VERT '|' #define DASH '-' #define CROSS '+' #define MIN(a,b) ( (a) < (b) ? (a) : (b) ) #define MAX(a,b) ( (a) > (b) ? (a) : (b) ) void hplot( char *title, double x[], double y[], int n) { double ymin, ymax; /* min/max values of y */ double scale; /* scale factor relating y values */ /* to number of stars printed */ int i2; /* number of STAR's to print */ int i, j; /* dummies */ /* * find ymin, ymax, and scale factor */ ymin = y[0]; ymax = y[0]; for( j = 1; j < n; j++) { ymin = MIN( ymin, y[j]); ymax = MAX( ymax, y[j]); } scale = (ymax-ymin) / (SIZE-1); if( scale == 0.0) scale = 1.0; /* prevent divide by zero later */ /* * print table & plot * */ if( title) dprint("%28c%s\n", SPACE, title); for( j = 0; j < n; j++) { i2 = (y[j]-ymin) / scale + 1.5; /* round to nearest point */ dprint( "%12.5g %12.5g ", x ? x[j] : (double)(j+1), y[j]); for( i = 1; i <= i2; i++) dputchar(STAR); dputchar('\n'); } } void plot( char *title, double x[], double y[], int n) { double ymin, ymax; /* min/max values of y */ double scale; /* scale factor relating y values */ /* to number of stars printed */ int i1, i2, k1, k2; /* used in plotting section */ int i, j; /* dummies */ /* * find ymin, ymax, and scale factor */ ymin = y[0]; ymax = y[0]; for( j = 1; j < n; j++) { ymin = MIN( ymin, y[j]); ymax = MAX( ymax, y[j]); } scale = (ymax-ymin) / (SIZE-1); if( scale == 0.0) scale = 1.0; /* prevent divide by zero later */ /* * print table & plot * * i1 represents the position of the previous point, i2 the current point. * k1 & k2 are determined to print stars to connect the points. */ if( title) dprint("%28c%s\n", SPACE, title); i1 = (y[0]-ymin) / scale + 1.5; /* initial point */ for( j = 0; j < n; j++) { i2 = (y[j]-ymin) / scale + 1.5; /* round to nearest point */ if( i2 >= i1) { k1 = i1; k2 = i2; } else { k1 = i2; k2 = i1; } dprint( "%12.5g %12.5g ", x ? x[j] : (double)(j+1), y[j]); for( i = 1; i < k1; i++) dputchar(SPACE); for( i = k1; i <= k2; i++) dputchar(STAR); dputchar('\n'); i1 = i2; } } void plot2d( char *title, /* string title for the plot */ double x[], double y[], /* arrays to plot */ int n) /* number of points used in x & y */ { double xmin, xmax, xscale; /* x & y min/max values */ double ymin, ymax, yscale; /* and scale factors */ double xlabel[5], ylabel[5];/* numeric labels for x & y axes */ double dx, dy; /* delta x & y */ char points[21][62]; /* character array to contain the plot */ int row, col, i, m; /* dummies */ /* find min, max, and scales */ if( x) { xmin = x[0]; xmax = x[0]; for( i = 1; i < n; i++) { xmin = MIN( xmin, x[i] ); xmax = MAX( xmax, x[i] ); } } else { xmin = 1; xmax = n; } ymin = y[0]; ymax = y[0]; for( i = 1; i < n; i++) { ymin = MIN( ymin, y[i] ); ymax = MAX( ymax, y[i] ); } dx = xmax - xmin; xscale = dx / 60.0; if( xscale == 0.0) xscale = 1.0; /* prevent divide by zero later */ dy = ymax - ymin; yscale = dy / 20.0; if( yscale == 0.0) yscale = 1.0; /* * initialize labels and points */ for( i = 0; i < 5; i++) { xlabel[i] = xmin + i * dx / 4.0; ylabel[i] = ymin + i * dy / 4.0; } for( row = 0; row < 21; row++) points[row][61] = '\0'; /* terminate the strings */ for( row = 0; row < 21; row++) for( col = 0; col < 61; col++) points[row][col] = SPACE; /* all blanks to start with */ for( row = 0; row < 21; row++) /* make a grid with */ for( col = 0; col < 61; col += 15) points[row][col] = VERT; /* vertical line every 15 cols */ for( row = 0; row < 21; row += 5) for( col = 0; col < 61; col++) points[row][col] = DASH; /* dash every 5 rows */ for( row = 0; row < 21; row += 5) for( col = 0; col < 61; col += 15) points[row][col] = CROSS; /* cross at intersection */ for( i = 0; i < n; i++) { /* plot the points */ row = (y[i]-ymin) / yscale + 0.5; col = ((x ? x[i] : i+1) - xmin) / xscale + 0.5; points[row][col] = STAR; } if( title) dprint( "%12c%s\n", SPACE, title); m = 5; /* for ylabel index */ for( row = 20; row >= 0; row--) { if( row % 5 == 0) { /* print ylabel */ m--; dprint( "%12.5g%s\n", ylabel[m], points[row]); } else dprint( "%12c%s\n", SPACE, points[row]); } dprint( "%2c", SPACE); for( i = 0; i < 5; i++) dprint( "%3c%12.5g", SPACE, xlabel[i]); dputchar('\n'); }