Funciones y variables para Arrays
=================================

 -- Función: array (NOMBRE, DIM_1, ..., DIM_N)
 -- Función: array (NOMBRE, TYPE, DIM_1, ..., DIM_N)
 -- Función: array ([NOMBRE_1, ..., NOMBRE_M], DIM_1, ..., DIM_N)

     Crea un array de dimensión n, que debe ser menor o igual que 5. Los subíndices de la i-ésima dimensión son enteros que toman valores entre 0 y DIM_I.

     La llamada array (NOMBRE, DIM_1, ..., DIM_N) crea un array de tipo general.

     La llamada array (NOMBRE, TYPE, DIM_1, ..., DIM_N) crea un array con sus elementos del tipo especificado. El tipo TYPE puede ser fixnum para enteros de tamaño limitado o flonum para números decimales en coma flotante.

     La llamada array ([NOMBRE_1, ..., NOMBRE_M], DIM_1, ..., DIM_N) crea m arrays,  todos ellos de igual dimensión.

     Si el usuario asigna un valor a una variable subindicada antes de declarar el array correspondiente, entonces se construye un array no declarado. Los arrays no declarados, también conocidos por el nombre de "arrays de claves" (hashed arrays), son más generales que los arrays declarados. El usuario no necesita declarar su tamaño máximo y pueden ir creciendo de forma dinámica. Los subíndices de los arrays no declarados no necesitan ser necesariamente números. Sin embargo, a menos que un array tenga sus elementos dispersos, probablemente sea más eficiente declararlo siempre que sea posible antes que dejarlo como no declarado. La función array puede utilizarse para transformar un array no declarado a a uno declarado.

 -- Función: arrayapply (A, [I_1, ..., I_N])
     Evalúa A [I_1, ..., I_N], donde A es un array y I_1, ..., I_N son enteros.

     Esto es como apply, excepto por el hecho de que el primer argumento es un array en lugar de una función.

 -- Función: arrayinfo (A)
     Devuelve información sobre el arrayA. El argumento A puede ser un array declarado o no declarado, una función array o una función subindicada.

     En el caso de arrays declarados, arrayinfo devuelve una lista que contiene el átomo declared, el número de dimensiones y el tamaño de cada dimensión. Los elementos del array, tanto los que tienen valores asignados como los que no, son devueltos por listarray.

     En el caso de arrays no declarados (hashed arrays), arrayinfo devuelve una lista que contiene el átomo hashed, el número de subíndices y los subíndices de aquellos elementos que guarden un valor. Los valores son devueltos por listarray.

     En el caso de funciones array, arrayinfo devuelve una lista que contiene el átomo hashed, el número de subíndices y los subíndices para los que la función tiene valores almacenados. Los valores almacenados de la función array son devueltos por listarray.

     En el caso de funciones subindicadas, arrayinfo devuelve una lista que contiene el átomo hashed, el número de subíndices y los subíndices para los que hay expresiones lambda. Las expresiones lambda son devueltas por listarray.

     Ejemplos:

     arrayinfo y listarray aplicadas a una array declarado.

          (%i1) array (aa, 2, 3);
          (%o1)                          aa
          (%i2) aa [2, 3] : %pi;
          (%o2)                          %pi
          (%i3) aa [1, 2] : %e;
          (%o3)                          %e
          (%i4) arrayinfo (aa);
          (%o4)                 [declared, 2, [2, 3]]
          (%i5) listarray (aa);
          (%o5) [#####, #####, #####, #####, #####, #####, %e, #####,
                                                  #####, #####, #####, %pi]

     arrayinfo y listarray aplicadas a una array no declarado (hashed arrays).

          (%i1) bb [FOO] : (a + b)^2;
                                             2
          (%o1)                       (b + a)
          (%i2) bb [BAR] : (c - d)^3;
                                             3
          (%o2)                       (c - d)
          (%i3) arrayinfo (bb);
          (%o3)               [hashed, 1, [BAR], [FOO]]
          (%i4) listarray (bb);
                                        3         2
          (%o4)                 [(c - d) , (b + a) ]

     arrayinfo y listarray aplicadas a una función array.

          (%i1) cc [x, y] := y / x;
                                               y
          (%o1)                      cc     := -
                                       x, y    x
          (%i2) cc [u, v];
                                          v
          (%o2)                           -
                                          u
          (%i3) cc [4, z];
                                          z
          (%o3)                           -
                                          4
          (%i4) arrayinfo (cc);
          (%o4)              [hashed, 2, [4, z], [u, v]]
          (%i5) listarray (cc);
                                        z  v
          (%o5)                        [-, -]
                                        4  u

     arrayinfo y listarray aplicadas a una función subindicada.

          (%i1) dd [x] (y) := y ^ x;
                                               x
          (%o1)                     dd (y) := y
                                      x
          (%i2) dd [a + b];
                                              b + a
          (%o2)                  lambda([y], y     )
          (%i3) dd [v - u];
                                              v - u
          (%o3)                  lambda([y], y     )
          (%i4) arrayinfo (dd);
          (%o4)             [hashed, 1, [b + a], [v - u]]
          (%i5) listarray (dd);
                                   b + a                v - u
          (%o5)      [lambda([y], y     ), lambda([y], y     )]

 -- Función: arraymake (NAME, [I_1, ..., I_N])

     El resultado es una referencia a array no evaluada.

     Devuelve la expresión NAME [I_1, ..., I_N].

     Esta función es similar a funmake, excepto que el valor retornado es referencia a un array no evaluado, en lugar de una llamada a una función no evaluada.

     Ejemplos:

          (%i1) arraymake (A, [1]);
          (%o1)                          A
                                          1
          (%i2) arraymake (A, [k]);
          (%o2)                          A
                                          k
          (%i3) arraymake (A, [i, j, 3]);
          (%o3)                       A
                                       i, j, 3
          (%i4) array (A, fixnum, 10);
          (%o4)                           A
          (%i5) fillarray (A, makelist (i^2, i, 1, 11));
          (%o5)                           A
          (%i6) arraymake (A, [5]);
          (%o6)                          A
                                          5
          (%i7) ''%;
          (%o7)                          36
          (%i8) L : [a, b, c, d, e];
          (%o8)                    [a, b, c, d, e]
          (%i9) arraymake ('L, [n]);
          (%o9)                          L
                                          n
          (%i10) ''%, n = 3;
          (%o10)                          c
          (%i11) A2 : make_array (fixnum, 10);
          (%o11)          {Array:  #(0 0 0 0 0 0 0 0 0 0)}
          (%i12) fillarray (A2, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
          (%o12)          {Array:  #(1 2 3 4 5 6 7 8 9 10)}
          (%i13) arraymake ('A2, [8]);
          (%o13)                         A2
                                           8
          (%i14) ''%;
          (%o14)                          9

 -- Variable del sistema: arrays
     Valor por defecto: [] La variable arrays es una lista con todos los arrays que han sido alojados, lo que comprende a los arrays declarados por array, a los no declarados (hashed arrays) construidos implícitamente (asignando algo al elemento de un array) y a las funciones array definidas mediante := y define. Los arrays definidos mediante make_array no se incluyen en este grupo.

     Véanse también array, arrayapply, arrayinfo, arraymake, fillarray, listarray y rearray.

     Ejemplos:

          (%i1) array (aa, 5, 7);
          (%o1)                          aa
          (%i2) bb [FOO] : (a + b)^2;
                                             2
          (%o2)                       (b + a)
          (%i3) cc [x] := x/100;
                                             x
          (%o3)                      cc  := ---
                                       x    100
          (%i4) dd : make_array ('any, 7);
          (%o4)       {Array:  #(NIL NIL NIL NIL NIL NIL NIL)}
          (%i5) arrays;
          (%o5)                     [aa, bb, cc]

 -- Función: bashindices (EXPR)
     Transforma la expresión EXPR dándole a cada suma y producto un único índice. Esto le da a changevar mayor precisión cuando opera con sumas y productos. La forma del único índice es jNUMBER. La cantidad NUMBER se determina en función de gensumnum, valor que puede cambiar el usuario.  Por ejemplo, haciendo gensumnum:0$.

 -- Función: fillarray (A, B)
     Rellena el array A con los valores de B, que puede ser una lista o array.

     Si se ha declarado A de un determinado tipo en el momento de su creación, sólo podrá contener elementos de ese tipo, produciéndose un error en caso de intentar asignarle un elemento de tipo distinto.

     Si las dimensiones de los arrays A y B son diferentes, A se rellena según el orden de las filas. Si no hay suficientes elementos en B el último elemento se utiliza para cubrir el resto de A. Si hay demasiados, los elementos sobrantes son ignorados.

     La función fillarray devuelve su primer argumento.

     Ejemplos:

     Creación de un array de 9 elementos y posterior relleno a partir de una lista.

          (%i1) array (a1, fixnum, 8);
          (%o1)                          a1
          (%i2) listarray (a1);
          (%o2)              [0, 0, 0, 0, 0, 0, 0, 0, 0]
          (%i3) fillarray (a1, [1, 2, 3, 4, 5, 6, 7, 8, 9]);
          (%o3)                          a1
          (%i4) listarray (a1);
          (%o4)              [1, 2, 3, 4, 5, 6, 7, 8, 9]

     Si no hay suficientes elementos para cubrir el array, se repite el último elemento. Si hay demasiados, los elementos sobrantes son ignorados.

          (%i1) a2 : make_array (fixnum, 8);
          (%o1)             {Array:  #(0 0 0 0 0 0 0 0)}
          (%i2) fillarray (a2, [1, 2, 3, 4, 5]);
          (%o2)             {Array:  #(1 2 3 4 5 5 5 5)}
          (%i3) fillarray (a2, [4]);
          (%o3)             {Array:  #(4 4 4 4 4 4 4 4)}
          (%i4) fillarray (a2, makelist (i, i, 1, 100));
          (%o4)             {Array:  #(1 2 3 4 5 6 7 8)}

     Arrays multidimensionales se rellenan según el orden de las filas.

          (%i1) a3 : make_array (fixnum, 2, 5);
          (%o1)        {Array:  #2A((0 0 0 0 0) (0 0 0 0 0))}
          (%i2) fillarray (a3, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
          (%o2)        {Array:  #2A((1 2 3 4 5) (6 7 8 9 10))}
          (%i3) a4 : make_array (fixnum, 5, 2);
          (%o3)     {Array:  #2A((0 0) (0 0) (0 0) (0 0) (0 0))}
          (%i4) fillarray (a4, a3);
          (%o4)     {Array:  #2A((1 2) (3 4) (5 6) (7 8) (9 10))}

 -- Función: listarray (A)
     Devuelve una lista con los elementos del array A. El argumento A puede ser un array declarado o no declarado, una función array o una función subindicada.

     Los elementos se ordenan en primera instancia respecto del primer índice, después respecto del segundo índice y así sucesivamente. La ordenación de los índices es la misma que la establecida por orderless.

     En el caso de arrays no declarados, funciones array y funciones subindicadas, los elementos corresponden a los índices devueltos por arrayinfo.

     Los elementos de los arrays declarados que no tienen valores asignados (excepto fixnum y flonum) se devuelven como #####. Los elementos sin valores asignados de los arrays fixnum y flonum son devueltos como 0 y 0.0, respectivamente. Los elementos sin valor asignado de los arrays no declarados, funciones array y funciones subindicadas no son devueltos.

     Ejemplos:

     listarray y arrayinfo aplicadas a un array declarado.

          (%i1) array (aa, 2, 3);
          (%o1)                          aa
          (%i2) aa [2, 3] : %pi;
          (%o2)                          %pi
          (%i3) aa [1, 2] : %e;
          (%o3)                          %e
          (%i4) listarray (aa);
          (%o4) [#####, #####, #####, #####, #####, #####, %e, #####,
                                                  #####, #####, #####, %pi]
          (%i5) arrayinfo (aa);
          (%o5)                 [declared, 2, [2, 3]]

     listarray y arrayinfo aplicadas a un array no declarado (hashed array).

          (%i1) bb [FOO] : (a + b)^2;
                                             2
          (%o1)                       (b + a)
          (%i2) bb [BAR] : (c - d)^3;
                                             3
          (%o2)                       (c - d)
          (%i3) listarray (bb);
                                        3         2
          (%o3)                 [(c - d) , (b + a) ]
          (%i4) arrayinfo (bb);
          (%o4)               [hashed, 1, [BAR], [FOO]]

     listarray y arrayinfo aplicadas a una función array.

          (%i1) cc [x, y] := y / x;
                                               y
          (%o1)                      cc     := -
                                       x, y    x
          (%i2) cc [u, v];
                                          v
          (%o2)                           -
                                          u
          (%i3) cc [4, z];
                                          z
          (%o3)                           -
                                          4
          (%i4) listarray (cc);
                                        z  v
          (%o4)                        [-, -]
                                        4  u
          (%i5) arrayinfo (cc);
          (%o5)              [hashed, 2, [4, z], [u, v]]

     listarray y arrayinfo aplicadas a una función subindicada.

          (%i1) dd [x] (y) := y ^ x;
                                               x
          (%o1)                     dd (y) := y
                                      x
          (%i2) dd [a + b];
                                              b + a
          (%o2)                  lambda([y], y     )
          (%i3) dd [v - u];
                                              v - u
          (%o3)                  lambda([y], y     )
          (%i4) listarray (dd);
                                   b + a                v - u
          (%o4)      [lambda([y], y     ), lambda([y], y     )]
          (%i5) arrayinfo (dd);
          (%o5)             [hashed, 1, [b + a], [v - u]]

 -- Función: make_array (TIPO, DIM_1, ..., DIM_N)

     Construye y devuelve un array de Lisp. El argumento TIPO puede ser any, flonum, fixnum, hashed o functional. Hay n índices, y el índice i-ésimo va de  0 a DIM_I - 1.

     La ventaja de make_array sobre array estriba en que el valor retornado no tiene nombre, y una vez que un puntero deja de referenciarlo, el valor desaparece. Por ejemplo, si y: make_array (...) entonces y apunta a un objeto que ocupa cierto espacio en la memoria, pero después de y: false, y ya no apunta al objeto, por lo que éste puede ser considerado basura y posteriormente eliminado.

     Ejemplos:

          (%i1) A1 : make_array (fixnum, 10);
          (%o1)           {Array:  #(0 0 0 0 0 0 0 0 0 0)}
          (%i2) A1 [8] : 1729;
          (%o2)                         1729
          (%i3) A1;
          (%o3)          {Array:  #(0 0 0 0 0 0 0 0 1729 0)}
          (%i4) A2 : make_array (flonum, 10);
          (%o4) {Array:  #(0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0)}
          (%i5) A2 [2] : 2.718281828;
          (%o5)                      2.718281828
          (%i6) A2;
          (%o6)
               {Array:  #(0.0 0.0 2.718281828 0.0 0.0 0.0 0.0 0.0 0.0 0.0)}
          (%i7) A3 : make_array (any, 10);
          (%o7) {Array:  #(NIL NIL NIL NIL NIL NIL NIL NIL NIL NIL)}
          (%i8) A3 [4] : x - y - z;
          (%o8)                      - z - y + x
          (%i9) A3;
          (%o9) {Array:  #(NIL NIL NIL NIL ((MPLUS SIMP) $X ((MTIMES SIMP)\
           -1 $Y) ((MTIMES SIMP) -1 $Z))
            NIL NIL NIL NIL NIL)}
          (%i10) A4 : make_array (fixnum, 2, 3, 5);
          (%o10) {Array:  #3A(((0 0 0 0 0) (0 0 0 0 0) (0 0 0 0 0)) ((0 0 \
          0 0 0) (0 0 0 0 0) (0 0 0 0 0)))}
          (%i11) fillarray (A4, makelist (i, i, 1, 2*3*5));
          (%o11) {Array:  #3A(((1 2 3 4 5) (6 7 8 9 10) (11 12 13 14 15))
              ((16 17 18 19 20) (21 22 23 24 25) (26 27 28 29 30)))}
          (%i12) A4 [0, 2, 1];
          (%o12)                         12

 -- Función: rearray (A, DIM_1, ..., DIM_N)
     Cambia las dimensiones de un array. El nuevo array será rellenado con los elementos del viejo según el orden de las filas. Si el array antiguo era demasiado pequeño, los elementos restantes se rellenan con false, 0.0 o 0, dependiendo del tipo del array. El tipo del array no se puede cambiar.

 -- Función: remarray (A_1, ..., A_N)
 -- Función: remarray (all)
     Borra los arrays y las funciones relacionadas con ellos, liberando el espacio de memoria ocupado. Los argumentos pueden ser arrays declarados, arrays no declarados (hashed arrays), funciones array y funciones subindicadas.

     La llamada remarray (all) borra todos los elementos de la lista global arrays.

     La función remarray devuelve la lista de los arrays borrados.

 -- Función: subvar (X, I)
     Evalúa la expresión subindicada X[I].

     La función subvar evalúa sus argumentos.

     La instrucción arraymake (X, [I] construye la expresión X[I], pero no la evalúa.

     Ejemplos:

          (%i1) x : foo $

          (%i2) i : 3 $

          (%i3) subvar (x, i);
          (%o3)                         foo
                                           3
          (%i4) foo : [aa, bb, cc, dd, ee]$

          (%i5) subvar (x, i);
          (%o5)                          cc
          (%i6) arraymake (x, [i]);
          (%o6)                         foo
                                           3
          (%i7) ''%;
          (%o7)                          cc

 -- Variable opcional: use_fast_arrays
     Valor por defecto: false

     Si use_fast_arrays vale true entonces tan solo se reconocen dos tipos de arrays.