www.pudn.com > bayes.rar > attmap.c


/*----------------------------------------------------------------------
  File    : attmap.c
  Contents: attribute map management (for symbolic to numeric coding)
  Author  : Christian Borgelt
  History : 11.08.2003 file created
            12.08.2003 function am_cnt added
            10.08.2004 bug concerning marked operation fixed
            11.08.2004 extended to target attribute handling
----------------------------------------------------------------------*/
#include 
#include 
#include 
#include "attmap.h"

/*----------------------------------------------------------------------
  Functions
----------------------------------------------------------------------*/

ATTMAP* am_create (ATTSET *attset, int marked, int trgid)
{                               /* --- create an attribute map */
  int    i, n, off;             /* loop variable, offset */
  int    attcnt = 0;            /* number of attributes */
  ATTMAP *map;                  /* created attribute map */
  ATT    *att;                  /* to traverse the attributes */
  AMEL   *p;                    /* to traverse the map elements */

  assert(attset                 /* check the function argument */
     && (trgid < as_attcnt(attset)));
  for (i = n = as_attcnt(attset); --i >= 0; )
    if ((i == trgid) || !marked || (att_getmark(as_att(attset,i)) >= 0))
      attcnt++;                 /* count the attributes to map */
  map = (ATTMAP*)malloc(sizeof(ATTMAP) +(attcnt-1) *sizeof(AMEL));
  if (!map) return NULL;        /* create an attribute map */
  map->attset = attset;         /* note the attribute set and */
  map->attcnt = attcnt;         /* the number of mapped attributes */
  
  for (p = map->amels, i = off = 0; i < n; i++) {
    if (i == trgid) continue;   /* skip the target attribute and */
    att = as_att(attset, i);    /* traverse the (marked) attributes */
    if (marked && (att_getmark(att) < 0)) continue;
    p->att = att;               /* note the attribute and */
    switch (att_type(att)) {    /* evaluate the attribute type */
      case AT_FLT: p->type = -2;                 p->off = off++; break;
      case AT_INT: p->type = -1;                 p->off = off++; break;
      default    : p->type = att_valcnt(p->att); p->off = off;
                   off += (p->type > 2) ? p->type : 1;           break;
    } p++;                      /* note the type/number of values */
  }
  map->incnt = off;             /* note the number of inputs */

  if (trgid < 0) {              /* if no target is given, abort */
    map->outcnt = 0; return map; }

  p->att = as_att(attset, trgid);
  switch (att_type(p->att)) {   /* evaluate the target attribute type */
    case AT_FLT: p->type = -2; map->outcnt = 1; p->off = off++; break;
    case AT_INT: p->type = -1; map->outcnt = 1; p->off = off++; break;
    default    : p->type = att_valcnt(p->att);  p->off = off;
                 off += map->outcnt = (p->type > 2) ? p->type : 1;
                 break;         /* note the type/number of values */
  }                             /* and set the number of outputs */

  return map;                   /* return the created attribute map */
}  /* am_create() */

/*--------------------------------------------------------------------*/

void am_delete (ATTMAP *map)
{ free(map); }                  /* --- delete an attribute map */

/*--------------------------------------------------------------------*/

int am_cnt (ATTMAP *map, int attid)
{                               /* --- get number of attribute dim. */
  int n = map->amels[(attid < 0) ? map->attcnt -1 : attid].type;
  return (n > 2) ? n : 1;       /* check the attribute type */
}  /* am_cnt() */

/*--------------------------------------------------------------------*/

void am_exec (ATTMAP *map, const TUPLE *tpl, int mode, double *vec)
{                               /* --- execute an attribute map */
  int        k = 0, n, v;       /* loop variables, buffer */
  AMEL       *p;                /* to traverse the map elements */
  const INST *inst;             /* to traverse the instantiations */

  assert(map && vec);           /* check the function arguments */
  if (map->outcnt > 0) { k = map->attcnt -1; }
  else                 { k = map->attcnt; mode &= AM_INPUTS; }
  p = map->amels;               /* get the number of input attributes */
  if      (mode & AM_INPUTS) { if (mode & AM_TARGET) k++; }
  else if (mode & AM_TARGET) { p += k; k = 1; }
  else return;                  /* get the attribute range */
  while (--k >= 0) {            /* traverse the attributes */
    inst = (tpl) ? tpl_colval(tpl, att_id(p->att)) : att_inst(p->att);
    n    = (p++)->type;         /* get the attribute instantiation */
    if      (n <  0) {          /* if the attribute is numeric */
      *vec++ = (n < -1) ? inst->f : inst->i; }
    else if (n <= 2) {          /* if the attribute is binary, */
      v = inst->i;              /* set the value directly */
      *vec++ = ((v >= 0) && (v < n)) ? v : 0.5; }
    else {                      /* if the attribute is symbolic */
      for (v = n; --v >= 0; )  vec[v] = 0;
      v = inst->i;              /* clear all fields */
      if ((v >= 0) && (v < n)) vec[v] = 1;
      vec += n;                 /* get the symbolic value and */
    }                           /* set the corresponding field */
  }                             /* set input and target values */
}  /* am_exec() */