Add row matrix in loop at different positions

4 views (last 30 days)
Elise
Elise on 11 Jul 2014
Edited: dpb on 12 Jul 2014
Hi!
I am stuck! I want to add rows for every loop iteration to a matrix, each time a different row at a different position. However, adding a row in the loop changes the size of the matrix, and thus the rows should be added each time to the position I want to plus the number of rows already inserted. The problem is that the matrix index exceeds the matrix dimensions. But I really don't know a solution
here is my code: I basically want to insert copy in theta_out_sorted_left, at locations specified by copystart. The problem is that for each i copy is different (and of different length). theta_out_sorted_left_cop will always exceed the matrix dimensions!
Thank you so much!
----
copystart = find(theta_out_sorted_left_wr(2:end,3)-theta_out_sorted_left_wr(1:end-1,3)==-1);
copyend = find(theta_out_sorted_left_wr(2:end,3)-theta_out_sorted_left_wr(1:end-1,3)==1);
copy = 0;
copyold = 0
theta_out_sorted_left_cop = theta_out_sorted_left_wr;
for i = 1:length(copyend)
if copyend(i)-copystart(i) ==1
diffTh = Stepsize2;
nextTh2 = theta_out_sorted_left_wr(copystart(i)+1,2)-diffTh;
next = [theta_out_sorted_left_wr(copystart(i)+1,1) nextTh2 0]
copyold = copyold+length(copy(:,1))
copy = [next;...
theta_out_sorted_left_wr(copystart(i)+1, 1:2) 1]
elseif copyend(i)-copystart(i) ~=1
diffTh = Stepsize2;
nextTh2 = theta_out_sorted_left_wr(copyend(i),2)-diffTh;
next = [theta_out_sorted_left_wr(copyend(i),1) nextTh2 theta_out_sorted_left_wr(copyend(i),3)];
copyth = theta_out_sorted_left_wr(copystart(i)+1:copyend(i), :);
copyold = copyold+length(copy(:,1))
copy = [next;...
copyth]
end
theta_out_sorted_left_cop = [theta_out_sorted_left_cop(1:(copystart(i)+copyold),:);...
copy;...
theta_out_sorted_left_cop((copystart(i)+...
+copyold +1):end,:)];
end
  2 Comments
dpb
dpb on 12 Jul 2014
Besides the other questions, and the obfuscating terribly long names that confound the eyes trying to read the code, there's a syntax error in the following line --
theta_out_sorted_left_cop = ...
[theta_out_sorted_left_cop(1:(copystart(i)+copyold),:); ...
copy; ...
theta_out_sorted_left_cop((copystart(i)+ ...
+copyold +1):end,:)];
There are two consecutive '+' signs; is that an extra that couldn't see because of the aforementioned issues or is there another term missing between the two?
How much easier it would be to read and try to interpret if the code looked more like...
theta = [theta(1:(ix1(i) + ix2),:); ...
copy; ...
theta((ix1(i) + ??? + ix2+1):end,:)];
where ix1 and ix2 are the object indices. Then it's short-enough to fit on just a few lines with logical breaks and the eye can find the indices with a variable name that's descriptive but easily recalled and scanned.
Anyway, I'll try to see if I can figure out what the indices might be, but w/o any sample data it's difficult to predict what the results of your find operations are, hence it's tough to know what can be further simplified in the addressing other than just the code style itself.
dpb
dpb on 12 Jul 2014
Edited: dpb on 12 Jul 2014
for i = 1:length(copyend)
if copyend(i)-copystart(i) ==1
...
This presupposes that length() of the two find() operations is always the same? Is that a foregone conclusion? Also, in
diffTh = Stepsize2;
Stepsize2 is undefined.

Sign in to comment.

Answers (1)

dpb
dpb on 11 Jul 2014
This dynamically "growing" an array is, in general a_bad_idea (tm) for performance reasons. It would better if you can create the array a priori and then fill it in. If the exact size isn't known, then create a sizable starting point and check and reallocate when required.
Anyway, it's not absolutely clear what you want without reading more code than care to try (and since it apparently doesn't actually do what you want, anyway), hint--
Let ix be the insertion point for a set of rows to be inserted and presume it's intended to keep the complete data with the rows inserted and not overwriting any existing data.
For each pass thru the loop,
array=[array(1:ix-1,:); newarray; array(ix:end,:)];
This places the new at location ix; if want after add one to each row index.
If the array isn't terribly large or the number of insertions not too great, you may find the above is "acceptably fast" but it definitely has a lot of overhead as compared to the alternative of preallocating.
  2 Comments
Elise
Elise on 11 Jul 2014
Hi dpd! Thanks for your quick response! Yes, I should preallocate, but the speed is not the problem atm. I actually do exactly your answer (I named array theta_out_sorted_left_cop),
array=[array(1:ix-1,:); newarray; array(ix:end,:)];
but in stead of :ix-1 I use :ix+copyold, where copyold adds the number of rows already inserted to the index, because copystart contains the start positions of the places where the rows should be inserted at the unchanged matrix. But as the matrix changes with each loop, copystart should change as well to take the new dimension into account.
Here is where the problem lies. The final array will give an index out of bounds, because the sum of copyold and copystart will be larger than the size of the matrix.
I feel like I overlook something.. But I can't find the solution :(
dpb
dpb on 11 Jul 2014
Edited: dpb on 11 Jul 2014
I guess I need a small example that shows the problem. How about a start array of 2 or 3 lines and then what you want to insert (again, small but sufficient to create the issue) and where you want those new rows and what to do with the old.
Are you inserting a non-contiquous block? If not, there's no need to address the old array rows explicitly at all and there's bound to be another way to write it if so that avoids doing so.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!