Last active
August 10, 2017 04:10
-
-
Save reeichert/3bf82bbfae27113d3dd335335e87dbb6 to your computer and use it in GitHub Desktop.
Trabalho de calculo numérico onde é apresentado a Formula de Euler, Euler melhorado e Runge Kutta para calcular uma EDO de circuito elétrico de 2 ordem.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Site utilizado para execução durante a apresentação | |
// https://swift.sandbox.bluemix.net/ | |
import Foundation | |
// Extensão utilizada para arredondar as casas decimais | |
extension Double { | |
func roundTo(_ places:Int) -> Double { | |
let divisor = pow(10.0, Double(places)) | |
return (self * divisor).rounded() / divisor | |
} | |
} | |
/***************** | |
* | |
* Método de Euler | |
* - Chega no resultado de 0.0134 com 499750 iterações e utilizando h = 0,000001 | |
* demorando 27,3 segundos | |
*/ | |
// main | |
private func f(_ x:Double) -> Double { | |
//i' = -20 * exp(-10t) | |
return -20.0 * exp((-10 * x)) | |
} | |
public func euler(xo:Double, yo:Double, xf:Double, h:Double) { | |
var yn1:Double = yo | |
var yn:Double = yo | |
var xn:Double = xo | |
var count:Int = 0 | |
for i in stride(from: xo, through: xf - h, by: h) { | |
yn1 = yn + (h * (f(xn))) | |
count += 1 | |
// utilizado para jogar no console todos os dados obtido, nao necessario para execução | |
//print("\(count): i(\(i.roundTo(4))) = \(yn1.roundTo(6))") | |
yn = yn1 | |
xn += h | |
} | |
print("i(\(xf)) = \(yn1.roundTo(6))") | |
print("iterações: \(xf/h)") | |
} | |
euler(xo: 0.0, yo: 2.0, xf: 0.5, h: 0.0001) | |
/***************** | |
* | |
* Método de Euler Melhorado | |
* - Chega no resultado de 0.0134 com 500 iterações e utilizando h = 0,001 | |
* demorando 40 milisegundos | |
*/ | |
private func f(_ x:Double) -> Double { | |
//i' = -20 * exp(-10t) | |
return -20.0 * exp((-10 * x)) | |
} | |
public func eulerMelhorado(xo:Double, yo:Double, xf:Double, h:Double) { | |
var yn1:Double = yo | |
var yn1m:Double = yo | |
var yn:Double = yo | |
var xn:Double = xo | |
var xn1:Double = xo | |
var count:Int = 0 | |
for i in stride(from: xo, through: xf - h, by: h) { | |
yn1 = yn + (h * (f(xn))) | |
xn1 = xn + h | |
yn1m = yn + (h * (f(xn) + f(xn1))/2.0) | |
count += 1 | |
// utilizado para jogar no console todos os dados obtido, nao necessario para execução | |
//print("\(count): i(\(i.roundTo(4))) = \(yn1.roundTo(6))") | |
yn = yn1m | |
xn += h | |
} | |
print("i(\(xf)) = \(yn1m.roundTo(6))") | |
print("iterações: \(xf/h)") | |
} | |
eulerMelhorado(xo: 0.0, yo: 2.0, xf: 0.5, h: 0.0001) | |
/***************** | |
* | |
* Método de Runge-Kutta | |
* - Chega no resultado de 0.0134 com 50 iterações e utilizando h = 0,01 | |
* demorando 0,73 milisegundos | |
*/ | |
private func f(_ x:Double) -> Double { | |
//i' = -20 * exp(-10t) | |
return -20.0 * exp((-10 * x)) | |
} | |
public func rungeKutta(xo:Double, yo:Double, xf:Double, h:Double) { | |
var yn1:Double = yo | |
var yn:Double = yo | |
var xn:Double = xo | |
var count:Int = 0 | |
for i in stride(from: xo, through: xf - h, by: h) { | |
let k1 = h * f(xn) | |
let k2 = h * f(xn + h/2.0) | |
let k3 = h * f(xn + h/2.0) | |
let k4 = h * f(xn + h) | |
yn1 = yn + (k1 + (2.0 * k2) + (2.0 * k3) + k4)/6.0 | |
count += 1 | |
// utilizado para jogar no console todos os dados obtido, nao necessario para execução | |
//print("\(count): i(\(i.roundTo(4))) = \(yn1.roundTo(6))") | |
yn = yn1 | |
xn += h | |
} | |
print("i(\(xf)) = \(yn1.roundTo(6))") | |
print("iterações: \(xf/h)") | |
} | |
rungeKutta(xo: 0.0, yo: 2.0, xf: 0.5, h: 0.01) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment