simplification (Manual de Maxima 5.50.0)

## 72 simplification ¶

### 72.1 Introducción a simplification ¶

El directorio `maxima/share/simplification` contiene programas que implementan algunas reglas y funciones para simplificar expresiones, así como ciertas funciones no relacionadas con la simplificación.

### 72.2 Paquete absimp ¶

El paquete `absimp` contiene reglas para aplicar patrones que extienden el sistema de reglas nativo de Maxima para las funciones `abs` y `signum`, respetando las relaciones establecidas con la función `assume` o con declaraciones tales como `modedeclare (m, even, n, odd)` para enteros pares o impares.

En el paquete `absimp` se definen las funciones `unitramp` y `unitstep` en términos de `abs` y `signum`.

La instrucción `load ("absimp")` carga este paquete y `demo (absimp)` desarrolla una demostración sobre el uso del mismo.

Ejemplos:

    (%i1) load ("absimp")$
    (%i2) (abs (x))^2;
                                           2
    (%o2)                                 x
    (%i3) diff (abs (x), x);
                                          x
    (%o3)                               ------
                                        abs(x)
    (%i4) cosh (abs (x));
    (%o4)                               cosh(x)

### 72.3 Paquete facexp ¶

El paquete `facexp` contiene varias funciones que le aportan al usuario la posibilidad de estructurar expresiones controlando su expansión. Esta capacidad es especialmente útil cuando la expresión contiene variables con significado físico, ya que se suele dar el caso de que la forma más sencilla para estas expresiones se obtiene cuando se expanden respecto de estas variables y luego se factoriza respecto de sus coeficientes. Si bien es cierto que este procedimiento no es difícil de llevar a cabo con las funciones estándar de Maxima, pueden ser necesarios algunos retoques adicionales que sí pueden ser más difíciles de hacer.

La función `facsum` y sus formas relacionadas proporcionan un método para controlar la estructura de expresiones. La función `collectterms` puede usarse para añadir dos o más expresiones que ya hayan sido simplificadas de la forma indicada, sin necesidad de volver a simplificar la expresión completa. Esta función puede ser útil cuando las expresiones sean largas.

La instrucción `load ("facexp")` carga este paquete y `demo (facexp)` hace una demostración sobre su uso.

Función: facsum (expr, arg_1, ..., arg_n) ¶

  Devuelve una expresión equivalente a expr, la cual depende de los argumentos arg_1, ..., arg_n, y éstos pueden ser de cualquiera de las formas aceptables para `ratvars`, o listas de estas formas. Si los argumentos no son listas, la forma devuelta se expande completamente con respecto de los argumentos, siendo los coeficientes de tales argumentos factorizados. Estos coeficientes no contienen a ninguno de los argumentos, excepto quizás de una forma no racional.

  En caso de que cualquiera de los argumentos sea una lista, entonces todos ellos se combinan en una única lista, y en lugar de llamar a `factor` para los coeficientes de los argumentos, `facsum` se llama a sí misma utilizando esta nueva lista única como lista de argumentos.

  Es posible que se quiera utilizar `facsum` con respecto a expresiones más complicadas, tales como `log (x + y)`. Estos argumentos son también admisibles.

  En ocasiones puede ser necesario obtener cualquiera de las formas anteriores especificadas por sus operadores principales. Por ejemplo, se puede querer aplicar `facsum` con respecto a todos los `log`; en este caso, se puede incluir entre los argumentos bien los `log` específicos que se quieran tratar de esta manera, bien la expresión `operator (log)` o `'operator (log)`. Si se quiere aplicar `facsum` a expr con respecto a los operadores op_1, ..., op_n, se debe evaluar `facsum (expr, operator (op_1, ..., op_n))`. La forma `operator` puede aparecer también dentro de las listas de argumentos.

  Además, dándole valores a las variables opcionales `facsum_combine` y `nextlayerfactor` se puede controlar el resultado de `facsum`.

Variable global: nextlayerfactor ¶

  Valor por defecto: `false`

  Si `nextlayerfactor` vale `true`, las llamadas recursivas de `facsum` se aplican a los factores de la forma factorizada de los coeficientes de los argumentos.

  Si vale `false`, `facsum` se aplica a cada coeficiente como un todo cada vez que se efectúen llamadas recursivas a `facsum`.

  La inclusión del átomo `nextlayerfactor` en la lista de argumentos de `facsum` tiene el mismo efecto que `nextlayerfactor: true`, pero solamente para el siguiente nivel de la expresión. Puesto que `nextlayerfactor` toma siempre uno de los valores `true` o `false`, debe aparecer comentado (comilla simple) cada vez que aparezca en la lista de argumentos de `facsum`.

Variable global: facsum_combine ¶

  Valor por defecto: `true`

  La variable `facsum_combine` controla la forma del resultado final devuelto por `facsum` si su argumento es un cociente de polinomios. Si `facsum_combine` vale `false`, el resultado será una suma completamente expandida, pero si vale `true`, la expresión devuelta es un cociente de polinomios.

Función: factorfacsum (expr, arg_1, ... arg_n) ¶

  Devuelve una expresión equivalente a expr obtenida aplicando `facsum` a los factores de expr, de argumentos arg_1, ... arg_n. Si alguno de los factores de expr se eleva a una potencia, tanto el factor como el exponente se procesarán de esta manera.

Función: collectterms (expr, arg_1, …, arg_n) ¶

  Si algunas expresiones fueron ya simplificadas con `facsum`, `factorfacsum`, `factenexpand`, `facexpten` o `factorfacexpten`, debiendo ser luego sumadas, puede ser conveniente combinarlas utilizando la función `collecterms`, la cual admite como argumentos todos aquéllos que se puedan pasar a las anteriormente citadas funciones, con la excepción de `nextlayerfactor`, que no tiene efecto alguno sobre `collectterms`. La ventaja de `collectterms` es que devuelve una forma similar a la de `facsum`, pero debido a que suma expresiones que ya han sido previamente procesadas, no necesita repetir esta operación, lo cual resulta ser especialmente útil cuando las expresiones a sumar son muy grandes.

### 72.4 Paquete functs ¶

Función: rempart (expr, n) ¶

  Elimina la parte n de la expresión expr.

  Si n es una lista de la forma `[l, m]`, entonces las partes desde l a m serán eliminadas.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: wronskian ([f_1, ..., f_n], x) ¶

  Devuelve la matriz wronskiana de las expresiones f_1, ..., f_n dependeientes de la variable x. El determinante de la matriz wronskiana es el determinante wronskiano de la lista de expresiones.

  Para hacer uso de esta función ejecutar `load("functs")`.

  Ejemplo:

      (%i1) load("functs")$
      (%i2) wronskian([f(x), g(x)],x);
      (%o2) matrix([f(x),g(x)],['diff(f(x),x,1),'diff(g(x),x,1)])

Función: tracematrix (M) ¶

  Devuelve la traza (suma de los elementos de la diagonal) de la matriz M.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: rational (z) ¶

  Multiplica el numerador y denominador de z por el complejo conjugado del denominador, racionalizando así el denominador. Devuelve la expresión canónica racional (canonical rational expression, CRE) si el argumento z es de esta forma, en caso contrario devuelve una expresión en formato común.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: nonzeroandfreeof (x, expr) ¶

  Devuelve `true` si expr es diferente de cero y `freeof (x, expr)` devuelve `true`. En caso contrario devuelve `false`.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: linear (expr, x) ¶

  Si expr es una expresión de la forma `a*x + b`, siendo a no nulo y los argumentos a y b no contienen a x, `linear` devuelve una lista con tres ecuaciones, una por cada variable b, a y x. Si no se cumple la condición anterior, `linear` devuelve `false`.

  Para hacer uso de esta función ejecutar `load("functs")`.

  Ejemplo:

      (%i1) load ("antid");
      (%o1)        /usr/share/maxima/5.29.1/share/integration/antid.mac
      (%i2) linear ((1 - w)*(1 - x)*z, z);
      (%o2)  [bargumentb = 0, aargumenta = (w - 1) x - w + 1, xargumentx = z]
      (%i3) linear (cos(u - v) + cos(u + v), u);
      (%o3)                                false

Función: gcdivide (p, q) ¶

  Si la variable opcional `takegcd` vale `true`, que es su valor por defecto, `gcdivide` divide los polinomios p y q por su máximo común divisor y devuelve el cociente de los resultados. `gcdivide` hace una llamada a la función `ezgcd` para dividir los polinomios por su máximo común divisor.

  Si `takegcd` vale `false`, `gcdivide` devuelve el cociente `p/q`.

  Para hacer uso de esta función ejecutar `load("functs")`.

  Véanse también `ezgcd`, `gcd`, `gcdex` y `poly_gcd`.

  Ejemplos:

      (%i1) load("functs")$

      (%i2) p1:6*x^3+19*x^2+19*x+6;
                              3       2
      (%o2)                6 x  + 19 x  + 19 x + 6
      (%i3) p2:6*x^5+13*x^4+12*x^3+13*x^2+6*x;
                        5       4       3       2
      (%o3)          6 x  + 13 x  + 12 x  + 13 x  + 6 x
      (%i4) gcdivide(p1, p2);
                                   x + 1
      (%o4)                        ------
                                    3
                                   x  + x
      (%i5) takegcd:false;
      (%o5)                         false
      (%i6) gcdivide(p1, p2);
                             3       2
                          6 x  + 19 x  + 19 x + 6
      (%o6)          ----------------------------------
                        5       4       3       2
                     6 x  + 13 x  + 12 x  + 13 x  + 6 x
      (%i7) ratsimp(%);
                                   x + 1
      (%o7)                        ------
                                    3
                                   x  + x

Función: arithmetic (a, d, n) ¶

  Devuelve el n-ésimo término de la progresión aritmética `a, a + d, a + 2*d, ..., a + (n - 1)*d`.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: geometric (a, r, n) ¶

  Devuelve el n-ésimo término de la progresión geométrica `a, a*r, a*r^2, ..., a*r^(n - 1)`.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: harmonic (a, b, c, n) ¶

  Devuelve el n-ésimo término de la progresión armónica `a/b, a/(b + c), a/(b + 2*c), ..., a/(b + (n - 1)*c)`.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: arithsum (a, d, n) ¶

  Devuelve la suma de la progresión aritmética desde hasta el n-ésimo término.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: geosum (a, r, n) ¶

  Devuelve la suma de la sucesión geométrica hasta el n-ésimo término. Si n es infinito (`inf`) la suma será finita sólo si el valor absoluto de r es menor que 1.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: gaussprob (x) ¶

  Devuelve la función de densidad de probabilidad, normal `%e^(-x^2/2) / sqrt(2*%pi)`.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: gd (x) ¶

  Devuelve la función de Gudermann, `2*atan(%e^x)-%pi/2`.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: agd (x) ¶

  Devuelve la inversa de la función de Gudermann, `log (tan (%pi/4 + x/2))`.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: vers (x) ¶

  Devuelve `1 - cos (x)`.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: covers (x) ¶

  Devuelve `1 - sin (x)`.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: exsec (x) ¶

  Devuelve `sec (x) - 1`.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: hav (x) ¶

  Devuelve `(1 - cos(x))/2`.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: combination (n, r) ¶

  Calcula el número de combinaciones de n objetos tomados de r en r.

  Para hacer uso de esta función ejecutar `load("functs")`.

Función: permutation (n, r) ¶

  Calcula el número de permutaciones de r, seleccionados de un conjunto de n.

  Para hacer uso de esta función ejecutar `load("functs")`.

### 72.5 Paquete ineq ¶

El paquete `ineq` contiene reglas de simplificación para desigualdades

Una sesión de ejemplo:

    (%i1) load("ineq")$
    Warning: Putting rules on '+' or '*' is inefficient, and may not work.
    Warning: Putting rules on '+' or '*' is inefficient, and may not work.
    Warning: Putting rules on '+' or '*' is inefficient, and may not work.
    Warning: Putting rules on '+' or '*' is inefficient, and may not work.
    Warning: Putting rules on '+' or '*' is inefficient, and may not work.
    Warning: Putting rules on '+' or '*' is inefficient, and may not work.
    Warning: Putting rules on '+' or '*' is inefficient, and may not work.
    Warning: Putting rules on '+' or '*' is inefficient, and may not work.
    (%i2) a>=4;  /* a sample inequality */
    (%o2)                               a >= 4
    (%i3) (b>c)+%; /* add a second, strict inequality */
    (%o3)                            b + a > c + 4
    (%i4) 7*(x<y); /* multiply by a positive number */
    (%o4)                              7 x < 7 y
    (%i5) -2*(x>=3*z); /* multiply by a negative number */
    (%o5)                           - 2 x <= - 6 z
    (%i6) (1+a^2)*(1/(1+a^2)<=1); /* Maxima knows that 1+a^2 > 0 */
                                            2
    (%o6)                             1 <= a  + 1
    (%i7) assume(x>0)$ x*(2<3); /* assuming x>0 */
    (%o7)                              2 x < 3 x
    (%i8) a>=b; /* another inequality */
    (%o8)                               a >= b
    (%i9) 3+%; /* add something */
    (%o9)                           a + 3 >= b + 3
    (%i10) %-3; /* subtract it out */
    (%o10)                              a >= b
    (%i11) a>=c-b; /* yet another inequality */
    (%o11)                            a >= c - b
    (%i12) b+%; /* add b to both sides */
    (%o12)                            b + a >= c
    (%i13) %-c; /* subtract c from both sides */
    (%o13)                         - c + b + a >= 0
    (%i14) -%;  /* multiply by -1 */
    (%o14)                          c - b - a <= 0
    (%i15) (z-1)^2>-2*z; /* determining truth of assertion */
                                          2
    (%o15)                         (z - 1)  > - 2 z
    (%i16) expand(%)+2*z; /* expand this and add 2*z to both sides */
                                       2
    (%o16)                            z  + 1 > 0
    (%i17) %,pred;
    (%o17)                               true

Debe tenerse cuidado con el uso de paréntesis que incluyan desigualdades; si se escribe `(A > B) + (C = 5)` el resultado es `A + C > B + 5`, pero `A > B + C = 5` es un error sintáctico y `(A > B + C) = 5` es una cosa completamente diferente.

Ejecútese `disprule (all)` para ver la lista completa de las reglas definidas.

Maxima preguntará al usuario cuando desconozca el signo de una cantidad que multiplica a una desigualdad.

Los fallos más comunes son:

    eq: a > b;
    2*eq;
    % - eq;

Otro problema es el producto de una desigualdad por cero. Si se escribe `x*some_inequality` y Maxima pregunta por el signo de `x` y se responde que vale `zero` (o `z`), el programa devuelve `x*some_inequality` sin hacer uso de la información de que `x` es 0. En tal caso se debería escribir `ev (%, x: 0)`, ya que la base de datos sólo será utilizada para fines comparativos y no para evaluar `x`.

El usuario puede apreciar que las respuestas son más lentas al cargarse este paquete, ya que el simplificador deberá examinar más reglas que cuando no se hace uso del paquete, por lo que puede ser conveniente borrar estas reglas cuando ya no se haga uso de ellas. Ejecútese `kill (rules)` para eliminar todas las reglas (incluidas las definidas por el usuario); también es posible eliminar parte de ellas o utilizar `remrule` sobre una reglas específica.

Nótese que si se carga este paquete después de haber definido otras reglas de igual nombre,se borrarán las antiguas. Las reglas de este paquete son: `*rule1`, ..., `*rule8`, `+rule1`, ..., `+rule18`, debiéndose encerrar entre comillas el nombre de la reglas para referenciarse a ellas, como en `remrule ("+", "+rule1")` para eliminar la primera regla sobre `"+"`, o `disprule ("*rule2")` para mostrar la definición de la segunda regla multiplicativa.

### 72.6 Paquete rducon ¶

Función: reduce_consts (expr) ¶

  Sustituye subexpresiones constantes de expr por átomos, guardando la definición de todos ellos en la lista de ecuaciones `const_eqns` y devolviendo el expresión expr ya modificada. Se consideran partes constantes de expr aquellas que devuelven `true` cuando se les aplica la función `constantp`, por lo que antes de llamar a `reduce_consts` se debe ejecutar

      declare ([objetos a los que se quiera dar la propiedad de ser constantes], constant)$

  para crear la base de datos de las cantidades constantes presentes en la expresión.

  Si se pretende generar código Fortran después de estos cálculos simbólicos, una de las primeras secciones del código debe ser el cálculo de las constantes. Para generar este segmento de código hacer

      map ('fortran, const_eqns)$

  Junto a `const_eqns`, otras variables que afectan a `reduce_consts` son:

  `const_prefix` (Valor por defecto: `xx`) es la cadena de caracteres utilizada como prefijo para todos los símbolos generados por `reduce_consts` para representar subexpresiones constantes.

  `const_counter` (Valor por defecto: 1) es el índice entero utilizado para generar los símbolos que representen a las subexpresiones constantes encontradas por `reduce_consts`.

  La instrucción `load ("rducon")` carga esta función y `demo (rducon)` hace una demostración sobre su uso.

### 72.7 Paquete scifac ¶

Función: gcfac (expr) ¶

  Es una función de factorización que intenta aplicar la misma heurística que los humanos cuando tratan de hacer las expresiones más simples, limitándose a la factorización de monomios. En caso de sumas, `gcfac` hace lo siguiente:

  1. Factoriza los enteros.
  2. Factoriza las potencias mayores de los términos que aparecen como coeficientes, independientemente de su complejidad.
  3. Utiliza (1) y (2) en la factorización de pares de términos adyacentes.
  4. Aplica estas técnicas repetida y recursivamente hasta que la expresión deje de sufrir cambios.

  En general, el apartado (3) no hace una factorización óptima debido a la naturaleza combinatoria y compleja de encontrar cuál de todas las ordenaciones posibles de los pares da lugar a la expresión más compacta.

  La instrucción `load ("scifac")` carga esta función y `demo (scifac)` hace una demostración sobre su uso.

### 72.8 Paquete sqdnst ¶

Función: sqrtdenest (expr) ¶

  Reduce expresiones en las que se encuentren raíces cuadradas anidadas, siempre que sea posible

  Ejemplo:

      (%i1) load ("sqdnst")$
      (%i2) sqrt(sqrt(3)/2+1)/sqrt(11*sqrt(2)-12);
                                          sqrt(3)
                                     sqrt(------- + 1)
                                             2
      (%o2)                        ---------------------
                                   sqrt(11 sqrt(2) - 12)
      (%i3) sqrtdenest(%);
                                        sqrt(3)   1
                                        ------- + -
                                           2      2
      (%o3)                            -------------
                                          1/4    3/4
                                       3 2    - 2

  A veces conviene aplicar `sqrtdenest` más de una vez, como en el caso `(19601-13860 sqrt(2))^(7/4)`.

  La sentencia `load ("sqdnst")` carga esta función.