Logo Search packages:      
Sourcecode: gretl version File versions

compat.c

/* 
 *  gretl -- Gnu Regression, Econometrics and Time-series Library
 *  Copyright (C) 2001 Allin Cottrell and Riccardo "Jack" Lucchetti
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */

#include "libgretl.h"
#include "libset.h"
#include "gretl_scalar.h"
#include "compat.h"

/*
    compat.c - older functions retained for backward compatibility
*/

/* ASCII graphics */

static void initpx (int n, char *pp)
{
    int i;

    pp[0] = '|';
    for (i=1; i<=n; i++) {
      pp[i] = ' ';
    }
    pp[n + 1] = '\n';
}

static void drawline (int n, PRN *prn)
{
    int t;

    pputs(prn, "       |+");
    for (t=1; t<=n; t++) {
      pputc(prn, (t % 10)? '-' : '+');
    }
    pputc(prn, '\n');
}

static void prntdate (int nt, int n, const DATAINFO *pdinfo, PRN *prn)
{
    if (n != pdinfo->t2 - pdinfo->t1 + 1) {
      pprintf(prn, "%5d  ", nt);
    } else {
      double xx = date(nt, pdinfo->pd, pdinfo->sd0);

      if (pdinfo->pd == 1) {
          pprintf(prn, "%5.0f ", xx);
      } else if (pdinfo->pd < 10) {
          pprintf(prn, "%5g ", xx);
      } else {
          pprintf(prn, "%6.2f", xx);
      }
    }
}

static void printgx (double x, PRN *prn)
{
    char word[32];
    int lw;

    sprintf(word, "%11g", x);
    lw = strlen(word);
    pputs(prn, word);
    bufspace(13 - lw, prn);
} 

static int z_to_xy (int v1, int v2, double *x, double *y, 
                const double **Z, const DATAINFO *pdinfo)
{
    int t, m = 0;

    for (t=pdinfo->t1; t<=pdinfo->t2; t++)  {
      if (na(Z[v1][t]) || na(Z[v2][t])) {
          continue;
      }
      x[m] = Z[v1][t];
      y[m] = Z[v2][t];
      m++;
    }

    return m;
}

static int z_to_xyz (int v1, int v2, int v3, 
                 double *x, double *y, double *z,
                 const double **Z, const DATAINFO *pdinfo)
{
    int t, m = 0;

    for (t=pdinfo->t1; t<=pdinfo->t2; t++)  {
      if (na(Z[v1][t]) || na(Z[v2][t]) || na(Z[v3][t])) {
          continue;
      }
      x[m] = Z[v1][t];
      y[m] = Z[v2][t];
      z[m] = Z[v3][t];
      m++;
    }

    return m;
}

/* graph one or two y variables against a given x variable */

static int graphyzx (const double *y1, const double *y2, const double *x, 
                 int n, const char *yname, const char *y2name,
                 const char *xname, gretlopt opt, PRN *prn)
{
    int ix, iy1, iy2, lx, ly, xzero, yzero;
    int nrows, nr2, nc2, ls, lw, t1, t2;
    double xx, xmin, xmax, xrange;
    double ymin, ymax, yrange;
    int ncols = 60;
    char p[41][132];
    char word[32];
    int i, j;

    t1 = 0;
    t2 = n - 1;

    if (y2 != NULL) {
      double y1min, y1max;
      double y2min, y2max;

      gretl_minmax(t1, t2, y1, &y1min, &y1max);
      gretl_minmax(t1, t2, y2, &y2min, &y2max);
      ymin = (y1min < y2min)? y1min : y2min;
      ymax = (y1max > y2max)? y1max : y2max;
    } else {
      gretl_minmax(t1, t2, y1, &ymin, &ymax);
    }

    if (na(ymin) || na(ymax)) {
      return E_MISSDATA;
    }

    yrange = ymax - ymin;
    xzero = yzero = 0;

    /* set the number of rows to be used */
    if (opt & OPT_O) {
      nrows = 40;
    } else {
      nrows = (y2 != NULL)? 16 : 18;
    }

    nr2 = nrows / 2;
    nc2 = ncols / 2;

    gretl_minmax(t1, t2, x, &xmin, &xmax);

    if (na(xmin) || na(xmax)) {
      return E_MISSDATA;
    }    

    xrange = xmax - xmin;

    /* Initialize picture matrix */

    for (i=0; i<=nrows; i++) {
      p[i][0] = (i % 5 == 0)? '+' : '|'; 
      for (j=1; j<=ncols+1; j++) {
          p[i][j] = ' ';
      }
    }

    if (xmin < 0 && xmax > 0) {
      xzero = 0.5 - xmin * ncols / xrange;
      for (i=0; i<=nrows; i++) {
          p[i][xzero+1] = '|';
      }
    }

    if (ymin < 0 && ymax > 0) {
      yzero = 0.5 - ymin * nrows / yrange;
      for (j=0; j<=ncols; j++) {
          p[yzero][j+1] = '-';
      }
    }

    /* replace blanks in PICTURE with o's that correspond to the
       scaled values of the specified variables */

    if (y2 != NULL) {
      for (i=0; i<n; i++) {
          ix = (floatneq(xrange, 0.0))? ((x[i] - xmin)/xrange) * ncols : nc2;
          iy1 = (floatneq(yrange, 0.0))? ((y1[i] - ymin)/yrange) * nrows : nr2;
          iy2 = (floatneq(yrange, 0.0))? ((y2[i] - ymin)/yrange) * nrows : nr2;
          if (iy1 != iy2) {
            p[iy1][ix+1] = 'o';
            p[iy2][ix+1] = 'x';
          } else {
            p[iy1][ix+1] = '+';
          }
      }
    } else {
      for (i=0; i<n; i++) {
          ix = (floatneq(xrange, 0.0))? ((x[i] - xmin)/xrange) * ncols : nc2;
          iy1 = (floatneq(yrange, 0.0))? ((y1[i] - ymin)/yrange) * nrows : nr2;
          p[iy1][ix+1] = 'o';
      }
    }

    /* print out the 2-dimensional picture matrix */

    if (y2name == NULL) {
      pprintf(prn, "  %s\n", yname);
    } else {
      pputs(prn, "  ");
      pprintf(prn, _("'o' stands for %s and 'x' stands for %s (+ means they "
                   "are equal)"), yname, y2name);
      pprintf(prn, "\n\n  %s, %s\n", yname, y2name);
    }

    for (i=nrows; i>=0; i--) {
      if (i && i == yzero) {
          pputs(prn, "        0.0  ");
      } else if (i == nrows || i % 5 == 0) {
          xx = ymin + ((ymax - ymin) * i/nrows);
          printgx(xx, prn);
      } else {
          bufspace(13, prn);
      }
      for (j=0; j<=ncols+1; j++) {
          pputc(prn, p[i][j]);
      }
      pputc(prn, '\n');
    }

    bufspace(13, prn);
    pputc(prn, '|');
    for (j=0; j<=ncols; j++) {
      pputc(prn, (j % 10)? '-' : '+');
    }

    pputc(prn, '\n');
    bufspace(14, prn);

    sprintf(word, "%g", xmin);
    lx = strlen(word);
    lw = 13 + lx;
    pputs(prn, word);

    sprintf(word, "%s", xname);
    ly = strlen(word);
    ls = 30 - lx - ly / 2;
    bufspace(ls, prn);
    pputs(prn, word);

    lw = lw + ls + ly; 

    sprintf(word, "%g", xmax);
    ls = strlen(word);
    if (ls < 7) {
      bufspace(73 - lw, prn);
    } else { 
      lw = lw + ls;
      bufspace(79 - lw, prn);
    }
    pprintf(prn, "%s\n\n", word);

    return 0;
}

/**
 * graphyx:
 * @y: y-axis data.
 * @x: x-axis data.
 * @n: number of observations.
 * @yname: y-axis label.
 * @xname: x-axis label.
 * @prn: gretl printing struct.
 *
 * Generates a simple ascii scatter-plot of @y against @x and 
 * prints the plot to @prn.
 *
 * Returns: 0 on successful completion, error code on error.
 */

int graphyx (const double *y, const double *x, int n,
           const char *yname, const char *xname, 
           PRN *prn)
{
    return graphyzx(y, NULL, x, n, yname, NULL, xname, 
                OPT_NONE, prn);
}

/* OPT_O: force the two variables to be plotted on the same; 
   otherwise they are scaled to fit
*/

static int ascii_plot (const int *list, const double **Z, 
                   const DATAINFO *pdinfo, gretlopt opt, 
                   PRN *prn)
{
    int i, nc2, vy, vz, cntrline;
    int ix = 0, iy = 0, iz = 0, n = 0;
    int ncols = 70;
    int ls, t, t1 = pdinfo->t1, t2 = pdinfo->t2;
    char word[32], px[132];
    char s1[10], s2[10];
    double xmin, xmax, xrange, ymin, ymax, yrange, xymin, xymax; 
    double xyrange, xx, yy;
    double *x, *y;

    x = malloc(pdinfo->n * sizeof *x);
    y = malloc(pdinfo->n * sizeof *y);

    if (x == NULL || y == NULL) {
      return E_ALLOC;
    }

    pputc(prn, '\n');

    nc2 = ncols / 2;
    vy = list[1];
    strcpy(s1, pdinfo->varname[vy]);

    if (list[0] == 1) {
      /* only one variable is to be plotted */
      n = ztox(vy, x, Z, pdinfo);
      gretl_minmax(t1, t2, x, &xmin, &xmax);
      xrange = xmax - xmin;
      cntrline = (floatgt(xmax, 0) && floatlt(xmin, 0))? 1 : 0;

      /* print headings */
      pprintf(prn, _("%25cNOTE: o stands for %s\n\n%8c"), ' ', s1, ' ');

      sprintf(word, "x-min = %g", xmin);
      ls = 8 + strlen(word);
      pputs(prn, word);

      sprintf(word, "x-max = %g", xmax);
      ls = 78 - ls - strlen(word);
      bufspace(ls, prn);
      pprintf(prn, "%s\n", word); 

      if (cntrline) {
          iy = -(xmin / xrange) * ncols;
          bufspace(iy + 7, prn);
          pputs(prn, "0.0\n"); 
      }

      drawline(ncols, prn);

      gretl_push_c_numeric_locale();

      for (t=t1; t<=t2; ++t) {
          xx = Z[vy][t];
          if (na(xx)) {
            continue;
          }
          prntdate(t, n, pdinfo, prn);
          ix = (floatneq(xrange, 0.0))? ((xx-xmin)/xrange) * ncols : nc2;
          initpx(ncols, px);
          if (cntrline) {
            px[iy+1] = '|';
          }
          px[ix+1] = 'o';
          for (i=0; i<=ncols+1; i++) {
            pprintf(prn, "%c", px[i]); 
          }
          if (ix == ncols) {
            pputc(prn, '\n');
          }
      }

      gretl_pop_c_numeric_locale();

      pputs(prn, "\n\n");

      free(x);
      free(y);

      return 0;
    }

    /* two variables are to be plotted */
    vz = list[2];
    strcpy(s2, pdinfo->varname[vz]);
    n = z_to_xy(vy, vz, x, y, Z, pdinfo);

    /* find maximum and minimum using all values from both arrays */
    gretl_minmax(t1, t2, x, &xmin, &xmax);
    xrange = xmax - xmin;
    gretl_minmax(t1, t2, y, &ymin, &ymax);
    yrange = ymax - ymin;
    xymin = (xmin <= ymin) ? xmin : ymin;
    xymax = (xmax >= ymax) ? xmax : ymax;
    xyrange = xymax - xymin;

    /* print headings for the two variables */
    pprintf(prn, _("%17cNOTE: o stands for %s,   x stands for %s\n%17c+ means %s "
         "and %s are equal when scaled\n"), ' ', s1, s2, ' ', s1, s2);

    if (opt & OPT_O) {
      pprintf(prn, _("%20c%s and %s are plotted on same scale\n\n%8c"),
             ' ', s1, s2, ' ');

      sprintf(word, "xy-min = %g", xymin);
      ls = 8 + strlen(word);
      pputs(prn, word);

      sprintf(word, "xy-max = %g", xymax);
      ls = 78 - ls - strlen(word);
      bufspace(ls, prn);
      pprintf(prn, "%s\n", word);
    } else {
      pputc(prn, '\n');

      sprintf(word, "        o-min = %g", ymin);
      ls = strlen(word);
      pputs(prn, word);

      sprintf(word, "o-max = %g", ymax);
      ls = 78 - ls - strlen(word);
      bufspace(ls, prn);
      pprintf(prn, "%s\n", word);

      sprintf(word, "        x-min = %g", xmin);
      ls = strlen(word);
      pputs(prn, word);

      sprintf(word, "x-max = %g", xmax);
      ls = 78 - ls - strlen(word);
      bufspace(ls, prn);
      pprintf(prn, "%s\n", word);
    }

    /*  First x and y values are scaled, then we check to see which scaled
      value is smaller: print that one first, then print the larger
      scaled value. If the scaled values are equal then print a "+" ,
      otherwise print an "x" for the first variable and an "o" for the
      second variable.
    */

    pputc(prn, '\n');

    cntrline = (floatgt(xymax, 0) && floatlt(xymin, 0))? 1 : 0;
    if (cntrline) {
      iz = (-xymin / xyrange) * ncols;
      bufspace(iz + 7, prn);
      pputs(prn, "0.0\n");
    }

    drawline(ncols, prn);

    gretl_push_c_numeric_locale();

    for (t=t1; t<=t2; ++t) {

      xx = Z[vy][t];
      yy = Z[vz][t];

      if (na(xx) || na(yy)) {
          continue;
      }

      prntdate(t, n, pdinfo, prn);

      if (opt & OPT_O) {
          ix = (floatneq(xyrange, 0.0))? ((xx-xymin)/xyrange) * ncols : nc2;
          iy = (floatneq(xyrange, 0.0))? ((yy-xymin)/xyrange) * ncols : nc2;
      } else {
          ix = (floatneq(xrange, 0.0))? ((xx-xmin)/xrange) * ncols : nc2;
          iy = (floatneq(yrange, 0.0))? ((yy-ymin)/yrange) * ncols : nc2;
      }

      initpx(ncols, px);

      if (iz) {
          px[iz+1] = '|';
      }

      if (ix == iy) {
          px[ix+1] = '+';
      } else {
          px[ix+1] = 'o';
          px[iy+1] = 'x';
      }

      for (i=0; i<=ncols+1; i++) {
          pprintf(prn, "%c", px[i]);
      }

      if (ix == ncols || iy == ncols) {
          pputc(prn, '\n');
      }
    }

    gretl_pop_c_numeric_locale();

    pputs(prn, "\n\n");

    free(x);
    free(y);

    return 0;
}

/**
 * ascii_graph:
 * @list: contains ID numbers of variables to graph.
 * @Z: data matrix.
 * @pdinfo: data information struct.
 * @opt: if includes OPT_O, use 40 rows, otherwise use 20 rows;
 * if includes OPT_T do a time-series plot.
 * @prn: gretl printing struct.
 *
 * Graph (using ascii graphics) one variable against another, as given
 * in @list: by default, the first variable will appear on the y-axis, 
 * the second on the x-axis.  But if @opt contains %OPT_T the listed
 * variables will be plotted against time (or by observation).
 *
 * Returns: 0 on successful completion, error code on error.
 */

int ascii_graph (const int *list, const double **Z, const DATAINFO *pdinfo, 
             gretlopt opt, PRN *prn)
{
    int T = sample_size(pdinfo);
    int vx, vy1, vy2 = -1;
    double *x = NULL;
    double *y1 = NULL;
    double *y2 = NULL;
    int err = 0;

    if (opt & OPT_T) {
      return ascii_plot(list, Z, pdinfo, opt, prn);
    }

    if (list[0] < 2) {
      return E_ARGS; 
    }

    x = malloc(T * sizeof *x);
    y1 = malloc(T * sizeof *y1);

    if (x == NULL || y1 == NULL) {
      free(x);
      free(y1);
      return E_ALLOC;    
    }

    if (list[0] > 2) {
      y2 = malloc(T * sizeof *y2);
      if (y2 == NULL) {
          free(x);
          free(y1);
          return E_ALLOC;    
      }
    }

    vy1 = list[1];

    /* Put values from Z array into x and y arrays */
    if (list[0] == 2) {
      vx = list[2];
      T = z_to_xy(vx, vy1, x, y1, Z, pdinfo);
    } else {
      vy2 = list[2];
      vx = list[3];
      T = z_to_xyz(vx, vy1, vy2, x, y1, y2, Z, pdinfo);
    }

    pputc(prn, '\n');

    err = graphyzx(y1, y2, x, T, pdinfo->varname[vy1], 
               (vy2 < 0)? NULL : pdinfo->varname[vy2], 
               pdinfo->varname[vx], opt, prn);

    pputc(prn, '\n');

    free(x); 
    free(y1); 
    free(y2);

    return err;
}

Generated by  Doxygen 1.6.0   Back to index