Prev: array assignment issue
Next: find 'first' option
From: Matthias Fripp on 2 Jul 2010 10:28 I have several row vectors that I would like repeated various numbers of times vertically, to produce a large matrix. For example, vector 1 should be repeated 2 times, vector 2 should be repeated 5 times, vector 3 should be repeated 3 times, etc. This will create a matrix divided vertically into several "blocks", each of which consist of some number of repetitions of one of the original vectors. I have matlab code to do this with a for loop (below). But is there any way to do this directly with vector/matrix operations? I haven't mastered all of Matlab's indexing options yet! ==== example code starts here ===== lines=[2 5; 4 2; 6 7]; starts=[1 3 8 11]; % Is there a vectorized way to repeat the rows from "lines" % in vertical blocks, starting at the rows listed in "starts" % (neglecting the last)? expanded=zeros(starts(end)-1, size(lines, 2)); for i=1:length(starts)-1, expanded(starts(i):starts(i+1)-1,:)=repmat(lines(i, :), starts(i+1)-starts(i), 1); end
From: Sean on 2 Jul 2010 12:07 "Matthias Fripp" <mfripp.mini.turing.test(a)gmail.com> wrote in message > ==== example code starts here ===== > > lines=[2 5; 4 2; 6 7]; > starts=[1 3 8 11]; > > % Is there a vectorized way to repeat the rows from "lines" > % in vertical blocks, starting at the rows listed in "starts" > % (neglecting the last)? > expanded=zeros(starts(end)-1, size(lines, 2)); > for i=1:length(starts)-1, > expanded(starts(i):starts(i+1)-1,:)=repmat(lines(i, :), starts(i+1)-starts(i), 1); > end Not sure if it'll be any faster but here's one way: lines=[2 5; 4 2; 6 7]; starts=[1 3 8 11]; Term = [diff(starts)]'; Expan = cell2mat(cellfun(@(x,y)(repmat(x,y,1)),mat2cell(lines,ones(size(lines,1),1)),mat2cell(Term,ones(numel(Term),1)),'UniformOutput',false));
From: Jan Simon on 2 Jul 2010 12:31 Dear Matthias, > lines=[2 5; 4 2; 6 7]; > starts=[1 3 8 11]; > > % Is there a vectorized way to repeat the rows from "lines" > % in vertical blocks, starting at the rows listed in "starts" > % (neglecting the last)? > expanded=zeros(starts(end)-1, size(lines, 2)); > for i=1:length(starts)-1, > expanded(starts(i):starts(i+1)-1,:)=repmat(lines(i, :), starts(i+1)-starts(i), 1); > end Sorry if this appears twice - my browser boke the posting process with a "cannot find server" message. ??? The idea is to create the list of indices instead of the matrix directly: lines = [2 5; 4 2; 6 7]; s = [1 3 8 11]; v(s) = 1; v = cumsum(v); expanded = lines(v(1:end - 1), :) Good luck, Jan
From: Matthias Fripp on 2 Jul 2010 15:27 Dear Jan, Thanks very much -- that's a really neat solution, and just what I was looking for! Matthias "Jan Simon" <matlab.THIS_YEAR(a)nMINUSsimon.de> wrote in message <i0l48d$8fl$1(a)fred.mathworks.com>... > The idea is to create the list of indices instead of the matrix directly: > lines = [2 5; 4 2; 6 7]; > s = [1 3 8 11]; > v(s) = 1; > v = cumsum(v); > expanded = lines(v(1:end - 1), :)
|
Pages: 1 Prev: array assignment issue Next: find 'first' option |