Está en la página 1de 3

Examen 01 - Programación e introducción a los métodos numéricos

William Oquendo, woquendo@gmail.com

Contents
1 (2.5/5.0) Derivadas de primer orden: comparación de diversos métodos 1

2 (1.0/5.0) BONO: Gráfica del error de las derivadas numéricas 2

3 (2.5/5.0) Derivada de orden 2 2

Abstract
Solamente se califica lo enviado al repositorio asignado hasta la hora límite. Debe estar presente en el salón
para presentar el examen. Para cada ejercicio cree un archivo con el numero de ejercicio y la extensión apropiada.
Por ejemplo, si en el problema 1 le piden hacer un programa, entonces la solución sería un archivo llamado 1.cpp .
Pero si en el ejercicio 5 le piden responder o hacer un análisis, entonces la solución se escribiría en un archivo 5.txt .
Cada archivo de respuesta debe estar incluido en el repositorio pero en commits diferentes. A menos que se indique
lo contrario, ningún programa deberá pedir entrada de usuario. Haga uso de lo visto hasta ahora en el curso, además
de lo que se pide explícitamente en cada punto. Si un programa no compila y/o no se ejecuta correctamente tendrá
nota 0.0 . Debe hacer uso de funciones.

1 (2.5/5.0) Derivadas de primer orden: comparación de diversos méto-


dos
El objetivo de este problema es comparar los diferentes métodos de derivación estudiados en clase. La función a usar es

f (x) = e−2x − x. (1)

Guarde el código en el archivo 1.cpp. El código debe incluir las siguientes funciones:
• una función que retorne f (x).
• una función que retorne la derivada forward, y que reciba x y el paso h, para ser llamada como ( forward(x, h) ).
• una función que retorne la derivada central, y que reciba x y el paso h, para ser llamada como ( central(x, h) ).
• una función que retorne la derivada de richardson, y que reciba x y el paso h, para ser llamada como ( richardson(x,
h) ).
• una función que retorne la derivada teórica f 0 (x).
Y obviamente la función main y las funciones matemáticas que requiera. Su código debe imprimir una tabla de la
diferencia porcentual de cada uno de los tres métodos de derivación respecto al valor exacto, como función de h. Tome
x = 2 y h = {0.001, 0.002, 0.003, . . . , 0.500}. La función main debe ser algo como

int main(void)
{
std::cout.precision(16);
std::cout.setf(std::ios::scientific);

const double x = 2.0;


double h = 0;
double deltac, deltaf, deltar; // percentual diffs

1
for (int ii = 1; ii <= 500; ++ii) {
h = 0.001*ii;
deltac = std::fabs(1.0 - central(x,h)/deriv_exact(x));
deltaf = std::fabs(1.0 - forward(x,h)/deriv_exact(x));
deltar = std::fabs(1.0 - richardson(x,h)/deriv_exact(x));
std::cout << h << " \t" << deltac << "\t" << deltaf << "\t" << deltar << "\n";
}

return 0;
}

La salida de su código deber ser algo como

1.0000000000000000e-03 5.8897646759703548e-09 3.5313297912731301e-05 1.6964207816272392e-13


2.0000000000000000e-03 2.3557800155060704e-08 7.0579550669580549e-05 4.1966430330830917e-13
3.0000000000000001e-03 5.3005311251297371e-08 1.0579882860817236e-04 3.1086244689504383e-15
.. .. .. ..
. . . .
5.0000000000000000e-01 1.4908830399154027e-03 1.2999698433818652e-02 4.6355114257101704e-06

2 (1.0/5.0) BONO: Gráfica del error de las derivadas numéricas


Usando la salida del punto anterior, haga una gráfica del error porcentual de cada uno de los métodos en función de h.
Utilice escala log-log (en gnuplot puede sar el comando set log xy). Guarde la figura en el archivo 2.pdf. No
olvide colocarle título a cada línea de datos y a los ejes. Debe obtener leyes de potencias (rectas en escala log-log) en
donde se observa que el método de Richardson siempre es el mejor. La forma de crear un archivo pdf es (una vez tenga
listo todo)

set term pdf ; set out "2.pdf"; replot; set term x11; set out "null.pdf"

3 (2.5/5.0) Derivada de orden 2


La segunda derivada de una función puede calcularse como

d2 f (x) [f (x + h) − f (x)] − [f (x) − f (x − h)]


2
' , (2)
dx h2
1. re-organizando los términos,
d2 f (x) f (x + h) + f (x − h) − 2f (x)
' . (3)
dx2 h2
Escriba un programa que calcule la segunda derivada usando las dos aproximaciones mostradas, como función de h.
Guarde el programa en el archivo 3.cpp. Use x = π/6, y h = π × {10−1 , 10−2 , . . . , 10−16 }. Su programa debe
imprimir algo como
3.1415926535897931e-01 8.1976598890984853e-03 8.1976598890972641e-03
3.1415926535897934e-02 8.2243997575170980e-05 8.2243997575170980e-05
3.1415926535897933e-03 8.2245085908372317e-07 8.2245085908372317e-07
.. .. ..
. . .
3.1415926535897929e-16 1.2989123698962140e+15 2.5978247397924290e+15
La función main debe ser como

2
int main(void)
{
std::cout.precision(16);
std::cout.setf(std::ios::scientific);
const double x = M_PI/6.0;
double h = 0;
double delta1, delta2; // percentual diffs
for (int ii = 1; ii <= 16; ++ii) {
h = M_PI*std::pow(10.0, -ii);
delta1 = std::fabs(1.0 - deriv2a(x,h)/deriv2_exact(x));
delta2 = std::fabs(1.0 - deriv2b(x,h)/deriv2_exact(x));
std::cout << h << " \t" << delta1 << "\t" << delta2 << "\n";
}

return 0;
}

Como puede ver, la primera forma produce menos error.