R 如何简单有效地编写二次型代码

R 如何简单有效地编写二次型代码,r,quadratic,R,Quadratic,我正试图编写一个二次型Z的^{-1}Z 代码如下 z <- matrix(rnorm(200 * 100), 200, 100) S <- cov(z) quad.naive <- function(z, S) { Sinv <- solve(S) rowSums((z %*% Sinv) * z) } 因为天真地说,我们应该键入与数学公式完全相同的 t(Z) %*% Sinv %*% Z 因此,任何人都可以解释为什么行和的形式与简

我正试图编写一个二次型Z的^{-1}Z

代码如下

z <- matrix(rnorm(200 * 100), 200, 100)
S <- cov(z)
quad.naive <- function(z, S) {
        Sinv <- solve(S)
        rowSums((z %*% Sinv) * z) 
}
因为天真地说,我们应该键入与数学公式完全相同的

t(Z) %*% Sinv %*% Z

因此,任何人都可以解释为什么行和的形式与简单的数学形式相同,特别是为什么在两个度量z和Sin乘法之后,它使用元素级乘法符号*乘以z,而不是使用%*%

(z %*% Sinv) * z 

下面的评论太长了一点

我试图编写一个二次型Z的^{-1}Z,我认为二次型不正确

假设Z是一个m×n矩阵。然后:

S=covZ是一个nxn矩阵 S^-1是一个nxn矩阵 tZ是一个nxm矩阵 所以Z的^-1z在R:tZ%*%solveS%*%Z中意味着将矩阵与以下维数相乘

(n x m) (n x m) (m x n)
这显然行不通

也许你的意思是Z%*%解%*%tZ,它返回一个m x m矩阵,其对角线与rowSumsZ%*%Sinv*Z相同


更根本的问题是:不应该是标量吗?或者你说的是另一种二次型

下面的评论太长了一点

我试图编写一个二次型Z的^{-1}Z,我认为二次型不正确

假设Z是一个m×n矩阵。然后:

S=covZ是一个nxn矩阵 S^-1是一个nxn矩阵 tZ是一个nxm矩阵 所以Z的^-1z在R:tZ%*%solveS%*%Z中意味着将矩阵与以下维数相乘

(n x m) (n x m) (m x n)
这显然行不通

也许你的意思是Z%*%解%*%tZ,它返回一个m x m矩阵,其对角线与rowSumsZ%*%Sinv*Z相同


更根本的问题是:不应该是标量吗?或者你说的是另一种二次型

好的,在我们交换了评论和你给书中相关章节的链接之后,我想我理解了问题所在

我把这篇文章作为一个独立的、真实的回答,以避免让未来的读者感到困惑,因为他们可能想通过评论中的思路来阅读

让我们回到你文章中给出的代码,它是从第1.3.3节多元正态分布中复制的

设定日期2017-07-13
z好的,在我们交换了评论和你给书中相关章节的链接之后,我想我理解了问题所在

我把这篇文章作为一个独立的、真实的回答,以避免让未来的读者感到困惑,因为他们可能想通过评论中的思路来阅读

让我们回到你文章中给出的代码,它是从第1.3.3节多元正态分布中复制的

设定日期2017-07-13
亲爱的毛里塔尼亚,非常感谢你的回答,这澄清了我的一个困惑,所以考虑到大小,最简单的编码方式是z%*%solutions%*%tZ。但是当你说得到的m×m矩阵的对角线与rowSumsZ%*%Sinv*Z相同时,为什么我们需要考虑二次矩阵的对角线?我们不应该关注二次型及其结果矩阵吗?非常感谢。是因为结果本质上是一个标量,所以标量的对角线就是它本身吗?此外,我发现很难想象“rowSumsZ%*%Sinv*Z”。第一部分Z%*%Sinv应生成一个m×n矩阵,然后代码使用该矩阵明智地对Z元素计时,最后获取生成的m×n矩阵的每一行的总和。谢谢大家!@skylar是因为结果本质上是一个标量,所以标量的对角线就是它本身?我很难理解这意味着什么。矩阵的对角线就是它所说的:它是矩阵的对角线元素。矩阵的轨迹是对角线元素的和,这是一个标量。通常,随机变量中的二次型是标量。我不知道你对二次型的定义是从哪里来的。我觉得这有点像XY问题,但在不了解你的背景或背景的情况下,我真的帮不了你。[续1]关于行和如何在这里工作。考虑两个矩阵A [续2 ],我有一种感觉,这归结为对二次型是什么的误解。据我所知,在quad.naive的原始代码中,参数z应该是一个随机变量的n个观测值的向量,而不是一个矩阵。亲爱的毛里茨,非常感谢你的回答,这澄清了我的一个困惑,因此考虑到大小,编写代码的简单方法是z%*%solutions%*%tZ。但是当你说得到的m×m矩阵的对角线与rowSumsZ%*%Sinv*Z相同时,为什么我们需要考虑二次矩阵的对角线?我们不应该关注二次型及其结果矩阵吗?非常感谢。是因为结果本质上是一个标量,所以标量的对角线就是它本身吗?此外,我发现很难想象“rowSumsZ%*%Sinv*Z”。第一部分Z%*%Sinv应生成一个m乘n的矩阵,然后代码使用该矩阵明智地对Z元素计时,最后取e的和
得到的m乘n矩阵的每一行。谢谢大家!@skylar是因为结果本质上是一个标量,所以标量的对角线就是它本身?我很难理解这意味着什么。矩阵的对角线就是它所说的:它是矩阵的对角线元素。矩阵的轨迹是对角线元素的和,这是一个标量。通常,随机变量中的二次型是标量。我不知道你对二次型的定义是从哪里来的。我觉得这有点像XY问题,但在不了解你的背景或背景的情况下,我真的帮不了你。[续1]关于行和如何在这里工作。考虑两个矩阵A [续2 ],我有一种感觉,这归结为对二次型是什么的误解。据我所知,在quad.naive的原始代码中,参数z应该是一个随机变量的n个观测值的向量,而不是一个矩阵。非常感谢您如此详细的解释!我想现在我明白了每一个细节。1.所以通常,z应该是一个p*1向量,因此二次型z'Sinv z是一个标量。但在该示例中,Z是200个转置的p*1向量行绑定在一起。结果实际上是二次型标量的分布。感谢您的大力推广,这样的分布实际上是卡方分布!续二。rowSumsz%*%Sinv*z与diag z%*%Sinv%*%tz相同,但保存失败。继续该网站是一个很棒的资源!谢谢分享!但我还有另一个困惑,这个网站上没有介绍,这是关于矩阵微分的。e、 g.d X'A X/dX=X'A+A'。这种微分与单变量微分中直接使用的规则有点不同。我不确定你是否有什么好的方法或书籍可以推荐。我自学了维基百科,并在网上搜索了一些课堂讲稿。但我更喜欢一些正式的阅读材料。非常感谢。有些人建议使用矩阵食谱。但我不认为这是一个好的方法,因为它只有结果,没有证据。@skylar对你的观点1的反应,二次型总是一个标量,通常没有,z应该是。。。;我们在这里看到的是二次型的分布,这是一个向量。2是的,我认为这是使用行和的优势;但是请记住,这在计算上仍然不是很有效/稳定,因为我们仍然需要反转矩阵。Cholesky分解解决了这个问题。非常感谢您如此详细的解释!我想现在我明白了每一个细节。1.所以通常,z应该是一个p*1向量,因此二次型z'Sinv z是一个标量。但在该示例中,Z是200个转置的p*1向量行绑定在一起。结果实际上是二次型标量的分布。感谢您的大力推广,这样的分布实际上是卡方分布!续二。rowSumsz%*%Sinv*z与diag z%*%Sinv%*%tz相同,但保存失败。继续该网站是一个很棒的资源!谢谢分享!但我还有另一个困惑,这个网站上没有介绍,这是关于矩阵微分的。e、 g.d X'A X/dX=X'A+A'。这种微分与单变量微分中直接使用的规则有点不同。我不确定你是否有什么好的方法或书籍可以推荐。我自学了维基百科,并在网上搜索了一些课堂讲稿。但我更喜欢一些正式的阅读材料。非常感谢。有些人建议使用矩阵食谱。但我不认为这是一个好的方法,因为它只有结果,没有证据。@skylar对你的观点1的反应,二次型总是一个标量,通常没有,z应该是。。。;我们在这里看到的是二次型的分布,这是一个向量。2是的,我认为这是使用行和的优势;但是请记住,这在计算上仍然不是很有效/稳定,因为我们仍然需要反转矩阵。Cholesky分解可以解决这个问题。
set.seed(2020)
nSamples <- 100
z <- matrix(rnorm(nSamples * 2), nSamples, 2)
S <- cov(z)
Sinv <- solve(S)
dquadform <- rowSums(z %*% Sinv * z)
library(ggplot2)
bw = 0.2
ggplot(data.frame(x = dquadform), aes(x)) +
    geom_histogram(binwidth = bw) +
    stat_function(fun = function(x) dchisq(x, df = 2) * nSamples * bw)
ks.test(dquadform, pchisq, df = 2)
#
#   One-sample Kolmogorov-Smirnov test
#
#data:  dquadform
#D = 0.063395, p-value = 0.8164
#alternative hypothesis: two-sided