home *** CD-ROM | disk | FTP | other *** search
-
- /*
- YAMP - Yet Another Matrix Program
- Version: 1.6
- Author: Mark Von Tress, Ph.D.
- Date: 01/11/93
-
- Copyright(c) Mark Von Tress 1993
- Portions of this code are (c) 1991 by Allen I. Holub and are used by
- permission
-
- DISCLAIMER: THIS PROGRAM IS PROVIDED AS IS, WITHOUT ANY
- WARRANTY, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED
- TO FITNESS FOR A PARTICULAR PURPOSE. THE AUTHOR DISCLAIMS
- ALL LIABILITY FOR DIRECT OR CONSEQUENTIAL DAMAGES RESULTING
- FROM USE OF THIS PROGRAM.
-
- */
-
- #include "virt.h"
-
- Axis::Axis(VMatrix &grf_vec, int col, int pixels, int pxlspplot)
- {
- Dispatch->Inclevel();
- getlinesettings(&lineinfo);
- valmin = 0;
- step = 0;
- ir = 0;
- ifault = 0;
- iv = 30;
- maxpr = 6;
- mpv = pxlspplot;
- fmn = fmx = grf_vec.m(1, col);
- double temp;
- for (int i = 2; i <= grf_vec.r; i++) {
- temp = grf_vec.m(i, col);
- fmn = (temp < fmn) ? temp : fmn;
- fmx = (temp > fmx) ? temp : fmx;
- }
- if (fmn == fmx) {
- fmx = fmn + 0.5;
- fmn = fmn - 0.5;
- }
-
- vals = new double[iv];
- getvals(fmn, fmx, pixels, vals, &offset, &ifact, &nvals, &irprin);
- Vals = new VMatrix;
- *Vals = Fill(nvals, 1, 0);
- for (i = 0; i < nvals; i++) {
- double temp = (irprin != 0) ?
- floor(0.5 + vals[i] *exp(((double) irprin) *log(10.0)))
- *exp(- ((double) irprin) *log(10.0)) :
- vals[i];
- Vals->M(i + 1, 1) = temp;
- }
- Dispatch->Declevel();
-
- }
- Axis::~Axis(void)
- {
- delete vals;
- delete Vals;
- }
- double Axis::dmax(double x, double y)
- {
- return ((x > y) ? x : y);
- }
-
- void Axis::scale(double fmn, double fmx, int n, int mpv,
- double *valmin, double *step, int *nvals, int *ir, int *ifault)
- { double unit[13] = { 0, 12, 15, 20, 25, 30, 40, 50, 60, 80, 100, 120, 150};
- double tol = 5.0e-6, bias = 1.0e-5, cover = 0.7, temp;
- int i, j, minn = 2, maxn = 10000;
- char buf[80] = { '\0' };
-
- double fmax, fmin, finter, s, aj, tstep;
- int nunit = 12;
-
- fmax = fmx;
- fmin = fmn;
- *ifault = 0;
- if (fmax < fmin) *ifault++;
- if ((n < minn) || (n > maxn)) *ifault += 2;
- if ((mpv <= 0) || (mpv >= n)) *ifault += 4;
- if (*ifault) {
- sprintf(buf, "SCALE: bad parameters in scale irprn = %d", *ifault);
- closegraph();
- Dispatch->Nrerror(buf);
- }
- *nvals = 1+ (n - 1) / mpv;
- if ((fmax - fmin) <= (tol*((double) dmax(fabs(fmax), fabs(fmin))))){
- *ifault = -1;
- if (fmax < 0) fmax = 0;
- if (fmax == 0) fmax = 1;
- if (fmax > 0) fmin = 0;
- }
- finter =((double) n) / ((double) mpv);
- s =(fmax - fmin) *(1.0+2.0*bias) / finter;
- *ir = 0;
- while (s <= 10.0) {
- s *= 10;
- (*ir)++;
- }
- while (s > 100) {
- s /= 10;
- (*ir)--;
- }
- i = 0;
- while (s > unit[i]) i++;
-
- LABEL1 :
- *step = unit[i] *exp(- ((double) (*ir)) *log(10));
- aj = 0;
-
- LABEL2 :
- do {
- aj += 1.0;
- } while ((unit[i] - 0.1) > (floor((unit[i] + 0.1) / aj) *aj));
- tstep = (*step) / aj;
- temp = fmin / tstep + aj*(0.5 / ((double) mpv) - finter*bias);
- *valmin = floor(temp) *tstep;
- if ((temp < 0) && (temp != floor(temp))) (*valmin) -= tstep;
- if (fmax < ((*valmin) +(*step) *(finter*(1.0-bias) - 0.5 / ((double)mpv))))
- goto LABEL3;
- if ((unit[i] / unit[i + 1] *(1.0-1.0 / (aj*finter))) < cover) goto LABEL2;
- i++;
- if (i == nunit) printf("problem");
- goto LABEL1;
- LABEL3 :
- for (j = 1; j <= 2; j++) {
- aj *= 10;
- if ((unit[i] - 0.1) < (floor((unit[i] + 0.1) / aj) *aj)) (*ir) -= 1;
- }
- } /* scale */
-
-
-
- void Axis::axis(double valmin, double step, int nvals, int maxpr, int ir,
- int *irprin, double *offset, int *ifact, double *vals, int iv,
- int *ifault)
- {
- int irmax = 200, mprmax = 20;
- double fmax, tmax, fl, fs, vstep, vmin, temp1 = 0, temp2 = 0;
- double dtemp1 = 0, dtemp2 = 0;
- int i, il, is, it, ilprin;
- char buf[80] = { '\0' };
-
- *ifault = 0;
- if (nvals < 2) (*ifault)++;
- fmax = valmin + step*((double) (nvals - 1));
- if ((nvals >= 2) && (fmax <= valmin)) (*ifault) += 2;
- if ((maxpr < 2) || (maxpr > mprmax)) (*ifault) += 4;
- if (nvals > iv) (*ifault) += 8;
- if (ir > irmax) (*ifault) += 16;
- if (*ifault) {
- sprintf(buf, "Axis: bad parameters in axis: error %d", *ifault);
- closegraph();
- Dispatch->Nrerror(buf);
- }
-
- tmax = exp(((double) maxpr) *log(10.0));
- fl = fabs(fmax);
- fs = fabs(valmin);
- il = 0;
- while (!((fl < 1.0) && (fs < 1.0))) {
- fl /= 10;
- fs /= 10;
- il++;
- }
- while (!((fl >= 0.1) || (fs >= 0.1))) {
- fl *= 10;
- fs *= 10;
- il -= 1;
- }
-
- is = il + ir;
- it = is;
- if ((valmin <= 0.0) && (fmax >= 0.0)) goto LABEL50;
- LABEL40 :
- fl = ((double) modf(fl, &dtemp1)) *10;
- fs = ((double) modf(fs, &dtemp2)) *10;
- if (it <= 0) {
- closegraph();
- Dispatch->Nrerror("Axis: error 16 in axis ");
- }
-
- if (((int) floor(fl)) != ((int) floor(fs))) goto LABEL50;
- it--;
- goto LABEL40;
-
- LABEL50 :
- *ifact = 0;
- *offset = 0.0;
- *irprin = (ir > 0) ? ir : 0;
- ilprin = (il > 0) ? il : 0;
-
- if (((*irprin) + ilprin) <= maxpr) goto LABEL70;
- if (is <= maxpr) goto LABEL60;
- *irprin = maxpr - 1;
- *ifact = (it > maxpr) ? it : maxpr;
- *ifact = (*ifact) - 1 - ir;
- goto LABEL70;
- LABEL60 :
- *ifact = il - 1;
- *irprin = is - 1;
- LABEL70 :
- fs = exp(- ((double) (*ifact)) *log(10.0));
- vstep = step*fs;
- vmin = valmin*fs;
- if (!(is <= maxpr)) {
- *offset = floor(vmin / 10.0) *10;
- vmin -= (*offset);
- }
- for (i = 0; i < nvals; i++) {
- vals[i] = vmin;
- vmin += vstep;
- }
- fs = pow(0.1, ((double) (*irprin)));
- temp1 = fabs(vals[0]) *fs + 0.5;
- temp2 = fabs(vals[nvals - 1]) * fs + 0.5;
- if ((temp1 < tmax) && (temp2 < tmax)) return;
- il++;
- is++;
- it++;
- goto LABEL50;
-
- } /* end axis */
-
- /* get scale and axis Applied Statistics algorithm 168 */
-
- void Axis::getvals(double fmn, double fmx, int n, double *vals,
- double *offset, int *ifact, int *nvals, int *irprin)
- {
-
- scale(fmn, fmx, n, mpv, &valmin, &step, nvals, &ir, &ifault);
- axis(valmin, step, *nvals, maxpr, ir, irprin, offset, ifact,
- vals, iv, &ifault);
-
- //
- // the following code fixes an axis where data is out of range
- //
-
- double st = Rescale(step);
- double t = Rescale(fmn);
- double trace;
- int down = 0, up = 0;
-
- if (t < vals[0])
- for (trace = vals[0]; (t < trace) && (down + *nvals < iv);
- down++, trace -= st);
-
- t = Rescale(fmx);
- if (t > vals[*nvals - 1])
- for (trace = vals[*nvals - 1]; (t > trace) && (up + down + *nvals < iv);
- up++, trace += st);
-
- if (down + up + *nvals >= iv) {
- // prevent a writeover past the end of vals
- ifault = 8;
- char buf[80] = { '\0' };
- sprintf(buf, "Axis: bad parameters in axis: error %d", ifault);
- closegraph();
- Dispatch->Nrerror(buf);
- }
-
- t = vals[0] - ((double) down) *st;
- for (int i = 0; i < down + up + *nvals; i++) {
- vals[i] = t;
- t += st;
- }
- *nvals += down + up;
- }
- strtype Axis::GetAxisLabel(strtype &name)
- {
- char xo[20] = { '\0' }, xi[20] = { '\0' };
- char buf[80] = { '\0' };
- strtype newname;
- newname = name + " ";
-
- gcvt(offset, 8, buf);
- strcpy(xo, (const char *) buf);
- gcvt(ifact, 8, buf);
- strcpy(xi, (const char *) buf);
- if (offset && ifact)
- newname = newname + "((x+" + xo + ")*10**" + xi + ")";
- if (!offset && ifact)
- newname = newname + "(x*10**" + xi + ")";
- if (offset && !ifact)
- newname = newname + "(x+" + xo + ")";
- return newname;
- }
- double Axis::Rescale(double x)
- {
- static double log10 = log(10.0);
- double xo = x + offset;
- double si = (xo <= 0.0) ? - 1.0 : 1.0;
- double xv = (xo == 0.0) ? 0.0 :
- si*exp(log(fabs(xo)) - ((double) ifact) *log10);
- return xv;
- }
-
-
- //////////////////////// yaxis
-
-
- YAxis::YAxis(VMatrix &grf, int xxlen, int yylen, int ww, int hh,
- int bbmarg, int uumarg, int llmarg, int rrmarg) :
- Axis(grf, 4, yylen, yylen / hh)
- {
- Dispatch->Inclevel();
- h = hh;
- w = ww;
- bmarg = bbmarg;
- umarg = uumarg;
- lmarg = llmarg;
- rmarg = rrmarg;
- ylen = yylen;
- xlen = xxlen;
-
- maxy =(Mmax(*Vals)).m(3, 1);
- miny =(Mmin(*Vals)).m(3, 1);
-
- deltay =(fabs(maxy - miny) < 1.0e-10) ? 1.1*miny : maxy - miny;
- deltay =((double) ylen) / deltay;
-
- Dispatch->Cleanstack();
- Dispatch->Declevel();
- }
-
-
-
- void YAxis::Show(boolean gridon)
- {
- // show yaxis
-
- char *buf = new char[80];
- strtype *junk = new strtype;
- setviewport(lmarg, umarg, rmarg, bmarg, 1);
- line(0, 0, 0, ylen + 1);
-
- setviewport(0, umarg - h, lmarg, bmarg + h, 1);
- settextjustify(RIGHT_TEXT, CENTER_TEXT);
-
- int tickloc;
- for (int i = 1; i <= nvals; i++) {
- double temp = Vals->m(i, 1);
- tickloc = ylen - (int) (deltay*(temp - miny)) + h;
- gcvt(temp, (maxpr + 2), buf);
- *junk = "";
- *junk = *junk + buf + " ";
- outtextxy(lmarg, tickloc, junk->StringAddress());
- line(lmarg - w + 1, tickloc - 1, lmarg, tickloc - 1);
- }
- if (gridon) {
- setviewport(lmarg, umarg - h, rmarg, bmarg + h, 1);
- setlinestyle(lineinfo.linestyle, lineinfo.upattern, NORM_WIDTH);
- for (int i = 1; i <= nvals; i++) {
- double temp = Vals->m(i, 1);
- tickloc = ylen - (int) (deltay*(temp - miny)) + h;
- line(0, tickloc - 1, xlen, tickloc - 1);
-
- }
- setlinestyle(lineinfo.linestyle, lineinfo.upattern, THICK_WIDTH);
- }
-
- setviewport(lmarg, umarg, rmarg, bmarg, 1);
- delete buf;
- delete junk;
-
-
- }
- //////////// xaxis
-
- XAxis::XAxis(VMatrix &grf, int xxlen, int yylen, int ww, int hh,
- int bbmarg, int uumarg, int llmarg, int rrmarg) :
- Axis(grf, 3, xxlen, xxlen / ww)
- {
- Dispatch->Inclevel();
- xlen = xxlen;
- ylen = yylen;
- w = ww;
- h = hh;
- bmarg = bbmarg;
- umarg = uumarg;
- lmarg = llmarg;
- rmarg = rrmarg;
-
- maxx =(Mmax(*Vals)).m(3, 1);
- minx =(Mmin(*Vals)).m(3, 1);
-
- deltax =(fabs(maxx - minx) < 1.0e-10) ? 1.1*minx : maxx - minx;
- deltax =((double) xlen) / deltax;
-
- Dispatch->Cleanstack();
- Dispatch->Declevel();
-
- }
-
- void XAxis::Show(boolean gridon)
- {
- char *buf = new char[80];
- setviewport(lmarg, umarg, rmarg, bmarg, 1);
- line(0, ylen, xlen, ylen);
-
-
- int mdelta = w*(maxpr + 2) / 2 + w;
- setviewport(lmarg - mdelta, bmarg, rmarg + mdelta, bmarg + 5*h, 1);
- settextjustify(CENTER_TEXT, TOP_TEXT);
-
- int tickloc;
- for (int i = 1; i <= nvals; i++) {
- double temp = Vals->m(i, 1);
- tickloc = mdelta + (int) (deltax*(temp - minx));
- gcvt(temp, (maxpr + 2), buf);
- outtextxy(tickloc, h, buf);
- line(tickloc + 1, 0, tickloc + 1, h / 2);
- }
-
- if (gridon) {
- setviewport(lmarg - mdelta, umarg, rmarg + mdelta, bmarg, 1);
- setlinestyle(lineinfo.linestyle, lineinfo.upattern, NORM_WIDTH);
- for (int i = 1; i <= nvals; i++) {
- double temp = Vals->m(i, 1);
- tickloc = mdelta + (int) (deltax*(temp - minx));
- line(tickloc + 1, 0, tickloc + 1, ylen);
- }
- setlinestyle(lineinfo.linestyle, lineinfo.upattern, THICK_WIDTH);
- }
-
- setviewport(lmarg, umarg, rmarg, bmarg, 1);
- delete buf;
- }
-
-
- /////////////////////////////// graph matrix class
-
- GMatrix::GMatrix(void)
- {
- title = new strtype;
- title2 = new strtype;
- xname = new strtype;
- yname = new strtype;
- PathToDriver = new strtype;
- hrefs = new double[20];
- vrefs = new double[20];
-
-
- graphnum = 0;
- nhrefs = nvrefs = -1;
- RectangleOn = TTRUE;
- XGridOn = YGridOn = FFALSE;
- grf = new VMatrix("graph", 1, 4);
- }
-
- GMatrix::GMatrix(VMatrix &ROp, int symbol)
- {
- Dispatch->Inclevel();
-
- nvrefs = nhrefs = -1;
-
- title = new strtype;
- *title = ROp.Getname(ROp);
- title2 = new strtype;
- xname = new strtype;
- yname = new strtype;
- PathToDriver = new strtype;
- hrefs = new double[20];
- vrefs = new double[20];
-
- graphnum = 1;
- RectangleOn = TTRUE;
- XGridOn = YGridOn = FFALSE;
- grf = new VMatrix("graph", 1, 4);
- int n = ROp.r;
- printf("\nMaking a Graph\n");
- *grf =
- Ch(Fill(n, 1, (double) graphnum), Ch(Fill(n, 1, (double) symbol), ROp));
- Dispatch->Declevel();
- }
-
- GMatrix::~GMatrix(void)
- {
- delete grf;
- delete title;
- delete title2;
- delete xname;
- delete yname;
- delete PathToDriver;
- delete hrefs;
- delete vrefs;
- }
- void GMatrix::Href(double href)
- {
- hrefs[++ nhrefs % 20] = href;
- }
-
- void GMatrix::Vref(double vref)
- {
- vrefs[++ nvrefs % 20] = vref;
- }
-
-
-
- void GMatrix::AddVec(VMatrix &ROp, int symbol)
- {
- Dispatch->Inclevel();
- VMatrix *temp = new VMatrix;
- graphnum++;
- int n = ROp.r;
- printf("\nAppending a new graph\n");
- *temp =
- Ch(Fill(n, 1, (double) graphnum), Ch(Fill(n, 1, (double) symbol), ROp));
- *grf = Cv(*grf, *temp);
- delete temp;
- Dispatch->Declevel();
- }
-
- int GMatrix::gprintf(int *xloc, int *yloc, char *fmt,...)
- {
- va_list argptr; // Argument list pointer
- char str[140]; // Buffer to build sting into
- int cnt; // Result of SPRINTF for return
-
- va_start(argptr, fmt); // Initialize va_ functions
-
- cnt = vsprintf(str, fmt, argptr); // prints string to buffer
- outtextxy(*xloc, *yloc, str); // Send string in graphics mode
- *yloc += textheight("H") + 2; // Advance to next line
- va_end(argptr); // Close va_ functions
- return (cnt); // Return the conversion count
-
- }
- void GMatrix::Pause(void)
- {
- static char msg[] = "Esc aborts or press a key...";
- int c;
- c = getch();
- if (0x1b == c) {
- closegraph();
- exit(1);
- }
- if (0 == c) {
- c = getch();
- }
- cleardevice();
- restorecrtmode();
- }
-
- void GMatrix::plotpoint(int ix, int iy, int symbol)
- {
- char str[2] = { (char) symbol, '\0' };
- outtextxy(ix, iy, str);
- }
-
- void GMatrix::Show(void)
- {
-
- Dispatch->Inclevel();
- GraphDriver = DETECT;
- // GraphDriver = CGA;
- // GraphMode = CGAHI;
- initgraph(&GraphDriver, &GraphMode, PathToDriver->StringAddress());
- ErrorCode = graphresult();
- if (ErrorCode != grOk) {
- printf(" Graphics System Error: %s\n", grapherrormsg(ErrorCode));
- exit(1);
- }
-
- cleardevice();
-
- MaxX = getmaxx();
- MaxY = getmaxy(); // Read size of screen
-
- getviewsettings(&viewinfo);
- getlinesettings(&lineinfo);
- setcolor(MaxColors - 1);
- MaxColors = getmaxcolor() + 1;
- setcolor(MaxColors - 1);
- //Black on white for screen captures for EGA/VGA
- if (GraphDriver == VGA || GraphDriver == EGA ){
- setbkcolor(WHITE);
- setpalette(1,BLACK);
- setcolor( 1 );
- }
-
- setviewport(0, 0, MaxX, MaxY, 1);
- settextjustify(CENTER_TEXT, CENTER_TEXT);
- int x = MaxX / 2, y = 4;
- gprintf(&x, &y, title->StringAddress());
- gprintf(&x, &y, title2->StringAddress());
- int h = textheight("H");
- int w = textwidth("Z");
- int lmarg = 10*w, rmarg = MaxX - 10 * w, umarg = 5*h, bmarg = MaxY - 5*h;
-
- setviewport(lmarg, umarg - 1, rmarg, bmarg, 1);
- getviewsettings(&viewinfo);
- int xlen = viewinfo.right - viewinfo.left;
- int ylen = viewinfo.bottom - viewinfo.top;
-
- setlinestyle(lineinfo.linestyle, lineinfo.upattern, THICK_WIDTH);
- if (RectangleOn) rectangle(0, 0, xlen, ylen);
-
-
- ///////////// draw axies
- YAxis *yaxis = new YAxis(*grf, xlen, ylen, w, h, bmarg, umarg, lmarg, rmarg);
- yaxis->Show(YGridOn);
-
- XAxis *xaxis = new XAxis(*grf, xlen, ylen, w, h, bmarg, umarg, lmarg, rmarg);
- xaxis->Show(XGridOn);
-
- ////////////// plot points
-
- setlinestyle(lineinfo.linestyle, lineinfo.upattern, NORM_WIDTH);
-
- setviewport(lmarg, umarg, rmarg, bmarg, 1);
- settextjustify(CENTER_TEXT, CENTER_TEXT);
-
- int lx, ly, ix, iy, cnter = 1;
- boolean newgraph = TTRUE;
- double deltax = ((double) xlen) / (xaxis->maxx - xaxis->minx);
- double deltay = ((double) ylen) / (yaxis->maxy - yaxis->miny);
- for (int i = 1; i <= grf-> r; i++) {
- if (cnter != ((int) grf->m(i, 1))) {
- cnter++;
- newgraph = TTRUE;
- }
- double symbol = grf->m(i, 2);
- double tempx = xaxis->Rescale(grf->m(i, 3));
- double tempy = yaxis->Rescale(grf->m(i, 4));
- ix = (int) ((tempx - xaxis->minx) *deltax);
- iy = ylen - (int) ((tempy - yaxis->miny) *deltay);
- plotpoint(ix, iy, abs(symbol));
- if (symbol <= 0.0) {
- if (!newgraph) line(lx, ly, ix, iy);
- newgraph = FFALSE;
- }
- lx = ix;
- ly = iy;
- }
-
- if (nhrefs > - 1) {
- int indx = (nhrefs > 19) ? 19 : nhrefs;
- for (i = 0; i <= indx; i++) {
- double temph = yaxis->Rescale(hrefs[i]);
- iy = ylen -((int) ((temph - yaxis->miny) *deltay));
- line(0, iy, xlen, iy);
- }
- }
- if (nvrefs > - 1) {
- int indx = (nvrefs > 19) ? 19 : nvrefs;
- for (i = 0; i <= indx; i++) {
- double tempv = xaxis->Rescale(vrefs[i]);
- ix = (int) ((tempv - xaxis->minx) *deltax);
- line(ix, 0, ix, ylen);
- }
- }
-
- /////////// display axis labels
- setviewport(0, 0, MaxX, MaxY, 1);
- strtype *ylabel = new strtype;
- *ylabel = yaxis->GetAxisLabel(*yname);
- x = lmarg;
- y = umarg - h - 3;
- gprintf(&x, &y, ylabel->StringAddress());
-
- strtype *xlabel = new strtype;
- *xlabel = xaxis->GetAxisLabel(*xname);
- y = bmarg + 3*h + h / 2 + 2;
- x = MaxX / 2;
- gprintf(&x, &y, xlabel->StringAddress());
-
- Pause();
- delete xaxis;
- delete yaxis;
- delete xlabel;
- delete ylabel;
- Dispatch->Cleanstack();
- Dispatch->Declevel();
-
- }
-