0

我需要为我的工作生成大量随机均值不变正交矩阵。均值不变矩阵具有属性A*1_n=1_n,其中 1_n 是标量 1 的大小为 n 的向量,基本为np.ones(n)。我使用 Python,特别是 Numpy 来创建我的矩阵,但我想确保我的方法既正确又最有效。此外,我想介绍我尝试过的 3 种独立正交化方法的发现,并希望能解释为什么一种方法比其他方法更快。我在帖子的末尾就我的发现提出了四个问题。

一般来说,为了创建一个均值不变的随机正交矩阵 A,您需要创建一个随机方阵 M1,将其第一列替换为一列并正交化矩阵。然后,使用另一个矩阵 M2 再次执行此操作,最终均值不变随机正交矩阵为 A = M1*(M2.T)。这个过程的瓶颈是正交化。正交化的主要方法有 3 种,即使用投影的Gram-Schmidt 过程、使用反射的Householder 变换和Givens 旋转

使用 Numpy: 创建 nxn 随机矩阵非常简单 M1 = np.random.normal(size=(n,n))。然后,我将 M1 的第一列替换为 1_n。

据我所知,Gram–Schmidt 过程在任何非常流行的库中都不存在,所以我发现这段代码运行良好:

def gram_schmidt(M1):
    """Orthogonalize a set of vectors stored as the columns of matrix M1."""
    # Get the number of vectors.
    n = M1.shape[1]
    for j in range(n):
        # To orthogonalize the vector in column j with respect to the
        # previous vectors, subtract from it its projection onto
        # each of the previous vectors.
        for k in range(j):
            M1[:, j] -= np.dot(M1[:, k], M1[:, j]) * M1[:, k]
        M1[:, j] = M1[:, j] / np.linalg.norm(M1[:, j])
    return M1

显然,上面的代码必须对 M1 和 M2 都执行。

对于 10,000x10,000 随机均值不变正交矩阵,此过程在我的计算机上大约需要1 小时(8 核 @3.7GHz,16GB RAM,512GB SSD)。

我发现代替 Gram-Schmidt 过程,我可以用以下方法对 Numpy 中的矩阵进行正交化: q1, r1 = np.linalg.qr(M1) 其中 q1 是正交化矩阵,r1 是上三角矩阵(我们不需要保留 r1)。我对 M2 做同样的事情并得到 q2。那么,A=q1*(q2.T)。对于相同的 10,000x10,000 矩阵,此过程在同一台计算机上大约需要70 秒。我相信linalg.qr()图书馆使用 Householder 转换,但我希望有人确认它。

最后,我尝试改变初始随机矩阵 M1 和 M2 的生成方式。而不是 M1 = np.random.normal(size=(n,n))我使用 Dirichlet 分布: M1 = np.random.default_rng().dirichlet(np.ones(n),size=(n)). 然后,我linalg.qr()之前使用过类似的东西,我得到了 10000x10000 的矩阵M1 = np.random.normal(size=(n,n))

我的问题是:

  1. Numpy 的np.linalg.qr()方法是否真的使用了 Householder 变换?或者可能是吉文斯轮换?
  2. 为什么 Gram-Schmidt 过程比 慢得多np.linalg.qr()
  3. 我知道狄利克雷过程会产生一个几乎正交的矩阵。是不是因为我们正在创建一万维,所以很可能随机得到一个与其他所有向量正交的向量?np.linalg.qr()不关心矩阵与正交性的接近程度。
  4. 有没有更快的方法来生成随机正交矩阵?我可以对我的代码进行任何优化以使其更快/更高效吗?

编辑:cp.linalg.qr()在我的 2080ti 上,cupy 在同一个 10,000x10,000 随机矩阵上只需要 16 秒,而不是 CPU 上的 70 秒(8 核 @3.7GHz,多线程,16GB RAM 和 512GB SSD)。

4

1 回答 1

0

这是制造这种矩阵的另一种方法。我不知道分布是什么样的,但它可能比你描述的方法更快。

首先,这里的户主反射器是以下形式的矩阵

H = I - 2*h*h'/(h'*h)

其中 h 是一个向量。

注意:

H 是正交且对称的

H 可以应用于 O(dim) 中的向量

如果 x 和 y 是具有相同范数的任意两个向量,那么我们可以找到这样一个矩阵来将 x 映射到 y(h 是 xy)

制造“随机”正交矩阵的一种方法是计算“随机”Householder 矩阵的乘积

如果 Q 是一个正交矩阵并且 u 是所有 1 的向量并且

q = Q*u 

那么 q 和 u 具有相同的范数,所以如果 H 是将 q 映射到 u 的户主反射器,

R = H*Q is orthogonal
R*u = H*Q*u = H*q = u
于 2021-03-08T17:09:35.230 回答