2

let's say I have a matrix of size n (an odd number that's not 1) and I want to calculate the distance each entry is from the center. For example, if n = 2, then the matrix is 5 by 5 and to find the center of the matrix you would do..

import numpy as np
import math
center = math.floor(5/2)
Matrix[math.floor(5/2)][math.floor(5/2)] = 0

The center is zero because the distance to itself is 0. my approach is make the center like the origin of a coordinate plane and treat each of the 25 "squares" (5 by 5 matrix) as a dot in the center of each square and then calculate the euclidean distance that dot is from the center. visually: enter image description here

my idea so far..

Matrix = [[0 for x in range(n)] for y in range(n)] #initialize the n by n matrix
for i in range(0, n):
 for j in range(0, n):
 Matrix[i][j] = ...

or is there a better way to find the distance matrix?

the output should be symmetric and for a n = 5 matrix it would be

Matrix
[[2.82843, 2.23607, 2, 2.23607, 2.82843],
 [2.23607, 1.41421, 1, 1.41421, 2.23607],
 [2, 1, 0, 1, 2],
 [2.23607, 1.41421, 1, 1.41421, 2.23607],
 [2.82843, 2.23607, 2, 2.23607, 2.82843]]

TIA

asked Sep 30, 2018 at 16:37

4 Answers 4

3

Try to avoid loops when using numpy:

x_size, y_size = 5, 5
x_arr, y_arr = np.mgrid[0:x_size, 0:y_size]
cell = (2, 2)
dists = np.sqrt((x_arr - cell[0])**2 + (y_arr - cell[1])**2)
answered Sep 30, 2018 at 23:17
Sign up to request clarification or add additional context in comments.

Comments

2

The answer is Pythagoras famous theorem: https://www.mathsisfun.com/pythagoras.html For a cell at (i,j) you'll need the (x,y) offset to the center cell - then apply Pythagoras theorem to compute distance to that cell...

def pythag(a, b):
 return math.sqrt(a*a + b*b)
n = 5
import math
center = math.floor(n/2)
for i in range(0, n):
 for j in range(0, n):
 dist = pythag(i-center, j-center)
 print(dist)

Here's a repl with the code: https://repl.it/@powderflask/DizzyValuableQuark

answered Sep 30, 2018 at 17:03

1 Comment

better use math.hypot, as it is more efficient and handles corner cases
0

For a built-in option without numpy, and where you can shift the origin:

import math
def dist(n, shift=(0,0)):
 sx,sy = shift
 return [[math.hypot(min(i, n-i), min(j, n-j)) for j in range(-sx,n-sx)] for i in range(-sy,n-sy)]
print(*dist(5, (2,2)), sep='\n') # shift origin to center
print(*dist(5), sep='\n') # no shift

Output:

[2.8284271247461903, 2.23606797749979, 2.0, 2.23606797749979, 2.8284271247461903]
[2.23606797749979, 1.4142135623730951, 1.0, 1.4142135623730951, 2.23606797749979]
[2.0, 1.0, 0.0, 1.0, 2.0]
[2.23606797749979, 1.4142135623730951, 1.0, 1.4142135623730951, 2.23606797749979]
[2.8284271247461903, 2.23606797749979, 2.0, 2.23606797749979, 2.8284271247461903]
[0.0, 1.0, 2.0, 2.0, 1.0]
[1.0, 1.4142135623730951, 2.23606797749979, 2.23606797749979, 1.4142135623730951]
[2.0, 2.23606797749979, 2.8284271247461903, 2.8284271247461903, 2.23606797749979]
[2.0, 2.23606797749979, 2.8284271247461903, 2.8284271247461903, 2.23606797749979]
[1.0, 1.4142135623730951, 2.23606797749979, 2.23606797749979, 1.4142135623730951]
answered Mar 20, 2023 at 17:32

Comments

0

Here is the code that utilizes numpy broadcasting and will help you:

def generate_distance_matrix(center: Tuple[float, float], size: Tuple[int, int]) -> np.array:
 width, height = size
 x_c, y_c = center
 dist_array_w = (np.arange(width) - x_c)**2
 dist_array_h = (np.arange(height)[np.newaxis, :] - y_c)**2
 dist_matrix = np.zeros(size)
 dist_matrix += dist_array_w
 dist_matrix += dist_array_h.T
 return np.sqrt(dist_matrix)

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.