Using randsample on a matrix of weights

10 views (last 30 days)
Hi,
I have some code like this:
for k = 1:p
new_index = randsample([1:n,nan],1,true,tot_weights(k,:));
curr_indexes(k) = new_index;
if ~isnan(new_index)
currx(k) = x(i,new_index);
curry(k) = y(i,new_index);
else
currx(k) = nan;
curry(k) = nan;
end
end
where tot_weights is a p x n matrix that has the weights for the sampling. I am trying to get rid of the for loop and vectorize the function. Basically I just want to get a total of p values that are between 1 to n or nan. The probability for the kth value to be a certain value is given by the weights in the kth row of tot_weights.
Any suggestions would be greatly appreciated! Right now, this for loop takes an annoying amount of time to run.
Cheers,
Sam
  2 Comments
Jeff Miller
Jeff Miller on 5 Jul 2020
The weights seem to change for different values of k, so I'd guess you need to build curr_indices in a for loop. Seems like you could move everything else outside the for loop and vectorize that part of it, though.
Might be a little quicker to replace [1:n,nan] with [1:n+1] and treat n+1 as a special index pointing to nan.
Samuel Moor-Smith
Samuel Moor-Smith on 5 Jul 2020
Yeah, you're right! I moved everything else outside and it works a little faster. Thank you!

Sign in to comment.

Accepted Answer

Sindar
Sindar on 5 Jul 2020
Edited: Sindar on 5 Jul 2020
it doesn't seem like the assignment statement has any reason to be in the loop. Pulling it out may save a decent amount of time (especially if nan is common):
% sample each row of tot_weights
% there may be a direct way to sample a weight matrix like this loop-free, but I don't know it
for k = 1:p
curr_indexes(k) = randsample([1:n,nan],1,true,tot_weights(k,:));
end
% set currx and curry to all-nans of the correct size
currx = nan(1,p);
curry = nan(1,p);
% update currx where curr_indexes is not nan
% fill these with curr_indexes of x (excluding places where curr_indexes is nan)
currx(~isnan(curr_indexes)) = x(i,curr_indexes(~isnan(curr_indexes)))
% same for curry
curry(~isnan(curr_indexes)) = y(i,curr_indexes(~isnan(curr_indexes)));
  1 Comment
Samuel Moor-Smith
Samuel Moor-Smith on 5 Jul 2020
Yeah, you're right! I moved everything else outside and it works a little faster. Thank you!

Sign in to comment.

More Answers (0)

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!