# Why does numpy SVD return a non-normal vector when given a set of points exactly in a plane?

I am attempting to fit a plane using numpy's SVD method `np.linalg.svd()`. As a test, I will use two sets of points in R3. In both cases, all points have value 100 in the 3rd dimension. Since the set of points I created is perfectly within the `Z=100` plane, I expect that:

1. The third singular value will be 0 (within machine-precision).
2. The third column of `vh` will be `[0, 0, 1]` (within machine-precision).

# Set 1

For some points in this set, the first and second values have magnitudes much larger than the third value.

``````pts = [[2345,-124, 100], [981, -123, 100], [4987,12345, 100], [-1324, 0, 100]]
svd = np.linalg.svd(pts)
``````

The result here is roughly as-expected:

`svd[1]` produces `array([13349.56221861, 2705.21722461, 158.26983058])`. I would expect the third singular value to be closer to 0, since my points fit perfectly into a plane, but it's at least clear enough to indicate that the third column of `svd[2]` will be my plane normal vector.

`svd[2]` produces the following:

``````array([[-0.38833201, -0.92148669, -0.00778029],
[-0.92117922,  0.38840419, -0.02389612],
[ 0.02504185, -0.00211259, -0.99968417]])
``````

Again, it's close. I would expect the first two dimensions of the 3rd column to be closer to zero (more like within machine-precision) but this is workable for my fitting application.

# Set 2

For all points in this set, the first and second values have magnitudes smaller than the third value.

``````pts = [[57, 37, 100], [34, 37, 100], [11, -37, 100], [-11, 38, 100]]
svd = np.linalg.svd(pts)
``````

This is where things started to look pretty weird.

`svd[1]` produces `array([209.35774076, 64.78329726, 46.58820429])`. This is surprising. The third singular value should be closer to 0.

`svd[2]` produces the following:

``````array([[-0.23396901, -0.2018738 , -0.95105493],
[ 0.31100035,  0.91126958, -0.26993803],
[-0.92116084,  0.35893555,  0.15042602]])
``````

This is extremely unexpected. The third column of `vh` is quite far from `[0, 0, 1]`. Certainly well outside machine precision. It's actually closer to `[1, 0, 0]`.

What is going on here? Is there something about how the SVD is implemented in numpy that does not give higher precision results? Am I just not using it right or misinterpreting the results?