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

Manuel Almeida

Modelo de simulação utilizando Python

Mensagens Recomendadas

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


Ligação para a mensagem
Partilhar noutros sites
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


Ligação 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 os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.