-2

I am trying to turn each element in a matrix from a value from 1 to 10 into a 10x1 zeros matrix where the element of the zeros matrix corresponding to the value of the original element is equal to 1.

Here is the code:

function q = convert

% Convert y matrix values to 10x1 vector

load('y.mat');

ZERO = zeros(10,1);

% Set 10x1 Matrix of zeros

for i = 1:length(y)

   ZERO(y(i)) = 1; % Set yth element of ZERO to 1

   y(i) = ZERO;    % Set ith element of y equal to new zero

   ZERO = zeros(10,1); % Re-establish zero

endfor

When I run it I get the error A(I) = X: X must have the same size as I. Where the matrix I am trying to input does not agree with the size of element of matrix y. Can I get around this?

Sample input:

y = [1; 2; 3; 4; 5] 

Sample output:

y = [[1;0;0;0;0;0;0;0;0;0], 
     [0;1;0;0;0;0;0;0;0;0], 
     [0;0;1;0;0;0;0;0;0;0],
     [0;0;0;0;1;0;0;0;0;0],
     [0;0;0;0;0;1;0;0;0;0]]
beaker
  • 16,331
  • 3
  • 32
  • 49
Peter Lynch
  • 119
  • 1
  • 2
  • 6
  • 1
    Can you give us some sample input and the corresponding expected output? – beaker Jul 07 '16 at 16:55
  • y = [1; 2; 3; 4; 5] input and y = [[1;0;0;0;0;0;0;0;0;0];[0;1;0;0;0;0;0;0;0;0]; [0;0;1;0;0;0;0;0;0;0]; [0;0;0;0;1;0;0;0;0;0]; [0;0;0;0;0;1;0;0;0;0] output. I got around it by doing the transformation element by element where required. I just would have prefered to do it in one step like this one. – Peter Lynch Jul 09 '16 at 08:52

1 Answers1

1

I'm going to make a couple of assumptions:

  1. You want the return value to be q as in the function signature, and
  2. You want the output in your sample case to be a 10x5 matrix like so:

    1   0   0   0   0
    0   1   0   0   0
    0   0   1   0   0
    0   0   0   1   0
    0   0   0   0   1
    0   0   0   0   0
    0   0   0   0   0
    0   0   0   0   0
    0   0   0   0   0
    0   0   0   0   0
    

Fixing the loop

The problem that gives the error is that you're assigning a 10x1 vector ZERO to a single (scalar) element of the 5x1 vector y:

y(i) = ZERO;

A vector doesn't fit in a scalar. But even if you change this to assign ZERO to a column of y, it doesn't fit because the lengths of the columns are different. That's not what you want to do anyway, because if it had worked, you would have just wiped out the values in y. So let's set the values in the columns of the output array q. (Changes are marked with <== in the comments.)

function q = convert
% Convert y matrix values to 10xn matrix

%load('y.mat');
y = [1; 2; 3; 4; 5];   % <== replace load temporarily

% Set 10x1 Matrix of zeros
ZERO = zeros(10,1);
% Preallocate output array
q = zeros(10, length(y));   % <== preallocate for speed

for i = 1:length(y)
  ZERO(y(i)) = 1;     % Set yth element of ZERO to 1
  q(:,i) = ZERO;      % <== Set ith *column* of *q* equal to new zero
  ZERO = zeros(10,1); % Re-establish zero
endfor

Improving the loop

This will work, but if you preallocate q, you've already got the correct number of ZERO vectors, so why not just set the values directly?

function q = convert
% Convert y matrix values to 10xn matrix

%load('y.mat');
y = [1; 2; 3; 4; 5];   % <== replace load temporarily

% Preallocate output array
q = zeros(10, length(y));   % <== preallocate for speed

for i = 1:length(y)
  q(y(i),i) = 1;      % <== Set element at y(ith) row and ith column of q to 1
endfor

Killing the loop

Either of these loops will give you the desired results, but you can do this whole operation without a loop. This answer summarizes different ways to do this, but I'll just show you the first one using sub2ind:

function q = convert
% Convert y matrix values to 10xn matrix

%load('y.mat');
y = [1; 2; 3; 4; 5];   % <== replace load temporarily

% Preallocate output array
q = zeros(10, length(y));   % <== preallocate for speed

idx = sub2ind(size(q), y, [1:length(y)].');
q(idx) = 1;

Final note

It's best not to use i as a variable name in Octave/MATLAB. It's natural in other languages, but in MATLAB i (or j) is the imaginary unit. If you use i as a variable, it shadows that constant. That doesn't make a difference if you use 1i (or 1j) when assigning complex values, but you're going to have to remember to do that and at some point you're going to forget.

Community
  • 1
  • 1
beaker
  • 16,331
  • 3
  • 32
  • 49