如何利用R语言矩阵批量生成向量外积数组(无循环)
问题描述
现有四个三维向量:
v1 <- c(1, 2, 3) v2 <- c(4, 5, 6) v3 <- c(2, 2, 2) v4 <- c(3, 2, 1)
目标是创建一个包含每个向量自身外积的数组,常规写法如下:
tmp_array <- array(NA, dim = c(3, 3, 4)) tmp_array[, , 1] <- outer(v1, v1) tmp_array[, , 2] <- outer(v2, v2) tmp_array[, , 3] <- outer(v3, v3) tmp_array[, , 4] <- outer(v4, v4)
已将向量行绑定为矩阵:
tmp_matrix <- rbind(v1, v2, v3, v4)
要求不使用显式循环,通过该矩阵紧凑生成上述tmp_array,此前尝试outer(t(tmp_matrix), tmp_matrix)等方法未成功,求可行方案。
可行方案
方法1:用apply批量计算外积
apply属于隐式循环,代码简洁且符合无显式循环的要求:
# 对矩阵每行计算自身外积,得到维度为(4,3,3)的临时数组 tmp_array <- apply(tmp_matrix, 1, function(x) outer(x, x)) # 调整维度顺序为(3,3,4),匹配目标结构 tmp_array <- aperm(tmp_array, c(2, 3, 1))
方法2:利用矩阵乘法结合数组重塑
向量自身的外积等价于tcrossprod(x)(即x %*% t(x)),可以用向量化操作批量生成后重塑:
# 对每行计算tcrossprod,再直接重塑为目标数组 tmp_array <- array(apply(tmp_matrix, 1, tcrossprod), dim = c(3,3,4))
或者用元素级乘法的广播特性,效率更高:
# 生成所有外积的扁平化结果,再重塑为数组 prod_vals <- tmp_matrix[, rep(1:3, each=3)] * tmp_matrix[, rep(1:3, 3)] tmp_array <- array(prod_vals, dim = c(3,3,4))
方法3:修正outer的使用方式
如果坚持用outer,可以通过维度调整实现(可读性稍差):
# 生成所有行向量的外积元素对,再截取自身外积部分重塑 prod_vals <- outer(as.vector(t(tmp_matrix)), as.vector(tmp_matrix)) tmp_array <- array(prod_vals[rep(1:12, each=3) + rep(0:2, 12)*12], dim = c(3,3,4))
内容的提问来源于stack exchange,提问作者MinChul Park
相关产品推荐
相关产品推荐

