function M2 = ndlinspace(M1,M2,N)
% NDLINSPACE - Generalized linearly spaced matrix for multiple points
%
% R = NDLINSPACE(M1,M2, N) returns a matrix of size [size(M1) N] holding
% N equally spaced points between corresponding point of M1 and M2. If N
% is smaller than 2, M2 is returned. R = NDLINSPACE(M1,M2) uses N = 100.
%
% For scalar inputs, NDLINSPACE(S1,S2,N) mimicks LINSPACE, returning
% equally spaced points between the S1 and S2. Example:
%
% ndlinspace(0, 2, 4)
% % -> 0 0.67 1.33 2.00
%
% For two M-by-1 column vectors, NDLINSPACE(V1,V2,N) returns a M-by-N
% matrix in which the k-th row holds the N equally spaced numbers between
% V1(k) and V2(k). Similary, for two 1-by-M row vectors, a N-by-M matrix
% is returned. Example:
%
% ndlinspace([0 ; 12 ; 10], [3 ;18 ; 11],4)
% % -> 0 1.00 2.00 3.00
% % 12.00 14.00 16.00 18.00
% % 10.00 10.33 10.67 11.00
%
% For two ND arrays of size P-by-Q-by-R-by-.. matrices, NDLINSPACE
% (M1,M2,N) returns a P-by-Q-by-R-by-..-by-N matrix, holding N equally
% space points between M1(i,j,k,..) and M2(i,j,k,..). Example:
%
% M1 = reshape(1:2*3*4*5,[2 3 4 5]) ;
% M2 = 10 * M1 ;
% size(M1) ; % ans = 2 3 4 5
% R = ndlinspace(M1,M2,5) ;
% squeeze(R(2,1,4,3,:)).'
% % ans = 68 221 374 527 680
% % Compare with LINSPACE for scalars
% linspace(M1(2,1,4,3),M2(2,1,4,3),5)
% % ans = 68 221 374 527 680
%
% In general, M1 and M2 have to have the same size. Scalar expansion is
% applied when one of the inputs is a scalar. Example:
% ndlinspace(0,[4 ; 8 ; -12],5) % expand M1
% % ans = 0 1 2 3 4
% % 0 2 4 6 8
% % 0 -3 -6 -9 -12
%
% See also LINSPACE, LOGSPACE, REPMAT, INTERP1, SQUEEZE
% for Matlab R13 and up
% version 1.1 (feb 2009)
% (c) Jos van der Geest
% email: jos@jasen.nl
% History
% 1.0 (feb 2009) - inspired by a submissions on the File Exchange (#22824)
% 1.1 (feb 2009) - some minor textual corrections
if nargin == 2
N = 100 ; % default
end
% scalar expansion
if numel(M1)==1 && numel(M2) > 1
M1 = repmat(M1,size(M2)) ;
elseif numel(M2)==1 && numel(M1) > 1
M2 = repmat(M2,size(M1)) ;
end
sz = size(M1) ;
if ~isequal(size(M2), sz)
error('The two matrices M1 and M2 should have the same size.') ;
end
if N < 2 || isempty(M2),
return
elseif numel(M1) == 1,
% simple case for linspace
M2 = [M1+(0:N-2)*(M2-M1)/(floor(N)-1) M2];
else
% This is the real ND case. For each pair (M1(i), M2(i)) we have to find
% the Y-values of the points along the straight line between (1,M1(i))
% and (N M2(i)). The x-values are specified by the number 1:N.
% We use linear interpolation for this. Pass a 2-by-P vector to INTERP1
% and let that function handle the calculations in one step. See the
% help of INTERP1 for more details.
M2 = interp1([1 N],[M1(:) M2(:)].',1:N).' ;
% Take care of the proper output format
if numel(sz)==2
% return proper format for scalar and vector input
M2 = squeeze(M2) ;
% for row vector inputs return a column oriented matrix
if sz(1)==1
M2 = M2.' ;
end
else
% for any matrix with ND dimensions (ND>2) return a ND+1
% dimensional matrix. The last dimension holds the interpolated
% equally spaced points.
M2 = reshape(M2, [sz N]) ;
end
end