EDIT: I have changed my code below presenting the working version, thanks to @hpaulj
I am trying to solve the 2D Laplace equation using Gauss-Seidel iteration: every non-boundary element in the matrix is replaced by the average of the surrounding matrix elements. I first create the basic matrix.
# creation of matrix using random values and boundary conditions.
matrix = np.random.random((4,4))
for n in range(4): matrix.itemset((4-1, n), 10)
for n in range(4): matrix.itemset((n, 4-1), 0)
for n in range(4): matrix.itemset((0, n), 0)
for n in range(4): matrix.itemset((n, 0), 0)
Output:
[[ 0. 0. 0. 0. ]
[ 0. 0.33285936 0.59830215 0. ]
[ 0. 0.07021714 0.45341002 0. ]
[ 0. 10. 10. 0. ]]
Using the following code snippet, I try to find the left, right, up and down element around each non-boundary element in my array.
# opening the matrix and preparing it to be read and rewritten.
#with np.nditer(matrix, op_flags=['readwrite']) as it:
with np.nditer(matrix, op_flags=['readwrite'], flags=['multi_index']) as it:
# loop to find each element in our matrix
#for index, x in np.ndenumerate(matrix):
for x in it:
#row, colum = index
# only non-border values may be adjusted
if x != 0 and x != 10:
row, colum = it.multi_index
# finding each element around x
left = matrix[row][colum-1]
right = matrix[row][colum+1]
up = matrix[row-1][colum]
down = matrix[row+1][colum]
# finding average of elements around x
newvalue = 1/4*(left+right+up+down)
x[...] = newvalue
Instead of replacing the values, python prints out the following error:
x[...] = newvalue
TypeError: 'numpy.float64' object does not support item assignment
I don't get the error if I just use
for x in it:
but then I cannot keep track of the x, y values in my array. Does anybody know how to keep track of the position of the element or resolve the error?
xin the iteration is the value at slot inmatrix, but it is not a reference to that slot. As the error says, it's a number.matrix[row, col] = newvalueshould work.nditeris a reference to the slot, a 0d array.x[...]=newvaluedoes work for that. Do aprint(type(x))in both loops to see the difference. There's no point in nesting thendenumerate(matrix)loop inside thenditercontext.multi-indexoption innditerif you want to trackrow/col, numpy.org/devdocs/reference/…numpyarray methods. List iteration is faster (andnditerdoes not help!).