Azzera filtri
Azzera filtri

how to save values in a matrix from a loop

84 visualizzazioni (ultimi 30 giorni)
Hello, im programming RLE on matlab and i'm still having one issue only and it is to save my values into a matrix instead of a vector so that when i decode, i can go row by row
this is my code
clear all;
x=[2 2 2 3 3 5; 6 6 5 5 5 7]
x = 2×6
2 2 2 3 3 5 6 6 5 5 5 7
f=size(x);
c=1;
y=[];
for i=1:f(1)
for j=1:f(2)-1
if x(i,j)==x(i,j+1)
c = c + 1;
else
y=[y c x(i,j)];
c=1;
end
end
y =[y c x(i,f(2))]
end
y = 1×6
3 2 2 3 1 5
y = 1×12
3 2 2 3 1 5 2 6 3 5 1 7
y
y = 1×12
3 2 2 3 1 5 2 6 3 5 1 7
My output is coming this way y = 3 2 2 3 1 5 2 6 3 5 1 7 and instead i want it something like y = 3 2 2 3 1 5
2 6 3 5 1 7
  1 Commento
Voss
Voss il 4 Mar 2022
What would you do if the number of unique values on each row of x is not the same? For example, if
x = [2 2 2 3 3 5; 6 6 5 5 5 5]
then what would y be? Maybe this?:
y = [3 2 2 3 1 5; 2 6 4 5 0 0]

Accedi per commentare.

Risposta accettata

Voss
Voss il 4 Mar 2022
Modificato: Voss il 4 Mar 2022
To handle the case that not all rows of x have the same number of unique values, you can make y a cell array and construct each cell the same as you are already doing:
clear all;
x=[2 2 2 3 3 5; 6 6 5 5 5 5]
x = 2×6
2 2 2 3 3 5 6 6 5 5 5 5
f=size(x);
c=1;
y=cell(1,f(1)); % make a cell in y for each row of x
y
y = 1×2 cell array
{0×0 double} {0×0 double}
for i=1:f(1)
for j=1:f(2)-1
if x(i,j)==x(i,j+1)
c = c + 1;
else
y{i} = [y{i} c x(i,j)];
c=1;
end
end
y{i} = [y{i} c x(i,f(2))];
end
y
y = 1×2 cell array
{[3 2 2 3 1 5]} {[2 6 4 5]}
If all cells of y contain vectors of the same length, as in your example x, then you can make y a matrix like this:
new_y = cell2mat(y(:)) % won't work if not all cells of y are the same length
If not, then you can make a matrix of zeros (or NaNs or whatever) and fill in each row to the appropriate column:
N = max(cellfun(@numel,y));
new_y = zeros(f(1),N);
for i = 1:f(1)
new_y(i,1:numel(y{i})) = y{i};
end
new_y
new_y = 2×6
3 2 2 3 1 5 2 6 4 5 0 0
  3 Commenti
Jan
Jan il 4 Mar 2022
A small simplification:
sx = size(x);
y = cell(1, sx(1)); % pre-allocate the output
for i = 1:sx(1) % Loop over rows
c = 1;
a = []; % Accumulate
for j = 1:sx(2) - 1
if x(i, j) == x(i, j+1)
c = c + 1;
else
a = [a, c, x(i, j)]; % append to the last cell of y
c = 1;
end
end
y{i} = [a, c, x(i, sx(2))]; % Insert in output
end

Accedi per commentare.

Più risposte (2)

Walter Roberson
Walter Roberson il 4 Mar 2022
clear all;
x=[2 2 2 3 3 5; 6 6 5 5 5 7]
x = 2×6
2 2 2 3 3 5 6 6 5 5 5 7
f=size(x);
c=1;
y = {};
for i=1:f(1)
y{i} = [];
for j=1:f(2)-1
if x(i,j)==x(i,j+1)
c = c + 1;
else
y{i}=[y{i} c x(i,j)];
c=1;
end
end
y{i} =[y{i} c x(i,f(2))]
end
y = 1×1 cell array
{[3 2 2 3 1 5]}
y = 1×2 cell array
{[3 2 2 3 1 5]} {[2 6 3 5 1 7]}
y
y = 1×2 cell array
{[3 2 2 3 1 5]} {[2 6 3 5 1 7]}
However you should not proceed to vertcat(y{:}) because you have no reason ahead of time to believe that the encodings will be the same length for each row.

Jan
Jan il 4 Mar 2022
Modificato: Jan il 4 Mar 2022
A completely different approach:
x = [2 2 2 3 3 5; 6 6 5 5 5 7];
nRow = size(x, 2);
y = cell(1, nRow); % Pre-allocate: avoid iterative growing of arrays
for k = 1:nRow
[b, n] = RunLengthEnc(x(k, :)); % Get elements and count them
y{k} = reshape([n; b], 1, []); % Store a row vector
end
% Determine run length parameters without a loop:
function [b, n] = RunLengthEnc(x)
d = [true, diff(x) ~= 0]; % TRUE if values change
b = x(d); % Elements without repetitions
n = diff(find([d, true])); % Number of repetitions
end

Categorie

Scopri di più su Mathematics in Help Center e File Exchange

Tag

Community Treasure Hunt

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

Start Hunting!

Translated by