I am trying to do a very simple thing
- take a square shape 2d array
- take its transpose
- multiply the array with its transpose
I am trying to perform the above steps in C++ and Python as shown in the programs below:
C++ Program:
#include <iostream>
#include <iomanip> // For setw
int main() {
float R[16] = {
0.5, 0.63245553, -0.5, 0.31622777,
0.5, 0.31622777, 0.5, -0.63245553,
0.5, -0.31622777, 0.5, 0.63245553,
0.5, -0.63245553, -0.5, -0.31622777
};
const int nRows = 4;
const int nCols = 4;
float result[nRows][nRows] = { 0 };
// Perform matrix multiplication
for (int i = 0; i < nRows; i++) {
for (int j = 0; j < nRows; j++) {
for (int k = 0; k < nCols; k++) {
result[i][j] += R[i * nCols + k] * R[j * nCols + k];
}
}
}
// Print the result with left-aligned columns and a padding of 15 characters
for (int i = 0; i < nRows; i++) {
for (int j = 0; j < nRows; j++) {
std::cout << std::left << std::setw(15) << result[i][j] << " ";
}
std::cout << std::endl;
}
return 0;
}
Python Program:
import numpy as np
R = np.array([
0.5, 0.63245553, -0.5, 0.31622777,
0.5, 0.31622777, 0.5, -0.63245553,
0.5, -0.31622777, 0.5, 0.63245553,
0.5, -0.63245553, -0.5, -0.31622777
]).reshape(4, 4)
result = np.dot(R, R.T)
# Print the result
print(result)
Problem: As can be seen in the above programs, I am using exactly the same input array/matrix. But the precision of results of the multiplicaiton is quite different.
Except for the diagonal, most of the values are quite different with huge differences in precision. How can I get the same precision in both languages? Why are even the signs flipped for some elements?
C++ Results:
1 -1.49012e-08 0 -7.45058e-09
-1.49012e-08 1 0 0
0 0 1 -1.49012e-08
-7.45058e-09 0 -1.49012e-08 1
Python Results:
[[1.00000000e+00 2.77555756e-17 0.00000000e+00 5.32461714e-11]
[2.77555756e-17 1.00000000e+00 5.32461852e-11 0.00000000e+00]
[0.00000000e+00 5.32461852e-11 1.00000000e+00 2.77555756e-17]
[5.32461714e-11 0.00000000e+00 2.77555756e-17 1.00000000e+00]]
doublerather thanfloatwhen aiming for max precision.double, it works but why would the signs be different if I am using float?floats the value-1.49012e-08is as close to0as you can expect it to get in the presence of rounding errorsdouble, and 32-bit floating point forfloat. People almost always usedoublein C, rather thanfloat. Usingfloatin C is asking for trouble, unless you really don't want 64-bit floating point.