29.12.2014 Views

MÉTODOS NUMÉRICOS

MÉTODOS NUMÉRICOS

MÉTODOS NUMÉRICOS

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

<strong>MÉTODOS</strong> <strong>NUMÉRICOS</strong><br />

<strong>MÉTODOS</strong> DE APROXIMACIÓN DE RAÍCES<br />

(MÉTODO DE BISECCIÓN)<br />

Luís Roberto Olascoaga Surmay<br />

Universidad de Córdoba<br />

Facultad de Ciencias Básicas e Ingenierías<br />

Departamento de Ingeniería de Sistemas y Telecomunicaciones


CURSO: Métodos Numéricos<br />

TEMA: Métodos de aproximación de raíces (Método de bisección)<br />

DESCRIPCION: Desarrollo practico del tema del método de bisección para<br />

aproximación de raíces empleando un lenguaje de programación orientado a<br />

objetos, diseño e implementación de clases y aplicado a una función<br />

matemática particular.<br />

OBJETIVO: Diseñar e implementar en lazarus una clase para realizar la<br />

aproximación de los ceros de una función matemática dada usando el método<br />

de bisección.<br />

PALABRAS CLAVES: Métodos de aproximación de raíces, teorema del valor<br />

medio, funciones continuas, recursividad, ceros de una función, intervalos<br />

numéricos, errores de redondeo relativos, funciones de retrollamada, diseño de<br />

eventos, punteros a funciones, programación orientada a objetos, diseño de<br />

clases, implementación con eventos.<br />

AUTOR: Lic. Luis Olascoaga Surmay<br />

DESARROLLO: A continuación se presenta el diseño y la implementación de<br />

en lazarus de una clase para hallar los ceros de una función matemática<br />

especifica, dando como entrada un intervalo y una tolerancia porcentual para el<br />

control del error de redondeo relativo entre cada par de aproximaciones<br />

seguidas encontradas por el método. Analice la teoría expuesta en clase y<br />

consulte otras fuentes acerca del método de bisección y en particular del<br />

algoritmo seguido por este para encontrar las aproximaciones a los ceros de<br />

una función continua en un intervalo dado. A continuación estudie, pase, revise<br />

y compile el código presentado habiendo creado el proyecto correspondiente


en lazarus. Diseñe la ventana como se indica al final y haga la programación de<br />

los eventos correspondientes usando instancia de la clase presentada.<br />

unit ubiseccion;<br />

{$mode objfpc}{$H+}<br />

interface<br />

uses Classes, SysUtils;<br />

type<br />

{<br />

Evento para función callback que captura cada raíz<br />

con el error de redondeo relativo respectivo.<br />

}<br />

TOnCalcRaiz = procedure(xr,error:real) of object;<br />

{ TBiseccion }<br />

TBiseccion = class<br />

private<br />

Xa:double;<br />

Xb:double;<br />

Tol:double;<br />

CalcRaiz:TOnCalcRaiz;<br />

public<br />

constructor Create;<br />

procedure SetXa(ValXa:double);<br />

procedure SetXb(ValXb:double);<br />

procedure SetTol(ValTol:double);<br />

procedure SetCalcRaiz(ProCal:TOnCalcRaiz);<br />

function GetXa:double;<br />

function GetXb:double;<br />

function GetTol:double;<br />

function GetCalcRaiz:TOnCalcRaiz;<br />

function ValorFx(x:double):double;<br />

function ValidaIntervalo:boolean;<br />

function CalcError(xact,xant:double):double;<br />

procedure Aproximar;<br />

end;<br />

implementation<br />

{ TBiseccion }<br />

constructor TBiseccion.Create;<br />

begin<br />

Xa:=0;<br />

Xb:=0;


Tol:=0;<br />

CalcRaiz:=nil;<br />

end;<br />

procedure TBiseccion.SetXa(ValXa: double);<br />

begin<br />

Xa:=ValXa;<br />

end;<br />

procedure TBiseccion.SetXb(ValXb: double);<br />

begin<br />

Xb:=ValXb;<br />

end;<br />

procedure TBiseccion.SetTol(ValTol: double);<br />

begin<br />

Tol:=ValTol;<br />

end;<br />

procedure TBiseccion.SetCalcRaiz(ProCal: TOnCalcRaiz);<br />

begin<br />

CalcRaiz:=ProCal;<br />

end;<br />

function TBiseccion.GetXa: double;<br />

begin<br />

result:=Xa;<br />

end;<br />

function TBiseccion.GetXb: double;<br />

begin<br />

result:=Xb;<br />

end;<br />

function TBiseccion.GetTol: double;<br />

begin<br />

result:=Tol;<br />

end;<br />

function TBiseccion.GetCalcRaiz: TOnCalcRaiz;<br />

begin<br />

result:=CalcRaiz;<br />

end;<br />

function TBiseccion.ValorFx(x: double): double;<br />

begin<br />

result:=Exp(­x)­Ln(x);<br />

end;<br />

function TBiseccion.ValidaIntervalo: boolean;<br />

begin<br />

result:=(ValorFx(Xa)*ValorFx(Xb))


function TBiseccion.CalcError(xact,xant: double): double;<br />

begin<br />

result:=Abs((xact­xant)/xact)*100;<br />

end;<br />

procedure TBiseccion.Aproximar;<br />

var<br />

a,b,xr:double;<br />

ant,err,prod:double;<br />

begin<br />

a:=Xa;<br />

b:=xb;<br />

ant:=0;<br />

repeat<br />

xr:=(a+b)/2;<br />

err:=CalcError(xr,ant);<br />

if Assigned(CalcRaiz) then<br />

CalcRaiz(xr,err);<br />

prod:=ValorFx(a)*ValorFx(xr);<br />

if prod0 then<br />

a:=xr;<br />

ant:=xr;<br />

until (prod=0)or(Err


En la sección private del formulario (clase de la ventana) asegúrese de declarar<br />

el siguiente procedimiento que será el evento (función de retrollamada) para<br />

capturar cada raíz obtenida por la clase TBiseccion y presentarla hasta la<br />

matriz (TStringGrid) de la ventana:<br />

private<br />

procedure AgregaRaiz(xr,error:real);<br />

Pulse shift + ctrl + c e implemente este método como se ilustra a continuación:<br />

procedure TForm1.AgregaRaiz(xr, error: real);<br />

var<br />

Fila:Integer;<br />

begin<br />

if Datos.Cells[0,1]'' then<br />

Datos.RowCount:=Datos.RowCount + 1;<br />

Fila:=Datos.RowCount­1;<br />

Datos.Cells[0,Fila]:=FloatToStr(xr);<br />

if Fila>1 then<br />

Datos.Cells[1,Fila]:=FormatFloat('0.00',error);<br />

end;<br />

El código para el evento click del botón aproximar es el siguiente:<br />

procedure TForm1.Button1Click(Sender: TObject);<br />

var<br />

Bis:TBiseccion;<br />

begin<br />

Datos.RowCount:=2;<br />

Datos.Rows[1].Clear;<br />

Bis:=TBiseccion.Create;<br />

Bis.SetXa(StrToFloat(Exa.Text));<br />

Bis.SetXb(StrToFloat(Exb.Text));<br />

Bis.SetTol(StrToFloat(ETol.Text));<br />

if Bis.ValidaIntervalo then<br />

begin<br />

Bis.SetCalcRaiz(@AgregaRaiz);<br />

Bis.Aproximar;<br />

end<br />

else<br />

begin<br />

ShowMessage('Intervalo no apropiado');<br />

Exa.SetFocus;<br />

end;<br />

Bis.Free;<br />

end;


Pruebe la aplicación con las entradas indicadas en la siguiente pantalla:

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!