Code optimieren
Verfasst: Samstag 29. Februar 2020, 11:07
Guten Tag,
ich habe nummerische Simulation geschrieben, die sehr rechenintensiv ist. Die Rechendauer an meinem Coputer betraegt fuer den Parameter T = 10^4 (Anzahl der Schleifendurchlaeufe) fast 42 Stunden.
Um ein exaktes Resultat zu erhalten, muss der Parameter jedoch auf T = 10^6 gesetzt werden ---> Rechnendauer ca. 4000 std.
Kann sich bitte jemand von euch mal meinen Code anschauen und vielleicht eine Moeglichkeit finden um die Rechendauer zu verringern.
ich habe nummerische Simulation geschrieben, die sehr rechenintensiv ist. Die Rechendauer an meinem Coputer betraegt fuer den Parameter T = 10^4 (Anzahl der Schleifendurchlaeufe) fast 42 Stunden.
Um ein exaktes Resultat zu erhalten, muss der Parameter jedoch auf T = 10^6 gesetzt werden ---> Rechnendauer ca. 4000 std.
Kann sich bitte jemand von euch mal meinen Code anschauen und vielleicht eine Moeglichkeit finden um die Rechendauer zu verringern.
Code: Alles auswählen
from numpy import cos, sin, arctan, sqrt, pi, array, random, mean, linspace,log, zeros, shape, array, savetxt, dot, std, fill_diagonal
import matplotlib.pyplot as plt
from numpy.linalg import norm
import time
import numpy as np
# Initial Condition
#---------------------------------------------------------------
T = 10**4 # time steps
#---------------------------------------------------------------
Teq = 10**3 # transition time
N = 50 # Number of Oscillators
dt = 0.01 # time increment
Tepsilon = 33 # number of steps
depsilon = 0.05 # increment of coupling constant
d = zeros([N,N])
fill_diagonal(d,1)
L_values = []
epsilon_points = []
def field( phi ) :
real = 1 / N * sum( cos( phi ))
imag = 1 / N * sum( sin( phi ))
R = sqrt( real**2 + imag**2 )
Phi = 2 * arctan( imag / ( real+R ))
return R,Phi
def phi_dot( phi, epsilon, R, Phi ) : # time evolutions of phases
return omega + epsilon * R * sin( Phi - phi )
def jacobian(phi): # compute jacobi-matrix of phi_dot
A = zeros([N,N])
for i in range(N):
for j in range(N):
if i != j :
A[i,j] = cos(phi[j] - phi[i]) # non diagonal elements
else:
mask = np.ones(N, bool)
mask[i] = False
phi_new = phi[mask] # phi[i] is excluded from phi
A[i,i] = sum(-cos(phi_new - phi[i])) # diagonal elements of the jacobian
return (epsilon / N) * A
# The tangent space (linearized) flow
def g(d, phi):
M = jacobian(phi)
return dot(d,M.T)
# Runge-Kutta integrator
def RK4(phi, d):
k1 = dt * phi_dot(phi, epsilon, R, Phi)
k11 = dt * g(d, phi)
k2 = dt * phi_dot(phi + 0.5 * k1, epsilon, R, Phi)
k22 = dt * g(d + 0.5 * k11, phi + 0.5 * k1)
k3 = dt * phi_dot(phi + 0.5 * k2, epsilon, R, Phi)
k33 = dt * g(d + 0.5 * k22, phi + 0.5 * k2)
k4 = dt * phi_dot(phi + k3, epsilon, R, Phi)
k44 = dt * g(d + k33, phi + k3)
phi += (k1 + 2 * k2 + 2 * k3 + k4) / 6
d += (k11 + 2 * k22 + 2 * k33 + k44) / 6
return phi, d
# Gram-Schmidt - Scheme
def gram_schmidt(A, method = 'transient'):
n = A.shape[1]
if method == 'transient':
for i in range(n):
for j in range(i):
A[i] -= dot(d[i], d[j]) * d[j]
A[i] = A[i] / norm(A[i])
return A
if method == 'computation':
for i in range(n):
for j in range(i):
A[i] -= dot(d[i], d[j]) * d[j]
L[i] += log(norm(A[i]))
A[i] = A[i] / norm(A[i])
return A
#---------------------------------------------------------------------------------------
#-------------------------------Main Loop-----------------------------------------------
#---------------------------------------------------------------------------------------
start_time = time.time()
for i in range( Tepsilon ) :
epsilon = i * depsilon
epsilon_points.append(epsilon)
omega = linspace(-1,1,N) # regular sampling from [-1,1]
phi = random.uniform(low=0.0, high=2*pi, size=N) # reset initial condition for every new epsilon
L = zeros( N ) # ...
# Transient
for j in range( Teq ) :
R,Phi = field(phi)
phi, d = RK4(phi, d)
d = gram_schmidt(d, 'transient')
# Computation
for k in range(T):
R,Phi = field(phi)
r, d = RK4(phi, d)
d = gram_schmidt(d, 'computation')
L_values.append( list( L )) # contains avg freq of oscl for a given epsilon
print("--- %s seconds ---" % (time.time() - start_time))