我正在编写一些matlab代码并编写了一个有效的算法,但我认为它不是特别有效。由于我正在努力提高我的编程技巧,我想知道是否有更有效的方法来做到这一点。
我有一个(相当大的~E07)值矩阵,它们是无序的,但是在[-100,100]范围内。我想通过使用以下规则创建基于第一个矩阵的第二个矩阵:
以下是我目前正在做的事情:
data = 100*(-1+2*rand(1,10000000)); % create random dataset for stackoverflow
new_data = zeros(1,length(data));
for i = 1:length(data)
if (data(i) > 70)
new_data(i) = 70;
elseif (data(i) < -70)
new_data(i) = -70;
else
new_data(i) = round(data(i)/5.0)*5.0;
end
end
有更有效的方法吗?我认为应该有一种方法可以使用逻辑索引来做到这一点,但这些对我来说是一个新发现......
答案 0 :(得分:8)
根本不需要循环:
data = 100*(-1+2*rand(1,10000000)); % create random dataset for stackoverflow
new_data = zeros(1,length(data)); % note that this memory allocation is not necessary at this point
new_data = round(data/5.0)*5.0;
new_data(data>70) = 70;
new_data(data<-70) = -70;
答案 1 :(得分:5)
更容易使用max和min。只需一行即可。
new_data = round(5*max(-70,min(70,data)))/5;
答案 2 :(得分:2)
H.Muster和woodchips的两个答案当然是这样做的方法,但仍然有一些小改进。如果您在演出后可能想要利用问题的具体细节。例如,您的输出数据是整数-100 <= x <= 100
。这显然符合8位有符号整数数据类型。此代码(注意从任意双精度数据显式转换为int8
)
% your double precision input data
data = 100*(-1+2*rand(1,10000000));
% cast to int8 - matlab does usual round here
data = int8(data);
new_data = 5*(max(-70,min(70,data))/5);
是最快的,有两个原因:
以下是H.Muster,木片和我的小修改代码的一些时间:
H.Muster Elapsed time is 0.235885 seconds.
woodchips Elapsed time is 0.167659 seconds.
my code Elapsed time is 0.023061 seconds.
差异非常惊人。尽管MATLAB在任何地方都使用了双精度数,但您应尽可能尝试使用整数数据类型。
编辑这是因为matlab实现整数运算。与C不同,double到int的强制转换意味着round
操作:
a = 0.1;
int8(a)
ans =
0
a = 0.9;
int8(a)
ans =
1