如何在MATLAB中成功地将向量和矩阵相乘?

时间:2015-08-04 21:24:35

标签: matlab vector vectorization

我想计算以下表达式:

a_2 = c_k2 * (b - t_k2)

其中t_k2是大小为K1 x K2的列向量,b的大小为K1 x 1c_k2为常量(1 x 1)。但我有那些t矢量的K2。我知道我可以这样做:

t % (K1 x K2)
b % (K1 x 1)
a_k2 % (K1 x K2)
c % (K2 x 1)
for k2=1:K2
    t_k2 = t(:,k2); % K1 x 1
    c_k2 = c(k2);
    a_k2(:,k2) = c_k2 * (b - t_k2); % K1 x 1
end

但我想知道是否有一种切割方法可以将它作为单行写入MATLAB(以避免所有索引和循环,并希望提高速度)。这可能吗?

我最初的想法可能是将b复制到大小为'K1 x K2'的矩阵中。假设可以完成,用B表示。然后我们可以计算B - t,我们每个条目都有(b - t_k2)。假设我们甚至可以做到这一点,我唯一的想法是将每个常量c_k复制到c_k_vec = [c_k, ... c_k]中的那个数字的向量中,然后对这些矩阵进行元素相乘。很明显B应该:

B = repmat(b, [1,K2]);

B - t

完成了部分任务...但我不清楚如何在一行中生成列c_k_vec = [c_k, ... c_k]的矩阵而不进行循环。想法是向量c与每个列B-t匹配,并且我们想要将每个B-t列乘以向量x中的条目。

也许这是不可能的......

2 个答案:

答案 0 :(得分:3)

你几乎回答了你的问题(再次:))。您当然可以使用repmat上的b水平复制列向量K2次以使尺寸保持一致。但是,c矩阵存在轻微问题,因为如果要实现矢量化输出矩阵的计算,则尺寸当前不兼容。

如果我正确理解您的问题,您输出的每一行都应乘以c的相应行。在这种情况下,只是在repmat上运行c的另一种情况,但复制此向量 K1

具体来说,你可以这样做:

a_k2 = repmat(c.', K1, 1) .* (repmat(b, 1, K2) - t);

注意我必须转置c,因为你说它是K2 x 1向量。为了确保匹配大小,我将其转换为1 x K2repmat'ing将复制此矩阵变为K1 x K2以匹配中间结果。< / p>

然而,这看起来有点不雅。我鼓励你利用bsxfun,它在幕后进行复制:

a_k2 = bsxfun(@times, c.', bsxfun(@minus, b, t));

首先要做的是b复制的列数与t一样多,然后我们会通过复制{c将这个中间结果乘以正确的c值{1}}向量以匹配形状与中间结果。 bsxfun的美妙之处在于,您不需要知道repmat某事需要多少次。 bsxfun为你找出了解决方法。

为了表明所有三个语句都是等价的,让我们生成一些示例数据,并运行你的for循环,然后是我上面写的两段代码:

%// Data setup
rng(123);
K1 = 10;
K2 = 12;

t = rand(K1, K2);
b = rand(K1, 1);
c = rand(K2, 1);

%// Your code
for k2=1:K2
    t_k2 = t(:,k2); % K1 x 1
    c_k2 = c(k2); %// Note - typo here
    a_k2(:,k2) = c_k2 * (b - t_k2); % K1 x 1
end

%// Using repmat
a_k2r = repmat(c.', K1, 1) .* (repmat(b, 1, K2) - t);

%// Using bsxfun
a_k2b = bsxfun(@times, c.', bsxfun(@minus, b, t));

a_2k是根据您的代码生成的内容,a_k2ra_k2b是我建议的两段代码的输出。如果我们全部显示它们,我们得到:

>> a_k2

a_k2 =

  Columns 1 through 7

    0.1527    0.0905    0.1628    0.7042    0.2768    0.0623    0.1011
   -0.0574   -0.0840   -0.3855   -0.1957    0.0905   -0.0491   -0.1620
    0.0480   -0.0235   -0.2595   -0.1198   -0.0244   -0.0246   -0.1424
   -0.0229    0.0741   -0.0547    0.0228    0.1035   -0.0020   -0.0663
    0.1334    0.0812    0.1078    0.4122    0.0350    0.0444    0.0255
    0.4098    0.0396    0.3969    0.5813    0.7211    0.0539    0.3857
   -0.5287    0.0121   -0.0626   -0.1462   -0.2218   -0.0127   -0.2168
   -0.0881    0.0626    0.2019   -0.2849   -0.4143   -0.0093    0.1374
    0.2384    0.0444    0.3083   -0.1188    0.2827   -0.0054    0.2625
    0.0016   -0.0221   -0.1421   -0.0931   -0.2149   -0.0092   -0.0763

  Columns 8 through 12

    0.1656    0.2643    0.1098    0.0366    0.1747
   -0.1386   -0.2183   -0.4315   -0.0428   -0.0435
   -0.0685   -0.1180   -0.0347    0.0174    0.0360
   -0.0416    0.0591   -0.1329    0.0363   -0.0918
    0.1812   -0.0105    0.1691    0.0541    0.1672
    0.0796    0.0640    0.1599    0.0301    0.1280
   -0.0612   -0.0450    0.0583   -0.0550   -0.0953
    0.0829    0.2347    0.0906    0.0010    0.0127
    0.1338    0.2263    0.3101   -0.0044    0.2388
   -0.0616   -0.0017    0.0279    0.0009   -0.1763

>> a_k2b

a_k2b =

  Columns 1 through 7

    0.1527    0.0905    0.1628    0.7042    0.2768    0.0623    0.1011
   -0.0574   -0.0840   -0.3855   -0.1957    0.0905   -0.0491   -0.1620
    0.0480   -0.0235   -0.2595   -0.1198   -0.0244   -0.0246   -0.1424
   -0.0229    0.0741   -0.0547    0.0228    0.1035   -0.0020   -0.0663
    0.1334    0.0812    0.1078    0.4122    0.0350    0.0444    0.0255
    0.4098    0.0396    0.3969    0.5813    0.7211    0.0539    0.3857
   -0.5287    0.0121   -0.0626   -0.1462   -0.2218   -0.0127   -0.2168
   -0.0881    0.0626    0.2019   -0.2849   -0.4143   -0.0093    0.1374
    0.2384    0.0444    0.3083   -0.1188    0.2827   -0.0054    0.2625
    0.0016   -0.0221   -0.1421   -0.0931   -0.2149   -0.0092   -0.0763

  Columns 8 through 12

    0.1656    0.2643    0.1098    0.0366    0.1747
   -0.1386   -0.2183   -0.4315   -0.0428   -0.0435
   -0.0685   -0.1180   -0.0347    0.0174    0.0360
   -0.0416    0.0591   -0.1329    0.0363   -0.0918
    0.1812   -0.0105    0.1691    0.0541    0.1672
    0.0796    0.0640    0.1599    0.0301    0.1280
   -0.0612   -0.0450    0.0583   -0.0550   -0.0953
    0.0829    0.2347    0.0906    0.0010    0.0127
    0.1338    0.2263    0.3101   -0.0044    0.2388
   -0.0616   -0.0017    0.0279    0.0009   -0.1763

>> a_k2r

a_k2r =

  Columns 1 through 7

    0.1527    0.0905    0.1628    0.7042    0.2768    0.0623    0.1011
   -0.0574   -0.0840   -0.3855   -0.1957    0.0905   -0.0491   -0.1620
    0.0480   -0.0235   -0.2595   -0.1198   -0.0244   -0.0246   -0.1424
   -0.0229    0.0741   -0.0547    0.0228    0.1035   -0.0020   -0.0663
    0.1334    0.0812    0.1078    0.4122    0.0350    0.0444    0.0255
    0.4098    0.0396    0.3969    0.5813    0.7211    0.0539    0.3857
   -0.5287    0.0121   -0.0626   -0.1462   -0.2218   -0.0127   -0.2168
   -0.0881    0.0626    0.2019   -0.2849   -0.4143   -0.0093    0.1374
    0.2384    0.0444    0.3083   -0.1188    0.2827   -0.0054    0.2625
    0.0016   -0.0221   -0.1421   -0.0931   -0.2149   -0.0092   -0.0763

  Columns 8 through 12

    0.1656    0.2643    0.1098    0.0366    0.1747
   -0.1386   -0.2183   -0.4315   -0.0428   -0.0435
   -0.0685   -0.1180   -0.0347    0.0174    0.0360
   -0.0416    0.0591   -0.1329    0.0363   -0.0918
    0.1812   -0.0105    0.1691    0.0541    0.1672
    0.0796    0.0640    0.1599    0.0301    0.1280
   -0.0612   -0.0450    0.0583   -0.0550   -0.0953
    0.0829    0.2347    0.0906    0.0010    0.0127
    0.1338    0.2263    0.3101   -0.0044    0.2388
   -0.0616   -0.0017    0.0279    0.0009   -0.1763

...并且为了一些奖励,让我们比较原始矩阵(您的代码)与其中每一个之间的绝对差异,并找出最大偏差:

>> format long g
>> max_diff1 = max(abs(a_k2(:) - a_k2r(:)))

max_diff1 =

     0

>> max_diff2 = max(abs(a_k2(:) - a_k2b(:)))

max_diff2 =

     0

正如您所看到的,如果我们在计算a_2k与我使用repmatbsxfun生成的内容之间采用了元素明确的减法,那么它就说明了差异中最大的元素这两个矩阵是0 ....所以,我们可以看到源和任何一种替代方法之间没有区别。

答案 1 :(得分:-2)

我不确定c_k_vec来自哪里,但是通过。*所以很容易对每个元素进行向量乘法。所以如果你已经解决了(b-t_k2)部分,那么乘以常量应该非常简单。*