Different floating point precision in Matrix multiplication in Python and C++

102 Views Asked by At

I am trying to do a very simple thing

  1. take a square shape 2d array
  2. take its transpose
  3. 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]]
0

There are 0 best solutions below