Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #57 da revista programar. Faz já o download aqui!

Manuel Almeida

Modelo de simulação utilizando Python

Mensagens Recomendadas

Manuel Almeida    0
Manuel Almeida

Olá boa tarde,

Tenho que desenvolver um modelo unidimensional de simulação da temperatura de um lago.

Pensei fazê-lo da seguinte forma.

O lago é dividido em camadas, cada camada tem um determinado valor de temperatura. Estes valores são armazenados numa lista.

temp=[9,10,10,10,10]

Esta é a base do modelo, uma lista de elementos que vão sendo alterados ao longo do tempo.

time step 0    temp=[9,10,10,10,10]

time step 1    temp=[10,11,12,13,14] 

time step 3    temp=[10,12,13,13,14]

...

time step n    temp=[10,12,13,13,14]

A simulação desenvolve-se ao longo do tempo. sendo que cada valor da lista no time step seguinte é obtido através do valor obtido no time step anterior mais o resultado de uma qualquer função ou funções.

Como deve abordar o problema com uma matriz 2D? EM que uma das dimensões é o tempo e outra os valores da temperatura?

Tentei o seguinte:

Este é apenas um exemplo generico, pretendo uma forma de aceder e editar a matriz temp de uma forma simples. Este exemplo corresponde a uma simulação de 365 dias.

numlayer=10
N=365        
      
mlist=[[0]*numlayer]*N
mlist[0]=temp
print mlist

for i in range(len(mlist)-1):
    for j in range(len(mlist[0])):
        mlist[i][0]=12
        mlist[i+1][1]=mlist[i][1]
        
print mlist

Quando se trata de simular um qualquer processo fisico que evolui com o tempo mas que apenas retorna um valor em cada time step é simples por exemplo: Neste caso dt corresponde ao incremento temporal. é fácil aceder ao valor existente no time step anterior com uma expressão deste tipo  v[k+1] = v[k] - alpha*dt*sin(theta[k+1]), mas quando se pretende modificar varios valores armazenados numa lista em cada time step qual deverá ser a aproximação.

def pendulum(T, n, theta0, v0, alpha):
    dt = T/float(n)
    t = linspace(0, T, n+1)
    v = zeros(n+1)
    theta = zeros(n+1)
    v[0] = v0
    theta[0] = theta0
    for k in range(n):
        theta[k+1] = theta[k] + dt*v[k]
        v[k+1] = v[k] - alpha*dt*sin(theta[k+1])
        return theta, v, t

Naõ sei de me consegui explicar bem. Se não o fiz as minhas desculpas. Obrigado

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites
Pedro C.    15
Pedro C.

Olá. Não sei se percebi toda a conjectura do teu processo mas penso que algumas alterações seriam benéficos no teu código. Geralmente quando se pretende fazer processos de simulação, tipicamente numéricos, usa-se uma biblioteca especialmente orientada para essas situações. A mais conhecida é o numpy, de longe muito mais rápida e eficiente para simulação. Para fazer uma matriz como a que tentaste fazer com listas do python nativo mas neste caso usando o numpy faz-se assim:

# Estou a importar o numpy.
import numpy as np
# Estou a declarar as variáveis que determinam o tamanho da matriz.
N=365
camadas=10
tinicial=1 # suponho que no teu código isto seria o temp.
# Estou a fazer uma matriz com "N" linhas e com "camadas" columnas.
mlist=np.zeros((N,camadas))
# Estou a criar uma série temporal na primeira coluna.
mlist[:,0]=np.arange(tinicial,tinicial+N,1)
# E agora a fazer print para verificar o resultado.
print mlist

O resultado é isto:

[[   1.    0.    0. ...,    0.    0.    0.]
[   2.    0.    0. ...,    0.    0.    0.]
[   3.    0.    0. ...,    0.    0.    0.]
..., 
[ 363.    0.    0. ...,    0.    0.    0.]
[ 364.    0.    0. ...,    0.    0.    0.]
[ 365.    0.    0. ...,    0.    0.    0.]]

Neste ponto terias a tua matriz numérica feita e pronta a utilizar consoante o tempo inicial e o número de dias que pretendias do mesmo (no exemplo começa em 1 e acaba em 365). Nota também que penso que o código que fizeste para dar origem a uma lista estilo matriz não está correcto especialmente por causa deste passo:

mlist[0]=temp

No entanto continuando para o que pretendes fazer a seguir, se quiseres percorrer uma matriz (linhas e colunas) controlando o incremento, nomeadamente o valor com que ele começa, podes usar ciclos while para ir percorrendo todas as células e uma função exterior para fazer o cálculo da temperatura:

# Esta função está a gerar com números aleatórios as temperaturas.
# Seria neste ponto que terias de fazer as modificações especificamente para o teu caso.
def get_temperature(time,previous_layer):
    """
    time é o tempo actual para o calculo da temperatura.
    previous_layer era a temperatura na mesma camada no tempo anterior.
    """
    anual_mean=20
    m=182.5
    v=abs(time-m)
    return np.random.normal(anual_mean/v,abs((anual_mean/v)-previous_layer))
    
# Estou a dar as temperaturas iniciais para a primeira linha da matriz (exceptuando a célula do tempo, e.g. :1).    
mlist[0,1:]=np.linspace(-3,3,camadas-1)

# Estou a criar dois ciclos while, um para as linhas outro para colunas.
i=1
while i < N:
    j=1
    while j < camadas:
        # Aqui estou a chamar a tal funçao que daria a temperatura
        # consoante o tempo e a temperature da mesma camada no tempo anterior.
        mlist[i,j]=get_temperature(time=mlist[i,0],previous_layer=mlist[i-1,j])
        j=j+1
    i=i+1

Talvez com este exemplo consigas adaptar o caso à simulação que pretendes fazer.

Partilhar esta mensagem


Link para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora


×

Aviso Sobre Cookies

Ao usar este site você aceita a nossa Política de Privacidade