warp.svd3#

warp.svd3(
A: Matrix[Float, Literal[3], Literal[3]],
) tuple[Matrix[Float, Literal[3], Literal[3]], Vector[Float, Literal[3]], Matrix[Float, Literal[3], Literal[3]]]#
  • Kernel: true
  • Python: true
  • Differentiable: true

Compute the singular value decomposition of a 3x3 matrix.

Multiplying any two corresponding column pairs of U and V by -1 produces an equivalent factorization.

When components of sigma have equal magnitudes, the corresponding singular vectors are not unique.

Derivatives of individual singular vectors are not uniquely defined at repeated magnitudes and may be numerically unstable when the magnitudes are close.

The decomposition is a finite-precision approximation. It currently uses a fixed number of Jacobi iterations rather than a convergence tolerance. Check the orthogonality of U and V and the reconstruction error when accuracy is critical.

Parameters:

A – Matrix to decompose.

Returns:

A tuple (U, sigma, V) such that A = U * wp.diag(sigma) * wp.transpose(V). U and V are orthogonal matrices with determinant +1 whose columns are the left and right singular vectors, respectively. The components of sigma are sorted by decreasing magnitude. The first two components are nonnegative; for a nonsingular matrix, sigma[2] has the sign of wp.determinant(A).

Example

Separate an orientation-reversing deformation gradient into signed principal stretches and a proper rotation:

@wp.kernel
def decompose_deformations(
    deformation_gradients: wp.array[wp.mat33],
    signed_stretches: wp.array[wp.vec3],
    rotations: wp.array[wp.mat33],
):
    i = wp.tid()
    U, sigma, V = wp.svd3(deformation_gradients[i])
    signed_stretches[i] = sigma
    rotations[i] = U * wp.transpose(V)

deformation_gradients = wp.array(
    [
        wp.mat33(
            2.598076, -1.0, 0.0,
            1.5, 1.732051, 0.0,
            0.0, 0.0, -1.0,
        )
    ],
    dtype=wp.mat33,
)
signed_stretches = wp.empty(1, dtype=wp.vec3)
rotations = wp.empty(1, dtype=wp.mat33)

wp.launch(
    decompose_deformations,
    dim=1,
    inputs=[deformation_gradients],
    outputs=[signed_stretches, rotations],
)

print(f"Signed stretches: {np.round(signed_stretches.numpy()[0], 3)}")
print(f"Rotation:\n{np.round(rotations.numpy()[0], 3)}")
Signed stretches: [ 3.  2. -1.]
Rotation:
[[ 0.866 -0.5    0.   ]
 [ 0.5    0.866  0.   ]
 [ 0.     0.     1.   ]]
warp.svd3(
A: Matrix[Float, Literal[3], Literal[3]],
U: Matrix[Float, Literal[3], Literal[3]],
sigma: Vector[Float, Literal[3]],
V: Matrix[Float, Literal[3], Literal[3]],
) None
  • Kernel: true
  • Python: false
  • Differentiable: true

Compute the singular value decomposition of a 3x3 matrix and store the factors in caller-provided output arguments.

See the return-value overload for the factorization convention, numerical behavior, and autodiff guidance.

Parameters:
  • A – Matrix to decompose.

  • U – Output matrix for the left singular vectors.

  • sigma – Output vector for the signed singular values.

  • V – Output matrix for the right singular vectors.

Example

Store the singular value decomposition of A in U, sigma, and V:

@wp.kernel
def compute_svd3(A: wp.mat33):
    U = wp.mat33()
    sigma = wp.vec3()
    V = wp.mat33()

    wp.svd3(A, U, sigma, V)