Prolog get squares of NxN matrix - list

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!

Related

Finding element at x,y in a given matrix after rotation in C/C++?

How can I find the element at index x,y in a given matrix after rotating the total matrix without performing the matrix rotation.
That means I am just interested in that coordinate don't want to perform total operation on total matrix and than simply get the element at any index.
Example:
suppose a matrix is given
1 2 3
4 5 6
7 8 9
and i want to find the element at 1,1 after rotating the matrix by 90 degree.
answer should be "7".
**NOTE**: Without performing the rotation on total matrix.
and if i want the element at 1,2 than the answer should be "4".
I hope I clearly communicated the question please help if you know the solution or algorithm for this question.
Thank you.
Suppose you have a m x n matrix and you are interested in the position of M[i][j] after rotation.
So, after a rotation of 90 degrees clockwise, M[i][j] -> M[j][m+1-i].
As in your example, M[3][1] will be M[1][3+1-3] after rotation.
Hope this solves your problem.
Here's one way to solve the problem (other than using somebody else's solution).
It's fairly clear that the column index of each element is the row index of that element after rotation (at least, I hope that's clear).
So, the problem is the column index of an element after rotation.
The first row will become the last column, the second will be the second last, and so on until the last row which becomes the first column.
One way of viewing this is that we have the sequence (of rows) i = 1, 2, ..., m and want to map that to the sequence (of columns) j = m, m - 1, m - 2, ..., 2, 1.
But m = m + 1 - 1, m - 1 = m + 1 - 2, m - 2 = m + 1 - 3, ..., 1 = m + 1 - m.
So the desired sequence is j = m + 1 - i.
In other words, M[i][j] -> M[j][m + 1 - i].
You want to map:
(x,y) -> (x', y')
Assume following:1
x' = ax + by + c
y' = dx + ey + f
Now, (1, 1) maps to (W, 1)2
w = a + b + c
1 = d + e + f
(1, W) maps to (1, 1)3
1 = a + bw + c
1 = d + ew + f
and (W, H) maps to (1, H)4
1 = aw + bh + c
h = dw = eH + f
Solve 2, 3 and 4 equation and fill in to 1 get the value. (Hint: b = -1, e = 0)
// For 90 degree rotation using correct indexing for x and y (starting at 0 not 1)
// Assuming square matrix
template<class T, int size>
T elemAfter90degRot(int x, int y, T[size][size] mat) {
int j = y;
int i = size - 1 - x;
return mat[i][j];
}
I think that should do the trick for a 90 degree rotation of a square matrix

Python: Forming overlapping matrix of 3*3 using 9*9 matrix

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.

Adjacency matrix and Bron–Kerbosch algorithm

I want to find maximum cliques in a graph that is given to me in a form of adjacency matrix. I what I am trying to do I am being given the amount of shops I need to find with the same product tag that are being collected and whether sufficient amount of those shops was found
so input goes along lines
x - shop count.
y - product count/tag.
z - in how many shops does the product need to be present.
so let's say I got
5 - x
2 - y
4 - z
Then the adjacency matrix going with it is:
0 1 1 1 1
1 0 2 2 1
1 2 0 2 2
1 2 2 0 1
1 1 2 1 0
There are two different products available, now I want to find out whether there are atleast 4 shops selling specific product. I found out about Bron–Kerbosch algorithm e.g. http://en.wikipedia.org/wiki/Bron%E2%80%93Kerbosch_algorithm
But I don't know how to pick my R, P and X subsets and how to represent them. It does not have to be very efficient nor I believe there is a need for any more advanced data structure than a 2D array but I just don't know how to use this adjacency matrix as a list of my vertices etc. Could anyone give me an idea on how to get started with this algorithm? Probably telling me how to treat R, P and X with my data would be sufficient. I would want to create my program in C++
From the wikipedia article:
BronKerbosch3(G):
P = V(G)
R = X = empty
for each vertex v in a degeneracy ordering of G:
BronKerbosch2(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
P := P \ {v}
X := X ⋃ {v}
where G is the graph and BronKerbosch2() is defined as :
BronKerbosch2(R,P,X):
if P and X are both empty:
report R as a maximal clique
choose a pivot vertex u in P ⋃ X
for each vertex v in P \ N(u):
BronKerbosch2(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
P := P \ {v}
X := X ⋃ {v}
So now you know your choice of R, P and X. Also lookup what an adjacency matrix actually is as mentioned in the comments. Also, read the article carefully for the use of degeneracy in the algorithm.
In C++, you could use std::array<std::array<int, SIZE>, SIZE> for the 2D adjacency matrix and then proceed with the algorithm.

Haskell OpenGL procedural generation

I am trying to use Haskell to procedurally generate a triangulated square terrain of a given width to be given to OpenGL.
The only thing that is actually procedurally generated is the heights, which is not hard at all, I just use a random function to create a [[GLfloat]], representing rows of heights.
Then I also have a function, heightsToCoords that takes the [[GLfloat]] and returns a [GLfloat] containing the x, y, and z coords of each vertex.
So if I call heightsToCoords [[0, 1], [1, 0]], it will return
[0, 0, 0,
1, 1, 0,
0, 1, 1,
1, 0, 1]
The problem I'm having is getting the data to OpenGL. OpenGL needs each face triangulated (at least with my setup) and all I have is the points, I am not sure how to create the faces.
How could I transform this data from a list of points to a list of faces? Disregard normals and order of vertices.
On the GL side, I'd use drawElements, which needs a list of points and a list of indices as inputs. So the question becomes how to generate a list of indices into your list of points.
Keeping in mind the original XZ grid, the idea is to draw two triangles for each cell of the grid. So we need 6 indices per grid cell. In Haskell, we can write something like:
concat [[x + width * (y+1), 1 + x + width*y, x + width * y,
x + width* (y+1), 1 + x + width * (y+1), 1 + x + width*y]
| y <- [0..height-1], x <- [0..width-1]]

How to normalize a mesh into -1 to 1, then revert from normalized mesh to original one?

I have a mesh model in X, Y, Z format. Lets say.
Points *P;
In first step, I want to normalize this mesh into (-1, -1, -1) to (1, 1, 1).
Here normalize means to fit this mesh into a box of (-1, -1, -1) to (1, 1, 1).
then after that I do some processing to normalized mesh, finally i want to revert the dimensions to similar with the original mesh.
step-1:
P = Original Mesh dimensions;
step-2:
nP = Normalize(P); // from (-1, -1, -1) to (1, 1, 1)
step-3:
cnP = do something with (nP), number of vertices has increased or decreased.
step-4:
Original Mesh dimensions = Revert(cnP); // dimension should be same with the original mesh
how can I do that?
I know how easy it can be to get lost in programming and completely miss the simplicity of the underlying math. But trust me, it really is simple.
The most intuitive way to go about your problem is probably this:
determine the minimum and maximum value for all three coordinate axes (i.e., x, y and z). This information is contained by the eight corner vertices of your cube. Save these six values in six variables (e.g., min_x, max_x, etc.).
For all points p = (x,y,z) in the mesh, compute
q = ( 2.0*(x-min_x)/(max_x-min_x) - 1.0
2.0*(y-min_y)/(max_y-min_y) - 1.0
2.0*(z-min_z)/(max_z-min_z) - 1.0 )
now q equals p translated to the interval (-1,-1,-1) -- (+1,+1,+1).
Do whatever you need to do on this intermediate grid.
Convert all coordinates q = (xx, yy, zz) back to the original grid by doing the inverse operation:
p = ( (xx+1.0)*(max_x-min_x)/2.0 + min_x
(yy+1.0)*(max_y-min_y)/2.0 + min_y
(zz+1.0)*(max_z-min_z)/2.0 + min_z )
Clean up any mess you've made and continue with the rest of your program.
This is so easy, it's probably a lot more work to find out which library contains these functions than it is to write them yourself.
It's easy - use shape functions. Here's a 1D example for two points:
-1 <= u <= +1
x(u) = x1*(1-u)/2.0 + x2*(1+u)/2.0
x(-1) = x1
x(+1) = x2
You can transform between coordinate systems using the Jacobean.
Let's see what it looks like in 2D:
-1 <= u <= =1
-1 <= v <= =1
x(u, v) = x1*(1-u)*(1-v)/4.0 + x2*(1+u)*(1-v)/4.0 + x3*(1+u)*(1+v)/4.0 + x4*(1-u)*(1+v)/4.0
y(u, v) = y1*(1-u)*(1-v)/4.0 + y2*(1+u)*(1-v)/4.0 + y3*(1+u)*(1+v)/4.0 + y4*(1-u)*(1+v)/4.0