KZ-Spectra
KZ-Spectra

Reputation: 151

Plotting numbers in a Cell array

I want to just plot the data, which is all real numbers, that is stored in a Cell Array. My cell array is 1-100 1-dimensional, but I am confused on how to actually apply the plot() function with the hold on function.

Here is my code:

% Initalize arrays for storing data
C = cell(1,100); % Store output vector from floww()
D = cell(1,6); % User inputted initial point
I1 = cell(1,100);
I2 = cell(1,100);
I3 = cell(1,100);


%Declare alpha and beta variables detailed in Theorem 1 of paper

a1 = 0; a2 = 2; a3 = 4; a4 = 6;
b1 = 2; b2 = 3; b3 = 7; b4 = 10;

% Declare the \lambda_i, i=1,..., 6, variables
L = cell(1,6);
L1 = abs((b2 - b3)/(a2 - a3));
L2 = abs((b1 - b3)/(a1 - a3));
L3 = abs((b1 - b2)/(a1 - a2));
L4 = abs((b1 - b4)/(a1 - a4));
L5 = abs((b2 - b4)/(a2 - a4));
L6 = abs((b3 - b4)/(a3 - a4)); 
L{1,1} = L1;
L{1,2} = L2;
L{1,3} = L3;
L{1,4} = L4;
L{1,5} = L5;
L{1,6} = L6;

% Create function handle for floww()
F = @floww;

for j = 1:6
   D{1,j} = input('Input in1 through in6: ');
end

% Iterate through floww()
k = [0:5:100];
for i = 1: 100
   C{1,i} = F(D{1,1}, D{1,2}, D{1,3}, D{1,4}, D{1,5}, D{1,6},L); % Output from floww() is a 6-by-1 vector
   for j = 1:6
       D{1,j} = C{1,i}(j,1); % Reassign input values to put back into floww()
   end

   % First integrals as described in the paper
   I1{1,i} = 2*(C{1,i}(1,1)).^2 + 2*(C{1,i}(2,1)).^2 + 2*(C{1,i}(3,1)).^2 + 2*(C{1,i}(4,1)).^2 + 2*(C{1,i}(5,1)).^2 + 2*(C{1,i}(6,1)).^2;
   I2{1,i} = (-C{1,i}(3,1))*(-C{1,i}(6,1)) - (C{1,i}(2,1))*(-C{1,i}(5,1)) + (-C{1,i}(1,1))*(-C{1,i}(4,1));
   I3{1,i} = 2*L1*(C{1,i}(1,1)).^2 + 2*L2*(C{1,i}(2,1)).^2 + 2*L3*(C{1,i}(3,1)).^2 + 2*L4*(C{1,i}(4,1)).^2 + 2*L5*(C{1,i}(5,1)).^2 + 2*L6*(C{1,i}(6,1)).^2;
   plot(k, I1{1,i});
   hold on;
end


% This function will solve the linear system
% Bx^(n+1) = x detailed in the research notes
function [out1] = floww(in1, in2, in3, in4, in5, in6, L)

% A_ij = (lambda_i - lambda_j)
% Declare relevant A_ij values

A32 = L{1,3} - L{1,2};
A65 = L{1,6} - L{1,5};
A13 = L{1,1} - L{1,3};
A46 = L{1,4} - L{1,6};
A21 = L{1,2} - L{1,1};
A54 = L{1,5} - L{1,4};
A35 = L{1,3} - L{1,5};
A62 = L{1,6} - L{1,2};
A43 = L{1,4} - L{1,3};
A16 = L{1,1} - L{1,6};
A24 = L{1,2} - L{1,4};
A51 = L{1,5} - L{1,1};

% Declare del(T)
delT = 1;

% Declare the 6-by-6 coefficient matrix B

B = [1, -A32*(delT/2)*in3, -A32*(delT/2)*in2, 0, -A65*(delT/2)*in6, -A65*(delT/2)*in5;
    -A13*(delT/2)*in3, 1, -A13*(delT/2)*in1, -A46*(delT/2)*in6, 0, A46*(delT/2)*in4;
    -A21*(delT/2)*in2, -A21*(delT/2)*in1, 1, -A54*(delT/2)*in5, -A54*(delT/2)*in4, 0;
    0, -A62*(delT/2)*in6, -A35*(delT/2)*in5, 1, -A35*(delT/2)*in3, -A62*(delT/2)*in2;
    -A16*(delT/2)*in6, 0, -A43*(delT/2)*in4, -A43*(delT/2)*in3, 1, -A16*(delT/2)*in1;
    -A51*(delT/2)*in5, -A24*(delT/2)*in4, 0, -A24*(delT/2)*in2, -A51*(delT/2)*in1, 1];

% Declare input vector

N = [in1; in2; in3; in4; in5; in6];

% Solve the system Bx = N for x where x
% denotes the X_i^(n+1) vector in research notes

x = B\N;

% Assign output variables
out1 = x;

%disp(x);
%disp(out1(2,1));
end

The plotting takes place in the for-loop with plot(k, I1{1,i});. The figure that is outputted is not what I expect nor want:

Can someone please explain to me what I am doing wrong and/or how to get what I want?

Upvotes: 0

Views: 148

Answers (1)

Wolfie
Wolfie

Reputation: 30045

You need to stop using cell arrays for numeric data, and indexed variable names when an array would be way simpler.

I've edited your code, below, to plot the I1 array.

To make it work, I changed almost all cell arrays to numeric arrays and simplified a bunch of the indexing. Note initialisation is now with zeros instead of cell, therefore indexing with parentheses () not curly braces {}.

I didn't change the structure too much, because your comments indicated you were following some literature with this layout

For the plotting, you were trying to plot single points during the loop - to do that you have no line (the points are distinct), so need to specify a marker like plot(x,y,'o'). However, what I've done is just plot after the loop - since you're storing the resulting I1 array anyway.

% Initalize arrays for storing data
C = cell(1,100); % Store output vector from floww()
D = zeros(1,6); % User inputted initial point
I1 = zeros(1,100);
I2 = zeros(1,100);
I3 = zeros(1,100);

%Declare alpha and beta variables detailed in Theorem 1 of paper
a1 = 0; a2 = 2; a3 = 4; a4 = 6;
b1 = 2; b2 = 3; b3 = 7; b4 = 10;

% Declare the \lambda_i, i=1,..., 6, variables
L = zeros(1,6);
L(1) = abs((b2 - b3)/(a2 - a3));
L(2) = abs((b1 - b3)/(a1 - a3));
L(3) = abs((b1 - b2)/(a1 - a2));
L(4) = abs((b1 - b4)/(a1 - a4));
L(5) = abs((b2 - b4)/(a2 - a4));
L(6) = abs((b3 - b4)/(a3 - a4)); 

for j = 1:6
   D(j) = input('Input in1 through in6: ');
end

% Iterate through floww()
for i = 1:100
   C{i} = floww(D(1), D(2), D(3), D(4), D(5), D(6), L); % Output from floww() is a 6-by-1 vector
   for j = 1:6
       D(j) = C{i}(j,1); % Reassign input values to put back into floww()
   end

   % First integrals as described in the paper
   I1(i) = 2*(C{i}(1,1)).^2 + 2*(C{i}(2,1)).^2 + 2*(C{i}(3,1)).^2 + 2*(C{i}(4,1)).^2 + 2*(C{i}(5,1)).^2 + 2*(C{i}(6,1)).^2;
   I2(i) = (-C{i}(3,1))*(-C{i}(6,1)) - (C{i}(2,1))*(-C{i}(5,1)) + (-C{i}(1,1))*(-C{i}(4,1));
   I3(i) = 2*L(1)*(C{i}(1,1)).^2 + 2*L(2)*(C{i}(2,1)).^2 + 2*L(3)*(C{i}(3,1)).^2 + 2*L(4)*(C{i}(4,1)).^2 + 2*L(5)*(C{i}(5,1)).^2 + 2*L(6)*(C{i}(6,1)).^2;
end
plot(1:100, I1);


% This function will solve the linear system
% Bx^(n+1) = x detailed in the research notes
function [out1] = floww(in1, in2, in3, in4, in5, in6, L)
    % A_ij = (lambda_i - lambda_j)
    % Declare relevant A_ij values
    A32 = L(3) - L(2);
    A65 = L(6) - L(5);
    A13 = L(1) - L(3);
    A46 = L(4) - L(6);
    A21 = L(2) - L(1);
    A54 = L(5) - L(4);
    A35 = L(3) - L(5);
    A62 = L(6) - L(2);
    A43 = L(4) - L(3);
    A16 = L(1) - L(6);
    A24 = L(2) - L(4);
    A51 = L(5) - L(1);

    % Declare del(T)
    delT = 1;
    % Declare the 6-by-6 coefficient matrix B
    B = [1, -A32*(delT/2)*in3, -A32*(delT/2)*in2, 0, -A65*(delT/2)*in6, -A65*(delT/2)*in5;
        -A13*(delT/2)*in3, 1, -A13*(delT/2)*in1, -A46*(delT/2)*in6, 0, A46*(delT/2)*in4;
        -A21*(delT/2)*in2, -A21*(delT/2)*in1, 1, -A54*(delT/2)*in5, -A54*(delT/2)*in4, 0;
        0, -A62*(delT/2)*in6, -A35*(delT/2)*in5, 1, -A35*(delT/2)*in3, -A62*(delT/2)*in2;
        -A16*(delT/2)*in6, 0, -A43*(delT/2)*in4, -A43*(delT/2)*in3, 1, -A16*(delT/2)*in1;
        -A51*(delT/2)*in5, -A24*(delT/2)*in4, 0, -A24*(delT/2)*in2, -A51*(delT/2)*in1, 1];

    % Declare input vector
    N = [in1; in2; in3; in4; in5; in6];
    % Solve the system Bx = N for x where x
    % denotes the X_i^(n+1) vector in research notes
    x = B\N;
    % Assign output variables
    out1 = x;
end

Output with in1..6 = 1 .. 6:

plot

Note: you could simplify this code a lot if you embraced arrays over clunky variable names. The below achieves the exact same result for the body of your script, but is much more flexible and maintainable:

See how much simpler your integral expressions become!

% Initalize arrays for storing data
C = cell(1,100);  % Store output vector from floww()
D = zeros(1,6);   % User inputted initial point
I1 = zeros(1,100);
I2 = zeros(1,100);
I3 = zeros(1,100);

%Declare alpha and beta variables detailed in Theorem 1 of paper
a = [0, 2, 4, 6];
b = [2, 3, 7, 10];

% Declare the \lambda_i, i=1,..., 6, variables
L = abs( ( b([2 1 1 1 2 3]) - b([3 3 2 4 4 4]) ) ./ ...
         ( a([2 1 1 1 2 3]) - a([3 3 2 4 4 4]) ) );  

for j = 1:6
   D(j) = input('Input in1 through in6: ');
end

% Iterate through floww()
k = 1:100;
for i = k
   C{i} = floww(D(1), D(2), D(3), D(4), D(5), D(6), L); % Output from floww() is a 6-by-1 vector
   D = C{i}; % Reassign input values to put back into floww()

   % First integrals as described in the paper
   I1(i) = 2*sum(D.^2);
   I2(i) = sum( D(1:3).*D(4:6) );
   I3(i) = 2*sum((L.').*D.^2).^2;
end
plot( k, I1 );

Edit:

You can simplify the floww function by using a couple of things

  1. A can be declared really easily as a single matrix.

  2. Notice delT/2 is a factor in almost every element, factor it out!

  3. The only non-zero elements where delT/2 isn't a factor are the diagonal of ones... add this in using eye instead.

  4. Input the in1..6 variables as a vector. You already have the vector when you call floww - makes no sense breaking it up.

  5. With the input as a vector, we can use utility functions like hankel to do some neat indexing. This one is a stretch for a beginner, but I include it as a demo.

Code:

% In code body, call floww with an array input
C{i} = floww(D, L);
% ...

function [out1] = floww(D, L)
    % A_ij = (lambda_i - lambda_j)
    % Declare A_ij values in a matrix
    A = L.' - L;

    % Declare del(T)
    delT = 1;
    % Declare the 6-by-6 coefficient matrix B
    % Factored out (delt/2) and the D coefficients
    B = eye(6,6) - (delT/2) * D( hankel( [4 3 2 1 6 5], [5 4 3 2 1 6] ) ) .*...
        [     0, A(3,2), A(3,2),      0, A(6,5),  A(6,5);
         A(1,3),      0, A(1,3), A(4,6),      0, -A(4,6);
         A(2,1), A(2,1),      0, A(5,4), A(5,4),       0;
           0,    A(6,2), A(3,5),      0, A(3,5),  A(6,2);
         A(1,6),      0, A(4,3), A(4,3),      0,  A(1,6);
         A(5,1), A(2,4),      0, A(2,4), A(5,1),       0];

    % Solve the system Bx = N for x where x
    % denotes the X_i^(n+1) vector in research notes
    out1 = B\D(:);
end

You see when we simplify things like this, code is easier to read. For instance, it looks to me (without knowing the literature at all) like you've got a sign error in your B(2,6) element, it's the opposite sign to all other elements...

Upvotes: 3

Related Questions