function D = bspline_approx(k,t,x,M)
% B-spline curve control point approximation with known knot vector.
%
% Input arguments:
% k:
%    B-spline order (2 for linear, 3 for quadratic, etc.)
% t:
%    knot vector
% x:
%    B-spline values corresponding to which data points are observed
% M:
%    d-by-m matrix of observed data points, possibly polluted with noise,
%    d is typically 2 for plane, 3 for space, or 3 or 4, respectively, if
%    weights are present
%
% Output arguments:
% D:
%    d-by-n matrix of control points

% Copyright 2010 Levente Hunyadi

validateattributes(k, {'numeric'}, {'positive','integer','scalar'});
validateattributes(t, {'numeric'}, {'real','vector'});
validateattributes(x, {'numeric'}, {'real','vector'});
validateattributes(M, {'numeric'}, {'real','2d'});

B = bspline_basismatrix(k,t,x);
Q = M * B;
D = Q / (B'*B);
