We can design such matrix with:
a = 3 # sample a
b = 5 # sample b
arr = np.zeros((10, 7)) # sample zeros
m, n = arr.shape
arr[:,:] = np.maximum(np.arange(m).reshape(-1,1) - a, np.arange(n) - b)
But if you do not need to modify the matrix itself, we can simply construct a new one (with arr = np.maximum(..)).
For a 10×7 matrix with a = 3, and b = 5, we then obtain:
>>> arr
array([[-3., -3., -3., -2., -1., 0., 1.],
[-2., -2., -2., -2., -1., 0., 1.],
[-1., -1., -1., -1., -1., 0., 1.],
[ 0., 0., 0., 0., 0., 0., 1.],
[ 1., 1., 1., 1., 1., 1., 1.],
[ 2., 2., 2., 2., 2., 2., 2.],
[ 3., 3., 3., 3., 3., 3., 3.],
[ 4., 4., 4., 4., 4., 4., 4.],
[ 5., 5., 5., 5., 5., 5., 5.],
[ 6., 6., 6., 6., 6., 6., 6.]])
EDIT: if we want absolute values np.abs(..):
arr[:,:] = np.maximum(np.abs(np.arange(m).reshape(-1,1) - a), np.abs(np.arange(n) - b))
then the result is:
>>> arr
array([[5, 4, 3, 3, 3, 3, 3],
[5, 4, 3, 2, 2, 2, 2],
[5, 4, 3, 2, 1, 1, 1],
[5, 4, 3, 2, 1, 0, 1],
[5, 4, 3, 2, 1, 1, 1],
[5, 4, 3, 2, 2, 2, 2],
[5, 4, 3, 3, 3, 3, 3],
[5, 4, 4, 4, 4, 4, 4],
[5, 5, 5, 5, 5, 5, 5],
[6, 6, 6, 6, 6, 6, 6]])
Performance
We defined two functions f and g:
>>> def f():
... a, b = 3, 5
... m, n = 10, 7
... arr = np.zeros((m, n))
... arr[:,:] = np.maximum(np.arange(m).reshape(-1,1) - a, np.arange(n) - b)
...
>>> def g():
... a, b = 3, 5
... m, n = 10, 7
... arr = np.zeros((m, n))
... i, j = np.indices((m, n))
... arr[:,:] = np.maximum(np.abs(i - a), np.abs(j - b))
then we run both functions 1'000'000 times:
>>> timeit(f, number=1000000)
7.471106000011787
>>> timeit(g, number=1000000)
18.07209299999522
We also ran it 1'000 times for an 1000×700 matrix:
>>> timeit(f, number=1000)
2.5362389999936568
>>> timeit(g, number=1000)
43.055561000001035
My hypothesis for this "performance gap" is that the np.indices() creates a 2×m×n matrix, which thus allocates a similar amount of memory. By constructing two 1d arrays, we take linear time in the intermediate matrices, and make use of broadcasting to calculate the elements of the final matrix.
m[i, j] = max(i, j)?index1, andindex2are the "indices" of the matrix for that element, right?f(a,b) = max(abs(index1-a), abs(index2-b))and try to find a way to predict the results for all indexes. For example, it seems like the function has a minimum in (index1=a,index2=b), where it corresponds to zero, and that from there for each increment of ±1 of one or both of the variables, f(a±1,b)=f(a,b±1)= f(a,b)+1. Edit: i mixed (index1,index2) with (a,b), but the result is the same given the abs()