1

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]]
9
  • 7
    use double rather than float when aiming for max precision. Commented Oct 5, 2023 at 16:39
  • 1
    @463035818_is_not_an_ai: with double, it works but why would the signs be different if I am using float? Commented Oct 5, 2023 at 16:42
  • 3
    because floating point math is not exact. stackoverflow.com/questions/588004/…. With floats the value -1.49012e-08 is as close to 0 as you can expect it to get in the presence of rounding errors Commented Oct 5, 2023 at 16:44
  • 2
    I dont think this stackoverflow.com/questions/588004/… is the right duplicate, but it is closely related and the top answer refers to docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html which should cover what you are looking for Commented Oct 5, 2023 at 16:47
  • 2
    On most platforms, Python uses a 64-bit floating point representation. And on most platforms C uses 64-bit floating point for double, and 32-bit floating point for float. People almost always use double in C, rather than float. Using float in C is asking for trouble, unless you really don't want 64-bit floating point. Commented Oct 5, 2023 at 17:10

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.