5.5 数组的外积
数组一个非常重要的运算就是外积运算(outer product)。如果 a
和 b
是两个数值数组,它们的外积将是这样的一个数组:维度向量通过连接两个操作数的维度向量(顺序非常的重要)得到;数据向量则由 a
的数据向量元素和 b
的数据向量元素的所有可能乘积得到。外积是通过特别的操作符 %o%
实现:
> ab <- a %o% b
一种备选的方案是,
> ab <- outer(a, b, "*")
命令中的乘法操作符可以被任意一个双变量函数代替。例如,我们想研究函数 f(x; y) = cos(y)/(1 + x2) 在 R 在向量 x
和 y
形成的格子平面(regular grid)上的特征,可以按下面的步骤进行:
> f <- function(x, y) cos(y)/(1 + x^2) > z <- outer(x, y, f)
特别是,两个常规向量的外积是一个双下标的数组(就是矩阵,最大秩为1)。注意,外积运算不符合交换律。定义你自己的 R 函数可以参考编写你自己的函数。
一个例子:2×2 数字矩阵的行列式
这是一个简单但能说明问题的例子,计算一个2×2的矩阵 [a, b; c, d] 的行列式。 该矩阵的所有元素是0, 1, . . . , 9里面的一个非负整数。
我们的问题是找出所有这种组合形式的矩阵行列式ad − bc同时以高密度(high density)图的形式显示这些行列式值的分布。如果所有数字的选取是独立随机的,这样做实际上会得到所有行列式的概率分布图。
解决这个问题一个巧妙的办法就是两次使用函数 outer()
:
> d <- outer(0:9, 0:9)
> fr <- table(outer(d, d, "-"))
> plot(fr, xlab="Determinant", ylab="Frequency")
注意,此处 plot()
使用一种类似直方图的作图方法,因为它将 fr
“看作“了 table
类。
“显式”解决这个问题是用 for
循环语句。这个将在循环和条件控制部分讨 论,不过效率太低以至现实中很少采用。
还有一点比较奇怪的是,每20个这样的矩阵就有有一个矩阵是奇异矩阵1。
1. 译者注: 原文是”It is also perhaps surprising that about 1 in 20 such matrices is singular.” ↩