Problems updating the context within a loop? C.scene.update()
Maybe use matrix_parent_inverse * location

Not sure what the issue is here.  The three values "np", "xx", and "tr" in test code below correlate.

Using mpw * mpi * ob.location avoids a scene update for each iter.

(of-course if our parent inverse isn't Identity only the "xx" and "tr" values will match)

import bpy
import numpy as np
from mathutils import Matrix
ball = bpy.context.object
mw = ball.matrix_world
mpi = ball.matrix_parent_inverse.copy()
mwp = ball.parent.matrix_world if ball.parent else Matrix()
for ix in np.arange (3, 50, 0.25):
    for iy in np.arange (2, 50, 0.25): 
        #mw.translation = mw * Vector((ix, iy, ball.location.z))
        ball.location.xy = (ix, iy)
        print("np", ix, iy)
        xx = mwp * mpi * ball.location
        print("xx", xx.x, xx.y)
        # required or matrices don't update in loop
        bpy.context.scene.update()
        tr = mw.translation
        print("tr", tr.x, tr.y)


Last few results

np 49.75 49.0
xx 49.75 49.0
tr 49.75 49.0
np 49.75 49.25
xx 49.75 49.25
tr 49.75 49.25
np 49.75 49.5
xx 49.75 49.5
tr 49.75 49.5
np 49.75 49.75
xx 49.75 49.75
tr 49.75 49.75