我有一个由矩阵描述的范数sigma
sigma <- matrix(c(1,0.5,0,0.5,1,0,0,0,1),3,3))
计算我计算的向量的范数
t(x) %*% sigma %*% x
这适用于矢量,例如 x = 1:3
.
但是我想同时计算许多向量的范数,也就是说我有
x <- t(matrix(rep(1:3, 10),3,10))
(当然充满了不同的条目)。
有没有办法同时计算每个向量的范数?即类似的东西
lapply(1:10, function(i) t(x[i,]) %*% sigma %*% x[i,])
你可以做:
sigma <- matrix(c(1,0.5,0,0.5,1,0,0,0,1),3,3)
x <- t(matrix(rep(1:3, 10),3,10))
mynorm <- function(x, sig) t(x) %*% sig %*% x
apply(x, 1, mynorm, sig=sigma)
这是带有tcrossprod()
的变体:
mynorm <- function(x, sig) tcrossprod(x, sig) %*% x
apply(x, 1, mynorm, sig=sigma)
这是基准测试(包括仅计算 R 中矩阵乘法对角线的解决方案变体,这要归功于链接的@Benjamin):
mynorm1 <- function(x, sig) t(x) %*% sig %*% x
mynorm2 <- function(x, sig) tcrossprod(x, sig) %*% x
microbenchmark(n1=apply(x, 1, mynorm1, sig=sigma),
n2=apply(x, 1, mynorm2, sig=sigma),
n3 = colSums(t(x) * (sigma %*% t(x))),
n4 = rowSums(x * t(sigma %*% t(x))),
n5 = rowSums(x * (x %*% t(sigma) )),
n6 = rowSums(x * tcrossprod(x, sigma)),
Eugen1 = diag(x %*% sigma %*% t(x)),
Eugen2 = diag(x %*% tcrossprod(sigma, x)),
unit="relative")
这应该可以
> sigma <- matrix(c(1,0.5,0,0.5,1,0,0,0,1),3,3)
> x <- t(matrix(rep(1:30, 10),3,10))
>
> # should give
> t(x[1, ]) %*% sigma %*% x[1, ]
[,1]
[1,] 16
> t(x[2, ]) %*% sigma %*% x[2, ]
[,1]
[1,] 97
>
> # which you can get by
> rowSums((x %*% sigma) * x)
[1] 16 97 250 475 772 1141 1582 2095 2680 3337
你如何看待这个简单的矩阵乘法:
diag(t(x) %*% sigma %*% x)
编辑:矩阵乘法后,您需要对角线(当然)。
然后它比应用的解决方案更快