我必须编写一个执行此操作的Matlab脚本:
输入是2个矩阵,A(m x n)和D(m x 1)。输出是矩阵,C(m×n)。 C计算如下:
function c = scanrow(a,d)
[rows columns] = size(d);
for i=1:columns
a(i,:) = a(i,:).*d(i);
end
c = a;
end
要求不使用递归。我不知道解决这个问题。很高兴你可以提供帮助。 谢谢。
答案 0 :(得分:10)
就像FYI - bsxfun +函数句柄一样,它是在矩阵和向量上执行操作的新热点,其中至少一个矩阵维度与一个向量维度匹配。这避免了明显的rempat,这可能是缓慢和浪费的:
a = 1:5; b = magic(5); c = bsxfun(@times,a,b);
但要小心 - 这只适用于相对较新的MATLAB版本。 -pete
答案 1 :(得分:3)
如果问题是“将A的每一行中的每个元素与D的相应行上的相应元素相乘”,那么我建议如下:
dd = repmat(d, 1, size(a, 2))
c = a.*dd
示例:
>> a = [1 2; 3 4; 5 6];
>> d = [1 2 3]';
>> dd = dd = repmat(d, 1, size(a, 2))
dd =
1 1
2 2
3 3
>> a.*dd
ans =
1 2
6 8
15 18
答案 2 :(得分:3)
(我会回答,尽管这是家庭作业。我认为很多人不理解为什么会创建bsxfun。)
通过乘法的方式还有其他解决方案。典型的是使用repmat,使用循环,或乘以对角矩阵。如果使对角矩阵成为稀疏矩阵则更好。但是,bsxfun绝对是正确的解决方案。它是为了解决这样的问题而编写的。问题是当你做
之类的事情时A = magic(3) + 5
MATLAB理解它必须为魔法的每个元素添加5(3)。同样,当你做
时A = magic(4).*2
再次,MATLAB理解乘法将扩展到所有元素。本质上,MATLAB隐式地将标量扩展为与加法或乘法中的伙伴相同大小的数组,然后执行操作。这是由repmat求解器明确完成的。
显式标量扩展的问题在于,这需要时间和内存来进行扩展。因此,时间和加号足够聪明,可以识别标量扩展是合适的,但实际上并不是显式内存占用操作。当您尝试
时,MATLAB不知道该怎么做A = magic(3).*rand(1,3)
过去,解决方案是使用repmat。但是,当您使用repmat将向量显式扩展为矩阵时,会占用大量内存来以矢量化方式解决问题。是的,矢量化在MATLAB中交换内存的时间很常见,但如果你的内存有限,并且你正在解决一个大问题,这可能是一件坏事。当没有必要时,强制MATLAB(和你的操作系统)进入虚拟内存是一个非常糟糕的主意。 (对于一个小问题,任何解决方案都是可以接受的。)
因此,当您尝试将像魔术(3)这样的数组乘以行或列向量时,MATLAB是否应该理解它应该将向量隐式扩展为数组?或者MATLAB是否应该假设您犯了错误,并将其标记为这样?这个问题,称为单体尺寸的扩展是问题。 (单个维度在向量中找到,其中一个维度为1.)返回错误消息对于许多用户来说是一个好主意,因为这通常表示发现了一个错误,这是一个错误。简单,自动扩展所有单例尺寸以适应手头的问题似乎是危险的。事实上,有很多关于该做什么的讨论。例如,MATLAB是否应该创建首选项,用户可以在其MATLAB版本中启用单例维度的扩展?这将是一个糟糕的主意,因为它会使代码跨系统不可移植。
此外,如果修改基本的MATLAB运算符以始终展开所有单例维度,那么MATLAB代码将非常不可移植回旧版本。
我们甚至讨论过创建一整套新的MATLAB运算符,比如。*与*并行存在,以便在扩展单例维度时进行操作。这也是一个糟糕的主意,并且正确地避免了。
解决方案是创建BSXFUN(二进制标量扩展功能),以便在需要时有效地完成此操作。在文件交换机上找到了一个bsxfun,允许旧版本的用户获得此行为,因此可以保持可移植性。 BSXFUN允许您对任何参数对进行操作,在它们之间应用用户提供的函数。所以它允许你做这样的事情:
A = rand(5,1);
B = rand(1,3);
C = bsxfun(@plus,A,B);
创建A和B中每个元素之和的5x3矩阵。您也可以使用任何函数作为第一个操作数,因此BSXFUN非常强大。
最后,另一种看待BSXFUN的方法是作为外部产品的变体。因此,MATLAB中的这个操作得到了很好的定义:
A = rand(5,1);
B = rand(1,3);
C = A*B;
但是,这些操作中的任何一个
D = A-B;
E = A^B;
会产生错误。 BSXFUN允许您有效地执行它们,而不会占用单个维度扩展的内存。
D = bsxfun(@minus,A,B);
E = bsxfun(@power,A,B);
答案 3 :(得分:0)
也许vectorize()
就是你想要的 - > Code Vectorization Guide
答案 4 :(得分:0)
您确定问题中包含的代码是否正确?这就是它的表现:
我假设输入 a 和 d 表示矩阵 A (大小为m-by-n)和 D 你提到的强>(大小为m-by-1)。由于您将 d 定义为始终具有1列,因此for循环是不必要的,因为它只会循环一次。单次循环将简单地将 a 的第一行中的值乘以 d 中的第一个值。因此,问题中的整段代码可以替换为以下内容:
c = a;
c(1,:) = c(1,:).*d(1);