The function array.row returns incorrect data when called on an af::array returned by af::solve.
double y_data[] = {
1.0000, -2.0000, 4.0000,
1.0000, -1.0000, 1.0000,
1.0000, 0.0000, 0.0000,
1.0000, 1.0000, 1.0000,
1.0000, 2.0000, 4.0000 };
double i_data[] = {
1.0000, 0.0000, 0.0000, 0.0000, 0.0000,
0.0000, 1.0000, 0.0000, 0.0000, 0.0000,
0.0000, 0.0000, 1.0000, 0.0000, 0.0000,
0.0000, 0.0000, 0.0000, 1.0000, 0.0000,
0.0000, 0.0000, 0.0000, 0.0000, 1.0000 };
af::array y = af::array(3, 5, y_data).T();
af::array i = af::array(5, 5, i_data).T();
af::array w = af::solve(y, i);
af::print("w", w);
af::print("w row0", w.row(0)); // wrong output
af::print("w row1", w.row(1)); // wrong output
af::print("w row2", w.row(2)); // wrong output
// Doing a double transpose fixes the issue.
af::array wT = w.T();
af::array wTT = wT.T();
af::print("wTT", wTT);
af::print("wTT row0", wTT.row(0)); // correct
af::print("wTT row1", wTT.row(1)); // correct
af::print("wTT row2", wTT.row(2)); // correct
Annotated output of the above code:
w
[3 5 1 1]
-0.0857 0.3429 0.4857 0.3429 -0.0857
-0.2000 -0.1000 0.0000 0.1000 0.2000
0.1429 -0.0714 -0.1429 -0.0714 0.1429
w row0
[1 5 1 1]
-0.0857 -0.0258 -0.1000 0.7414 -0.1429 // Wrong
w row1
[1 5 1 1]
-0.2000 -0.3371 -0.0714 0.4857 -0.6882 // Wrong
w row2
[1 5 1 1]
0.1429 0.3429 0.2809 0.0000 -0.2017 // Wrong
wTT
[3 5 1 1]
-0.0857 0.3429 0.4857 0.3429 -0.0857 // wTT is w transposed twice.
-0.2000 -0.1000 0.0000 0.1000 0.2000 // wTT == w.
0.1429 -0.0714 -0.1429 -0.0714 0.1429
wTT row0
[1 5 1 1]
-0.0857 0.3429 0.4857 0.3429 -0.0857 // Correct
wTT row1
[1 5 1 1]
-0.2000 -0.1000 0.0000 0.1000 0.2000 // Correct
wTT row2
[1 5 1 1]
0.1429 -0.0714 -0.1429 -0.0714 0.1429 // Correct
The behavior is the same with cpu and cuda backends. Incorrect results can also be obtained by using w(0, span) and w.rows(0,2).