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);

 채택된 답변

Image Analyst
Image Analyst 2013년 2월 1일

0 개 추천

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

J.C.
J.C. 2013년 2월 1일
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.
Image Analyst
Image Analyst 2013년 2월 1일
편집: Image Analyst 2013년 2월 1일
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().
J.C.
J.C. 2013년 2월 1일
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. 2013년 2월 1일
편집: J.C. 2013년 2월 1일
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.
Image Analyst
Image Analyst 2013년 2월 1일
편집: Image Analyst 2013년 2월 1일
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.
J.C.
J.C. 2013년 2월 1일
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.
J.C.
J.C. 2013년 2월 4일
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
Image Analyst
Image Analyst 2013년 2월 4일
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);

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 App Building에 대해 자세히 알아보기

질문:

2013년 2월 1일

Community Treasure Hunt

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

Start Hunting!

Translated by