Ejemplo n.º 1
0
nialptr
arithconvert(nialptr x, int *newk)
{
  int         k,
              ki,
              changed;
  nialint     i,
              t = tally(x);
  nialptr     z,
              x0,
              xi;

  if (t == 0) { /* x is empty */
    *newk = kind(x);
    return (x);
  }

  /* set k based on kind of first item */
  x0 = fetch_array(x, 0);    /* first item */
  k = kind(x0);

  /* loop to find maximum kind in x */
  for (i = 1; i < t; i++) {  
    xi = fetch_array(x, i);
    ki = kind(xi);
    if (ki > k)
      k = ki;
  }

  /* convert to highest kind */
  changed = true;
  if (homotype(k) && k != chartype) {
    switch (k) {
      case inttype:
          z = to_int(x);
          break;

      case realtype:
          z = to_real(x);
          break;
      default:

          z = x;
          changed = false;
          break;
    }
  }
  else {
    z = x;
    changed = false;
  }

  if (changed)               /* argument has been converted */
    freeup(x);
  *newk = k;
  return (z);
}
Ejemplo n.º 2
0
void
iloaddefs(void)
{
  nialptr     nm,
              x = apop();
  int         mode;

  /* get the file name as a Nial array */
  if (atomic(x) || kind(x) == chartype)
    nm = x;
  else if (kind(x) == atype)
    nm = fetch_array(x, 0);
  else {
    buildfault("invalid file name");
    freeup(x);
    return;
  }

  mode = 0;  /* default to silent mode */
  if (kind(x) == atype && tally(x) == 2) {
    /* argument has a mode filed, select it */
    nialptr     it = fetch_array(x, 1);

    if (kind(it) == inttype)
      mode = intval(it);
    if (kind(it) == booltype)
      mode = boolval(it);
  }

  /* try to put filename into gcharbuf */
  if (!ngetname(nm, gcharbuf)) {
    buildfault("invalid file name");
    freeup(x);
  }

  else 
  { /* check the extension as .ndf */
    check_ext(gcharbuf, ".ndf",NOFORCE_EXTENSION);
    freeup(x);      /* do freeup here so file name doesn't show in iusedspace */

    /* load the definition file */
    if (loaddefs(true, gcharbuf, mode)) {
      apush(Nullexpr);
    }
    else
      buildfault(errmsgptr); /* this is safe since call is from iloaddefs */
  }

#ifdef DEBUG
  memchk();
#endif
}
Ejemplo n.º 3
0
nialptr
testfaults(nialptr x, nialptr stdfault)
{
  int         found = false;
  nialint     t = tally(x),
              i = 0;
  nialptr     xi = Null,
              z;

  /* find first fault */
  while (!found && i < t) {
    xi = fetch_array(x, i++);
    if (kind(xi) == chartype || kind(xi) == phrasetype)
      return (stdfault);     /* result is stdfault if other literal types occur */
    found = kind(xi) == faulttype;

  }

  if (!found)
    return (stdfault);       /* used in "and" and "or" in cases like "and o -12" */

  z = xi;
#ifdef V4AT
  if (stdfault==Logical)
  { /* Logical faults are different in V4 */
    i = 0;  /* scan all the items */
    /* find other faults and compare */
    while (i < t) {
      xi = fetch_array(x, i++);
      if ((kind(xi) == faulttype && z != xi) || kind(xi) != faulttype)
         /* result is stdfault if fault value changes or other type */
        return (stdfault);
    }	
  }
  else
#endif

  /* find other faults and compare */
  { while (i < t) {
      xi = fetch_array(x, i++);
      if ((kind(xi) == faulttype && z != xi) || kind(xi) == chartype ||
          kind(xi) == phrasetype) /* result is stdfault if fault value changes
                                     or other literal type */
        return (stdfault);
    }
  }
  freeup(stdfault);   /* since this is a temporary and not used */
  return (z);
}
Ejemplo n.º 4
0
nialptr
to_real(nialptr x)
{
  nialptr     z,
              xi;
  nialint     i,
              t = tally(x);
  int         v = valence(x);
  double      r = 0.0;

  /* create the result container */
  z = new_create_array(realtype, v, 0, shpptr(x, v));
  for (i = 0; i < t; i++) {
    int         k;

    xi = fetch_array(x, i);
    k = kind(xi);
    if (k == realtype)
      r = *pfirstreal(xi);

    else  /* must be boolean or integer */ 
    if (k == inttype)
      r = 1.0 * intval(xi);

    else 
    if (k == booltype)
      r = 1.0 * boolval(xi);
    store_real(z, i, r);
  }
  return (z);
}
Ejemplo n.º 5
0
/*
;@cc_solv(a, b, n)
;@     Solve a general linear system  A*x = b.
; 
;     int solv(double a[],double b[],int n)
;
;       a = array containing system matrix A in row order
;            (altered to L-U factored form by computation)
;
;       b = array containing system vector b at entry and
;           solution vector x at exit
;
;       n = dimension of system
;@
;@
*/
static LISP cc_solv1(LISP a1, LISP a2, LISP b1, LISP b2)
{
	int row, col, sheet;
	buffer *buf;
	int ax1 = get_c_long(CAR(a1)), ay1 = get_c_long(CDR(a1));
	int ax2 = get_c_long(CAR(a2)), ay2 = get_c_long(CDR(a2));
	int bx1 = get_c_long(CAR(b1)), by1 = get_c_long(CDR(b1));
	int bx2 = get_c_long(CDR(b2)), by2 = get_c_long(CDR(b2));
	int n = by2-by1+1;
	double *a = fetch_array(ax1, ay1, ax2, ay2);
	double *b = fetch_array(bx1, by1, bx2, by2);
	if (a == NULL || b == NULL || solv(a, b, n) == 0) return NIL;
	get_siod_coords(&row, &col, &sheet, &buf);
	store_array(row, col, row+n-1, col, b);
	return flocons(b[0]);
}
Ejemplo n.º 6
0
nialptr
testbinfaults(nialptr x, nialptr stdfault, int divflag)
{
  nialptr     x0 = fetch_array(x, 0),
              x1 = fetch_array(x, 1);

  switch (kind(x0)) {
    case booltype:
    case inttype:
    case realtype:
        freeup(stdfault);
        return (x1);
    case chartype:
    case phrasetype: /* fall out to return stdfault */
        break;
    case faulttype:
        switch (kind(x1)) {
          case booltype:
              if (divflag && boolval(x1) == 0)
                break;
              freeup(stdfault);
              return (x0);
          case inttype:
              if (divflag && intval(x1) == 0)
                break;
              freeup(stdfault);
              return (x0);
          case realtype:
              if (divflag && realval(x1) == 0.0)
                break;
              freeup(stdfault);
              return (x0);
          case chartype:
          case phrasetype:
              break;
          case faulttype:
              if (x0 == x1) {
                freeup(stdfault);
                return (x0);
              }
              break;
        }
  }
  return (stdfault);
}
Ejemplo n.º 7
0
static      nialptr
to_int(nialptr x)
{
  nialptr     z,
              xi;
  nialint     i,
              t = tally(x);
  int         v = valence(x);

  /* create the result container */
  z = new_create_array(inttype, v, 0, shpptr(x, v));
  for (i = 0; i < t; i++) {
    xi = fetch_array(x, i);
    if (kind(xi) == inttype) {
      copy1(z, i, xi, 0);
    }
    else   /* type must be boolean */
      store_int(z, i, boolval(xi));
  }
  return (z);
}
Ejemplo n.º 8
0
void
ifromraw(void)
{
  nialptr     z = apop();
  nialptr     res;
  int         slen;
  int         totype;
  int         dataerror = 0;
  int         numelements;
  nialptr     bools;

  if (tally(z) != 2) {
    apush(makefault("?Must supply a type and a value to fromraw"));
    freeup(z);
    return;
  }

  totype = kind(fetch_array(z, 0));

  if (totype == atype) {
    apush(makefault("?fromraw cannot convert to a nested array"));
    freeup(z);
    return;
  }

  bools = fetch_array(z, 1);

  if ((kind(bools) != booltype)) {
    apush(makefault("?Must supply a Boolean value to fromraw"));
    freeup(z);
    return;
  }

  /* no conversion needed */
  if (totype == booltype) {
    apush(bools);
    freeup(z);
    return;
  }

  /* compute number of elements by type and validate length of bools */
  slen = 0;
  switch (totype) {
    case inttype:
        numelements = tally(bools) / sizeof(int);
        if (tally(bools) % sizeof(int) != 0)
          dataerror = 1;
        break;
    case realtype:
        numelements = tally(bools) / sizeof(double);
        if (tally(bools) % sizeof(double) != 0)
          dataerror = 1;
        break;
    case phrasetype:
    case faulttype:
        slen = tally(bools) / sizeof(char);
        numelements = 1;
    case chartype:
        numelements = tally(bools) / sizeof(char);
        break;
  }

  numelements /= 8;

  if (dataerror) {
    apush(makefault("?fromraw must have correct multiple of bools for desired datatype"));
    freeup(z);
    return;
  }

  /* create the result copy */
  res = new_create_array(totype, 1, slen, &numelements);

  /* do the data copy */
  switch (totype) {
    case inttype:
        memcpy(pfirstchar(res), pfirstchar(bools), tally(bools) / 8);
        break;
    case realtype:
        memcpy_fwo(pfirstchar(res), pfirstchar(bools), tally(bools) / 8, MCPY_FROMRAW);
        break;

        /* Have to use strncpy here to preserve the data */
    case chartype:
    case phrasetype:
    case faulttype:
        memcpy_fbo(pfirstchar(res), pfirstchar(bools), tally(bools) / 8, MCPY_FROMRAW);
        break;
  }


  if (totype == chartype)
    *(pfirstchar(res) + numelements) = '\0';

  apush(res);
  freeup(z);
  return;

}
Ejemplo n.º 9
0
void
iregisterdllfun(void)
{
  int         i,
              index;
  ResType     argtypes[MAX_ARGS];  /* list of types of arguments */
  bool        vararg[MAX_ARGS];    /* is the argument a variable arg */
  bool        ispointer[MAX_ARGS]; /* is the argument a pointer */
  int         varargcount = 0;     /* number of variable args */
  int         ispointercount = 0;  /* number of pointer args */
  nialptr     z = apop();
  char       *nialname;            /* names used by calldllfun */
  char       *dllname;             /* the real name of the function */
                                   /* in the DLL file */
  char       *library;             /* name of the DLL file */
  ResType     resulttype;          /* the type of the result */
  nialptr     nargtypes;           /* the arg type array */
  int         argcount;
  int         j;
  int         sz;
  nialptr     current;       /* usually hold the current entry in the dlllist */
  int         is_register;

  /* if we have 5 args we are registering a function */

  if ((tally(z) == 5) && (kind(z) == atype))
    is_register = 1;         /* register mode */

  else 
  /* only one arg and it is a char or a phrase, we are deleting the fun */
  if ((kind(z) == chartype) || (kind(z) == phrasetype))
    is_register = 0;         /* delete mode */

  else {                     /* error mode */
    apush(makefault("?Incorrect number of arguments to registerdllfun"));
    freeup(z);
    return;
  }

  if (is_register) {
    /* The Nial level name for the DLL function */
    STRING_CHECK(z, 0)
      nialname = STRING_GET(z, 0);


    /* The internal DLL name for the function */
    STRING_CHECK(z, 1)
      dllname = STRING_GET(z, 1);

    /* The name of the library file */
    STRING_CHECK(z, 2)
      library = STRING_GET(z, 2);

    /* The name of the result type */
    STRING_CHECK(z, 3)
      resulttype = StringToTypeID(STRING_GET(z, 3));

    /* did we find an unrecognized result type? */
    if (resulttype < 0) {
      apush(makefault("?Return type not recognized"));
      freeup(z);
      return;
    }

    if (kind(fetch_array(z, 4)) != atype) {
      apush(makefault("?Argument must be a list of strings or phrases"));
      freeup(z);
      return;
    }

    nargtypes = fetch_array(z, 4);
    argcount = tally(nargtypes);

    /* Check each of the argument type */
    for (j = 0; j < argcount; j++)
      STRING_CHECK_FREEUP(nargtypes, j, z)
      /* create an integer list of argument types from the phrase/string list */
        for (i = 0; i < argcount; i++) {
        char       *tmp;

        tmp = pfirstchar(fetch_array(nargtypes, i));  /* safe: no allocation */
        argtypes[i] = StringToTypeID(tmp);

        /* the ith argument name was not recognized */
        if (argtypes[i] < 0) {
          char        stmp[256];

          wsprintf(stmp, "?Type \"%s\" for argument %d not recognized", tmp, i + 1);
          apush(makefault(stmp));
          freeup(z);
          return;
        }
        /* set the vararg and ispointer flags for this arg */
        vararg[i] = IsVarArg(tmp);
        ispointer[i] = IsPointer(tmp);
        /* keep count of these special args */
        if (vararg[i])
          varargcount++;
        if (ispointer[i])
          ispointercount++;
      }

    /* NEW workspace Version */

    /* If the list does not yet exist, then create a one element list here */
    if (tally(dlllist) == 0) {
      nialptr     tmp = create_new_dll_entry; /* build a empty entry */

      setup_dll_entry(tmp)   /* fill it with empty data */
        apush(tmp);
      isolitary();           /* make it a list */
      decrrefcnt(dlllist);
      freeup(dlllist);
      dlllist = apop();
      incrrefcnt(dlllist);
      index = 0;
    }
    else {
      int         pos;

      /* does the requested name already exist in out list? */
      if ((pos = inlist(nialname)) >= 0) {
        /* yes it's here already, so note its position, and free the old
         * entry */
        index = pos;
        freeEntry(index);
      }
      else {
        /* if we got here, then we need to create a new entry and add it to
         * and existing dlllist */
        nialptr     tmp = create_new_dll_entry;

        setup_dll_entry(tmp)
          decrrefcnt(dlllist);
        append(dlllist, tmp);
        dlllist = apop();
        incrrefcnt(dlllist);
        index = tally(dlllist) - 1; /* this is the location of the new entry */
      }
    }



    /* grab the entry to work on */
    current = fetch_array(dlllist, index);

    /* fill in data */
    set_handle(current, NULL);
    set_nialname(current, nialname);
    set_dllname(current, dllname);
    set_callingconvention(current, (dllname[0] == '_' ? C_CALL : PASCAL_CALL));
    set_library(current, library);
    set_isloaded(current, false);
    set_resulttype(current, resulttype);
    set_argcount(current, argcount);
    set_varargcount(current, varargcount);
    set_ispointercount(current, ispointercount);

    sz = argcount;
    replace_array(current, 10, (sz == 0 ? Null : new_create_array(inttype, 1, 0, &sz)));
    for (j = 0; j < sz; j++)
      set_argtypes(current, j, argtypes[j]);

    replace_array(current, 11, (sz == 0 ? Null : new_create_array(booltype, 1, 0, &sz)));
    for (j = 0; j < sz; j++)
      set_ispointer(current, j, ispointer[j]);

    replace_array(current, 14, (sz == 0 ? Null : new_create_array(booltype, 1, 0, &sz)));
    for (j = 0; j < sz; j++)
      set_vararg(current, j, vararg[j]);
  }
  else { /* delete entry code */
Ejemplo n.º 10
0
void
iinnerproduct()
{
  nialptr     z,
              a,
              b,
              x;
  int         va,
              vb,
              vx,
              replicatea,
              replicateb;
  nialint     m,
              n,
              bn,
              p,
              i,
              j,
              k,
              sh[2];

  double      sum,
             *ap,
             *bp,
             *xp;

  z = apop();
  if (tally(z) != 2) {
    buildfault("arg to innerproduct not a pair");
    freeup(z);
    return;
  }
  splitfb(z, &a, &b);
  va = valence(a);
  vb = valence(b);
  if (va > 2 || vb > 2) {
    buildfault("incorrect valence in innerproduct");
    freeup(a);
    freeup(b);
    freeup(z);
    return;
  }
  /* ensure b is realtype */
  switch (kind(b)) {
    case booltype:
        b = bool_to_real(b);
        break;
    case inttype:
        b = int_to_real(b);
        break;
    case realtype:
        break;
    case chartype:
    case phrasetype:
    case faulttype:
        {
          buildfault("second arg not numeric type in innerproduct");
          freeup(a);
          freeup(b);
          freeup(z);
          return;
        }
    case atype:
        {
          nialint     i = 0;

          if (!simple(b)) {
            buildfault("arg not simple in innerproduct");
            freeup(a);
            freeup(b);
            freeup(z);
            return;
          }
          while (i < tally(b)) {
            if (!numeric(kind(fetch_array(b, i)))) {
              buildfault("second arg not numeric type in innerproduct");
              freeup(a);
              freeup(b);
              freeup(z);
              return;
            }
            i++;
          }
          b = to_real(b);    /* safe because freeup(z) will clear old b */
        }
  }
  /* ensure a is realtype */
  switch (kind(a)) {
    case booltype:
        a = bool_to_real(a);
        break;
    case inttype:
        a = int_to_real(a);
        break;
    case realtype:
        break;
    case chartype:
    case phrasetype:
    case faulttype:
        {
          buildfault("first arg not numeric type in innerproduct");
          freeup(a);
          freeup(b);
          freeup(z);
          return;
        }
    case atype:
        {
          nialint     i = 0;

          if (!simple(a)) {
            buildfault("first arg not simple in innerproduct");
            freeup(a);
            freeup(b);
            freeup(z);
            return;
          }
          while (i < tally(a)) {
            if (!numeric(kind(fetch_array(a, i)))) {
              buildfault("first arg not numeric type in innerproduct");
              freeup(a);
              freeup(b);
              freeup(z);
              return;
            }
            i++;
          }
          a = to_real(a);    /* safe becasue freeup of z clears old a */
        }
  }


  if (va == 0) {
    m = 1;
    n = 1;
  }
  else if (va == 1) {
    m = 1;
    n = pickshape(a, 0);
  }
  else {
    m = pickshape(a, 0);
    n = pickshape(a, 1);
  }

  if (vb == 0) {
    bn = 1;
    p = 1;
  }
  else if (vb == 1) {
    bn = pickshape(b, 0);
    p = 1;
  }
  else {
    bn = pickshape(b, 0);
    p = pickshape(b, 1);
  }

  replicatea = (va == 0);
  replicateb = (vb == 0);

  if (!(replicatea || replicateb) && n != bn) {
    buildfault("conform error in innerproduct");
    freeup(a);
    freeup(b);
    freeup(z);
    return;
  }

  /* get valence for the result */
  vx = (va <= 1 ? (vb <= 1 ? 0 : 1) : (vb <= 1 ? 1 : 2));
  if (vx == 2) {
    sh[0] = m;
    sh[1] = p;
  }
  else if (vx == 1)
    sh[0] = (va == 2 ? m : p);
  /* if vx==0 then sh is not used */

  /* allocate space for the result matrix */
  x = new_create_array(realtype, vx, 0, sh);

  ap = pfirstreal(a);        /* safe: no allocations */
  bp = pfirstreal(b);        /* safe: no allocations */
  xp = pfirstreal(x);        /* safe: no allocations */

  /* type of loop chosen on the kind of ip being done */

  if (vx == 2) {             /* matrix - matrix */
    for (i = 0; i < m; i++) {
      for (j = 0; j < p; j++) {
        sum = 0.;
        for (k = 0; k < n; k++)
          sum += *(ap + (n * i + k)) * *(bp + (p * k + j));
        *(xp + (p * i + j)) = sum;
      }
      checksignal(NC_CS_NORMAL);
    }
  }
  else if (va == 2) {        /* matrix - vector */
    for (i = 0; i < m; i++) {
      sum = 0.;
      if (replicateb)
        for (k = 0; k < n; k++)
          sum += *(ap + (n * i + k)) * *bp;
      else
        for (k = 0; k < n; k++)
          sum += *(ap + (n * i + k)) * *(bp + k);
      *(xp + i) = sum;
    }
  }
  else if (vb == 2) {        /* vector - matrix */
    for (j = 0; j < p; j++) {
      sum = 0.;
      if (replicatea)
        for (k = 0; k < bn; k++)
          sum += *ap * *(bp + (p * k + j));
      else
        for (k = 0; k < bn; k++)
          sum += *(ap + k) * *(bp + (p * k + j));
      *(xp + j) = sum;
    }
  }
  else {                     /* vector - vector */
    sum = 0.;
    if (replicatea)
      for (k = 0; k < bn; k++)
        sum += *ap * *(bp + k);
    else if (replicateb)
      for (k = 0; k < n; k++)
        sum += *(ap + k) * *bp;
    else
      for (k = 0; k < n; k++)
        sum += *(ap + k) * *(bp + k);
    *xp = sum;
  }

  apush(x);
  freeup(a);
  freeup(b);
  freeup(z);
}
Ejemplo n.º 11
0
void
isolve()
{
  nialptr     z,
              a,
              aa = Null,
              b,
              x = Null;
  int         va,
              vb,
              afreed,
              bfreed;
  nialint     n,
              nrhs;
  char        errmsg[80];

  z = apop();
  if (tally(z) != 2) {
    buildfault("arg to solve not a pair");
    freeup(z);
    return;
  }
  splitfb(z, &a, &b);
  va = valence(a);
  vb = valence(b);
  if (va != 2 || vb > 2) {
    buildfault("incorrect valence in solve");
    freeup(a);
    freeup(b);
    freeup(z);
    return;
  }
  n = pickshape(a, 0);
  if (n != pickshape(a, 1) || n != pickshape(b, 0)) {
    buildfault("shapes do not conform in solve");
    freeup(a);
    freeup(b);
    freeup(z);
    return;
  }
  bfreed = false;
  switch (kind(b)) {
    case booltype:
        x = bool_to_real(b);
        bfreed = true;
        break;
    case inttype:
        x = int_to_real(b);
        bfreed = true;
        break;
    case realtype:
        { /* make a copy of b in x */
          x = new_create_array(realtype, vb, 0, shpptr(b, vb));
          copy(x, 0, b, 0, tally(b));
          break;
        }
    case chartype:
    case phrasetype:
    case faulttype:
        {
          buildfault("second arg not numeric type in solve");
          freeup(a);
          freeup(b);
          freeup(z);
          return;
        }
    case atype:
        {
          nialint     i = 0;

          if (!simple(b)) {
            buildfault("second arg not simple in solve");
            freeup(a);
            freeup(b);
            freeup(z);
            return;
          }
          while (i < tally(b)) {
            if (!numeric(kind(fetch_array(b, i)))) {
              buildfault("second arg not numeric type in solve");
              freeup(a);
              freeup(b);
              freeup(z);
              return;
            }
            i++;
          }
          x = to_real(b);  /* makes a copy of b as reals */
        }
  }
  afreed = false;
  switch (kind(a)) {
    case booltype:
        aa = bool_to_real(a); /* makes a copy of a as reals */
        afreed = true;
        break;
    case inttype:
        aa = int_to_real(a); /* makes a copy of a as reals */
        afreed = true;
        break;
    case realtype:
        { /* makes a copy of a */
          aa = new_create_array(realtype, va, 0, shpptr(a, va));
          copy(aa, 0, a, 0, tally(a));
          break;
        }
    case chartype:
    case phrasetype:
    case faulttype:
        {
          buildfault("first arg not numeric type in solve");
          freeup(a);
          if (!bfreed)
            freeup(b);
          freeup(z);
          freeup(x);
          return;
        }
    case atype:
        {
          nialint     i = 0;

          if (!simple(a)) {
            buildfault("first arg not simple in solve");
            freeup(a);
            if (!bfreed)
              freeup(b);
            freeup(z);
            freeup(x);
            return;
          }
          while (i < tally(a)) {
            if (!numeric(kind(fetch_array(a, i)))) {
              buildfault("first arg not numeric type in solve");
              freeup(a);
              if (!bfreed)
                freeup(b);
              freeup(z);
              freeup(x);
              return;
            }
            i++;
          }
          aa = to_real(a); /* makes a copy of a as reals */
        }
  }


  nrhs = (vb == 1 ? 1 : pickshape(x, 1));

  /* use the Gaussian elimination algorithm to solve the equation(s) */
  if (Gausselim(pfirstreal(aa), pfirstreal(x), n, nrhs, errmsg)) {
    apush(x);
  }
  else {
    buildfault(errmsg);
    freeup(x);
  }
  freeup(aa);                /* the modified copy of a has to be freed */
  if (!bfreed)
    freeup(b);
  if (!afreed)
    freeup(a);
  freeup(z);
}
Ejemplo n.º 12
0
void
iinverse()
{
  nialptr     a,
              aa = Null,
              x;
  int         va,
              afreed;
  nialint     n,
              i,
              j;
  double     *ptr;
  char        errmsg[80];

  a = apop();
  va = valence(a);
  if (va != 2) {
    buildfault("incorrect valence in inverse");
    freeup(a);
    return;
  }
  n = pickshape(a, 0);
  if (n != pickshape(a, 1)) {
    buildfault("matrix is not square in inverse");
    freeup(a);
    return;
  }
  afreed = false;
  switch (kind(a)) {
    case booltype:
        aa = bool_to_real(a);  /* makes a real copy of a */
        afreed = true;
        break;
    case inttype:
        aa = int_to_real(a);  /* makes a real copy of a */

        afreed = true;
        break;
    case realtype:
        {  /* make a real copy of a */
          aa = new_create_array(realtype, va, 0, shpptr(a, va));
          copy(aa, 0, a, 0, tally(a));
          break;
        }
    case chartype:
    case phrasetype:
    case faulttype:
        {
          buildfault("arg not numeric type in inverse");
          freeup(a);
          return;
        }
    case atype:
        {
          nialint     i = 0;

          if (!simple(a)) {
            buildfault("arg not simple in inverse");
            freeup(a);
            return;
          }
          while (i < tally(a)) {
            if (!numeric(kind(fetch_array(a, i)))) {
              buildfault("arg not numeric type in inverse");
              freeup(a);
              return;
            }
            i++;
          }
          aa = to_real(a);  /* makes a real copy of a */

        }
  }
  /* initialize x to a real identity matrix */
  x = new_create_array(realtype, va, 0, shpptr(aa, va));
  ptr = pfirstreal(x);
  for (i = 0; i < n; i++)
    for (j = 0; j < n; j++)
      *ptr++ = (i == j ? 1.0 : 0.0);

  if (Gausselim(pfirstreal(aa), pfirstreal(x), n, n, errmsg)) {
    apush(x);
  }
  else {
    buildfault(errmsg);
    freeup(x);
  }
  freeup(aa);                /* the modified copy of a has to be freed */
  /* if a direct copies of a was made, then it needs to be freed up. the
   * conversion routine does its own freeup. */
  if (!afreed)
    freeup(a);
}