Skip to content

SVD: Occasional loss of accuracy #1172

@robertsonj3

Description

@robertsonj3

Hi, I haven't been using nalgebra long, and I am not an expert with SVD functionality, so I'm not 100% sure if this is an issue with nalgebra or me.

I am using SVD for alignment of 3d points using random point clouds, and random transformations (the euler angle is random, the rotation matrix is valid). Occasionally, the alignment is poor.

I have traced this back to what appears to be low accuracy in the SVD result, that is, u * s * v_t does not yield the same matrix that the svd was performed on.

Example:
H:
│ 0.24777976656646927 0.5496207895780494 -0.7403583528727136 │
│ 0.5832953614864118 -0.38015695826419854 -0.03392366142812886 │
│ -0.3738110622901052 0.359160059894174 -0.09620293929130566 │

nalgebra svd produced:
u:
│ -0.873792828198889 0.47077673362678457 0.1218825683347777 │
│ 0.31813462431343165 0.7429469762516004 -0.5889143836684206 │
│ -0.3677994755313523 -0.4758140997850944 -0.7989521188685604 │

s:
│ 0.9999999999999996 0 0 │
│ 0 0.8220531474729237 0 │
│ 0 0 0.00000000000000012761238385273053 │

v (this is the transpose of v_t produced by the svd):
│ 0.1065457803497895 0.885789524773893 0.45169117158794986 │
│ -0.7332946769207143 -0.23679742707193852 0.6373428397117634 │
│ 0.6715109183694628 -0.3991289219449654 0.624314976736623 │

u * s * v_t:
│ 0.24970470373979137 0.5491061976155459 -0.7412257125301849 │
│ 0.574884679370761 -0.3779085371334399 -0.030133882488828305 │
│ -0.3856591637197468 0.36232740366575733 -0.09086428962516223 │

The derived matrix is in error by the 3rd and 4th decimal.

I have tested this same matrix H in Octave (free Matlab) and the SVD results were different but yielded an exact match for the original H matrix when re-combined. I know that SVD can yield different results, but I understood that u * s * v_t will always re-produce the original matrix.

Note: although the copy from octave below only shows 6dp, it was loaded with the full precision presented above, as printed from rust debug.

Octave results for comparison, accurate to at least 6 figures:
H =

0.247780 0.549621 -0.740358
0.583295 -0.380157 -0.033924
-0.373811 0.359160 -0.096203

[U,S,V] = svd(H)
U =

0.87379 0.46823 -0.13133
-0.31813 0.75465 0.57384
0.36780 -0.45964 0.80837

S =

Diagonal Matrix

1.0000e+00 0 0
0 8.2189e-01 0
0 0 3.6928e-17

V =

-0.10655 0.88579 0.45169
0.73329 -0.23680 0.63734
-0.67151 -0.39913 0.62431

U * S * transpose(V)
ans =

0.247780 0.549621 -0.740358
0.583295 -0.380157 -0.033924
-0.373811 0.359160 -0.096203

Thanks for any help with this.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions