Skip to content

Fix failed atan2 elimination by splitting SVD into two methods - #583

Open
tomcur wants to merge 1 commit into
linebender:mainfrom
tomcur:push-tlpnlpzvuxyz
Open

Fix failed atan2 elimination by splitting SVD into two methods#583
tomcur wants to merge 1 commit into
linebender:mainfrom
tomcur:push-tlpnlpzvuxyz

Conversation

@tomcur

@tomcur tomcur commented May 12, 2026

Copy link
Copy Markdown
Member

One method calculates the singular values, the other the rotation.

This is motivated by the observations in #569 (comment): we're often interested only in the scaling, but the atan2 call for the rotation is not optimized out by the compiler when it's dead code (probably because the compiler does not know the call is side-effect free). With this change, the call no longer shows up in places where we only use the scales.

This is somewhat more verbose, but the methods are not public.

The overlap between the two calculations is quite small, and when we do need both (e.g., in Ellipse::radii_and_rotation), the inlining of both methods should still allow the compiler to optimize (though I haven't directly verified).

One method calculates the singular values, the other the rotation.

This is motivated by the observations in
linebender#569 (comment):
we're often interested only in the scaling, but the `atan2` call for the
rotation is not optimized out by the compiler when it's dead code
(probably because the compiler does not know the call is side-effect
free). With this change, the call no longer shows up in places where we
only use the scales.

This is somewhat more verbose, but the methods are not public.

The overlap between the two calculations is quite small, and when we do
need both (e.g., in `Ellipse::radii_and_rotation`), the inlining of both
methods should still allow the compiler to optimize (though I haven't
directly verified).
Comment thread kurbo/src/affine.rs
Comment on lines -796 to +795
let s = mat(1., 1., 1., 1.).svd().0;
assert_near(s.to_point(), Point::new(2., 0.));

let s = mat(1., 1., 1., 1.).svd().0;
let s = mat(1., 1., 1., 1.).svd_singular_values();

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test was duplicated. Removed one, updated the other.

@raphlinus raphlinus left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, looks good. Glad we didn't make svd a public API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants