Sei sulla pagina 1di 11

Implementação

do Método de
Runge-Kutta de
2ª e 4ª Ordem no
Scilab

rftg.development.googlepages.com

Data de criação: 25 de Abril de 2007

Versão: v0.04 – 12/MAI/2008

Autor: Ricardo Filipe Teixeira Gomes


AVISO LEGAL
Este documento foi elaborado por Ricardo Filipe Teixeira Gomes, a quem se reservam todos os
direitos.

© 2008 Ricardo Filipe Teixeira Gomes

Este documento encontra-se disponível para consulta e utilização desde que sejam respeitados
todos os direitos de autor e/ou propriedade intelectual. A cópia parcial ou integral, através de
qualquer tipo de meio, dos textos e imagens disponíveis neste documento encontra-se
expressamente proíbida a menos que o utilizador respeite os direitos de autoria e/ou
propriedade intelectual, citando para isso convenientemente o documento, e incluindo
imperterivelmente uma referência clara à página web do autor:
“rftg.development.googlepages.com”.

O material contido neste documento constitui apenas uma informação de carácter geral
baseada em experiências pessoais e não pretende de forma alguma influenciar o leitor sobre
qualquer matéria específica. O conteúdo deste documento é fornecido como uma comodidade
para os leitores e é constituído apenas por informação não vinculativa.

O conteúdo deste documento é fornecido “como está” e não se oferece qualquer garantia
sobre o mesmo. O autor do documento declina qualquer responsabilidade em caso de prejuízos
que possam ocorrer pelo facto de alguém se basear na informação contida neste documento,
uma vez que essa informação é de carácter meramente informativo, não se prometendo ou
garantindo que seja precisa, completa e actualizada. O mesmo se aplica ao conteúdo de
qualquer referência realizado no mesmo.

Quaisquer conflitos decorrentes do uso ou relacionados com este documento, ou respeitantes a


direitos de autor e/ou propriedade intelectual sobre materiais que façam parte deste
documento deverão ser regidos pela Legislação Portuguesa e sujeitos à jurisdição dos
tribunais de Portugal.

A leitura deste documento e sua utilização pressupõe a aceitação destas condições.

© 2008 Ricardo Filipe Teixeira Gomes. rftg.development.googlepages.com


Instituto Politécnico do Porto

Instituto Superior de Engenharia do Porto

Departamento de Engenharia Electrotécnica

Licenciatura em Engenharia Electrotécnica, ramo Automação e Sistemas

Disciplina de Matemática Aplicada II

Implementação do Método RK2 e RK4 no Scilab

25-04-2007

Professor/Orientador:
Prof. José Magalhães

Trabalho realizado por:


Ricardo Filipe Teixeira Gomes
Na continuação do estudo dos métodos de resolução de equações
diferenciais ordinárias foram implementados os métodos Runge-Kutta de 2ª e
4ª ordem

A fórmula geral de aplicação do método de Runge-Kutta de 2ª ordem


implementada foi:

A fórmula geral de aplicação do método de Runge-Kutta de 4ª ordem


implementada foi:

4/11
De seguida é apresentado o código desenvolvido para a implementação do
método RK2:

// (c) 2008 Ricardo Gomes - TODOS OS DIREITOS RESERVADOS


// http://rftg.development.googlepages.com
//Implementação do RK2
//v0.02 25-04-2007

clear //apaga todas as variáveis definidas

//g=input('Qual a função (introduza de modo explicitado)? ','s');


//x0=input('Qual o valor inicial de x ? ');
//xF=input('Qual é o valor final de x pertendido ? ');
//y0=input('Qual o valor inicial de y ? ');
//h=input('Qual passo de iteração h ? ');

//Parâmetros usados para teste


g = '2*x*y';
x0 = 0;
y0 = 1;
xF = 2;
h = 0.2;

//FUNÇÕES:
function out = f(x,y)
out = evstr(g)
endfunction

//Valores iniciais
x(1) = x0;
y(1) = y0;

//cálculo do comprimento dos vectores (de dados) a apresentar


c_vect = (xF-x0) / h;

//*************************** Passo h ***************************


//cálculo do nº de iterações
n_iter = (xF - x0) / h; // que neste caso é igual a 'c_vect'

for i = 1 : n_iter

k1 = h * f(x(i),y(i));
k2 = h * f(x(i) + h,y(i) + k1);

y(i+1) = y(i) + (1/2)*(k1+k2);


x(i+1) = x(i) + h;

end

//copia para o vector de saída


xsaida = x;
y1 = y;
//***************************************************************

//*************************** Passo h/2 *************************


//cálculo do nº de iterações
n_iter = (xF - x0) / (h/2);

for i = 1 : n_iter

k1 = (h/2) * f(x(i),y(i));
k2 = (h/2) * f(x(i) + (h/2),y(i) + k1);

y(i+1) = y(i) + (1/2)*(k1+k2);


x(i+1) = x(i) + (h/2);

end

//copia para o vector de saída


5/11
y2(1) = y0;
for i = 1 : c_vect
y2(i+1) = y(2*i + 1);
end
//***************************************************************

//*************************** Passo h/4 *************************


//cálculo do nº de iterações
n_iter = (xF - x0) / (h/4);

for i = 1 : n_iter

k1 = (h/4) * f(x(i),y(i));
k2 = (h/4) * f(x(i) + (h/4),y(i) + k1);

y(i+1) = y(i) + (1/2)*(k1+k2);


x(i+1) = x(i) + (h/4);

end

//copia para o vector de saída


y4(1) = y0;
for i = 1 : c_vect
y4(i+1) = y(4*i + 1);
end
//***************************************************************

//************************** Cálculo EC1 ************************


EC1(1) = 0;
for i = 1 : c_vect
EC1(i+1) = y2(i+1) - y1(i+1);
end

//***************************************************************

//************************** Cálculo EC2 ************************


EC2(1) = 0;
for i = 1 : c_vect
EC2(i+1) = y4(i+1) - y2(i+1);
end

//***************************************************************

//*********************** Cálculo da Razão **********************


RAZAO(1) = 0;
for i = 1 : c_vect
if EC2(i+1) == 0
RAZAO(i+1) = 0;
else
RAZAO(i+1) = EC1(i+1) / EC2(i+1);
end
end

//***************************************************************

printf("\n\n\n\n")
printf("*********************************\n")
printf("* Tabela método RK2 *\n")
printf("*********************************\n")
printf("\nOs parâmetros apresentados são, respectivamente:\n")
printf("\n x; y para h; y para h/2; y para h/4; Erro 1; Erro 2; Razão \n\n")

Tabela=[xsaida y1 y2 y4 EC1 EC2 RAZAO]


printf("\n\nFim.\n")
6/11
De seguida é apresentado o código desenvolvido para a implementação do
método RK4:

//Implementação do RK4
//v0.01 25-04-2007
//Elaborado por: Ricardo Gomes, nº 1020405, 4ªano EC-AS

clear //apaga todas as variáveis definidas

//g=input('Qual a função (introduza de modo explicitado)? ','s');


//x0=input('Qual o valor inicial de x ? ');
//xF=input('Qual é o valor final de x pertendido ? ');
//y0=input('Qual o valor inicial de y ? ');
//h=input('Qual passo de iteração h ? ');

//Parâmetros usados para teste


g = '2*x*y';
x0 = 0;
y0 = 1;
xF = 2;
h = 0.2;

//FUNÇÕES:
function out = f(x,y)
out = evstr(g)
endfunction

//Valores iniciais
x(1) = x0;
y(1) = y0;

//cálculo do comprimento dos vectores (de dados) a apresentar


c_vect = (xF-x0) / h;

//*************************** Passo h ***************************


//cálculo do nº de iterações
n_iter = (xF - x0) / h; // que neste caso é igual a 'c_vect'

for i = 1 : n_iter

k1 = h * f(x(i) , y(i));

k2 = h * f(x(i) + (h/2) , y(i) + (k1/2));

k3 = h * f(x(i) + (h/2) , y(i) + (k2/2));

k4 = h * f(x(i) + h , y(i) + k3);

y(i+1) = y(i) + (1/6)*(k1 + (2*k2) + (2*k3) + k4);

x(i+1) = x(i) + h;

end

//copia para o vector de saída


xsaida = x;
y1 = y;
//***************************************************************

7/11
//*************************** Passo h/2 *************************
//cálculo do nº de iterações
n_iter = (xF - x0) / (h/2);

for i = 1 : n_iter

k1 = (h/2) * f(x(i) , y(i));

k2 = (h/2) * f(x(i) + (h/4) , y(i) + (k1/2));

k3 = (h/2) * f(x(i) + (h/4) , y(i) + (k2/2));

k4 = (h/2) * f(x(i) + (h/2), y(i) + k3);

y(i+1) = y(i) + (1/6)*(k1 + (2*k2) + (2*k3) + k4);

x(i+1) = x(i) + (h/2);

end

//copia para o vector de saída


y2(1) = y0;
for i = 1 : c_vect
y2(i+1) = y(2*i + 1);
end
//***************************************************************

//*************************** Passo h/4 *************************


//cálculo do nº de iterações
n_iter = (xF - x0) / (h/4);

for i = 1 : n_iter

k1 = (h/4) * f(x(i) , y(i));

k2 = (h/4) * f(x(i) + (h/8) , y(i) + (k1/2));

k3 = (h/4) * f(x(i) + (h/8) , y(i) + (k2/2));

k4 = (h/4) * f(x(i) + (h/4), y(i) + k3);

y(i+1) = y(i) + (1/6)*(k1 + (2*k2) + (2*k3) + k4);

x(i+1) = x(i) + (h/4);

end

//copia para o vector de saída


y4(1) = y0;
for i = 1 : c_vect
y4(i+1) = y(4*i + 1);
end
//***************************************************************

//************************** Cálculo EC1 ************************


EC1(1) = 0;
for i = 1 : c_vect
EC1(i+1) = y2(i+1) - y1(i+1);
end

//***************************************************************

//************************** Cálculo EC2 ************************


EC2(1) = 0;
for i = 1 : c_vect
EC2(i+1) = y4(i+1) - y2(i+1);
end

//***************************************************************
8/11
//*********************** Cálculo da Razão **********************
RAZAO(1) = 0;
for i = 1 : c_vect
if EC2(i+1) == 0
RAZAO(i+1) = 0;
else
RAZAO(i+1) = EC1(i+1) / EC2(i+1);
end
end

//***************************************************************

printf("\n\n\n\n")
printf("*********************************\n")
printf("* Tabela método RK4 *\n")
printf("*********************************\n")
printf("\nOs parâmetros apresentados são, respectivamente:\n")
printf("\n x; y para h; y para h/2; y para h/4; Erro 1; Erro 2; Razão \n\n")

Tabela=[xsaida y1 y2 y4 EC1 EC2 RAZAO]


printf("\n\nFim.\n")

9/11
Executando ambas as aplicações no Scilab:

*********************************
* Tabela método RK2 *
*********************************
Os parâmetros apresentados são, respectivamente:

x; y para h; y para h/2; y para h/4; Erro 1; Erro 2; Razão


Tabela =
0. 1. 1. 1. 0. 0. 0.
0.2 1.04 1.040704 1.0407966 0.000704 0.0000926 7.6054915
0.4 1.171456 1.1731928 1.1734579 0.0017368 0.0002651 6.5519068
0.6 1.4282392 1.4323558 1.4331284 0.0041166 0.0007727 5.3277604
0.8 1.8829905 1.8934455 1.895774 0.0104550 0.0023284 4.4901247
1. 2.6813785 2.709057 2.7159898 0.0276785 0.0069328 3.9923906
1.2 4.1185973 4.1933082 4.2136199 0.0747108 0.0203117 3.678215
1.4 6.8138074 7.0185901 7.0778855 0.2047827 0.0592954 3.4536048
1.6 12.123126 12.695619 12.870592 0.5724927 0.1749730 3.2718915
1.8 23.16002 24.80299 25.331289 1.6429696 0.5282996 3.1099202
2. 47.431722 52.301926 53.949643 4.8702043 1.6477169 2.9557287

Fim.

*********************************
* Tabela método RK4 *
*********************************
Os parâmetros apresentados são, respectivamente:

x; y para h; y para h/2; y para h/4; Erro 1; Erro 2; Razão


Tabela =
0. 1. 1. 1. 0. 0. 0.
0.2 1.0408107 1.0408108 1.0408108 0.0000001 4.266D-09 24.166112
0.4 1.1735095 1.1735108 1.1735109 0.0000013 5.486D-08 23.391857
0.6 1.4333214 1.433329 1.4333294 0.0000076 0.0000004 19.090177
0.8 1.8964412 1.8964785 1.8964807 0.0000372 0.0000023 16.425201
1. 2.718107 2.7182702 2.7182811 0.0001631 0.0000109 14.956092
1.2 4.2199866 4.2206456 4.2206925 0.0006590 0.0000469 14.051221
1.4 7.0965959 7.0991247 7.0993133 0.0025289 0.0001886 13.407448
1.6 12.925569 12.935029 12.935763 0.0094597 0.0007337 12.89329
1.8 25.495471 25.530679 25.533507 0.0352081 0.0028281 12.449457
2. 54.453867 54.586309 54.597302 0.1324421 0.0109936 12.047226

Fim.

10/11
Conclusões

Para este caso específico (da expressão usada no teste) efectuando uma
comparação directa dos valores obtidos através do método de Euler (de 1ª ordem) e o
método de Taylor de 2ª Ordem (ver abaixo) é possível observar que ocorreu um
aumento da precisão de cálculo aquando da aplicação dos métodos de Runge-Kutta de
2ª ordem (RK2) e 4ª ordem (RK4), visto que ocorreu uma redução significativa do
erro do relativamente ao valor analítico (disponível na 2ª coluna da tabela produzida
aquando da aplicação do método de Taylor de 2ª ordem). Ignorando o valor analítico
que serve de solução à expressão em causa e, tomando como referência a estimativa
do erro (EC1 e EC2), podemos também inferir a mesma conclusão.

Apesar de avaliação do critério da Razão demonstrar alguma instabilidade do


método nas primeiras iterações, não podemos concluir que o mesmo tenda a divergir,
isto porque por norma este tipo de comportamentos ocorre para os métodos que não
fazem uso directo da derivada analítica, mas sim de uma estimação da mesma.
Uma das vantagens mais interessantes da aplicação destes dois métodos (RK2
e RK4), assim como de outros do mesmo tipo, advém da dispensa de cálculo das
várias derivadas decorrentes dos métodos semelhantes aos de Taylor, com os quais a
ordem das derivadas cresce proporcionalmente com a ordem do método, levantando
em alguns casos sérios problemas de cálculo (por exemplo derivadas de quocientes).
Apesar de eventualmente exigir mais algum esforço computacional no decurso
das iterações, os métodos RK2 e RK4 são quase sempre (senão sempre) preferíveis
quando não possuímos uma ferramenta matemática com possibilidade de cálculo
símbolo para resolução das derivadas necessárias.

Método de Taylor de 2ª ordem:

*********************************
* Tabela método Taylor 2ª ordem *
*********************************
Os parâmetros apresentados são, respectivamente:
x; y(x); y para h; y para h/2; y para h/4; Erro 1; Erro 2; Razão
Tabela =
0. 1. 1. 1. 1. 0. 0. 0.
0.2 1.0408108 1.04 1.040502 1.0407196 0.000502 0.0002176 2.3069436
0.4 1.1735109 1.168128 1.1718627 1.1730583 0.0037347 0.0011956 3.1236791
0.6 1.4333294 1.4167056 1.4284046 1.4319937 0.0116989 0.0035891 3.259548
0.8 1.8964809 1.8541843 1.8839578 1.8930814 0.0297735 0.0091236 3.2633545
1. 2.7182818 2.6166249 2.6878302 2.7099647 0.0712052 0.0221345 3.2169335
1.2 4.2206958 3.9772699 4.1464242 4.2002253 0.1691543 0.0538011 3.1440693
1.4 7.0993271 6.5036318 6.9133307 7.0474891 0.4096990 0.1341584 3.053845
1.6 12.935817 11.42558 12.451365 12.799052 1.0257847 0.3476866 2.9503143
1.8 25.533722 21.534934 24.211098 25.154888 2.6761647 0.9437900 2.8355509
2. 54.59815 43.483338 50.794026 53.490859 7.3106883 2.6968328 2.7108422

Fim.

Método de Euler:

0. 1. 1. 1. 0. 0. 0.
0.2 1. 1.02 1.0302757 0.02 0.0102757 1.94633
0.4 1.08 1.124448 1.1482993 0.044448 0.0238513 1.8635484
0.6 1.2528 1.3358442 1.3824406 0.0830442 0.0465964 1.7822037
0.8 1.553472 1.7056059 1.7951229 0.1521339 0.0895170 1.699497
1. 2.050583 2.3346334 2.5106623 0.2840503 0.1760290 1.6136569
1.2 2.8708163 3.4179032 3.7769489 0.5470870 0.3590457 1.5237253
1.4 4.2488081 5.340132 6.1035986 1.091324 0.7634665 1.4294326
1.6 6.6281406 8.8859797 10.582204 2.2578391 1.6962242 1.3310971
1.8 10.870151 15.717521 19.660012 4.8473703 3.9424907 1.2295198
2. 18.696659 29.498643 39.092999 10.801984 9.5943562 1.1258686

11/11

Potrebbero piacerti anche