我的问题是:我正在尝试通过(截断的)Karhunen-Loeve 变换对随机过程进行谱分解,但我的协方差矩阵实际上是一个单参数矩阵族,我需要一种方法来估计/可视化如何我的随机过程取决于这个参数。为此,我需要一种方法来跟踪由 numpy.linalg.eigh() 生成的特征向量。
为了让您了解我的问题,这里有一个示例玩具问题:假设我有一组点 {xs},以及一个协方差为 C(x,y) = 1/(1+a*(xy) 的随机过程 R ^2) 这取决于参数 a。对于 [0,1] 范围内的网格点的随机样本和给定的 a 选择(例如,a=1),我可以填充我的协方差矩阵并使用以下方法实现 Karhunen-Loeve 变换:
num_x = 1000
xs = numpy.array([numpy.random.uniform() for i in range(num_x)])
z=numpy.random.standard_normal(num_x)
a0=1
def cov(x,y,a=a0): return 1/(1+a*(x-y)^2)
cov_m = numpy.array(map(lambda y: map(lambda x: cov(x,y),xs),xs))
w,v=numpy.linalg.eigh(cov_m)
R=numpy.dot(v,z*w^0.5)
这将使我在每个随机网格点 xs 处定义 R 的实现。然而,我需要能够做的是 - 对于特定的实现(这意味着我的网格 xs 和我的随机系数 z 的特定选择) - 跟踪 R 如何相对于我的协方差函数中的参数 a 变化。
如果我可以象征性地计算协方差矩阵并在事后指定 a ,这将很容易做到。但是,对于大型矩阵,这不是一个合理的选择。另一种方法是找到一种方法来跟踪 numpy.linalg.eigh() 返回的每个特征向量。不幸的是,numpy 似乎正在重新排序它们,以便始终首先列出最小的特征值;这意味着,当我改变 a 时,特征向量会意外地重新排序,并且点积 numpy.dot(v,z*w^0.5) 不再将相同的系数分配给相同的特征向量。
有没有解决的办法?
(这是来自 ASKSAGE 的交叉帖子。我的实现是使用 Sage,但由于问题不是 Sage 特定的,而且这里似乎有更多活动,我想我会重新发布。如果交叉发布不可接受,我深表歉意;如果是这样,请删除它。)
编辑:根据下面的对话,我认为我需要添加有关此问题性质的更多详细信息。
Karhunen-Loeve 变换背后的思想是对随机过程 R(x) 进行频谱分解,如下所示:
R(x) = \sum_{i} Z_i \lambda_i^{1/2} \phi^{(i)}(x),
其中每个 Z_i 是具有标准正态分布的 iid 随机变量,每个 \phi^{(i)}(x) 是由协方差矩阵的特征向量的解确定的 x 的非随机函数,并且每个 \lambda_i是与 \phi^{(i)} 相关的对应特征值。
为了证明 R 对参数 a 的依赖性,我需要能够唯一地为每个 \phi^{(i)} 分配一个系数 Z_i。我如何做这个分配并不重要,因为所有的 Z 都是相同分布的,但是分配需要是唯一的,它不能依赖于 lambda_i 的相应值,因为这将取决于参数 a。
解析解很简单:只需计算任意 a 的特征向量和特征值,通过指定我的 Z 来选择 R 的特定实现,然后观察 R 的实现如何依赖于 a。(对于玩具模型,R 通常会随着增加而变得更快。)
这里的问题是如何以数字方式实现这一点。Numpy 显然在计算时会扰乱特征向量,因此无法对它们进行唯一标记。我猜想做到这一点的唯一方法是深入研究底层代码并专门实现某种类型的任意标记功能。
简而言之:我需要一种对 numpy 产生的特征向量进行排序的方法,它不依赖于相关特征值的大小。
有没有办法做到这一点?
更新: 我已经设法找到了这个问题的部分答案,但我需要做更多的研究才能得到完整的答案。看起来我将不得不为此实现自己的算法。
对于我正在考虑的类型的矩阵,Lanczos 算法(对于给定的初始向量选择)是确定性的,并且步骤不依赖于我的参数选择。这给了我一个对称的三对角矩阵来求解特征值。
分而治之可能在这里奏效。似乎我可以实现它的一个版本,它允许我跟踪独立于相关特征值的特征向量。至少,“除法”部分可以以确定性、与参数无关的方式实现,但我需要了解更多关于算法的“征服”部分才能确定的信息。