1
votes

So I was looking at this question:

Matlab - Standard Deviation of Cartesian Points

Which basically answers my question, except the problem is I have xyz, not xy. So I don't think Ax=b would work in this case.


I have, say, 10 Cartesian points, and I want to be able to find the standard deviation of these points. Now, I don't want standard deviation of each X, Y and Z (as a result of 3 sets) but I just want to get one number.

This can be done using MATLAB or excel.


To better understand what I'm doing, I have this desired point (1,2,3) and I recorded (1.1,2.1,2.9), (1.2,1.9,3.1) and so on. I wanted to be able to find the variability of all the recorded points.

I'm open for any other suggestions.

2
So do you just want the RMS distance from all recorded points to the desired point, or are you interested in findin a 3D line or plane to which you can compute the distance?chappjc
You just brought up a good point, finding the RMS distance of all recorded to desired point is one way of finding the variability. Unfortunately, I just realized that I do not have an exact desired point, so I'm guessing a 3D line to compute the distance would be better-- that is to say that this distance would be the error -- can I call that variability as well?Smiley
I'll post a solution with a best fit 3D line shortly. Call it error or variability, as long as you know what it indicates. BTW, extending the answer from the other question directly as David did fits a plane, not a line, although that is an option.chappjc
Or you can just compute the distances to the centroid of the points, but if you expect them to be along a line, then I'd fit a line.chappjc
@chappjc -- I don't expect them to be along a line, so computing distance to centroid of the points make more sense. Everyday I learn something new!Smiley

2 Answers

2
votes

If you do the same thing as in the other answer you linked, it should work.

x_vals = xyz(:,1);
y_vals = xyz(:,2);
z_vals = xyz(:,3);

then make A with 3 columns,

A = [x_vals y_vals ones(size(x_vals))];

and

b = z_vals;

Then

sol=A\b;
m = sol(1);
n = sol(2);
c = sol(3);

and then

errs = (m*x_vals + n*y_vals + c) - z_vals;

After that you can use errs just as in the linked question.

2
votes

Randomly clustered data

If your data is not expected to be near a line or a plane, just compute the distance of each point to the centroid:

xyz_bar = mean(xyz);
M = bsxfun(@minus,xyz,xyz_bar);
d = sqrt(sum(M.^2,2)); % distances to centroid

Then you can compute variability anyway you like. For example, standard deviation and RMS error:

std(d)
sqrt(mean(d.^2))

Data about a 3D line

If the data points are expected to be roughly along the path of a line, with some deviation from it, you might look at the distance to a best fit line. First, fit a 3D line to your points. One way is using the following parametric form of a 3D line:

x = a*t + x0
y = b*t + y0
z = c*t + z0

Generate some test data, with noise:

abc = [2 3 1]; xyz0 = [6 12 3];
t = 0:0.1:10;
xyz = bsxfun(@plus,bsxfun(@times,abc,t.'),xyz0) + 0.5*randn(numel(t),3)
plot3(xyz(:,1),xyz(:,2),xyz(:,3),'*') % to visualize

Estimate the 3D line parameters:

xyz_bar = mean(xyz) % centroid is on the line
M = bsxfun(@minus,xyz,xyz_bar); % remove mean
[~,S,V] = svd(M,0)
abc_est = V(:,1).'
abc/norm(abc) % compare actual slope coefficients

Distance from points to a 3D line:

pointCentroidSeg = bsxfun(@minus,xyz_bar,xyz);
pointCross = cross(pointCentroidSeg, repmat(abc_est,size(xyz,1),1));
errs = sqrt(sum(pointCross.^2,2))

Now you have the distance from each point to the fit line ("error" of each point). You can compute the mean, RMS, standard deviation, etc.:

>> std(errs)
ans =
    0.3232
>> sqrt(mean(errs.^2))
ans =
    0.7017

Data about a 3D plane

See David's answer.