Python 波动方程矩阵运算程序的效率

Python 波动方程矩阵运算程序的效率,python,arrays,python-3.x,numpy,matplotlib,Python,Arrays,Python 3.x,Numpy,Matplotlib,我写了一个波叠加程序,它叠加了多个波源的波方程,然后给出了一个包含所有建设性和破坏性干扰的单一波,并绘制了叠加强度图。这段代码可以工作,但效率很低 如果我在这里以1000x1000网格的形式给出点,那么整个程序需要一段时间才能运行 使用以下一个或所有函数(函数、lambda函数、可映射、直接定义2D numpy数组或类似函数),是否有任何方法可以使此代码更加高效和干净 如果是这样,是否有办法测量运行操作所需的时间。这不是家庭作业,我想为我的光学研究建立一些自己的东西。事先非常感谢你的帮助,

我写了一个波叠加程序,它叠加了多个波源的波方程,然后给出了一个包含所有建设性和破坏性干扰的单一波,并绘制了叠加强度图。这段代码可以工作,但效率很低

  • 如果我在这里以1000x1000网格的形式给出点,那么整个程序需要一段时间才能运行

  • 使用以下一个或所有函数(函数、lambda函数、可映射、直接定义2D numpy数组或类似函数),是否有任何方法可以使此代码更加高效和干净

  • 如果是这样,是否有办法测量运行操作所需的时间。这不是家庭作业,我想为我的光学研究建立一些自己的东西。事先非常感谢你的帮助,我真的很感激

     import numpy as np
     from matplotlib import pyplot as plt
     from sklearn import mixture
     import matplotlib as mpl
     from mpl_toolkits.mplot3d import Axes3D
     from matplotlib import cm
     import scipy
     import scipy.ndimage
     import scipy.misc 
    
     xmin, xmax = 0,25
     ymin, ymax = -12.500,12.500
     xpoints, ypoints = 500,500
     points,amp,distance,wave=[],[],[],[]
     numsource=11
    
     x=np.linspace(xmin, xmax, xpoints)
     y=np.linspace(ymin, ymax, ypoints)
     xx,yy=np.meshgrid(x,y, sparse=False)
     pointer = np.concatenate([xx.reshape(-1,1),yy.reshape(-1, 1)], axis=-1)
     counter=len(pointer)
     A=[0]*counter #for storing amplitudes later
    
     # Arrays of point source locations
     source=tuple([0,(((numsource-1)/2)-i)*2.5] for i in range(0,numsource-1))
    
     # Arrays of Subtraction of Coordinates of Sources from Point sources (For Distance from source)   
     points=[(pointer-source[p]) for p in range(0,numsource-1)]
    
     # distance of each point in map from its source (Sqrt of Coordinate difference sum)
     distance=[(points[i][:,0]**2 + points[i][:,1]**2)**0.5 for i in range(0,numsource-1)]
    
     # Amplitudes of each wave defined arbitrarily
     amp= np.array([4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4])
     k=20
    
     # wave equation for each wave based on defined amplitude and distance from source
     wave=([amp[i] * np.sin (k*distance[i]) for i in range(0,numsource-1)])
    
     #superposition
     for i in range(0,numsource-1):
         A=A+wave[i]
    
     A=np.asarray(A)
     print(A)
     intensity = A**2
    
     #constructive, destructive superposition plot
     plt.figure(figsize=(10,10))
     plt.xlim(xmin,xmax)
     plt.ylim(ymin,ymax)
     plt.scatter(pointer[:,0], pointer[:,1],c=intensity, cmap='viridis')
     plt.colorbar()
    

我设法将计算机上的计算时间从166毫秒减少到146毫秒

您希望去掉将
A
初始化为250000x1列表然后转换为数组的部分。您可以直接将其初始化为数组。我禁用的部分在代码中保留为注释

#import matplotlib as mpl
from matplotlib import pyplot as plt
#from mpl_toolkits.mplot3d import Axes3D
#from matplotlib import cm
import numpy as np
#import scipy
#import scipy.ndimage
#import scipy.misc
#from sklearn import mixture
import time

class time_this_scope():
    "A handy context manager to measure timings."""

    def __init__(self):
        self.t0 = None
        self.dt = None

    def __enter__(self):
        self.t0 = time.perf_counter()
        return self

    def __exit__(self, *args):
        self.dt = time.perf_counter() - self.t0
        print(f"This scope took {int(self.dt*1000)} ms.")



def main():

    xmin, xmax = 0, 25
    ymin, ymax = -12.500, 12.500
    xpoints, ypoints = 500, 500
    points, amp, distance, wave = [], [], [], []
    numsource = 11

    x = np.linspace(xmin, xmax, xpoints)
    y = np.linspace(ymin, ymax, ypoints)
    xx, yy = np.meshgrid(x, y, sparse=False)
    pointer = np.concatenate([xx.reshape(-1, 1), yy.reshape(-1, 1)], axis=-1)


#    counter = len(pointer)
#    A = [0]*counter #for storing amplitudes later
    A = np.zeros(len(pointer))

    # Arrays of point source locations
    source = tuple((0, (((numsource-1)/2)-i)*2.5) for i in range(0, numsource-1))

    # Arrays of Subtraction of Coordinates of Sources from Point sources (For Distance from source)
    points = [(pointer-source[i]) for i in range(0, numsource-1)]

    # distance of each point in map from its source (Sqrt of Coordinate difference sum)
    distance = [(points[i][:,0]**2 + points[i][:,1]**2)**0.5 for i in range(0, numsource-1)]

    # Amplitudes of each wave defined arbitrarily
#    amp = np.array([4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4])
    amp = np.array([4]*numsource)
    k = 20

    # wave equation for each wave based on defined amplitude and distance from source
    wave = [amp[i] * np.sin(k*distance[i]) for i in range(0, numsource-1)]

    #superposition
    for i in range(0, numsource-1):
        A = A + wave[i]
#        A = np.asarray(A)


    print(A)
    intensity = A**2

    #constructive, destructive superposition plot
#    plt.figure(figsize=(10, 10))
#    plt.xlim(xmin, xmax)
#    plt.ylim(ymin, ymax)
#    plt.scatter(pointer[:,0], pointer[:,1], c=intensity, cmap='viridis')
#    plt.colorbar()

# Timing.
total_time = 0
N = 20
for _ in range(N):
    with time_this_scope() as timer:
        main()
    total_time += timer.dt
print(total_time/N)

现在绘图本身仍然需要500毫秒,因此我认为
imshow
scatter
更好。我怀疑matplotlib是否很高兴有25万个标记要渲染。

我设法将计算机上的计算时间从166毫秒减少到146毫秒

您希望去掉将
A
初始化为250000x1列表然后转换为数组的部分。您可以直接将其初始化为数组。我禁用的部分在代码中保留为注释

#import matplotlib as mpl
from matplotlib import pyplot as plt
#from mpl_toolkits.mplot3d import Axes3D
#from matplotlib import cm
import numpy as np
#import scipy
#import scipy.ndimage
#import scipy.misc
#from sklearn import mixture
import time

class time_this_scope():
    "A handy context manager to measure timings."""

    def __init__(self):
        self.t0 = None
        self.dt = None

    def __enter__(self):
        self.t0 = time.perf_counter()
        return self

    def __exit__(self, *args):
        self.dt = time.perf_counter() - self.t0
        print(f"This scope took {int(self.dt*1000)} ms.")



def main():

    xmin, xmax = 0, 25
    ymin, ymax = -12.500, 12.500
    xpoints, ypoints = 500, 500
    points, amp, distance, wave = [], [], [], []
    numsource = 11

    x = np.linspace(xmin, xmax, xpoints)
    y = np.linspace(ymin, ymax, ypoints)
    xx, yy = np.meshgrid(x, y, sparse=False)
    pointer = np.concatenate([xx.reshape(-1, 1), yy.reshape(-1, 1)], axis=-1)


#    counter = len(pointer)
#    A = [0]*counter #for storing amplitudes later
    A = np.zeros(len(pointer))

    # Arrays of point source locations
    source = tuple((0, (((numsource-1)/2)-i)*2.5) for i in range(0, numsource-1))

    # Arrays of Subtraction of Coordinates of Sources from Point sources (For Distance from source)
    points = [(pointer-source[i]) for i in range(0, numsource-1)]

    # distance of each point in map from its source (Sqrt of Coordinate difference sum)
    distance = [(points[i][:,0]**2 + points[i][:,1]**2)**0.5 for i in range(0, numsource-1)]

    # Amplitudes of each wave defined arbitrarily
#    amp = np.array([4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4])
    amp = np.array([4]*numsource)
    k = 20

    # wave equation for each wave based on defined amplitude and distance from source
    wave = [amp[i] * np.sin(k*distance[i]) for i in range(0, numsource-1)]

    #superposition
    for i in range(0, numsource-1):
        A = A + wave[i]
#        A = np.asarray(A)


    print(A)
    intensity = A**2

    #constructive, destructive superposition plot
#    plt.figure(figsize=(10, 10))
#    plt.xlim(xmin, xmax)
#    plt.ylim(ymin, ymax)
#    plt.scatter(pointer[:,0], pointer[:,1], c=intensity, cmap='viridis')
#    plt.colorbar()

# Timing.
total_time = 0
N = 20
for _ in range(N):
    with time_this_scope() as timer:
        main()
    total_time += timer.dt
print(total_time/N)

现在绘图本身仍然需要500毫秒,因此我认为
imshow
scatter
更好。我怀疑matplotlib是否很高兴有25万个标记要渲染。

我明白了,非常感谢!这很有帮助。当然效率更高。我现在会想出如何从分散到imshow,我还不知道。我明白了,非常感谢!这很有帮助。当然效率更高。我现在要弄清楚如何从分散到imshow,我还没有意识到这一点。