Skip to content

Instantly share code, notes, and snippets.

@reeichert
Last active August 10, 2017 04:10
Show Gist options
  • Save reeichert/3bf82bbfae27113d3dd335335e87dbb6 to your computer and use it in GitHub Desktop.
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.
// 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