0

I have a set of 3D points (x,y,z) and I would like to fit a straight line using Least absolute deviation method to those data.

I found a function from the internet which works pretty well with 2D data, how could I modify this to adapt 3D data points?

function B = L1LinearRegression(X,Y)
 % Determine size of predictor data 
[n m] = size(X); 
 % Initialize with least-squares fit 
 B = [ones(n,1) X] \ Y; 
 % Least squares regression 
 BOld = B; 
 BOld(1) = BOld(1) + 1e-5;
 % Force divergence
 % Repeat until convergence 
 while (max(abs(B - BOld)) > 1e-6) % Move old coefficients 
     BOld = B; % Calculate new observation weights (based on residuals from old coefficients) 
     W = sqrt(1 ./ max(abs((BOld(1) + (X * BOld(2:end))) - Y),1e-6)); % Floor to avoid division by zero 
     % Calculate new coefficients 
     B = (repmat(W,[1 m+1]) .* [ones(n,1) X]) \ (W .* Y);
 end

Thank you very much!

Lea Xin
  • 11
  • 4
  • 1
    You converted the points using some kind of transformation. Invert that transformation, and apply it to the fitted line! – Ander Biguri Mar 14 '16 at 14:04
  • 2
    What about to use `plot3` function. Or you can go to primitives and use `line('properties...',''xdata',X,'ydata',Y,'zdata',Z,'other properties...')`. – Crowley Mar 14 '16 at 14:06
  • @AnderBiguri thx for replying. Yes, I used transformation to convert thoes points from 3D to 2D. But now, I want to convert a line from 2D space to 3D space, i can not use transformation matrix – Lea Xin Mar 15 '16 at 10:27
  • @Crowley hey thx for the comments but the line is in 2d reference frame so i dont have a z axis to sue plot3 function – Lea Xin Mar 15 '16 at 10:28
  • @LeaXin Yes you can..... Any trasnformation is invertible. if you transformed something as pnew=T*pold; then you can always use `T^-1` to transform back. – Ander Biguri Mar 15 '16 at 10:30
  • Then, as @AnderBiguri proposed - You have transformed your 3D data to 2D to perform the fit, say by function `[u,v]=f(x,y,z)`. Now you need to perform another transformation `[x,y,z]=f'(u,v)`. where `f'` is inverse function to the `f` (for example `ln x` is inverse to the `e^x`). – Crowley Mar 15 '16 at 10:31
  • Please provide the code, how you got the 2D line. It will help. – Crowley Mar 15 '16 at 13:37
  • @Crowley hello, I have add the code to question,thx ! – Lea Xin Mar 16 '16 at 09:44
  • @AnderBiguri hello, i dont really understand how to inverse function to a created line? before i could do it becase i use transformation matrix to points but now its lines. – Lea Xin Mar 16 '16 at 09:45
  • @LeaXin May be I was not exact in my question. I'd like to know how you convert the 3D cloud into 2D cloud that the regression function could accept. – Crowley Mar 16 '16 at 09:59

1 Answers1

0

I know that this is not answer to the question but rather to different problem leading to the question.

We can use fit function several times.

% XYZ=[x(:),y(:),z(:)];        % suppose we have data in this format
M=size(XYZ,1);                 % read size of our data
t=((0:M-1)/(M-1))';            % create arbitrary parameter t

% fit all coordinates as function x_i=a_i*t+b_i

fitX=fit(t,XYZ(:,1),'poly1');  
fitY=fit(t,XYZ(:,2),'poly1');
fitZ=fit(t,XYZ(:,3),'poly1');

temp=[0;1];                   % define the interval where the line shall be plotted

%Evaluate and plot the line coordinates 
Line=[feval(fitX(temp)),feval(fitY(temp)),feval(fitZ(temp))];
plot(Line)

The advantage is that this work for any cloud, even if it is parallel to any axis. another advantage is that you are not limitted only to polynomes of 1st order, you can choose any function for different axis and fit any 3D curve.

Crowley
  • 2,279
  • 6
  • 22
  • 36