Logo Search packages:      
Sourcecode: gretl version File versions  Download package

laginfo.c

/* for inclusion in interact.c: provides a mechanism for handling
   the fallout from the auto-generation of lags when an estimation
   command using the syntax of "foo(-1)" in the regression list,
   or "foo(-1 to -4)", etc.
*/

struct Laginfo_ {
    int *reflist;
    int *genlist;
    int **lag_lists;
};

#undef LLDEBUG

static Laginfo *list_lag_info_new (void)
{
    Laginfo *linfo = malloc(sizeof *linfo);

    if (linfo != NULL) {
      linfo->reflist = NULL;
      linfo->genlist = NULL;
      linfo->lag_lists = NULL;
    }

    return linfo;
}

static void list_lag_info_destroy (Laginfo *linfo)
{
    if (linfo != NULL) {
      if (linfo->reflist != NULL) {
          int i;

          for (i=0; i<linfo->reflist[0]; i++) {
            free(linfo->lag_lists[i]);
          }
          free(linfo->lag_lists);
          free(linfo->reflist);
      }
      free(linfo->genlist);
      free(linfo);
    }
}

static void cmd_lag_info_destroy (CMD *cmd)
{
    list_lag_info_destroy(cmd->linfo);
    cmd->linfo = NULL;
}

static const int *
get_lag_list_by_varnum (int v, const Laginfo *linfo)
{
    int *list = NULL;

    if (linfo != NULL && linfo->reflist != NULL) {
      int i;
      
      for (i=1; i<=linfo->reflist[0]; i++) {
          if (linfo->reflist[i] == v) {
            list = linfo->lag_lists[i-1];
            break;
          }
      }
    }

    return list;
}

static int add_lagv_to_genlist (int lv, Laginfo *linfo)
{
    int *genlist;
    int n, err = 0;

    if (linfo->genlist != NULL) {
      n = linfo->genlist[0] + 2;
    } else {
      n = 2;
    }

    genlist = realloc(linfo->genlist, n * sizeof *genlist);
    if (genlist != NULL) {
      linfo->genlist = genlist;
      genlist[n - 1] = lv;
      genlist[0] = n - 1;
    } else {
      err = 1;
    }

    return err;
}

static int add_lag_to_laglist (int i, int lag, Laginfo *linfo)
{
    int err = 0;

    if (linfo->lag_lists[i] == NULL) {
      linfo->lag_lists[i] = gretl_list_new(1);
      if (linfo->lag_lists[i] != NULL) {
          linfo->lag_lists[i][1] = lag;
      } else {
          err = 1;
      }
    } else {
      int n = linfo->lag_lists[i][0] + 2;
      int *laglist;

      laglist = realloc(linfo->lag_lists[i], n * sizeof *laglist);
      if (laglist != NULL) {
          linfo->lag_lists[i] = laglist;
          laglist[n - 1] = lag;
          laglist[0] = n - 1;
      } else {
          err = 1;
      }
    }

    return err;
}

static int laginfo_add_lags_list (int n, Laginfo *linfo)
{
    int **llists;
    int err = 0;

    llists = realloc(linfo->lag_lists, n * sizeof *llists);

    if (llists != NULL) {
#if LLDEBUG
      fprintf(stderr, " realloced lag_lists, size %d\n", n);
#endif
      linfo->lag_lists = llists;
      linfo->lag_lists[n - 1] = NULL;
    } else {
      err = 1;
    }

    return err;
}

static int laginfo_expand_reflist (int n, int v, Laginfo *linfo)
{
    int *reflist;
    int l0, err = 0;

    if (linfo->reflist == NULL) {
      l0 = 1;
    } else {
      l0 = linfo->reflist[0] + 1;
    }

#if LLDEBUG
    fprintf(stderr, " now reallocing %p, %d elements\n", 
          (void *) linfo->reflist, n);
#endif

    reflist = realloc(linfo->reflist, n * sizeof *reflist);

    if (reflist != NULL) {
      linfo->reflist = reflist;
      linfo->reflist[0] = l0;
      linfo->reflist[l0] = v;
    } else {
      err = 1;
    }

    return err;
}

static int add_to_list_lag_info (int v, int lag, int lagv, CMD *cmd)
{
    int add_to_reflist = 0;
    int nl, llnum = 0, err = 0;

#if LLDEBUG
    fprintf(stderr, "*** add_to_list_lag_info: v=%d, lag=%d, lagv=%d\n",
          v, lag, lagv);
#endif

    if (cmd->linfo == NULL) {
      cmd->linfo = list_lag_info_new();
      add_to_reflist = 1;
    }

    if (cmd->linfo == NULL) {
      return 1;
    }

    if (!add_to_reflist) {
      if (get_lag_list_by_varnum(v, cmd->linfo) == NULL) {
          /* there's no list already started for this var */
          add_to_reflist = 1;
      }
    }

    if (cmd->linfo->reflist == NULL) {
      nl = 1;
    } else {
      nl = cmd->linfo->reflist[0] + 1;
    }

    if (add_to_reflist) {
      err = laginfo_add_lags_list(nl, cmd->linfo);
      if (!err) {
          err = laginfo_expand_reflist(nl + 1, v, cmd->linfo);
      }
    }

    if (!err) {
      err = add_lagv_to_genlist(lagv, cmd->linfo);
#if LLDEBUG
      fprintf(stderr, " add_lagv_to_genlist: lagv = %d, err = %d\n", 
            lagv, err);
#endif
    }

    if (!err) {
      llnum = cmd->linfo->reflist[0] - 1;
#if LLDEBUG
      printlist(cmd->linfo->reflist, "reflist");
      fprintf(stderr, " llnum = %d\n", llnum);
      fprintf(stderr, " doing add_lag_to_laglist(%d, %d, %p)\n", 
            llnum, lag, (void *) cmd->linfo);
#endif
      err = add_lag_to_laglist(llnum, lag, cmd->linfo);
    }

    return err;
}

static int var_lags_contiguous (const int *laglist)
{
    int i, ret = 1;

    /* actual lags */
    for (i=2; i<=laglist[0]; i++) {
      if (laglist[i] != laglist[i-1] + 1) {
          ret = 0;
          break;
      }
    }

    if (ret == 0) {
      /* check for contiguous leads? */
      int test = 1;

      for (i=2; i<=laglist[0]; i++) {
          if (laglist[i] != laglist[i-1] - 1) {
            test = 0;
            break;
          }
      }
      if (test == 1) {
          ret = 1;
      }
    } 

    return ret;    
}

static const char *lag_sign_str (int lag)
{
    if (lag > 0) return "-";
    if (lag < 0) return "+";
    else return "";
}

/* returns number of bytes printed */

static int print_var_lags (const int *laglist, PRN *prn)
{
    char tmp[32];
    int lag, lsign;
    int lmax = laglist[0];
    int ret = 0;
    
    if (lmax == 1) {
      lsign = laglist[1];
      lag = abs(laglist[1]);
      sprintf(tmp, "(%s%d)", lag_sign_str(lsign), lag);
      ret += pputs(prn, tmp); 
    } else if (var_lags_contiguous(laglist)) {
      /* first lag */
      lsign = laglist[1];
      lag = abs(laglist[1]);
      sprintf(tmp, "(%s%d to ", lag_sign_str(lsign), lag);
      ret += pputs(prn, tmp); 
      /* last lag */ 
      lsign = laglist[lmax];
      lag = abs(laglist[lmax]);
      sprintf(tmp, "%s%d)", lag_sign_str(lsign), lag);
      ret += pputs(prn, tmp); 
    } else {
      int i;

      pputc(prn, '(');
      ret++;
      for (i=1; i<=lmax; i++) {
          lsign = laglist[i];
          lag = fabs(laglist[i]);
          sprintf(tmp, "%s%d", lag_sign_str(lsign), lag);
          ret += pputs(prn, tmp);
          if (i < lmax) {
            ret += pputs(prn, ", ");
          } else {
            pputc(prn, ')');
            ret++;
          }
      }
    }

    return ret;
}

static int 
print_lags_by_varnum (int v, const Laginfo *linfo, int cli, 
                  const DATAINFO *pdinfo, PRN *prn)
{
    PRN *myprn = NULL;
    const int *laglist = NULL;
    int ret = 0;

    if (cli) {
      myprn = gretl_print_new(GRETL_PRINT_STDOUT);
    } else {
      myprn = prn;
    }

    laglist = get_lag_list_by_varnum(v, linfo);
    if (laglist != NULL) {
      pputc(myprn, ' ');
      ret = 1 + pputs(myprn, pdinfo->varname[v]);
      ret += print_var_lags(laglist, myprn);
    } 

    if (cli) {
      gretl_print_destroy(myprn);
    }

    return ret;
}

static int is_auto_generated_lag (int v, const Laginfo *linfo)
{
    int i, ret = 0;

    if (linfo != NULL && linfo->genlist != NULL) {
      for (i=1; i<=linfo->genlist[0]; i++) {
          if (v == linfo->genlist[i]) {
            ret = i;
            break;
          }
      }
    }

    return ret;
}

static int is_first_lag (int v, const Laginfo *linfo, int *src)
{
    int i, j, k = 0, ret = 0;

    for (i=0; i<linfo->reflist[0]; i++) {
      for (j=0; j<linfo->lag_lists[i][0]; j++) {
          k++;
          if (k == v) {
            if (j == 0) {
                ret = 1;
                if (src != NULL) {
                  *src = linfo->reflist[i+1];
                }
            }
            break;
          }
      }
    }

    return ret;
}



          

    

Generated by  Doxygen 1.6.0   Back to index