- on the first of the outer loop iteration the variable groupdata expands on each inner loop iteration.
- group_ave expands on each outer loop iteration.
- the inner loop can be replaced with some indexing (hint: group_size).
- i = i + 1 is completely superfluous and misleading: the for operator increments i already.
- superfluous square brackets around scalar values should be removed.
- "remove leading zero element" can be easily avoided (hint: empty or preallocation).
- return is not required.
Creating blocks of average values from a series but avoiding dynamic variable names
3 views (last 30 days)
Show older comments
Anthony Phipps
on 13 Feb 2021
Commented: Paul Hoffrichter
on 15 Feb 2021
Hi
I am trying to avoid using dyanmic variable names for all the good reasons listed:
https://www.mathworks.com/matlabcentral/answers/304528-tutorial-why-variables-should-not-be-named-dynamically-eval#answer_236124
My challenge
I have two long series of numbers stored in a single row matrix that I need to compare but in a particular way.
They are sutbley different. I'm ok to compare them but the first step I need to do is giving me a challenge. I need to break each series into groups (the length of which is a variable), take an average of each group, and store the recovered averages in a matrix.
Then I need to compare the results and the differnce is the answer I am looking for.
The bit that has me vexed is how to do this without using a for loop and dynamic named variables. If I try using the index its not having the desoired outcome despite much experimentation. Here a little test version of what I'm trying to do:
clear;
mynumberc = 100 * rand(1, 505);
lenny = length(mynumberc);
group_size = 100;
numberofgroups = floor(lenny/group_size);
nextstart = 1;
nextstop = group_size;
groupdata = [0];
group_ave = [0];
for i = 1:1:numberofgroups
for c = nextstart:1:nextstop
groupdata(c) = mynumberc(c)
nextstart = nextstart + 1
nextstop = nextstop + 1
end
group_ave(i, end+1) = mean (groupdata)
i = i + 1;
end
%remove leading zero element
group_ave = group_ave (2:end)
return
In this example I'd want the first 500 values of mynumberc to be split into 5 100 value chunks, each chunk averaged and then put in an array of averages called group_ave. The actual use of this will be at much bigger scale which is why I want to avoid dynamically named variables.
Any advice welcome....
2 Comments
Stephen23
on 15 Feb 2021
Edited: Stephen23
on 15 Feb 2021
Your code has a number of "features" which make it complex and inefficient. For example:
It is not clear why you expect the output to be a matrix:
group_ave(i, end+1) = ..
If you take the mean of N "groups", then that will give N values which can be trivially arranged in a vector. That matches with the row indexing... but then why do you also increment the column index?
Accepted Answer
Paul Hoffrichter
on 15 Feb 2021
Since you have 5 groups of 100 numbers, I thought you wanted the mean of each group. That gives 5 means. So I did not understand why you say "store the recovered averages in a matrix" rather than storing the 5 means in a vector. Below shows how to store the 5 means in a vector.
rng(1234);
mynumberc = 100 * rand(1, 505);
lenny = length(mynumberc);
group_size = 100;
numberofgroups = floor(lenny/group_size);
myGroupNumberC = mynumberc(1:group_size*numberofgroups);
myNumberChunks = reshape( myGroupNumberC, group_size, numberofgroups);
muGroupMeans = mean(myNumberChunks) % meanof each column
2 Comments
More Answers (0)
See Also
Categories
Find more on Particle & Nuclear Physics in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!