猫史档案馆


【成果展示&求助】量子波函数可视化!

用户:Planet_CubePlanet_Cube查看:8 回复:5 评论:8 创建时间:2024-01-27T22:57:44


刚才的格式被吞了,所以重发一遍

我写了一个计算波函数图像的程序(虽然和量子力学有关,但是不要怕,本质上就是一堆计算),代码如下:

from PIL import Image, ImageDraw
import math

'''这是一个处理波函数图像的程序
输入初始波函数图像,它会给你一段时间后的图像
红色分量表示振幅,绿色分量表示波高,蓝色分量表示相位'''


def vector_addition(m1, f1, m2, f2):
# 向量相加运算
h1 = m1 * math.cos(f1)
v1 = m1 * math.sin(f1)
h2 = m2 * math.cos(f2)
v2 = m2 * math.sin(f2)
h = h1 + h2
v = v1 + v2
length = math.sqrt(h ** 2 + v ** 2)
if h > 0:
angle = math.atan(v / h)
elif h < 0:
angle = math.atan(v / h) + math.radians(180)
elif h == 0 and v > 0:
angle = math.radians(90)
elif h == 0 and v < 0:
angle = math.radians(270)
else:
angle = 0
return length, angle


def calculate_wave(imgobj, time, scale, mode="all"):
w = int(imgobj.width)
h = int(imgobj.height)
image = imgobj.resize((w, h))
if mode == "all":
image_new = Image.new('RGB', (w, h), (0, 0, 0))
else:
image_new = Image.new('L', (w, h), 0)
draw = ImageDraw.Draw(image_new)
origin_wave = []
# 此循环用于读取图片中的信息
for y in range(h):
for x in range(w):
pos = (x, y)
pixel = image.getpixel(pos)
r = pixel[0]
b = pixel[2]
if r != 0 or b != 0:
origin_wave.append((r, b, x, y))
# 此循环用于生成新图片
for y in range(h):
print(y, 'row(s) had been completed') # 实时打印生成情况
for x in range(w):
r = 0
b = 0
for i in origin_wave:
"""每个像素都相当于波源,它们都各自给此位置传播一个波,所有的波相加得到此位置的新波
波的相加遵循向量运算法则,波在传播过程时的相位(即向量的辐角)发生改变,增量为m*d^2/t
其中m表示质量(此函数默认质量为1,故省去),d^2表示距离的平方,t表示时间
此处增加了scale变量以表示图像的缩放,不过其作用于质量类似。角采用弧度制表示"""
r, b = vector_addition(r, b, i[0],
math.radians(i[1] / 256 * 360) + (
(i[2] - x) ** 2 + (i[3] - y) ** 2)
* scale / time)
r /= len(origin_wave)
g = r * math.sin(b)
r = r ** 2 # 在某处找到粒子的可能性是振幅的平方
if mode == "all":
draw.point(xy=(x, y),
fill=(math.floor(r), math.floor(g), math.floor(b / math.radians(
360) * 256)))
elif mode == "red":
draw.point(xy=(x, y), fill=math.floor(r))
elif mode == "green":
draw.point(xy=(x, y), fill=math.floor(g))
elif mode == "blue":
draw.point(xy=(x, y), fill=math.floor(b / math.radians(360) * 256))
return image_new


img = Image.open(r"test_waveL.png")
calculate_wave(img, 5, 0.1, "red").save('new1L_red.jpg')

如果你输入这个图片:(名称为“test_waveL”,格式为PNG,如果想尝试的话记得把它和代码保存在同一个文件夹)center_image
你就会得到这个center_image
一个地方越亮,说明在此处找到粒子的概率越大,可以看到确实像波一样扩散出去了,nice
但是它有一个很严重的问题:性能。一个100*100的图片花了我5秒的世界渲染
为什么会这样?我们看这段代码:

# 此循环用于读取图片中的信息
for y in range(h):
for x in range(w):
pos = (x, y)
pixel = image.getpixel(pos)
r = pixel[0]
b = pixel[2]
if r != 0 or b != 0:
origin_wave.append((r, b, x, y))
# 此循环用于生成新图片
for y in range(h):
print(y, 'row(s) had been completed') # 实时打印生成情况
for x in range(w):
r = 0
b = 0
for i in origin_wave:
"""每个像素都相当于波源,它们都各自给此位置传播一个波,所有的波相加得到此位置的新波
波的相加遵循向量运算法则,波在传播过程时的相位(即向量的辐角)发生改变,增量为m*d^2/t
其中m表示质量(此函数默认质量为1,故省去),d^2表示距离的平方,t表示时间
此处增加了scale变量以表示图像的缩放,不过其作用于质量类似。角采用弧度制表示"""
r, b = vector_addition(r, b, i[0],
math.radians(i[1] / 256 * 360) + (
(i[2] - x) ** 2 + (i[3] - y) ** 2)
* scale / time)
r /= len(origin_wave)
g = r * math.sin(b)
r = r ** 2 # 在某处找到粒子的可能性是振幅的平方
if mode == "all":
draw.point(xy=(x, y),
fill=(math.floor(r), math.floor(g), math.floor(b / math.radians(
360) * 256)))

用到了一个2层循环和一个3层循环(代码格式被吞了),而且那个3层循环的基础是在前面的2层循环上建立的,所以本质上是4层循环
所以它达到了一个惊人的时间复杂度:n^4
以及n^2的空间复杂度(这个似乎不能再优化了)
我的电脑本身就比较烂,不卡才怪。如果我想扩大规模,就必须优化
我实在没有什么办法了,请各位大佬们帮帮忙,我将不胜感激emotion_编程猫_加油


回复

上一页1 页 / 共 1下一页
Planet_CubePlanet_Cube

代码在具体使用时请确保已经安装了pillow库

点赞0


评论


imgainary_numberimgainary_number

波粒二次象

不被观察时便呈现波的性质

点赞0


评论


初夏晴雨初夏晴雨

怎么做到的在 bcm 论坛发这么大段话还不炸格式啊

空间优化没必要,能用就可以,毕竟不是打竞赛。时间优化我看看?

点赞2


评论


囧仙_official囧仙_official

我根本不了解量子力学之类的玩意。

仅从外人视角给出建议。

1、使用c/c++等编程语言,运行效率可以提升数倍

2、想办法改变计算方式,比方说能否找到一个近似递推关系的方法,逐步扩展

3、换电脑

点赞0


评论


苹果真好吃苹果真好吃

我跑了三秒,电脑的问题

点赞0


评论