How can I populate an array dynamically?

It's a little hard to describe exactly what I'm trying to do, but the code below should make it clear. Basically I'm trying to populate an array with elements from another array, with the elements specified dynamically. The closest I've been able to come is the code below. I know it's best to avoid Eval, so if someone has a better, more elegant solution I'd love to hear it. I'm very new to Matlab, so I'm probably missing something easy. Thanks, J.C.
totalValue = rand(1, 10);
startSegmentEval = [1, 2, 3, 4, 5];
endSegmentEval = [3, 4, 5, 6, 7];
A = 'sum(totalValue(';
B = ':';
C = ')';
D = int2str(startSegmentEval');
E = int2str(endSegmentEval');
F = ';';
temp = [repmat(A, numel(D), 1), D, repmat(B, numel(D), 1), E, ...
repmat(C, numel(D), 1), repmat(C, numel(D), 1)];
a(1:5) = eval(temp);

 Accepted Answer

Your temp is this:
temp =
sum(totalValue(1:3))
sum(totalValue(2:4))
sum(totalValue(3:5))
sum(totalValue(4:6))
sum(totalValue(5:7))
yet totalValue is a 2D array, not a 1D array. Can you explain what you're doing? Are you using linear indexing?
Secondly, whatever you're doing, summing values like that is not a normal, or intuitive way to do it. You'd better off just using a for loop, or a vectorized function like conv(). I could suggest code to do it with conv() if it made more sense what elements you wanted to sum in the 2D array totalValue.

9 Comments

I'm not trying to use linear indexing. TotalValue should be a 1D array -- I'll edit the original question. I could easily do it with a loop, but I'm hoping there is a faster way.
Then here's how you'd to it for a 1D array:
% Compute all 8 possible sums of 3 elements.
a = conv(totalValue, [1 1 1], 'valid')
% Extract out only the first 5 sums.
first5Sums = a(1:5)
Don't worry about speed when you're only working with a handful of iterations. Now if you had tens of millions of sums to do, instead of only 5, then it would be a factor. However conv() is a highly efficient and optimized function - you won't get much faster than that, certainly not by using eval().
Thanks for the quick answer. I'm sure I'm missing something easy, but when I try to run the code you provided I get : "??? Error using ==> conv at 27 A and B must be vectors."
I'm still trying to understand exactly how your example works, but what I'm trying to do is be able to change startSegmentEval and endSegmentEval and have to code run properly.
J.C.
J.C. on 1 Feb 2013
Edited: J.C. on 1 Feb 2013
I also saw your concern about speed. Once implemented in the program, this piece of code will have to handle thousands of sums, and the program will run for thousands of iterations. As a result, I am somewhat concerned with speed. I'd love to use Conv, it looks much more elegant. I just have to figure out what I'm doing wrong.
You must have left out the line defining totalValue:
totalValue = rand(1, 10);
If you're concerned with speed, even though you still don't have a lot of data with only thousands of sums and thousands of iterations, then conv() is definitely the way to go. Even if you had a fair amount of data, like tens or hundreds of millions, then conv() is still the way to go.
Thanks. That was causing the error. I'm still not sure that this is exactly what I need, but if not, the fault is mine for not asking the question properly. your answer does exactly what I asked. I have to go to an appointment now, but I will spend some time later with conv to see if I can make it work for my purposes. Thanks for your help.
I believe I understand now how conv() works, and it appears to be a powerful function. I don't believe it will help with what I need, however. In the example I provided, it was coincidence that each segment to be evaluated was three elements. In the full implementation the number of elements will be variable. The startSegmentEval and endSegmentEval just specify the index where the evaluation should start. Is there another way to use conv() that will let me do that, or is there another vectorized function that is more appropriate? If I should re-ask the question with a better example, please let me know.
Thanks
No. If your window size is varying all over the place, like it's different on an element by element basis according to some function that decides the window width at that location, then you're stuck doing it very manually, not with an optimized routine like conv().
I think I actually just figured out how to solve my problem. The code below seems to do exactly what I need. Thanks again for your help. I've learned more about matlab through this process.
totalValue = rand(1, 10);
startSegmentEval = [1, 2, 3, 4, 5];
endSegmentEval = [3, 4, 5, 6, 7];
cumulativeTotalValue = cumsum(totalValue);
offsetCumulativeTotalValue = [0, cumulativeTotalValue(1:end - 1)];
temp = cumulativeTotalValue(endSegmentEval) - offsetCumulativeTotalValue(startSegmentEval);

Sign in to comment.

More Answers (0)

Categories

Find more on App Building 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!