Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't figure out interesting behavior by Matrix4f.transpose() #335

Closed
terraflops1048576 opened this issue May 24, 2023 · 1 comment
Closed
Labels

Comments

@terraflops1048576
Copy link

terraflops1048576 commented May 24, 2023

Hi, I've come across some weird behavior in my Java project related to transposing matrices, and I'm not sure how to go about debugging it.

public static void main(String[] args) throws Exception {
        Matrix4f matrix = new Matrix4f();
        for (int row = 0; row < 4; row++) {
            for (int col = 0; col < 4; col++) {
                matrix.set(col, row, row + col * 4);
            }
        }
        System.out.println("Original");
        System.out.println(matrix);
        System.out.println("Transposed");
        System.out.println(matrix.transpose(new Matrix4f()));
 }

This gives me the output:

Original
0.000E+0  4.000E+0  8.000E+0  1.200E+1
1.000E+0  5.000E+0  9.000E+0  1.300E+1
2.000E+0  6.000E+0  1.000E+1  1.400E+1
3.000E+0  7.000E+0  1.100E+1  1.500E+1

Transposed
1.000E+0  0.000E+0  0.000E+0  0.000E+0
0.000E+0  1.000E+0  0.000E+0  0.000E+0
0.000E+0  0.000E+0  1.000E+0  0.000E+0
0.000E+0  0.000E+0  0.000E+0  1.000E+0

which is unexpected (expected behavior is to see the matrix transposed).

But if I do this:

public static void main(String[] args) throws Exception {
        Matrix4f matrix = new Matrix4f();
        for (int row = 0; row < 4; row++) {
            for (int col = 0; col < 4; col++) {
                matrix.set(col, row, row + col * 4);
            }
        }
        System.out.println("Original");
        System.out.println(matrix);
        System.out.println("Transposed");
        System.out.println(matrix.transpose());
    }

I get this:

Original
 0.000E+0  4.000E+0  8.000E+0  1.200E+1
 1.000E+0  5.000E+0  9.000E+0  1.300E+1
 2.000E+0  6.000E+0  1.000E+1  1.400E+1
 3.000E+0  7.000E+0  1.100E+1  1.500E+1

Transposed
 0.000E+0  4.000E+0  8.000E+0  1.200E+1
 1.000E+0  5.000E+0  9.000E+0  1.300E+1
 2.000E+0  6.000E+0  1.000E+1  1.400E+1
 3.000E+0  7.000E+0  1.100E+1  1.500E+1

Expected behavior is that the matrix is transposed.

However, if I initialize the matrix like so:

Matrix4f matrix = new Matrix4f(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
        System.out.println("Original");
        System.out.println(matrix);
        System.out.println("Transposed");
        System.out.println(matrix.transpose());

then I get the expected behavior:

Original
 0.000E+0  4.000E+0  8.000E+0  1.200E+1
 1.000E+0  5.000E+0  9.000E+0  1.300E+1
 2.000E+0  6.000E+0  1.000E+1  1.400E+1
 3.000E+0  7.000E+0  1.100E+1  1.500E+1

Transposed
 0.000E+0  1.000E+0  2.000E+0  3.000E+0
 4.000E+0  5.000E+0  6.000E+0  7.000E+0
 8.000E+0  9.000E+0  1.000E+1  1.100E+1
 1.200E+1  1.300E+1  1.400E+1  1.500E+1

My build.gradle includes this:
implementation 'org.joml:joml:1.10.5'

Can anyone reproduce / tell me what's going on?

@httpdigest
Copy link
Member

httpdigest commented May 24, 2023

Thanks for reporting!
And, sorry about that. It is a bug about the Matrix4f.set(col, row, value) method not resetting the assumptions about the matrix properties, that are stored in the properties field in order to route/accelerate further operations.
It has been fixed for 1.10.6, which you can use right now with 1.10.6-SNAPSHOT or in the actual 1.10.6 release later.

Generally, manually setting any matrix field is highly discouraged, because it will break optimized matrix operations afterwards, which then always have to make no assumptions anymore and use the most general operation implementations.

In order to "reestablish" the properties of a matrix, there is the method determineProperties(), but this is not able to determine all properties of a matrix, such as orthogonality. So, this can be called after setting all matrix fields manually, to get back at least some performance for further operations.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants