tags:

views:

259

answers:

1

I'm trying to write some code to calculate a cumulative distribution function in matlab. When I try to actually put my results into an array it yells at me.

tempnum = ordered1(1);
k=2;
while(k<538)
    count = 1;
    while(ordered1(k)==tempnum)
        count = count + 1;
        k = k + 1;
    end
    if(ordered1(k)~=tempnum)
        output = [output;[(count/537),tempnum]];
        k = k + 1;
        tempnum = ordered1(k);
    end
end

The errors I'm getting look like this

??? Error using ==> vertcat
CAT arguments dimensions are not consistent.

Error in ==> lab8 at 1164
        output = [output;[(count/537),tempnum]];

The line to add to the output matrice was given to me by my TA. He didn't teach us much syntax throughout the year so I'm not really sure what I'm doing wrong. Any help is greatly appreciated.

+1  A: 

If you're building the matrix output from scratch, you should make sure it hasn't already been initialized to anything. To do this, you can set it to the empty matrix at the beginning of your code:

output = [];

Also, if you know how large output is going to be, your code will run more efficiently if you preallocate the array output and index into the array to assign values instead of appending values to it. In your case, output should have the same number of rows as there are unique values in the array ordered1, so you could use the function UNIQUE to preallocate output:

nRows = numel(unique(ordered1));  %# Get the number of unique values
output = zeros(nRows,2);          %# Initialize output

You would then have to keep a separate counter (say r) to track which index into output you will be adding to next:

...
output(r,:) = [count/537 tempnum];  %# Overwrite a row in output
r = r+1;                            %# Increment the row index
...

Some additional advice...

Even if you solve the error you are getting, you're going to run into more with the code you have above:

  • I believe you are actually computing a probability density function (or PDF) with your code. In order to get the cumulative distribution function (or CDF), you have to perform a cumulative sum over the final values in the first column of output. You can do this with the function CUMSUM:

    output(:,1) = cumsum(output(:,1));
    
  • Your loop will throw an error when it reaches the last element of ordered1. The value of k can become 538 in your inner while loop, which will then cause an error to be thrown when you try to access ordered1(k) anywhere. To get around this, you will have to add checks to the value of k at a number of points in your code. One such point is your inner while loop, which can be rewritten as:

    while (k <= 537) && (ordered1(k) == tempnum)
        count = count + 1;
        k = k + 1;
    end
    

    This solution uses the short-circuit AND operator &&, which will first check if (k <= 537) is true or false. If it is false (i.e. k > 537), the second logical check is skipped since its result doesn't matter, and you avoid the error that would result from evaluating ordered1(k).

Bonus MATLAB coolness...

MATLAB has a lot of cool functions that can do a lot of the work for you. One such function is ACCUMARRAY. Your TA may want you to do things using loops like you have above, but you can actually reduce your whole code to just a few lines like so:

nValues = numel(ordered1);              %# Get the number of values
p = accumarray(ordered1,ones(size(ordered1)))./nValues;  %# Create a PDF
output = [cumsum(p) unique(ordered1)];  %# Create the CDF output
gnovice

related questions