[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22. Métodos numéricos


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.1 Introducción a la transformada rápida de Fourier

El paquete fft contiene funciones para el cálculo numérico (no simbólico) de la transformada rápida de Fourier.

Función: polartorect (magnitude_array, phase_array)

Transforma valores complejos de la forma r %e^(%i t) a la forma a + b %i, siendo r el módulo y t la fase. Ambos valores r y t son arrays unidimensionales cuyos tamños son iguales a la misma potencia de dos.

Los valores originales de los arrays de entrada son reemplazados por las partes real e imaginaria, a y b, de los correspondientes números complejos. El resultado se calcula como

a = r cos(t)
b = r sin(t)

polartorect es la función inversa de recttopolar.

Para utilizar esta función ejecútese antes load(fft). Véase también fft.

Función: recttopolar (real_array, imaginary_array)

Transforma valores complejos de la forma a + b %i a la forma r %e^(%i t), siendo a la parte real y a la imaginaria. Ambos valores a y b son arrays unidimensionales cuyos tamños son iguales a la misma potencia de dos.

Los valores originales de los arrays de entrada son reemplazados por los módulos y las fases, r y t, de los correspondientes números complejos. El resultado se calcula como

r = sqrt(a^2 + b^2)
t = atan2(b, a)

El ángulo calculado pertence al rango de -%pi a %pi.

recttopolar es la función inversa de polartorect.

Para utilizar esta función ejecútese antes load(fft). Véase también fft.

Función: inverse_fft (y)

Calcula la transformada inversa rápida de Fourier.

y es una lista o array (declarado o no) que contiene los datos a transformar. El número de elementos debe ser una potencia de dos. Los elementos deben ser números literales (enteros, racionales, de punto flotante o decimales grandes), constantes simbólicas, expresiones del tipo a + b*%i, siendo a y b números literales, o constantes simbólicas.

La función inverse_fft devuelve un nuevo objeto del mismo tipo que y, el cual no se ve modificado. Los resultados se calculan siempre como decimales o expresiones a + b*%i, siendo a y b decimales.

La transformada inversa discreta de Fourier se define como se indica a continuación. Si x es el resultado de la transformada inversa, entonces para j entre 0 y n - 1 se tiene

x[j] = sum(y[k] exp(-2 %i %pi j k / n), k, 0, n - 1)

Para utilizar esta función ejecútese antes load(fft).

Véanse también fft (transformada directa), recttopolar y polartorect.

Ejemplos:

Datos reales.

(%i1) load (fft) $
(%i2) fpprintprec : 4 $
(%i3) L : [1, 2, 3, 4, -1, -2, -3, -4] $
(%i4) L1 : inverse_fft (L);
(%o4) [0.0, 14.49 %i - .8284, 0.0, 2.485 %i + 4.828, 0.0, 
                       4.828 - 2.485 %i, 0.0, - 14.49 %i - .8284]
(%i5) L2 : fft (L1);
(%o5) [1.0, 2.0 - 2.168L-19 %i, 3.0 - 7.525L-20 %i, 
4.0 - 4.256L-19 %i, - 1.0, 2.168L-19 %i - 2.0, 
7.525L-20 %i - 3.0, 4.256L-19 %i - 4.0]
(%i6) lmax (abs (L2 - L));
(%o6)                       3.545L-16

Datos complejos.

(%i1) load (fft) $
(%i2) fpprintprec : 4 $                 
(%i3) L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
(%i4) L1 : inverse_fft (L);
(%o4) [4.0, 2.711L-19 %i + 4.0, 2.0 %i - 2.0, 
- 2.828 %i - 2.828, 0.0, 5.421L-20 %i + 4.0, - 2.0 %i - 2.0, 
2.828 %i + 2.828]
(%i5) L2 : fft (L1);
(%o5) [4.066E-20 %i + 1.0, 1.0 %i + 1.0, 1.0 - 1.0 %i, 
1.55L-19 %i - 1.0, - 4.066E-20 %i - 1.0, 1.0 - 1.0 %i, 
1.0 %i + 1.0, 1.0 - 7.368L-20 %i]
(%i6) lmax (abs (L2 - L));                    
(%o6)                       6.841L-17
Función: fft (x)

Calcula la transformada rápida compleja de Fourier.

x es una lista o array (declarado o no) que contiene los datos a transformar. El número de elementos debe ser una potencia de dos. Los elementos deben ser números literales (enteros, racionales, de punto flotante o decimales grandes), constantes simbólicas, expresiones del tipo a + b*%i, siendo a y b números literales, o constantes simbólicas.

La función fft devuelve un nuevo objeto del mismo tipo que x, el cual no se ve modificado. Los resultados se calculan siempre como decimales o expresiones a + b*%i, siendo a y b decimales.

La transformada discreta de Fourier se define como se indica a continuación. Si y es el resultado de la transformada inversa, entonces para k entre 0 y n - 1 se tiene

y[k] = (1/n) sum(x[j] exp(+2 %i %pi j k / n), j, 0, n - 1)

Si los datos x son reales, los coeficientes reales a y b se pueden calcular de manera que

x[j] = sum(a[k]*cos(2*%pi*j*k/n)+b[k]*sin(2*%pi*j*k/n), k, 0, n/2)

con

a[0] = realpart (y[0])
b[0] = 0

y, para k entre 1 y n/2 - 1,

a[k] = realpart (y[k] + y[n - k])
b[k] = imagpart (y[n - k] - y[k])

y

a[n/2] = realpart (y[n/2])
b[n/2] = 0

Para utilizar esta función ejecútese antes load(fft).

Véanse también inverse_fft (transformada inversa), recttopolar y polartorect.

Ejemplos:

Datos reales.

(%i1) load (fft) $
(%i2) fpprintprec : 4 $
(%i3) L : [1, 2, 3, 4, -1, -2, -3, -4] $
(%i4) L1 : fft (L);
(%o4) [0.0, - 1.811 %i - .1036, 0.0, .6036 - .3107 %i, 0.0, 
                         .3107 %i + .6036, 0.0, 1.811 %i - .1036]
(%i5) L2 : inverse_fft (L1);
(%o5) [1.0, 2.168L-19 %i + 2.0, 7.525L-20 %i + 3.0, 
4.256L-19 %i + 4.0, - 1.0, - 2.168L-19 %i - 2.0, 
- 7.525L-20 %i - 3.0, - 4.256L-19 %i - 4.0]
(%i6) lmax (abs (L2 - L));
(%o6)                       3.545L-16

Datos complejos.

(%i1) load (fft) $
(%i2) fpprintprec : 4 $
(%i3) L : [1, 1 + %i, 1 - %i, -1, -1, 1 - %i, 1 + %i, 1] $
(%i4) L1 : fft (L);
(%o4) [0.5, .3536 %i + .3536, - 0.25 %i - 0.25, 
0.5 - 6.776L-21 %i, 0.0, - .3536 %i - .3536, 0.25 %i - 0.25, 
0.5 - 3.388L-20 %i]
(%i5) L2 : inverse_fft (L1);
(%o5) [1.0 - 4.066E-20 %i, 1.0 %i + 1.0, 1.0 - 1.0 %i, 
- 1.008L-19 %i - 1.0, 4.066E-20 %i - 1.0, 1.0 - 1.0 %i, 
1.0 %i + 1.0, 1.947L-20 %i + 1.0]
(%i6) lmax (abs (L2 - L));
(%o6)                       6.83L-17

Cálculo de los coeficientes del seno y coseno.

(%i1) load (fft) $
(%i2) fpprintprec : 4 $
(%i3) L : [1, 2, 3, 4, 5, 6, 7, 8] $
(%i4) n : length (L) $
(%i5) x : make_array (any, n) $
(%i6) fillarray (x, L) $
(%i7) y : fft (x) $
(%i8) a : make_array (any, n/2 + 1) $
(%i9) b : make_array (any, n/2 + 1) $
(%i10) a[0] : realpart (y[0]) $
(%i11) b[0] : 0 $
(%i12) for k : 1 thru n/2 - 1 do
   (a[k] : realpart (y[k] + y[n - k]),
    b[k] : imagpart (y[n - k] - y[k]));
(%o12)                        done
(%i13) a[n/2] : y[n/2] $
(%i14) b[n/2] : 0 $
(%i15) listarray (a);
(%o15)          [4.5, - 1.0, - 1.0, - 1.0, - 0.5]
(%i16) listarray (b);
(%o16)           [0, - 2.414, - 1.0, - .4142, 0]
(%i17) f(j) := sum (a[k] * cos (2*%pi*j*k / n) + b[k] * sin (2*%pi*j*k / n), k, 0, n/2) $
(%i18) makelist (float (f (j)), j, 0, n - 1);
(%o18)      [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.2 Funciones para la resolución numérica de ecuaciones

Función: horner (expr, x)
Función: horner (expr)

Cambia el formato de expr según la regla de Horner utilizando x como variable principal, si ésta se especifica. El argumento x se puede omitir, en cuyo caso se considerará como variable principal la de expr en su formato racional canónico (CRE).

La función horner puede mejorar las estabilidad si expr va a ser numéricamente evaluada. También es útil si Maxima se utiliza para generar programas que serán ejecutados en Fortran. Véase también stringout.

(%i1) expr: 1e-155*x^2 - 5.5*x + 5.2e155;
                           2
(%o1)            1.0E-155 x  - 5.5 x + 5.2E+155
(%i2) expr2: horner (%, x), keepfloat: true;
(%o2)            (1.0E-155 x - 5.5) x + 5.2E+155
(%i3) ev (expr, x=1e155);
Maxima encountered a Lisp error:

 floating point overflow

Automatically continuing.
To reenable the Lisp debugger set *debugger-hook* to nil.
(%i4) ev (expr2, x=1e155);
(%o4)                       7.0E+154
Función: find_root (expr, x, a, b, [abserr, relerr])
Función: find_root (f, a, b, [abserr, relerr])
Función: bf_find_root (expr, x, a, b, [abserr, relerr])
Función: bf_find_root (f, a, b, [abserr, relerr])
Variable opcional: find_root_error
Variable opcional: find_root_abs
Variable opcional: find_root_rel

Calcula una raíz de la expresión expr o de la función f en el intervalo cerrado [a, b]. La expresión expr puede ser una ecuación, en cuyo caso find_root busca una raíz de lhs(expr) - rhs(expr).

Dado que Maxima puede evaluar expr o f en [a, b], entonces, si expr o f es continua, find_root encuentrará la raíz buscada, o raíces, en caso de existir varias.

La función find_root aplica al principio la búsqueda por bipartición. Si la expresión es lo suficientemente suave, entonces find_root aplicará el método de interpolación lineal.

bf_find_root es una versión de find_root para números reales de precisión arbitraria (bigfloat). La función se evalúa utilizando la aritmética de estos números, devolviendo un resultado numérico de este tipo. En cualquier otro aspecto, bf_find_root es idéntica a find_root, siendo la explicación que sigue igualmente válida para bf_find_root.

La precisión de find_root está controlada por abserr y relerr, que son claves opcionales para find_root. Estas claves toman la forma key=val. Las claves disponibles son:

abserr

Error absoluto deseado de la función en la raíz. El valor por defecto es find_root_abs.

relerr

Error relativo deseado de la raíz. El valor por defecto es find_root_rel.

find_root se detiene cuando la función alcanza un valor menor o igual que abserr, o si las sucesivas aproximaciones x_0, x_1 difieren en no más que relerr * max(abs(x_0), abs(x_1)). Los valores por defecto de find_root_abs y find_root_rel son ambos cero.

find_root espera que la función en cuestión tenga signos diferentes en los extremos del intervalo. Si la función toma valores numéricos en ambos extremos y estos números son del mismo signo, entonces el comportamiento de find_root se controla con find_root_error. Cuando find_root_error vale true, find_root devuelve un mensaje de error; en caso contrario, find_root devuelve el valor de find_root_error. El valor por defecto de find_root_error es true.

Si en algún momento del proceso de búsqueda f alcanza un valor no numérico, find_root devuelve una expresión parcialmente evaluada.

Se ignora el orden de a y b; la región de búsqueda es [min(a, b), max(a, b)].

Ejemplos:

(%i1) f(x) := sin(x) - x/2;
                                        x
(%o1)                  f(x) := sin(x) - -
                                        2
(%i2) find_root (sin(x) - x/2, x, 0.1, %pi);
(%o2)                   1.895494267033981
(%i3) find_root (sin(x) = x/2, x, 0.1, %pi);
(%o3)                   1.895494267033981
(%i4) find_root (f(x), x, 0.1, %pi);
(%o4)                   1.895494267033981
(%i5) find_root (f, 0.1, %pi);
(%o5)                   1.895494267033981
(%i6) find_root (exp(x) = y, x, 0, 100);
                            x
(%o6)           find_root(%e  = y, x, 0.0, 100.0)
(%i7) find_root (exp(x) = y, x, 0, 100), y = 10;
(%o7)                   2.302585092994046
(%i8) log (10.0);
(%o8)                   2.302585092994046
(%i9) fpprec:32;
(%o9)                           32
(%i10) bf_find_root (exp(x) = y, x, 0, 100), y = 10;
(%o10)                  2.3025850929940456840179914546844b0
(%i11) log(10b0);
(%o11)                  2.3025850929940456840179914546844b0
Función: newton (expr, x, x_0, eps)

Devuelve una solución aproximada de expr = 0 obtenida por el método de Newton, considerando expr como una función de una variable, x. La búsqueda comienza con x = x_0 y continúa hasta que se verifique abs(expr) < eps, donde expr se evalúa con el valor actual de x.

La función newton permite que en expr haya variables no definidas, siempre y cuando la condición de terminación abs(expr) < eps pueda reducirse a un valor lógico true o false; de este modo, no es necesario que expr tome un valor numérico.

Ejecútese load(newton1) para cargar esta función.

Véanse también realroots, allroots, find_root y mnewton.

Ejemplos:

(%i1) load (newton1);
(%o1) /usr/share/maxima/5.10.0cvs/share/numeric/newton1.mac
(%i2) newton (cos (u), u, 1, 1/100);
(%o2)                   1.570675277161251
(%i3) ev (cos (u), u = %);
(%o3)                 1.2104963335033528E-4
(%i4) assume (a > 0);
(%o4)                        [a > 0]
(%i5) newton (x^2 - a^2, x, a/2, a^2/100);
(%o5)                  1.00030487804878 a
(%i6) ev (x^2 - a^2, x = %);
                                           2
(%o6)                6.098490481853958E-4 a

[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.3 Introducción a la resolución numérica de ecuaciones diferenciales

Las ecuaciones diferenciales ordinarias (EDO) que se resuelven con las funciones de esta sección deben tener la forma

       dy
       -- = F(x,y)
       dx

la cual es una EDO de primer orden. Las ecuaciones diferenciales de orden n deben escribirse como un sistema de n ecuaciones de primer orden del tipo anterior. Por ejemplo, una EDO de segundo orden debe escribirse como un sistema de dos ecuaciones,

       dx               dy
       -- = G(x,y,t)    -- = F(x,y,t) 
       dt               dt

El primer argumento de las funciones debe ser una lista con las expresiones de los miembros derechos de las EDOs. Las variables cuyas derivadas se representan por las expresiones anteriores deben darse en una segunda lista. En el caso antes citado, las variables son x y y. La variable independiente, t en los mismos ejemplos anteriores, pueden darse mediante una opción adicional. Si las expresiones dadas no dependen de esa variable independiente, el sistema recibe el nombre de autónomo.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

22.4 Funciones para la resolución numérica de ecuaciones diferenciales

Función: plotdf (dydx, ...options...)
Función: plotdf (dvdu, [u,v], ...options...)
Función: plotdf ([dxdt,dydt], ...options...)
Función: plotdf ([dudt,dvdt], [u,v], ...options...)

Dibuja un campo de direcciones en dos dimensiones x y y.

dydx, dxdt y dydt son expresiones que dependen de x y y. Además de esas dos variables, las dos expresiones pueden depender de un conjunto de parámetros, con valores numéricos que son dados por medio de la opción parameters (la sintaxis de esa opción se explica mas al frente), o con un rango de posibles valores definidos con la opción sliders.

Varias otras opciones se pueden incluir dentro del comando, o seleccionadas en el menú. Haciendo click en un punto del gráfico se puede hacer que sea dibujada la curva integral que pasa por ese punto; lo mismo puede ser hecho dando las coordenadas del punto con la opción trajectory_at dentro del comando plotdf. La dirección de integración se puede controlar con la opción direction, que acepta valores de forward, backward ou both. El número de pasos realizado en la integración numérica se controla con la opción nsteps y el incremento del tiempo en cada paso con la opción tstep. Se usa el método de Adams Moulton para hacer la integración numérica; también es posible cambiar para el método de Runge-Kutta de cuarto orden con ajuste de pasos.

Menú de la ventana del gráfico:

El menú de la ventana gráfica dispone de las siguientes opciones: Zoom, que permite cambiar el comportamiento del ratón, de manera que hará posible el hacer zoom en la región del gráfico haciendo clic con el botón izquierdo. Cada clic agranda la imagen manteniendo como centro de la misma el punto sobre el cual se ha hecho clic. Manteniendo pulsada la tecla Shift mientras se hace clic, retrocede al tamaño anterior. Para reanudar el cálculo de las trayectorias cuando se hace clic, seleccine la opción Integrate del menú.

La opción Config del menú se puede utilizar para cambiar la(s) EDO(S) y algunos otros ajustes. Después de hacer los cambios, se debe utilizar la opción Replot para activar los nuevos ajustes. Si en el campo Trajectory at del menú de diálogo de Config se introducen un par de coordenadas y luego se pulsa la tecla retorno, se mostrará una nueva curva integral, además de las ya dibujadas. Si se selecciona la opción Replot, sólo se mostrará la última curva integral seleccionada.

Manteniendo pulsado el botón derecho del ratón mientras se mueve el cursor, se puede arrastrar el gráfico horizontal y verticalmente. Otros parámetros, como pueden ser el número de pasos, el valor inicial de t, las coordenadas del centro y el radio, pueden cambiarse en el submenú de la opción Config.

Con la opción Save, se puede obtener una copia del gráfico en una impresora Postscript o guardarlo en un fichero Postscript. Para optar entre la impresión o guardar en fichero, se debe seleccionar Print Options en la ventana de diálogo de Config. Una vez cubiertos los campos de la ventana de diálogo de Save, será necesario seleccionar la opción Save del primer menú para crear el fichero o imprimir el gráfico.

Opciones gráficas:

La función plotdf admite varias opciones, cada una de las cuales es una lista de dos o más elementos. El primer elemento es el nombre de la opción, y el resto está formado por el valor o valores asignados a dicha opción.

La función plotdf reconoce las siguientes opciones:

Ejemplos:

NOTA: Dependiendo de la interface que se use para Maxima, las funciones que usan openmath, incluida plotdf, pueden desencadenar un fallo si terminan en punto y coma, en vez del símbolo de dólar. Para evitar problemas, se usará el símbolo de dólar en todos ejemplos.

Función: ploteq (exp, ...options...)

Dibuja curvas equipotenciales para exp, que debe ser una expresión dependiente de dos variables. Las curvas se obtienen integrando la ecuación diferencial que define las trayectorias ortogonales a las soluciones del sistema autónomo que se obtiene del gradiente de la expresión dada. El dibujo también puede mostrar las curvas integrales de ese sistema de gradientes (opción fieldlines).

Este programa también necesita Xmaxima, incluso si se ejecuta Maxima desde una consola, pues el dibujo se creará por el código Tk de Xmaxima. Por defecto, la región dibujada estará vacía hasta que el usuario haga clic en un punto, dé sus coordenadas a través del menú o mediante la opción trajectory_at.

La mayor parte de opciones aceptadas por plotdf se pueden utilizar también con ploteq y el aspecto del interfaz es el mismo que el descrito para plotdf.

Ejemplo:

(%i1) V: 900/((x+1)^2+y^2)^(1/2)-900/((x-1)^2+y^2)^(1/2)$
(%i2) ploteq(V,[x,-2,2],[y,-2,2],[fieldlines,"blue"])$

Haciendo clic sobre un punto se dibujará la curva equipotencial que pasa por ese punto (en rojo) y la trayectoria ortogonal (en azul).

Función: rk (ODE, var, initial, dominio)
Función: rk ([ODE1,...,ODEm], [v1,...,vm], [init1,...,initm], dominio)

La primera forma se usa para resolver numéricamente una ecuación diferencial ordinaria de primer orden (EDO), y la segunda forma resuelve numéricamente un sistema de m de esas ecuaciones, usando el método de Runge-Kutta de cuarto orden. var representa la variable dependiente. EDO debe ser una expresión que dependa únicamente de las variables independiente y dependente, y define la derivada de la variable dependiente en función de la variable independiente.

La variable independiente se representa con dominio, que debe ser una lista con cuatro elementos, como por ejemplo:

[t, 0, 10, 0.1]

el primer elemento de la lista identifica la variable independiente, el segundo y tercer elementos son los valores inicial y final para esa variable, y el último elemento da el valor de los incrementos que deberán ser usados dentro de ese intervalo.

Si se van a resolver m ecuaciones, deberá haber m variables dependientes v1, v2, ..., vm. Los valores iniciales para esas variables serán inic1, inic2, ..., inicm. Continuará existiendo apenas una variable independiente definida por la lista domain, como en el caso anterior. EDO1, ..., EDOm son las expresiones que definen las derivadas de cada una de las variables dependientes en función de la variable independiente. Las únicas variables que pueden aparecer en cada una de esas expresiones son la variable independiente y cualquiera de las variables dependientes. Es importante que las derivadas EDO1, ..., EDOm sean colocadas en la lista en el mismo orden en que fueron agrupadas las variables dependientes; por ejemplo, el tercer elemento de la lista será interpretado como la derivada de la tercera variable dependiente.

El programa intenta integrar las ecuaciones desde el valor inicial de la variable independiente, hasta el valor final, usando incrementos fijos. Si en algún paso una de las variables dependientes toma un valor absoluto muy grande, la integración será suspendida en ese punto. El resultado será una lista con un número de elementos igual al número de iteraciones realizadas. Cada elemento en la lista de resultados es también una lista con m+1 elementos: el valor de la variable independiente, seguido de los valores de las variables dependientes correspondientes a ese punto.


[ << ] [ >> ]           [Top] [Contents] [Index] [ ? ]

This document was generated by Jaime Villate on octubre, 13 2014 using texi2html 1.76.