6

在 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。

4

2 回答 2

5

在这种简单的情况下,您可以使用

sum(x.*x)

整数矩阵似乎正确支持times( ),尽管( ) 不支持。.*mtimes*

对于一般矩阵乘法:让AB是两个具有合适大小的矩阵,以便A*B存在。由于timessum支持整数,因此您可以推广上述技巧,使用bsxfunsum计算乘积矩阵的所有条目,如下所示。

编辑:正如@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).

于 2013-10-25T16:06:21.467 回答
1
  • 由于缺乏工业支持,MATLAB 不支持整数矩阵-矩阵乘法。

    MATLAB 使用 BLAS(更具体地说,Intel 的 BLAS 实现,即 MKL)来做矩阵乘法。目前,BLAS 本身并不支持整数矩阵的乘法。然而,一个好消息是 MKL 2018 增加了对整数矩阵的初始支持。(参见这张幻灯片

  • 至于你的问题,如果你的目标是性能并且你的矩阵不是太小,sum(x.*x)不如int64(double(x)*double(x.')).

  • native仅当您确定不会发生上溢和下溢时才使用。

    还有一点需要注意的是,虽然nativeflag 可以保持返回值的类型与输入值的类型相同。它可能会遭受整数溢出或下溢。检查以下代码段。

    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)
    

    尽管singleanddouble也可以上溢和下溢,但它们发生的频率较低。

于 2017-12-19T08:04:46.643 回答