Quspin中构造由spinless_fermion_basis_1d基矢线性组合构成的新基的方法咨询
嗨,我太懂你这种踩坑的感觉了——想用Quspin构造一个由原spinless费米子基矢线性组合成的新基,但试了自带的几种状态表示方式全踩雷了对吧?首先得理清楚一个核心点:Quspin自带的basis类本质是用来表示正交归一的离散基矢集合的,它本身并不支持直接把带系数的线性组合定义成基矢成员(因为基矢是线性无关的“基本单元”,而线性组合是态矢量,不是基矢)。你要的其实是将哈密顿量(或其他算符)变换到新的基底下,而非直接创建一个包含线性组合的“基类对象”,下面给你讲两种最常用的实现思路:
方法一:构造变换矩阵,将原基下的算符转到新基
这是最通用的方法,不管你的新基是什么形式的线性组合都能用:
- 第一步:把你要的每个新基矢(每个都是原
spinless_fermion_basis_1d基矢的线性组合)整理成一个变换矩阵U——其中U[:, i]是第i个新基矢在原基下的系数分量。如果是费米子系统常用的幺正变换,这个矩阵的逆就是它的共轭转置,会更方便计算。 - 第二步:用Quspin的
hamiltonian类生成原基下的哈密顿量,然后通过H.tocsc()或H.todense()拿到它的稀疏/稠密矩阵形式(希尔伯特空间大的话优先用稀疏矩阵,避免内存爆炸)。 - 第三步:计算新基下的哈密顿量:如果是幺正变换,直接算
H_new = U.conj().T @ H @ U;如果是非幺正变换,先求U的逆矩阵U_inv = np.linalg.inv(U),再计算H_new = U_inv @ H @ U。
举个极简例子:假设原基是3格点无自旋费米子的|001>和|010>,新基是(|001>+|010>)/√2和(|001>-|010>)/√2,那变换矩阵就是:
import numpy as np U = np.array([[1/np.sqrt(2), 1/np.sqrt(2)], [1/np.sqrt(2), -1/np.sqrt(2)]])
拿到原基哈密顿量H后,按上面的公式就能得到新基下的H_new。
方法二:针对单粒子幺正变换的专属优化(无相互作用费米子场景)
你提到你的哈密顿量可以通过换基变成无相互作用费米气体,那大概率你的新基是单粒子本征态的占据数基(也就是原单粒子轨道经过幺正变换后的占据数基),这种情况不用处理大矩阵,直接构造新的产生/湮灭算符就行:
- 假设原单粒子产生算符是
c_i^†,新的单粒子产生算符满足d_j^† = sum_i U_ji c_i^†,其中U是单粒子变换矩阵。 - 用Quspin的
fermion_create和fermion_destroy函数生成原基下的产生/湮灭算符,再按上面的线性组合规则组合成新的算符。 - 最后用这些新算符直接构造哈密顿量,得到的结果就是新基下的哈密顿量,全程不用手动处理变换矩阵,效率更高。
最后再回一下你踩的坑:为什么直接用Fock格式不行?因为spinless_fermion_basis_1d的Fock格式是用来表示占据数分布的(每个轨道0或1个费米子),它根本不识别系数——你输入2|001>,它会误以为是两个|001>的张量积,这完全偏离了你的需求。如果只是想单独表示一个线性组合的态矢量(比如新基的某个成员),直接用numpy数组就行,数组的每个元素对应原基下的系数,比如psi = np.array([0, 1/np.sqrt(2), 1/np.sqrt(2), 0, ...])就代表(|001>+|010>)/√2。
备注:内容来源于stack exchange,提问作者Spherk

