MÉTODOS NUMÉRICOS
MÉTODOS NUMÉRICOS
MÉTODOS NUMÉRICOS
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((xactxant)/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.RowCount1;<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: