Joan
Joan

Reputation: 71

Define a vector with random steps

I want to create an array that has incremental random steps, I've used this simple code.

t_inici=(0:10*rand:100);

The problem is that the random number keeps unchangable between steps. Is there any simple way to change the seed of the random number within each step?

Upvotes: 6

Views: 112

Answers (4)

Luis Mendo
Luis Mendo

Reputation: 112669

From your code it seems you want a uniformly random step that varies between each two entries. This implies that the number of entries that the vector will have is unknown in advance.

A way to do that is as follows. This is similar to Hunter Jiang's answer but adds entries in batches instead of one by one, in order to reduce the number of loop iterations.

  1. Guess a number of required entries, n. Any value will do, but a large value will result in fewer iterations and will probably be more efficient.
  2. Initiallize result to the first value.
  3. Generate n entries and concatenate them to the (temporary) result.
  4. See if the current entries are already too many.
  5. If they are, cut as needed and output (final) result. Else go back to step 3.

Code:

lower_value = 0;
upper_value = 100;
step_scale = 10;
n = 5*(upper_value-lower_value)/step_scale*2; % STEP 1. The number 5 here is arbitrary.
% It's probably more efficient to err with too many than with too few
result = lower_value; % STEP 2
done = false;
while ~done
    result = [result result(end)+cumsum(step_scale*rand(1,n))]; % STEP 3. Include
    % n new entries
    ind_final = find(result>upper_value,1)-1; % STEP 4. Index of first entry exceeding
    % upper_value, if any
    if ind_final % STEP 5. If non-empty, we're done
        result = result(1:ind_final-1);
        done = true;
    end
end

Upvotes: 2

Wolfie
Wolfie

Reputation: 30046

If you have a set number of points, say nPts, then you could do the following

nPts = 10;         % Could use 'randi' here for random number of points
lims = [0, 10]     % Start and end points
x = rand(1, nPts); % Create random numbers  
% Sort and scale x to fit your limits and be ordered 
x = diff(lims) * ( sort(x) - min(x) ) / diff(minmax(x)) + lims(1) 

This approach always includes your end point, which a 0:dx:10 approach would not necessarily.


If you had some maximum number of points, say nPtsMax, then you could do the following

nPtsMax = 1000;      % Max number of points
lims = [0,10];       % Start and end points
% Could do 10* or any other multiplier as in your example in front of 'rand'
x = lims(1) + [0 cumsum(rand(1, nPtsMax))];     
x(x > lims(2)) = []; % remove values above maximum limit

This approach may be slower, but is still fairly quick and better represents the behaviour in your question.

Upvotes: 5

Hunter Jiang
Hunter Jiang

Reputation: 1300

Here is an alternative solution with "uniformly random"

[initpoint,endpoint,coef]=deal(0,100,10);
t_inici(1)=initpoint;
while(t_inici(end)<endpoint)
  t_inici(end+1)=t_inici(end)+rand()*coef;
end
t_inici(end)=[];

In my point of view, it fits your attempts well with unknown steps, start from 0, but not necessarily end at 100.

Upvotes: 3

Ander Biguri
Ander Biguri

Reputation: 35525

My first approach to this would be to generate N-2 samples, where N is the desired amount of samples randomly, sort them, and add the extrema:

N=50;
endpoint=100;
initpoint=0;
randsamples=sort(rand(1, N-2)*(endpoint-initpoint)+initpoint);
t_inici=[initpoint randsamples endpoint];

However not sure how "uniformly random" this is, as you are "faking" the last 2 data, to have the extrema included. This will somehow distort pure randomness (I think). If you are not necessarily interested on including the extrema, then just remove the last line and generate N points. That will make sure that they are indeed random (or as random as MATLAB can create them).

Upvotes: 3

Related Questions