Hora de implementarmos os métodos de Euler descritos na seção anterior.
Vamos ver variações do modelo de crescimento natural. Primeiramente, vamos considerar o modelo clássico, de uma equação diferencial ordinária com um parâmetro constante, representando a taxa de crescimento específico. Depois, vamos permitir que seja uma variável aleatória, representando uma incerteza no parâmetro. Em seguida, vamos considerar o caso em que é um processo aleatório, representando uma variabilidade temporal aleatória no parâmetro. Por último, vamos considerar novamente constante mas com a equação perturbada por um termo estocástico,
Usaremos apenas dois pacotes do Julia. Um é o Plots.jl, para visualização das soluções. O outro é o Random, da biblioteca padrão, apenas para fixar a reprodução das notas (gerar sempre os mesmos conjuntos de números aleatórios, por motivos didáticos e de controle de versão).
using Plots
theme(:ggplot2)
using Random
rng = Xoshiro(123)
Consideramos o problema de crescimento populacional
Para cada fixo, temos a solução para
Resolvendo o problema de valor inicial pelo método de Euler, em um intervalo com e um passo de tempo obtemos a sequência de valores aproximados
onde é um inteiro mais próximo de
Escolhemos valores para e além de :
t0 = 0.0 T = 20.0 μ = 0.1 x₀ = 0.2 nothing
Escolhemos, também, um valor para o passo de tempo, obtendo a malha temporal:
Δt = 0.2 t = t0:Δt:T
Isso nos dá pontos na malha, onde
N = Int(round(T/Δt))
Podemos pré-alocar um vetor para a solução numérica:
x = Vector{Float64}(undef, N+1) nothing
Iniciando o vetor com o valor de e iterando de acordo com o método de Euler, obtemos a solução numérica aproximada:
x[1] = x₀
for n in 2:N+1
x[n] = (1.0 + μ * Δt)x[n-1]
end
De posse da solução podemos visualizar o crescimento exponencial e compará-lo com a solução exata
plot(t, x, title="Crescimento exponencial \$(x_0 = $x₀, \\mu = $μ, T = $T, \\Delta t = $Δt)\$", titlefont = 10, xlabel = "t", ylabel="x", label="aproximação")
plot!(t, t -> x₀ * exp(μ * t), label="sol. exata")
Refinando a malha, obtemos uma solução mais próxima, onde quase não vemos diferença:
Δt = 0.02
t = t0:Δt:T
N = Int(round(T/Δt))
x = Vector{Float64}(undef, N+1)
x[1] = x₀
for n in 2:N+1
x[n] = (1.0 + μ * Δt)x[n-1]
end
plot(t, x, title="Crescimento exponencial \$(x_0 = $x₀, \\mu = $μ, T = $T, \\Delta t = $Δt)\$", titlefont = 10, xlabel = "t", ylabel="x", label="aproximação", color=1)
Agora, vamos assumir uma incerteza em relação ao parâmetro, dada por uma distribuição normal, com média e desvio padrão :
Façamos uma amostragem de um certo número de valores.
M = 100
μ̄ = 0.1
σ = 0.02
μ = μ̄ .+ σ * randn(rng, M)
histogram(μ, bins = 20, xlims=(0.0, 0.2), title="Histogram das realizações de \$\\mu \\sim \\mathcal{N}(\\bar\\mu, \\sigma^2); \\bar\\mu = $μ̄, \\sigma=$σ \$", xlabel="\$\\mu\$", titlefont=10, label=false)
Agora, vamos resolver a equação para cada valor sorteado.
Δt = 0.2
t = t0:Δt:T
N = Int(round(T/Δt))
x = Array{Float64}(undef, N+1, M)
x[1, :] .= x₀
for n in 2:N+1
x[n, :] .= (1.0 .+ μ * Δt) .* x[n-1, :]
end
plot(t, x, alpha = 0.2, title="Conjunto de soluções \$(x_0 = $x₀, \\mu \\sim \\mathcal{N}($μ̄, {$σ}^2), T = $T, \\Delta t = $Δt)\$", titlefont = 10, xlabel = "t", ylabel="x", label=permutedims(["soluções"; fill(nothing, M-1)]), color=1)
plot!(t, x[:, 1], label="uma realização", linewidth=2, color=2)
plot!(t, sum(x, dims=2)/size(x, 2), linewidth=3, color=:orange, label="média")
Consideramos, agora, a equação aleatória
onde é um processo aleatório dado por onde e é tal que e independentes.
μ̄ = 0.1
σ = 0.05
wt = 0.0
for m in 1:M
x[1, m] = x₀
for n in 2:N+1
global wt += randn(rng) * √Δt
μt = μ̄ + σ * sin(wt)
x[n, m] = (1.0 + μt * Δt) .* x[n-1, m]
end
end
plot(t, x, alpha = 0.2, title="Soluções RODE \$(x_0 = $x₀, \\mu_t = $μ̄ + $σ\\sin(W_t), T = $T, \\Delta t = $Δt)\$", titlefont = 10, xlabel = "t", ylabel="x", label=permutedims(["soluções"; fill(nothing, M-1)]), color=1)
plot!(t, x[:, 1], label="uma realização", linewidth=2, color=2)
plot!(t, sum(x, dims=2)/size(x, 2), linewidth=3, color=:orange, label="média")
Finalmente, vamos considerar a equação estocástica
onde é um processo aleatório. Mais especificamente, vamos assumir que modela um movimento Browniano, tendo incrementos independentes e estacionários, dados por
μ̄ = 0.1
σ = 0.05
for m in 1:M
x[1, m] = x₀
for n in 2:N+1
dw = randn(rng) * √Δt
x[n, m] = (1.0 + μ̄ * Δt) * x[n-1, m] + σ * x[n-1, m] * dw
end
end
plot(t, x, alpha = 0.2, title="Soluções SDE \$(x_0 = $x₀, \\bar\\mu = $μ̄, \\sigma = $σ, dW_t \\sim \\mathcal{N}(0, \\Delta t), T = $T, Δt = $Δt)\$", titlefont = 9, xlabel = "t", ylabel="x", label=permutedims(["soluções"; fill(nothing, M-1)]), color=1)
plot!(t, x[:, 1], label="uma realização", linewidth=2, color=2)
plot!(t, sum(x, dims=2)/size(x, 2), linewidth=3, color=:orange, label="média")
Resolva, via método de Euler, a equação diferencial
com de sua escolha. Trace o gráfico da solução. Escolha parâmetros apropriados para que a mudança de concavidade, da solução, seja visível.
Resolva, via método de Euler, a equação diferencial
onde
com de sua escolha. Trace o gráfico de um conjunto de realizações dos parâmetros. Escolha parâmetros apropriados para que boa parte das realizações exiba a mudança de concavidade.
Resolva, via método de Euler, a equação diferencial aleatória
onde e com e de sua escolha. Trace o gráfico de um conjunto de realizações dos parâmetros. Escolha parâmetros apropriados para que a média das realizações exiba a mudança de concavidade.
Resolva, via método de Euler, a equação diferencial estocástica
onde com e de sua escolha. Trace o gráfico de um conjunto de realizações dos parâmetros. Novamente, escolha parâmetros apropriados para que a média das realizações exiba a mudança de concavidade.