1
votes

I have an Nx2 matrix A where each row is an upper bound and lower bound pair and I would like to create an MxN matrix B for which each column is a linspace of M elements from the upper and lower bounds in the coresponding row of A.

For example:

A = [   2  10  ;
       20 100  ;
       30  50  ;
      0.1 0.5  ]

with a value of 5 for M should give the result:

B = [  2  20 30 0.1 ; 
       4  40 35 0.2 ;
       6  60 40 0.3 ;
       8  80 45 0.4 ;
      10 100 50 0.5 ]

I can do this easily with a loop:

B = zeros(M,size(A,1));
for i = 1:size(A,1)
  B(:,i) = linspace(A(i,1),A(i,2),M)';
end

but I would like to know a more "Matlab-y" way if possible.

2

2 Answers

2
votes

You can generate that result with two calls of bsxfun, but I'm not sure if that's Matlaby enough :D

A = [   2  10  ;
        20 100  ;
        30  50  ;
        0.1 0.5  ]
M = 5;
B = bsxfun(@plus, A(:, 1), ...
    bsxfun(@times, A(:, 2)-A(:, 1), linspace(0, 1, M)))';

This performs better here, with R2016b.

nTest = 10000;
d = 1000;
M = 50;
A = rand(d, 2)*100;
tic
for i=1:nTest
    B1 = bsxfun(@plus, A(:, 1), ...
        bsxfun(@times, A(:, 2)-A(:, 1), linspace(0, 1, M)))';
end
toc
tic
for j=1:nTest
    B2 = zeros(M,size(A,1));
    for i = 1:size(A,1)
        B2(:,i) = linspace(A(i,1),A(i,2),M)';
    end
end
toc
maxDiff = max(max(abs(B1-B2)))

Results:

Elapsed time is 1.380361 seconds.
Elapsed time is 9.965803 seconds.

maxDiff =
2.8422e-14

2
votes

Here is a way using cumsum:

B = cumsum(repmat((A(:, 2)-A(:, 1))/(M-1),1,M),2).';