Is it possible to optomize this code with preallocation?

1 回表示 (過去 30 日間)
lachlan
lachlan 2019 年 5 月 16 日
編集済み: dpb 2019 年 5 月 16 日
Hello,
I have written the following code although it is quite slow to run. I will try to explain the goal of the code as best I can.
I have two small arrays of the same length with contain values at different positions. I need to create two much longer arrays using each of these smaller ones. The main problems are there needs to be a set of zeros of variable length between each of these small arrays, and I also need to use zero values for the small array length at psuedorandom points. In the code below, y and z are essentially just square waves that have their peaks at different points along these small arrays, however I won't actually be using square waves for one of these arrays and need to use the high sample value I have in the code.
The code is working as intended, but I am currently changing the size of yA or zB on each iteration of the loop, which is adding several thousand values each iteration to create two arrays with a length of ~100 million each. I'm guessing this is mainly why this code is taking quite long to run. I assume that by preallocating memory for the vector I could make this run a bit more smoothly, but I'm pretty new to MATLAB and haven't been able to figure out a way to preallocate when the p value is variable for each iteration of the loops generating the yA and zB arrays.
Also I should note I guess the most important thing for me is that it works, but I realize this is probably an awful way to go about what I'm trying to achieve and would like to learn how to implement the same concept in a better and more efficient way.
Any advice or help would be appreciated, thanks heaps.
%%
num = 300;
sample = 100e3;
A = 4.9;
d1 = 0.05;
d2 = 0.25;
pRange = [2 4];
p = min(pRange) + (diff(pRange)*rand(1, num));
%%
d1Sample = d1*sample;
d2Sample = d2*sample;
combined = d2Sample + d1Sample;
%%
x = zeros(1, combined);
for i = 1:d1Sample
x(i) = 1;
end
x = x.*A;
add = zeros(1, length(x));
y = [x add];
z = [add x];
zeroValues = zeros(1, length(z));
%%
blockValues = [1 2 3];
blockID = repmat(blockValues, (num/length(blockValues)));
blockID = blockID(randperm(length(blockID)));
%%
pSample = round(p.*sample);
aCreator = 1;
yA = [];
while aCreator <= num
if blockID(aCreator) == 1
yA = [yA y zeros(1, pSample(aCreator))];
elseif blockID(aCreator) == 2
yA = [yA zeroValues zeros(1, pSample(aCreator))];
elseif blockID(aCreator) == 3
yA = [yA y zeros(1, pSample(aCreator))];
end
aCreator = aCreator + 1;
end
bCreator = 1;
zB = [];
while bCreator <= num
if blockID(bCreator) == 1
zB = [zB z zeros(1, pSample(bCreator))];
elseif blockID(bCreator) == 2
zB = [zB z zeros(1, pSample(bCreator))];
elseif blockID(bCreator) == 3
zB = [zB zeroValues zeros(1, pSample(bCreator))];
end
bCreator = bCreator + 1;
end
yz = [yA' zB'];
  1 件のコメント
dpb
dpb 2019 年 5 月 16 日
編集済み: dpb 2019 年 5 月 16 日
Looks like num, sample and pRange are fixed, and therefore so is p once the particular random value is chosen then so is pSample.
And, while you randomized the sequence of blockID, you can count how many of each of the three choices are contained in the vector and thus compute the overall number of times that particular perturbation of added values are going to be added; all that is unknown is the order, but the number is fixed and computable before you begin the loop.
So, you can compute the overall length and preallocate it.
You then would have to keep running totals of the position in the vector to write to each pass.
I don't know how it would compare for speed but the alternative would be to create a cell array where each cell contains the next sequence to be added. Then cell2mat to convert to the long vector. Would at least save the recopying each iteration
ADDENDUM
"You then would have to keep running totals of the position in the vector to write to each pass."
Actually, you could sample the random variable and return the N values and from them precompute the starting location without the loop...

サインインしてコメントする。

回答 (0 件)

カテゴリ

Help Center および File ExchangeLoops and Conditional Statements についてさらに検索

製品


リリース

R2019a

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by