vittorio
vittorio

Reputation: 143

insert value in a matrix in a for loop

I wrote this matlab code in order to concatenate the results of the integration of all the columns of a matrix extracted form a multi matrix array.

"datimf" is a matrix composed by 100 matrices, each of 224*640, vertically concatenated. In the first loop i select every single matrix. In the second loop i integrate every single column of the selected matrix obtaining a row of 640 elements. The third loop must concatenate vertically all the lines previously calculated.

Anyway i got always a problem with the third loop. Where is the error?

singleframe = zeros(224,640); 
int_frame_all = zeros(1,640); 
conc = zeros(100,640); 

for i=0:224:(22400-224)  
   for j = 1:640         
      for k = 1:100      
         singleframe(:,:) = datimf([i+1:(i+223)+1],:);
         int_frame_all(:,j) = trapz(singleframe(:,j));
         conc(:,k) = vertcat(int_frame_all);
      end
   end
end

Upvotes: 0

Views: 415

Answers (3)

crjones
crjones

Reputation: 181

An alternate way to do this without using any explicit loops (edited in response to rayryeng's comment below. It's also worth noting that using cellfun may not be more efficient than explicitly looping.):

nmats = 100;
nrows = 224;
ncols = 640;

datimf = rand(nmats*nrows, ncols);

% convert to an nmats x 1 cell array containing each matrix
cellOfMats = mat2cell(datimf, ones(1, nmats)*nrows, ncols);

% Apply trapz to the contents of each cell
cellOfIntegrals = cellfun(@trapz, cellOfMats, 'UniformOutput', false);

% concatenate the results
conc = cat(1, cellOfIntegrals{:});

Taking inspiration from user2305193's answer, here's an even better "loop-free" solution, based on reshaping the matrix and applying trapz along the appropriate dimension:

datReshaped = reshape(datimf, nrows, nmats, ncols);
solution = squeeze(trapz(datReshaped, 1));

% verify solutions are equivalent: 
all(solution(:) == conc(:))  % ans = true

Upvotes: 1

user2305193
user2305193

Reputation: 2059

It looks like you're processing frames in a video.

The most efficent approach in my experience would be to reshape datimf to be 3-dimensional. This can easily be achieved with the reshape command.

something along the line of vid=reshape(datimf,224,640,[]); should get you far in this regard, where the 3rd dimension is time. vid(:,:,1) then would display the first frame of the video.

Upvotes: 0

Aero Engy
Aero Engy

Reputation: 3608

I think I understand what you want. The third loop is unnecessary as both the inner and outer loops are 100 elements long. Also the way you have it you are assigning singleframe lots more times than necessary since it does not depend on the inner loops j or k. You were also trying to add int_frame_all to conc before int_frame_all was finished being populated.

On top of that the j loop isn't required either since trapz can operate on the entire matrix at once anyway.

I think this is closer to what you intended:

datimf = rand(224*100,640);

singleframe = zeros(224,640); 
int_frame_all = zeros(1,640); 
conc = zeros(100,640); 

for i=1:100
   idx = (i-1)*224+1;
   singleframe(:,:) = datimf(idx:idx+223,:);     
%    for j = 1:640         
%          int_frame_all(:,j) = trapz(singleframe(:,j));
%    end
   % The loop is uncessary as trapz can operate on the entire matrix at once.    
   int_frame_all = trapz(singleframe,1);
   %I think this is what you really want... 
   conc(i,:) = int_frame_all; 
end

Upvotes: 0

Related Questions