在MATLAB中乘以整数值矩阵的最佳方法是什么?
我很惊讶地发现以下行为不被接受:
>> x = int64([1, 2])
>> x * x'
Error using *
MTIMES is not fully supported for integer classes. At least one input must be scalar.
To compute elementwise TIMES, use TIMES (.*) instead.
我总是可以转换为双倍然后再转回。这是最好的解决方案吗?我正在使用R2013b。
答案 0 :(得分:4)
在这个简单的例子中,你可以使用
sum(x.*x)
虽然times
(.*
)不是,但似乎mtimes
(*
)正确支持整数矩阵。
对于一般矩阵乘法:让A
和B
为两个具有合适大小的矩阵,以便A*B
存在。由于整数支持times
和sum
,因此您可以使用bsxfun
和sum
来概括上述技巧,以计算产品矩阵的所有条目,如下所示。
编辑:如@July所述,您需要'native'
中的sum
标记才能保留整数类型的结果。还要感谢您指出由squeeze
引起的问题,现在使用第二个permute
进行了更正。
permute(sum(bsxfun(@times, A.', permute(B, [1 3 2])), 1, 'native'), [2 3 1])
例如:
>> A = int64([1 2; 3 4])
A =
1 2
3 4
>> B = int64([5 7 9; 6 8 10])
B =
5 7 9
6 8 10
>> permute(sum(bsxfun(@times, A.', permute(B, [1 3 2])), 'native'), [2 3 1])
ans =
17 23 29
39 53 67
无论如何,最快的选择似乎是double(A)*double(B)
。
答案 1 :(得分:1)
由于缺乏工业支持,MATLAB不支持整数矩阵 - 矩阵乘法。
MATLAB使用BLAS(更具体地说,是英特尔的BLAS实现,即MKL)来进行矩阵乘法。目前,BLAS本身并不支持整数矩阵的乘法。然而,一个好消息是MKL 2018增加了对整数矩阵的初始支持。 (参见this slides)
至于你的问题,如果你的目标是表现并且你的矩阵不是太小,sum(x.*x)
不如int64(double(x)*double(x.'))
。
仅当您确定不会发生上溢和下溢时才使用native
。
另外需要注意的是,虽然native
标志可以保持返回值的类型与输入值的类型相同。它可能会遇到整数上溢或下溢。请查看以下代码段。
sum(int8(-ones(300,1)), 'native') % ans = -128 (of type int8)
sum(int8(ones(300,1)), 'native') % ans = 127 (of type int8)
sum(int8(ones(300,1))) % ans = 300 (of type double)
虽然single
和double
也可能会溢出和下溢,但它们的发生频率会降低。