Introducción informal a Matlab y Octave - Ejercicios resueltos (I)
05 de Noviembre de 2006
Encriptación
Este capítulo se basa en los ejemplos. Se propondrán una serie de ejercicios, se comentarán los algoritmos necesarios para resolverlos y finalmente se dará la solución a cada uno de ellos.
Esto genera una ley un poco paradójica: cuanto menos programemos mejores serán nuestros scripts. Uno puede pensar que el código que escribe uno mismo es mejor, que si al intérprete le pasamos todas las líneas que debe usar irá más rápido. Que si tenemos que cargar más funciones en memoria haremos que la ejecución vaya más lenta... Es justo lo contrario. La mayoría de las funciones en Octave, por ejemplo, son funciones escritas en C++ o en Fortran compiladas de una manera especial para que Octave las interprete. Significa que la velocidad de ejecución de estas subrutinas será mucho más cercana a la velocidad de los programas binarios que a la del intérprete.
Que genera una matriz de menor tamaño al perder los extremos. Escribir la función que devuelve el resultado en una variable tipo estructura: grad.x=δx′(M) y grad.y=δy′(M).
y representarla en el espacio.
La función lsode es mucho más versátil que las funciones para la integración de ecuaciones diferenciales de Matlab. También lo es en el sentido que es menos rigurosa en la manera de escribir la función, en este caso hemos escrito la variable xdot en forma de vector columna como nos obliga Matlab pero aceptaría igualmente el uso de un vector columna.
Octave permite definir la función en el script de modo que podemos resolver el problema con un único archivo.
tiene como resultado π. Calcular la solución con un único comando.
Por si alguien aún no está trabajando con Octave esta es la ayuda de la función quad2dg.
Metodología de programación
Quizás el mayor punto fuerte de Matlab o Octave no es su sencillez o su productividad sino la gran cantidad de funciones útiles que nos proporcionan. El núcleo de Matlab son sólo unos pocos Mbytes, en cambio la instalación completa ocupa tres CD-ROMs. Todo son funciones y archivos cuya razón de ser es hacernos la vida mucho más fácil.Esto genera una ley un poco paradójica: cuanto menos programemos mejores serán nuestros scripts. Uno puede pensar que el código que escribe uno mismo es mejor, que si al intérprete le pasamos todas las líneas que debe usar irá más rápido. Que si tenemos que cargar más funciones en memoria haremos que la ejecución vaya más lenta... Es justo lo contrario. La mayoría de las funciones en Octave, por ejemplo, son funciones escritas en C++ o en Fortran compiladas de una manera especial para que Octave las interprete. Significa que la velocidad de ejecución de estas subrutinas será mucho más cercana a la velocidad de los programas binarios que a la del intérprete.
8.1 Ejercicio. Cálculo de un gradiente
Un cálculo muy común con una muestra de datos bidimensional es calcular una especie de gradiente numérico definido como:| grad(M)= | 漂R> 缂R> 缂R> 缂R> 缂R> 缂R> 缂R> 輯FONT> |
|
?> ?> ?> ?> ?> ?> ?> ?NT> | = | 漂R> 輯FONT> |
|
?> ?NT> |
8.1.1 Guía para la resolución del ejercicio
Lo más complicado de este ejercicio es entender el enunciado. En el fondo es exactamente el mismo cálculo que un gradiente numérico con la diferencia de que en este caso no nos importa la distancia entre los puntos. Lo más práctico para calcular la fórmula es construir una submatriz por cada elemento de la ecuación en diferencias; para calcular la submatriz es necesario saber que el último elemento de cualquier matriz o vector se puede llamar end. Por ejemplo, si nosotros queremos los elementos del quinto al último del vector u pero no sabemos sus dimensiones, en vez de calcularlo lo más práctico es hacer > > u(5:end).8.1.2 Solución del ejercicio
function[grad]=mygradient(M) grad.x = 0.5*(M(:,3:end)-M(:,1:end-2)); grad.y = 0.5*(M(3:end,:)-M(1:end-2,:));
8.2 Ejercicio. Diseño de una tobera
Queremos diseñar una tobera convergente divergente. Para ello impondremos que el radio de salida sea 10 veces mayor que el radio de la garganta, y que la tobera se forma mediante dos parábolas, una con eje en y y otra con eje en x. Las condiciones serán que en el punto de empalme de los dos arcos haya continuidad tanto de la función como de la derivada primera. Las dos funciones a ajustar serán entonces (con el problema convenientemente adimensionalizado)y-=Px2+0.1 y+=Ax+B
Entonces tenemos el sistema de ecuaciones siguiente, donde l es el punto en x donde se empalman los dos arcos:
| 2Pl= |
|
Pl2+0.1=Ax+B
A+B=1
Donde se demuestra que existe solución para P aproximadamente 0.9<P<1.2.
- Resolver el sistema de ecuaciones anterior y representar las soluciones de P=0.9, P=1 y P=1.2
8.2.1 Guía para la resolución del ejercicio
Lo primero que debemos hacer es entender el enunciado, para ver más claro lo que se pide, es bueno dibujar las dos curvas que se nos proponen, para ello haremos;octave:1> fplot('[x. ^2+0.1,sqrt(x)]',[0,1])
Para resolver numéricamente sistemas de ecuaciones lineales usaremos la función fsolve. Para saber cómo funciona teclearemos en la línea de comandos: octave:2> help fsolve
8.2.2 Solución del ejercicio
El script que nos resuelve el problema es el siguiente:function[f]=ttb(x)
global Pi
f(1)=x(1)/(2*sqrt(x(1)*x(3)+x(2)))-2*Pi*x(3);
f(2)=Pi*x(3)**2+0.1-sqrt(x(1)*x(3)+x(2));
f(3)=sqrt(x(1)+x(2))-1;
end
function[f]=tobera(x,a,b,l,P)
if x<l
f=P*(x*x)+0.1;
else
f=sqrt(a*x+b);
endif
end
x0=[1 1 1];
P=[0.9 1 1.2];
hold on
for i=1:3
global Pi
Pi=P(i);
[res]=fsolve('ttb',x0);
xcoord=linspace(0,1,100);
for j=1:100
tob(j)=tobera(xcoord(j),res(1),res(2),res(3),P(i));
end
plot(xcoord,tob)
end
hold off
El resultado lo vemos en la figura 8.1.
Figure 8.1: Resultado del script
8.3 Ejercicio. El atractor de Lorentz
Se quiere integrar la ecuación diferencial del Atractor de Lorentz, de ecuaciones:
|
con a=10, b=28, c= |
|
8.3.1 Guía para la resolución del Ejercicio
- Primero escribimos la función correspondiente a la ecuación diferencial. En las subrutinas de resolución de EDOs siempre tenemos que introducir la función de la forma dx/dt=f(x,t) pudiendo ser cualquiera de las variables un vector.
- La rutina de Octave que nos integra la ecuación diferencial es lsode; en Matlab utilizaremos ode45 porque el problema no es stiff. Utilizar la ayuda para saber de qué manera tenemos que escribir la función de la ecuación diferencial.
- El comando para representar curvas paramétricas en 3 dimensiones es plot3.
- Escribiremos todo en un script y lo ejecutaremos
8.3.2 Solución del ejercicio
8.3.2.1 Octave
x=0; function xdot=func(x,t) a=10;b=28;c=8/3; xdot(1,1)=a*(x(2)-x(1)); xdot(2,1)=x(1)*(b-x(3))-x(2); xdot(3,1)=x(1)*x(2)-c*x(3); end x0=[1;1;1]; t=linspace(0,50,5000); tic;x=lsode( "func ",x0,t);toc plot3(x(:,1),x(:,2),x(:,3))dando como resultado la figura 8.2:
y el tiempo necesario para resolver la EDO que es de 3.1488 segundos
Figure 8.2: Resultado del script
La función lsode es mucho más versátil que las funciones para la integración de ecuaciones diferenciales de Matlab. También lo es en el sentido que es menos rigurosa en la manera de escribir la función, en este caso hemos escrito la variable xdot en forma de vector columna como nos obliga Matlab pero aceptaría igualmente el uso de un vector columna.
Octave permite definir la función en el script de modo que podemos resolver el problema con un único archivo.
8.3.2.2 Octave no stiff
El método de integración por defecto es explícito de modo que podemos acelerar el proceso si utilizamos un esquema Adams-Bashforth incluyendo este comando en el script:lsode_options('integration method','non-stiff')
Podemos hacerlo sin miedo porque el problema del atractor de Lorentz, aunque es caótico, no es stiff. El tiempo de ejecución desciende a 2.0016 segundos.8.3.2.3 Octave y C++
Ya hemos visto que podemos utilizar funciones escritas en otros lenguajes para aumentar la velocidad de nuestros scripts. En el caso de este ejercicio la velocidad conseguida por la función lsode es aceptable pero podemos rebajarla bastante más escribiendo la función de la ecuación diferencial en C++ y utilizando la aplicación mkoctfile. Ya hemos aprendido a hacerlo en la sección 7.4. Supongamos que ya disponemos del archivo eqlorentz.oct que usaremos del mismo modo que cualquier función. El script que resuelve el problema es:t=linspace(0,50,5000); tic;x=lsode( "eqlorentz ",[1;1;1],t);toc plot3(x(:,1),x(:,2),x(:,3))La nueva versión del script es capaz de resolver el problema en tan sólo 0.28444 segundos que es el 10% del tiempo anterior.
8.3.2.4 Octave y C++ no stiff
La máxima optimización se consigue de este modo. El tiempo se rebaja hasta 0.17314 segundos. Aunque todas estas consideraciones sobre velocidad pueden parecer inútiles debemos tener en cuenta que la integración de EDOs y EDPs son los problemas numéricos más exigentes en lo que respecta a uso de CPU. Entrar en este tipo de discusiones a menudo comporta grandes beneficios aunque en este caso sean irrisorios. Este último tiempo es comparable al obtenido con código enteramente escrito en C++ y sólo un poco más lento que el escrito en C o Fortran y el esfuerzo necesario para escribir el programa ha sido mucho menor.18.3.2.5 Octave, C++ y Fortran
Fortran es el lenguaje del cálculo matricial por excelencia. Hemos visto ya la manera de producir wrappers para funciones en Fortran. Su utilidad, más que para escribir pequeñas funciones donde el wrapper puede ser más largo que el código útil, es la de acoplar subrutinas que hagan uso de grandes cantidades de memoria con distintas precisiones en coma flotante. La velocidad de Fortran es aproximadamente la misma que la de C++ pero aporta ventajas distintas a la velocidad por lo dicho anteriormente.8.3.2.6 Matlab
En Matlab necesitaremos dos archivos. El archivo de función devuelve el resultado en forma de vector columna (lorentz.m):function xdot=lorentz(t,x) a=10;b=28;c=8/3; xdot(1,1)=a*(x(2)-x(1)); xdot(2,1)=x(1)*(b-x(3))-x(2); xdot(3,1)=x(1)*x(2)-c*x(3); endFijémonos que el orden de las variables de la cabecera x y t cambian según la rutina que usemos. El script será:
x=0;t=0; tic;[t,x]=ode45(@lorentz,[0,50],[1,1,1]);toc plot3(x(:,1),x(:,2),x(:,3))
8.4 Ejercicio. Cálculo de una integral doble
La integral| I= | ∫ |
|
∫ |
|
e-(x2+y2)dx dy |
8.4.1 Guía para la resolución del ejercicio
La función que implementa la integral doble en matlab es dblquad mientras que en Octave es quad2dg. Ambas funciones tienen una cabecera idéntica, las únicas diferencias son el nombre y el algoritmo de cálculo. Para pasarles la función a integrar como argumento usaremos una sentencia inline o con una función anónima. Las rutinas de integración tienen muchos problemas con las singularidades porque trabajan con una precisión limitada, esto nos impide usar límites de integración demasiado grandes y ni mucho menos podremos usar Inf . Con [-10,10]כ-10,10] vamos a conseguir 5 cifras significativas.Por si alguien aún no está trabajando con Octave esta es la ayuda de la función quad2dg.
>> help quad2dg
quad2dg is the user-defined function from the file
/usr/share/octave/2.1.64/site/m/octave-forge/integration/quad2dg.m
usage: int = quad2dg('Fun',xlow,xhigh,ylow,yhigh)
or
int = quad2dg('Fun',xlow,xhigh,ylow,yhigh,tol)
This function is similar to QUAD or QUAD8 for 2-dimensional integration,
but it uses a Gaussian quadrature integration scheme.
int -{}- value of the integral
Fun -{}- Fun(x,y) (function to be integrated)
xlow -{}- lower x limit of integration
xhigh -{}- upper x limit of integration
ylow -{}- lower y limit of integration
yhigh -{}- upper y limit of integration
tol -{}- tolerance parameter (optional)
Note that if there are discontinuities the region of integration
should be broken up into separate pieces. And if there are singularities,
a more appropriate integration quadrature should be used
(such as the Gauss-Chebyshev for a specific type of singularity).
8.4.2 Solución del ejercicio
Tenemos múltiples opciones:- Con inline
- Matlab:
>> dblquad(inline('exp(-(x.*x+y.*y))'),-10,10,-10,10) ans = 3.1416 - Octave:
>> quad2dg(inline('exp(-(x.*x+y.*y))'),-10,10,-10,10) ans = 3.1416
- Matlab:
- Con una función anónima:
- Matlab:
>> dblquad(@(x,y) exp(-(x. ^2+y. ^2)),-10,10,-10,10) ans = 3.1416
- Octave:
>> quad2dg(@(x,y) exp(-(x. ^2+y. ^2)),-10,10,-10,10) ans = 3.1416
- Matlab:
Valora este capítulo:
Autor y licencia de 'Introducción informal a Matlab y Octave - Ejercicios resueltos (I)'
|
Opiniona sobre 'Introducción informal a Matlab y Octave - Ejercicios resueltos (I)' (8)
Tu nombre debe tener tres caracteres como mínimo.
Es necesario que te des de alta con una cuenta de correo válida.
Es necesario que te des de alta con una cuenta de correo válida.
El contenido del título de tu opinión debe tener tres caracteres como mínimo.
Es obligatorio que selecciones una valoración del recurso.
El contenido del comentario de tu opinión debe tener tres caracteres como mínimo.
Opina sobre este tutorial |
Wikis relacionados con 'Introducción informal a Matlab y Octave - Ejercicios resueltos (I)'
Josep Palau i Fabre, poeta barcelonés nacido en 1917, es uno de los máximos representantes...
Más »
En los últimos años, el desarrollo basado en componentes se ha convertido en una de...
Más »
Este es el Diccionario de Plantas Mágicas elaborado por nosotr@s. Esta basado en nuestra propia...
Más »
Reflexión panorámica de los famosos aforismos en El Libro de amigo y de Amante, del...
Más »
El objetivo de este trabajo es dilucidar en lo posible las dimensiones de la intertextualidad...
Más »


