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))