你侬我侬

最近在深入尝试使用 Python 做科学计算,并成功将 Matlab 写的一些程序迁移到 Python 中。只是我们课题组大多使用 Mathematica、Matlab 或 Maple,Python 用户寥寥,许多东西只能现用现学,而今天正好遇到一个小问题。

$$ \rho-3 p=\frac{g T^{4}}{2 \pi^{2}} \cdot x^{2} \int_{0}^{\infty} d y \frac{y^{2}}{\sqrt{x^{2}+y^{2}}} \frac{1}{\exp\left(\sqrt{x^{2}+y^{2}}\right) \pm 1} $$

在做这个积分时出现了如下警告:

1
2
RuntimeWarning: overflow encountered in exp
RuntimeWarning: overflow encountered in double_scalars

这是因为分母的指数函数中出现了无穷大,溢出精度范围。对于分母是 “+” 的积分,可以通过导入 scipy.special.expit,将 exp(x) 改写成 expit(x) = 1/(1+exp(-x));而对于分母是 “-” 的积分,就比较麻烦一些。好在趋近于无穷时,被积函数相当于零了,在精度范围内结果是正确的,因此忽略警告即可。对于一般的简单积分,遇到这种情况可以做个变量代换消去无穷大。(此时,Mathematica 用户狂喜:一行 NIntegrate 就能解决的事情,有必要这么麻烦吗?QAQ)

因为不想看到警告,我顺手搜索了下,发现一个不太相关的原因是 Win10 默认支持的数据类型是 float64。大一些不好吗,于是将数据类型更改为 float128,结果却出现了错误:

1
AttributeError: module 'numpy' has no attribute 'float128'

只好再次请教谷先生,发现这在 Win10 中是一个长期的遗留问题,而 Linux 默认使用 float128,完全没烦恼。但实际上,Numpy 中所谓的 float128 只是徒有其名, Nathaniel J. Smith 就建议使用 longdouble 来代替,以减少代码对系统的依赖。

尽管如此,强迫症的我依然如鲠在喉(找个借口换 M1 就这么难吗)。就在这时,我突然想到 Win10 可以安装 Linux 子系统,搜索之后发现两个系统之间完美兼容,“我泥中有你,你泥中有我”,可以无缝地互相访问文件。那么在 Linux 上运行代码不就可以了吗,想到就做,我立马根据官方教程安装了 Ubuntu 20.04 子系统,顺便将软件源更换成清华的镜像

原本打算下一步安装 Linux 桌面,VS Code 在一旁突然不甘寂寞地跳出来,建议我安装 Remote - WSL 扩展。如此这般,只需点击左下角的图标,VS Code 就可以无缝地切换到 Linux 环境,远程访问、编辑和编译 Linux 中的文件。我简单测试了下,发现和本地的 VS Code 体验完全一致,而且原本在 Win10 环境中编译需要 40 秒的一个 Python 文件,在 Linux 环境中只需要 20 秒,足足快了一倍。好家伙,年轻人不讲武德,这样一来,还要什么虚拟机、双系统,或者 Linux 单系统!关键是,在 Linux 中可以直接访问 Win10 的文件夹 /mnt/c/Users/用户名,因此可以在 Linux 中编译 Win10 目录下的文件。Win10 与子系统水乳交融的地方还在于,他们共用一个本地主机(localhost),因此在 Linux 环境下做测试生成本地连接 http://localhost:port/ 时,可以直接在 Win10 的浏览器打开。例如,我通过 Hugo 搭建网站,在本地测试时,只需在终端输入 hugo server 就可以通过生成的本地链接查看我的网站了。同样,我用 JupyterLab 写 Python 代码也是生成一个本地连接,在浏览器中编译程序。

至此,我的内心恢复到不悲不喜,感觉手里的笔记本又香了。虽然并没有从根源上解决 numpy.float128 在 Win10 中的问题,但这也算是另类的釜底抽薪之法吧,毕竟 Python 在 Win10 中或多或少会出现一些问题,切换到 Linux 子系统运行再好不过了。最重要的是,强迫症的倔强使我无意间解锁了一个新的工作流程,即日常使用 Win10,通过 OneDrive 同步文件,工作时将 VS Code 切换到 Linux 环境,编译 Win10 目录下的代码。Linux 子系统没有虚拟机那么占用资源,也不像双系统那样地割裂。它和 VS Code 犹如任督二脉,“任督通则百脉皆通”,令人浑身舒畅,总之就是很优雅。