我正在做一些Matlab的家庭作业,我遇到的问题是概念化它解决矩阵的方式.在Matlab中,矩阵是d(row,col)格式的地址.
我已经编程了一段时间,并且总是倾向于将一维数组视为水平结构,第二维从下方延伸出来.
从计算机的角度来看,其中哪一种是更"正确"的思考阵列数据结构的方式
是否有矢量化方式来执行以下操作?(以示例显示):
input_lengths = [ 1 1 1 4 3 2 1 ]
result = [ 1 2 3 4 4 4 4 5 5 5 6 6 7 ]
Run Code Online (Sandbox Code Playgroud)
我已经间隔了input_lengths,因此很容易理解如何获得结果
合成矢量的长度为:sum(lengths).我目前result使用以下循环计算:
result = ones(1, sum(input_lengths ));
counter = 1;
for i = 1:length(input_lengths)
start_index = counter;
end_index = counter + input_lengths (i) - 1;
result(start_index:end_index) = i;
counter = end_index + 1;
end
Run Code Online (Sandbox Code Playgroud)
编辑:
我也可以使用arrayfun(虽然这不是一个矢量化函数)
cell_result = arrayfun(@(x) repmat(x, 1, input_lengths(x)), 1:length(input_lengths), 'UniformOutput', false);
cell_result : …Run Code Online (Sandbox Code Playgroud) 我理解在MATLAB这样的语言中使用矢量化是如何通过消除维护循环变量的开销来加速代码的,但是矢量化实际上是如何在汇编/机器代码中进行的?我的意思是在某个地方仍然必须有一个循环,对吗?
哪一个更好,使用所有的*fun功能(arrayfun,cellfun,structfun和spfun),或者干脆利用for循环?
在代码的可读性方面,哪种方法可以提供更好的性能,哪种方法应该被认为是更好的实践?
我正在寻找有关如何优雅地解决以下问题的建议.虽然在我的具体案例中表现不是问题,但我会对有关良好做法的评论表示赞赏.
提前致谢!
我试图根据一些逻辑平均矩阵行,而忽略NaN值.我目前的代码没有按照我想要的方式处理NaN值.
我的数据以下列方式构建:
这是一个例子:
DATA = [...
180 NaN NaN 1.733
180 NaN NaN 1.703
200 0.720 2.117 1.738
200 0.706 2.073 1.722
200 0.693 2.025 1.723
200 NaN NaN 1.729
210 NaN NaN 1.820
210 NaN NaN 1.813
210 NaN NaN 1.805
240 NaN NaN 1.951
240 NaN NaN 1.946
240 NaN NaN 1.946
270 NaN NaN 2.061
270 NaN NaN 2.052
300 0.754 2.356 2.103
300 0.758 2.342 2.057
300 NaN …Run Code Online (Sandbox Code Playgroud) 我有一个结构
s.a = [1 2 3];
s.b = [2 3 4 5];
s.c = [9, 6 ,3];
s.d = ... % etc. - you got the gist of it
Run Code Online (Sandbox Code Playgroud)
现在我想对存储在每个字段中的数据应用函数/操作并修改字段的内容,即我想申请
s.a = myFun( s.a );
s.b = myFun( s.b );
s.c = myFun( s.c ); % etc. ...
Run Code Online (Sandbox Code Playgroud)
如果没有明确地写上面的所有字段,我怎么能这样做呢?我在考虑structfun- 但我不太确定如何完成这个"到位"修改......
谢谢!
在Matlab中构造一个元素正好是它们的索引的矩阵的最佳方法是什么?
编辑:这个问题的现有答案适用于如何构建一个矩阵,其元素是其索引的函数.所以我把它添加到问题标题中.
格式可以是以矢量为元素的矩阵,也可以是每个存储一个索引的两个矩阵.
最后,我想创建一个矩阵,其元素是其索引的函数.因此非常感谢一种有效的方法(但可能不同).对效率的任何评论都受到欢迎.
对于我的应用程序,矩阵的大小往往很大(最小数百平方).因此,利用原生Matlab函数的方法可能比for/while循环要好得多.
例如,对于大小为[2 2]的矩阵,我想制作其中一个
IND =
[1 1] [1 2]
[2 1] [2 2]
Run Code Online (Sandbox Code Playgroud)
要么
X =
1 1
2 2
Y =
1 2
1 2
Run Code Online (Sandbox Code Playgroud)
最后,我希望做类似的事情
matrixIneed = arrayfun(@(s)..., IND)
Run Code Online (Sandbox Code Playgroud)
其中s是大小为2的向量,或
matrixIneed = arrayfun(@(i,j)..., X,Y)
Run Code Online (Sandbox Code Playgroud)
后者是优选的.
编辑:关于已接受答案的说明.
我已经接受了安德鲁的回答,因为它对我来说很直观,代码似乎很快(至少对我来说).
如果你曾经谷歌这个问题的答案,你可能会像我一样关注性能.(否则,如果不是最佳实践,任何人都可以想到双循环来完成任务.)
如果是这样,建议您检查对安德鲁的评论reshape()功能,罗迪的有关性能的答案meshgrid()和loops.
尽管如此,thewaywewalk的解决方案meshgrid()是学习该meshgrid()功能的有用示例.它在许多其他Matlab函数中很有用.
Jigg的repmat()解决方案也可以为您提供帮助.
假设我有两个矩阵A和B.
A = rand(4,5,3);
B = rand(4,5,6)
Run Code Online (Sandbox Code Playgroud)
我想应用函数'corr2'来计算相关系数.
corr2(A(:,:,1),B(:,:,1))
corr2(A(:,:,1),B(:,:,2))
corr2(A(:,:,1),B(:,:,3))
...
corr2(A(:,:,1),B(:,:,6))
...
corr2(A(:,:,2),B(:,:,1))
corr2(A(:,:,2),B(:,:,2))
...
corr2(A(:,:,3),B(:,:,6))
Run Code Online (Sandbox Code Playgroud)
如何避免使用循环来创建这样的矢量化?
假设我想将一个单元格数组的每个元素A与一个系数相乘k.我可以这样做:
A = cellfun(@(x) k*x, A, 'UniformOutput', false)
Run Code Online (Sandbox Code Playgroud)
但这非常缓慢.有更快更好的方法吗?单元阵列元素是可变长度向量,因此cell2num不适用.
编辑:基于fpe对for循环的推荐,这是一个示例基准.从这些数据开始
A = arrayfun(@(n) rand(n,1), randi(5,1000,1000), 'UniformOutput',false);
Run Code Online (Sandbox Code Playgroud)
cellfun上面的调用需要9.45 seconds,而for循环:
A2 = cell(size(A));
for i = 1:size(A,1), for j = 1:size(A,2), A2{i,j} = A{i,j}*k; end; end
A = A2;
Run Code Online (Sandbox Code Playgroud)
需要1.67 seconds,这是一个重大的进步.我仍然更喜欢几个数量级的东西.(我也不明白为什么Matlab解释器无法像for循环一样快地进行cellfun调用.它们在语义上是相同的.)
编辑2: Amro建议制作一个单循环的速度要快得多:
for i = 1:numel(A), A{i} = A{i}*k; end
Run Code Online (Sandbox Code Playgroud)
需要1.11 seconds,如果我pack在它之前运行,只是调整内存0.88 seconds.
实现MEX函数实现这一点实际上并没有好多少:0.73 seconds,(0.53 seconds …
我的问题是:如何在类似于 Haskell 或 Python 的 Matlab 中执行类似列表理解的操作?在Matlab中完成如下功能:
for xxx
if condition
expression1;
else
expression2;
end
end
Run Code Online (Sandbox Code Playgroud)
我最初的目标是利用矢量化操作并减少代码中的 for 循环以使其运行得更快。
编辑:我对答案的期望与 arrayfun 无关,向量化操作方法更受欢迎。
还有另一个与此问题相关的问题(通过名为“arrayfun”的函数)。Matlab 中的匿名函数接缝只有 1 行,那么我如何在其中编写 if-else 表达式?
谢谢大家~~
matlab ×10
arrays ×2
accumarray ×1
for-loop ×1
loops ×1
matrix ×1
nan ×1
octave ×1
performance ×1