Python: Forming overlapping matrix of 3*3 using 9*9 matrix - python-2.7

I am trying to create a neighborhood of pixel by using pixel matrix. The pixel matrix is the matrix of pixels in a 1 band image. Now I have to form matrix of 3*3 keeping each element of 9*9 matrix at center and have a neighbor for each element. Thus the element at (0,0) position will have neighboring elements as
[[0 0 0],
[0 2 3],
[0 3 4]]
Same case will happen to all elements in the first and last row and column. Attached image can help understanding better.
So the resultant matrix will have the size of 81*81. It is not necessary to save the small matrix in the form of matrix.
I have tried below,
n = size[0]
z= 3
x=y=0
m =0
while all( [x<0, y<0, x>=n, y>=n]):
continue
else:
for i in range(0, n):
arcpy.AddMessage("Hello" )
for x in range(m,m+3):
temp_matrix = [ [ 0 for i in range(3) ] for j in range(3) ]
for y in range(m,m+3):
temp_matrix[x][y] = arr_Pixels[x][y]
m+=1
y+=1
temp_List.append(temp_matrix)
But I am getting error: list assignment out of index. Also it looks too lengthy and confusing. I understood the error is occurring because, there is no increment in the array temp_matrix length.
Is there any better way to implement the matrix in image? Smaller matrices can be saved into list rather than matrix. Please help me.
Update #2
n = size[0]
new_matrix = []
for i in range(0,n):
for j in range(0,n):
temp_mat = [ [ 0 for k in range(3) ] for l in range(3) ]
for k in range(i-1, i+2):
for l in range(j-1,j+2):
if any([k<0, l<0, k>n-1, l>n-1]):
temp_mat[k][l] = 0
else:
temp_mat[k][l] = arr_Pixels[k][l]
new_matrix.append(temp_mat)

I think one issue is your use of while/else. The code in else only executes after the while condition is true and the while will not repeat again. This question might be helpful.
Thus, once it enters else, it will never check again that x<=n and y<=n, meaning that x and y can increase beyond n, which I assume is the length of arr_Pixels.
One better way to do it would be to create two nested for loops that increment from 0 to n and create the temp neighborhood matrices and add them to the 9x9 matrix. Here is an rough outline for that:
new_matrix = [] //future 9x9 matrix
for i in range(0, n):
for j in range(0, n):
// create a neighborhood matrix going around (i, j)
// add temp matrix to new_matrix
This method would avoid having to check that the indexes you are accessing are less than n because it assures that i and j will always be less than n-3.

I found better way of doing it by padding the whole matrix by zero. Thus it resolves the negative indexing problems.
matrix can be padded as
pixels = np.pad(arr_Pixels, (1,1), mode='constant', constant_values=(0, 0))
It adds rows and columns of zeros along the axes.

Related

How to flatten 3D matrices into arrays?

I'm trying to flatten 3D matrices of arbitrary sizes into arrays such that values can be retrieved from arrays based on the spatial indexes i, j, and k. Clearly, each array index will have to be unique. I've tried setting the array index to int idx = i + width * (j + height * k), but that's not unique because (1,0,0) and (0,1,0) would give the same index if width == 1. Does anyone know of a better way to index or flatten 3D matrices?
Your formula is OK, because if width == 1, then j must be always 0

Prolog get squares of NxN matrix

I have a list L = [[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]] Ii. That represents my matrix. The size can change dynamic, so the blocksize can be different, 4x4 = 4 elements, 9x9= 9 elements
I want to obtain the 4 squares that compose the List.(In this case it's a matrix 4 by 4). If I have that matrix:
5 6 7 8
10 11 12 13
1 2 3 4
14 15 16 17
The result should be:
R = [5,6,10,11],[7,8,12,13],[1,2,14,15],[3,4,16,17].
Any suggestions are welcomed. Thanks
The first thing you need is really a lever for turning a list of lists into a matrix. What distinguishes a 2-dimensional matrix from a list of lists? The idea of a coordinate system. So you need a way to relate a coordinate pair with the corresponding value in the matrix.
at(Matrix, X, Y, V) :- nth0(X, Matrix, Row), nth0(Y, Row, V).
This predicate makes it possible to index the matrix at (X,Y) and get the value V. This turns out to be, IMO, a massive demonstration of what makes Prolog powerful, because once you have this one, simple predicate, you gain:
The ability to obtain the value at the point supplied:
?- at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], 1,3, V).
V = 13.
The ability to iterate the entire matrix (only instantiate Matrix and leave the other arguments as variables):
?- at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], X,Y, V).
X = Y, Y = 0,
V = 5 ;
X = 0,
Y = 1,
V = 6 ;
...
X = 3,
Y = 2,
V = 16 ;
X = Y, Y = 3,
V = 17.
The ability to search the matrix for values:
?- at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], X,Y, 14).
X = 3,
Y = 0 ;
false.
So this is a pretty useful lever! In a conventional lanugage, you'd need three different functions to do all these things, but this is different, because in Prolog we just have to define the relationship between things (in this case, a data structure and a coordinate pair) and Prolog can do quite a bit of the heavy lifting.
It's easy to see how we could produce a particular submatrix now, by just defining the sets of X and Y values we'd like to see. For instance, to get the upper-left matrix we would do this:
?- between(0,1,X), between(0,1,Y),
at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], X,Y, V).
X = Y, Y = 0,
V = 5 ;
X = 0,
Y = 1,
V = 6 ;
X = 1,
Y = 0,
V = 10 ;
X = Y, Y = 1,
V = 11.
We can of course use findall/3 to gather up the solutions in one place:
?- findall(V, (between(0,1,X), between(0,1,Y),
at([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], X,Y, V)),
Vs).
Vs = [5, 6, 10, 11].
What's left for your problem is basically some arithmetic. Let's see if we have a square matrix:
square_matrix(M, Degree) :-
length(M, Degree),
maplist(length, M, InnerDegrees),
forall(member(I, InnerDegrees), I=Degree).
This is not a perfect predicate, in that it will not generate! But it will tell us whether a matrix is square and if so, what degree it has:
?- square_matrix([[5,6,7,8],[10,11,12,13],[1,2,3,4],[14,15,16,17]], D).
D = 4.
Once you have that, what you have to do is sort of formulaic:
Make sure the degree is a perfect square
Take the square root of the degree. That's how many rows or columns you have (square root 4 = 2, 2 rows and 2 columns, square root 9 = 3, 3 rows and 3 columns).
Make a relationship between the (row,column) coordinate and a list of (x,y) coordinates for the matrix in that location. For instance in the 4x4 matrix, you have four tiles: (0,0), (0,1), (1,0) and (1,1). The coordinates for (0,0) will be (0,0), (0,1), (1,0), (1,1), but the coordinates for (1,1) will be (2,2),(2,3),(3,2),(3,3). If you do a few of these by hand, you'll see it's going to amount to adding an x and y offset to all the permutations from 0 to row/column count (minus one) for both coordinates.
Now that you have that relationship, you need to do the iteration and assemble your output. I think maplist/N will suffice for this.
Hope this helps!

Rotation of Matrices in Z_p

I want to give the values for a matrix parameter mat_ZZ_p A for the mat_ZZ_p type in NTL. The dimension of my vector is big. So, I am looking at a big square matrix as parameter. So, I cannot assign the values manually. One advantage here to me is that the columns of my matrix are only rotations of the first column. It is of the form
p_0 p_(n-1) p_(n-2) .... p_1
p_1 p_0 p_(n-1) .... p_2
.
.
p_(n-1) p_(n-2) p_(n-3) .... p_0
and I have a variable p which is a vector with the values p_0, p_1, ...,p_(n-1). I have assigned the 1st column of the matrix using a loop through the vector p. but I am not sure how to do the rotation for the other columns. I tried to use that the values when viewed diagonally are the same but in that case, I am not sure how to bound the loop. I tried to use the fact that there is a diagonal downward shift of elements as we move from one column to another. But again in this case, I am not able to assign the value for the 1st row, 2nd column just by referring to the previous column. Is there a standard way to do such rotation of columns?
Since I am trying to solve the system of equations in Z_p, I think the comments in this post does not help me.
Best way to solve a linear equation in code
If you refer to m[i][j] for the generic element of the matrix n x n then what you need is
m[i][j] = m[(i + n - 1) % n][j-1] for every j > 0
For a square matrix with dimensions n * n, to refer to any element not in the first column or first row, use m[i - 1][j - 1], with i and j being the row and cols.

Initialize matrix

Why does the top line of code create a zeroed out matrix but the bottom four lines of code give an error ("list assignment index out of range")?
matrix = [ [ 0 for i in range (6)] for j in range(6)]
matrix = [[]]
for i in range (6):
for j in range (6):
matrix[i][j] = 0
becouse the first line is filling a matrix
the second matrix definition is actually creating an array of size 1 with another array as the 0 element
the moment i=1 it fails
the correct form of the second part should be
matrix = []
for i in range(6):
temp = []
for j in range(6):
temp.append(0)
matrix.append(temp)

trouble calculating offset index into 3D array

I am writing a CUDA kernel to create a 3x3 covariance matrix for each location in the rows*cols main matrix. So that 3D matrix is rows*cols*9 in size, which i allocated in a single malloc accordingly. I need to access this in a single index value
the 9 values of the 3x3 covariance matrix get their values set according to the appropriate row r and column c from some other 2D arrays.
In other words - I need to calculate the appropriate index to access the 9 elements of the 3x3 covariance matrix, as well as the row and column offset of the 2D matrices that are inputs to the value, as well as the appropriate index for the storage array.
i have tried to simplify it down to the following:
//I am calling this kernel with 1D blocks who are 512 cols x 1row. TILE_WIDTH=512
int bx = blockIdx.x;
int by = blockIdx.y;
int tx = threadIdx.x;
int ty = threadIdx.y;
int r = by + ty;
int c = bx*TILE_WIDTH + tx;
int offset = r*cols+c;
int ndx = r*cols*rows + c*cols;
if((r < rows) && (c < cols)){ //this IF statement is trying to avoid the case where a threadblock went bigger than my original array..not sure if correct
d_cov[ndx + 0] = otherArray[offset];//otherArray just contains a value that I might do some operations on to set each of the ndx0-ndx9 values in d_cov
d_cov[ndx + 1] = otherArray[offset];
d_cov[ndx + 2] = otherArray[offset];
d_cov[ndx + 3] = otherArray[offset];
d_cov[ndx + 4] = otherArray[offset];
d_cov[ndx + 5] = otherArray[offset];
d_cov[ndx + 6] = otherArray[offset];
d_cov[ndx + 7] = otherArray[offset];
d_cov[ndx + 8] = otherArray[offset];
}
When I check this array with the values calculated on the CPU, which loops over i=rows, j=cols, k = 1..9
The results do not match up.
in other words d_cov[i*rows*cols + j*cols + k] != correctAnswer[i][j][k]
Can anyone give me any tips on how to sovle this problem? Is it an indexing problem, or some other logic error?
Rather than the answer (which I haven't stared hard enough to find), here's the technique I usually use for debugging these sorts of issues. First, set all values in your destination array to NaN. (You can do this via cudaMemset -- set every byte to 0xFF.) Then try uniformly setting every location to the value of the row, then inspect the results. In theory, it should look something like:
0 0 0 ... 0
1 1 1 ... 1
. . . . .
. . . . .
. . . . .
n n n ... n
If you see NaNs, you've failed to write to an element; if you see row elements out of place, something is wrong, and they'll usually be out of place in a suggestive pattern. Do something similar with the column value, and with the plane. Usually, this trick helps me find part of the index calculation is awry, which is most of the battle. Hope that helps.
I might be just stupid, but what is the logic in this line?
int ndx = r*cols*rows + c*cols;
Shouldn't you have
int ndx = offset*9;
If you said that the size of your covariance array was rows*cols*9, then wouldn't offset*9 take you at the same location in the 3D covariance array as where you are in your input array. So then offset*9+0 would be the location (0,0) of the 3x3 covariance matrix of the element at offset, offset*9+1 would be (0,1), offset*9+2 would be (0,2), offset*9+3 would be (1,0) and so on until offset*9+8.