Search code examples
matlabvectorintervals

Algorithm to divide a vector R = 0:upper into a given number of subintervals?


I have been trying to write a MATLAB function that does the following:

Takes inputs "upper" and "number" which are both positive integers. The program should take the interval [0,"upper"] and cut it into "number" subintervals which have integer endpoints and are the same length, except for the last interval (if the interval isn't cleanly divisible by number, then the last interval can contain less integer entries).

Then the program should make a vector x with entries that are the beginnings/ends of those subintervals.


For example, if I have upper = 11 and number = 3, then the program should take the vector

R = [0 1 2 3 4 5 6 7 8 9 10 11]

and generate

x = [0 4 8 11].

It should first create subinterval vectors

r1 = [0 1 2 3 4] 
r2 = [4 5 6 7 8]
r3 = [8 9 10 11] 

and then loop through x and assign 0 to the first entry and the endpoints of the rs to the other entries of x but I am at a loss as to how to tell MATLAB to do this.

My other problem is that I don't know how to tell MATLAB how to figure out if the interval [0, "upper"] is cleanly divisible by "number" and if not, how to then do to make the last subinterval shorter than the others.

I've sat at this for several days, but I'm not getting anywhere.

Any ideas or pointers in the right direction would be greatly appreciated, thank you.


I've figured out how to handle cases for when mod(upper, number) = 0, i.e., when upper is cleanly divisible by number. For those cases, I simply make

delta = upper/number;

and then

for i=1:(number+1)
   x(i) = (i-1)*delta;
end

Where the difficulties arise is when upper and number aren't cleanly divisible.


Solution

  • Given

    upper = 12;
    number = 3;
    

    You can generate R using

    R = 0:upper; % [0, 1, 2, ..., upper]
    

    If number was a divisor of upper then the output interval would be upper/number. If not then this quotient should be rounded up, so there's a smaller "chunk" left in the final interval. So

    interval = ceil(upper/number);
    

    Now we just need to build the output array x. If number was a divisor of upper then the colon notation would give what you want

    x = 0:interval:upper; % only useful if number is a divisor of upper
    

    Otherwise, this will not actually include upper; we can handle the two possible cases in an if:

    if mod(upper,number) == 0
        x = 0:interval:upper; % When number divides upper, this includes upper
    else
        x = [0:interval:upper, upper]; % Otherwise we need to append upper 
    end
    

    You could instead handle this by subtracting 0.5 (or any positive value <1) from upper during the creation of x which would ensure it isn't included, and then always append it. Essentially forcing the else case above.

    Then the overall code becomes this, note we don't even need to generate R unless you want it as an output:

    upper = 11; % Upper limit
    number = 3; % Number of intervals
    
    interval = ceil(upper/number); % Interval size
    
    x = [0:interval:(upper-0.5), upper]; % Create output