Borrar filtros
Borrar filtros

How to "stretch" matrix

46 visualizaciones (últimos 30 días)
Daniel
Daniel el 21 de Abr. de 2012
Editada: Dana Monahan el 25 de Sept. de 2023
Hello,
I was wondering if MATLAB had a function for doing the following. Say I have the following vector:
[1 1 2 2 0 0]
And I want to make a new vector which contains 1.5 times the amount of the present elements, i.e. "stretch" it by 1.5
[1 1 1 2 2 2 0 0 0]
Just asking before writing any buggy, inneficient code.
regards,
Daniel
  2 comentarios
James Tursa
James Tursa el 21 de Abr. de 2012
Is it always adding one more element of each? Or by "1.5 times" do you mean that you have a larger problem in mind like [1 1 1 1 2 2 2 2 0 0 0 0] etc and would like the solution to be [1 1 1 1 1 1 2 2 2 2 2 2 0 0 0 0 0 0] etc? I.e., how generic is your real problem?
Walter Roberson
Walter Roberson el 21 de Abr. de 2012
Will the number of identical elements in a row always be the same?

Iniciar sesión para comentar.

Respuestas (5)

Image Analyst
Image Analyst el 21 de Abr. de 2012
Daniel, if you have the Image Processing Toolbox, you can do it in one single, and very simple, line of code:
% Create sample data.
m1 = [1 1 2 2 0 0]
% Now do the replication like Daniel wants.
m2 = imresize(m1, [1 9], 'nearest')
In the command window:
m1 =
1 1 2 2 0 0
m2 =
1 1 1 2 2 2 0 0 0
Of course you can change the 9 to be any length you want your output vector to be.
  1 comentario
Richard Brown
Richard Brown el 21 de Abr. de 2012
That's sneaky ...

Iniciar sesión para comentar.


Richard Brown
Richard Brown el 21 de Abr. de 2012
Further to Image Analyst's answer, you can do it without the image processing toolbox too (assuming m has an even number of entries)
m = [1 1 2 2 0 0 ];
n = numel(m);
m2 = interp1(1:n, m, linspace(1, n, 1.5*n), 'nearest')

Pippa Williams
Pippa Williams el 11 de Feb. de 2020
Another (perhaps simpler) option if you have R2015a or later: repelem ("repeat elements") will also do.
  3 comentarios
Image Analyst
Image Analyst el 19 de Sept. de 2023
@Dana Monahan repelem doesn't do what the original poster asked, as far as I can see. @Daniel wants to "stretch" (resize) the array by 1.5 times. repelem() takes each element and makes duplicate elements. So, if you wanted to add one copy, it would insert the first 1 one time, then add a second 1 for the second 1, then add a third 1 for the third one. So repelem would give 4 ones, not 3:
% Create sample data.
m1 = [1 1 2 2 0 0];
% Now use repelem to TRY to generate [1 1 1 2 2 2 0 0 0]:
m2 = repelem(m1, 2) % Not what was wanted
m2 = 1×12
1 1 1 1 2 2 2 2 0 0 0 0
If you gave a vector for the number of times to replicate the element you could do it:
m3 = repelem(m1, [1,2, 1,2, 1,2])
m3 = 1×9
1 1 1 2 2 2 0 0 0
but that depends on you knowing in advance which elements should be replicated and which should not. I guess you could use a for loop to try to generate the [1,2, 1,2, 1,2] vector, but that gets complicated.
Dana Monahan
Dana Monahan el 25 de Sept. de 2023
Editada: Dana Monahan el 25 de Sept. de 2023
@Image Analyst, I appreciate the reply. I was rooting through this thread for a HW assignment for college. I actually ended up settling on a different solution as repelem doesn't allow for lowering the size of a matrix and because my proffesor asked I use the tools we had learned in class. I ended up using this:
function [ output ] = vecResize( v , multiplier )
%output = vecResize(v, multiplier) Streches/Compacts the given vector "v" by the given scalar "multiplier"
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
s = length(v);
ns = ceil(s * multiplier);
index = round(linspace(1, s, ns));
output = v(index);

Iniciar sesión para comentar.


Andrei Bobrov
Andrei Bobrov el 21 de Abr. de 2012
a = [1 1 2 2 0 0];
t = 1.5
k=[true,diff(a)~=0];
k2 = find(k);
k3 = [k2(2:end)-1 numel(k)];
k4 = k3-k2+1;
m = round(k4*t);
if all(diff(m) == 0)
out = reshape(ones(m(1),1)*a(k),1,[]);
else
out = cell2mat(arrayfun(@(x,y)x(ones(1,y)),a(k),m,'un',0));
end
ADD on Walter's comment
out = kron(a(1:2:end),ones(1,t*2))
  2 comentarios
Walter Roberson
Walter Roberson el 21 de Abr. de 2012
You forgot the kron() call :-)
Andrei Bobrov
Andrei Bobrov el 21 de Abr. de 2012
Thank you Walter!

Iniciar sesión para comentar.


Ryan Jones
Ryan Jones el 7 de Dic. de 2016
You can also use repmat and indexing. If n is + integer than simply:
m = [1 1 2 2 0 0];
temp = repmat(a,n,1)
m2 = temp(1:end)
for your particular example where you want a resizing of 3/2:
%n1/n2
n1 = 3, n2 =2
m = [1 1 2 2 0 0];
temp = repmat(a(1:n2:end),n1,1)
m2 = temp(1:end)

Community Treasure Hunt

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

Start Hunting!

Translated by