Creating a precision matrix for Gaussian markov random field - normal-distribution

I am currently trying to create a precision matrix for a Gaussian markov random field. Lets say I have random variables in a spatial grid of 6x6. Then I will have a precision matrix of 36x36.
Now suppose that I have a neighbor hood of 3x3, then my precision matrix will be
Q= nnbs[1] -1 0 0 0 0 -1.......0
-1 nnbs[2] -1 0 0 0 0 ......0
0 -1 nnbs[3] -1 0 0 0 ......0
...................................................
...................................................
and so on. Can anyone suggest me how can I code this precision matrix. I mean if I change the window size/neighborhood size to 5x5, then I will have a new precision matrix. How can I code this? where nnbs is the number of neighbors of that element
rows=20;
columns=20;
%Random initialization
data=zeros(1000,3);
index=1;
value=-1;
%3x3 neighborhood
%For each element the neighbors are accessible within 1 hop so neighbors=1
neighbors=1;
for i=1:rows
for j=1:columns
for k=1:neighbors
%same row right
if j+k <= columns
data(index,1) = (i-1)*columns+j;
data(index,2) = ((i-1)*columns) + (j+k);
data(index,3) = value;
index=index+1;
end
%same row left
if j-k >= 1;
data(index,1) = (i-1)*columns+j;
data(index,2) = ((i-1)*columns) + (j-k);
data(index,3) = value;
index=index+1;
end
end
%row below -> bottom left right
for k=i+1:i+neighbors
if k <= rows
%bottom
data(index,1) = (i-1)*columns+j;
data(index,2) = (k-1)*columns + j;
data(index,3) = value;
index=index+1;
for l=1:neighbors
%right
if j+l <= columns
data(index,1) = (i-1)*columns+j;
data(index,2) = ((k-1)*columns) + (j+1);
data(index,3) = value;
index=index+1;
end
%left
if j-l >= 1;
data(index,1) = (i-1)*columns+j;
data(index,2) = ((k-1)*columns)+(j-1);
data(index,3) = value;
index=index+1;
end
end
end
end
%row above top left right
for k=i-1:i-neighbors
if k >= 1
%top
data(index,1) = (i-1)*columns+j;
data(index,2) = ((k-1)*columns) +j;
data(index,3) = value;
index=index+1;
for l=1:neighbors
%right
if j+l <= columns
data(index,1) = (i-1)*columns+j;
data(index,2) = ((k-1)*columns) + (j+1);
data(index,3) = value;
index=index+1;
end
%left
if j-k >= 1;
data(index,1) = (i-1)*columns+j;
data(index,2) = ((k-1)*columns) + (j-1);
data(index,3) = value;
index=index+1;
end
end
end
end
end
end
%Get the values for the diagonal elements(which is equal to the number of
%neighbors or absolute sum of the nondiagonal elements of the corresponding
%row)
diagonal_values = zeros(rows*columns,3);
for i=1:rows*columns
pointer=find(data(:,1) == i);
diag_value=abs(sum(data(pointer,3)));
diagonal_values(i,1) = i;
diagonal_values(i,2) = i;
diagonal_values(i,3) = diag_value;
end
data(index:index+rows*columns-1,:)=diagonal_values(:,:);
Q = sparse(data(:,1), data(:,2), data(:,3), rows*columns, rows*columns);
I tried something like this but I don't think this is the most efficient of ways. I think there should be a better way.

A bit too late but it may be useful for someone else :
Your precision matrix is a linear combination of kronecker product of symmetric Toeplitz matrix : to each neighbour type corresponds a kronecker product of 2 Toeplitz matrix.
More info about toeplitz Matrix
Example :
you want a precision matrix only with the horizontal link for each pixel
Writing I_n the identity matrix of size n and H_{n,p} the Symmetric Toeplitz matrix of dimension [n n] filled with 0 everywhere excepts on the p-th diagonals
H_{4,2} =
0 1 0 0
1 0 1 0
0 1 0 1
0 0 1 0
In Matlab :
H_nonSym_n_p = toeplitz(zeros(n,1), [[zeros(1,p-1) 1] zeros(1,n-p)]) ;
H_sym_n_p = H_nonSym + H_nonSym' ;
Then, if you have a [n m] image and if you want to code the horizontal neighbour of every pixel, you can express it through the kronecker product (hope the LaTeX-like code will work): Q = - I_n \otimes \H_{n,2}.
And finally, to get your nnbs : something like Q = Q - diag(sum(Q,2))...
Now, if you want other links, for instance 2 horizontal and 2 vertical links : Q = - I_n \otimes \H_{n,2} - I_n \otimes \H_{n,3} - \H_{n,2} \otimes I_{n} - \H_{n,3} \otimes I_{n}.
and again Q = Q - diag(sum(Q,2))
Note that the diagonal neighbours are a bit more difficult to produce but it is still represented by a kronecker product of toeplitz matrix (maybe non-symmetric this time).

Related

How to generate a 2D periodic pattern like below image from pseudorandom binary sequence?

I want to generate a 2 dimensional periodic pattern from a pseudorandom binary sequence like this one with the following context:
A periodic pattern satisfies the equations (1) and (2)
W(x + q0N0, y) = W(x, y); q0, N0 >1 (1)
W(x, y + q1N1) = W(x, y); q1, N1 > 1, (2)
where N0 and N1 determine the periodicity of repetitions and q0 and q1 a repetition number on the horizontal and vertical directions. Generation from pseudorandom values {−1, 1} produces a rectangular, binary valued pattern.
One way to achieve that would be to take a small pseudo-random 2D pattern (the sequence) and repeat it periodically so that neighboring tiles are always mirrored giving a sense of smooth continuity.
After you specified your requirements with W(x + q0N0, y) = W(x, y) and W(x, y + q1N1) = W(x, y); it becomes clear, that this is exactly (without the mirroring part) what you want.
You simply have to repeat a random pattern a certain number of times in both directions.
Example (similar to your image where the period length in the vertical direction is longer than in the horizontal direction)
Code (in Matlab)
% base pattern
N0 = 20;
N1 = 5;
base = rand([N0, N1]) > 0.5; % pseudo-random
% periodically repeating the pattern
Q0 = 5;
Q1 = 20;
pattern = zeros([N0*Q0,N1*Q1]);
for q0 = 1 : Q0
for q1 = 1 : Q1
pattern((q0-1)*N0+1:q0*N0, (q1-1)*N1+1:q1*N1) = base;
end
end
% save
imwrite(pattern, 'test.jpg');
% display
imagesc(pattern);
axis image;
colormap(gray);
The first lines just compute a random, binary pattern of a certain size N0 x N1
% base pattern
N0 = 20;
N1 = 5;
base = rand([N0, N1]) > 0.5; % pseudo-random
Then comes the definition of the number of repetitions of the pattern in each direction
Q0 = 5;
Q1 = 20;
Finally, in two nested but rather simple for loops, the base pattern is repeated
pattern = zeros([N0*Q0,N1*Q1]);
for q0 = 1 : Q0
for q1 = 1 : Q1
pattern((q0-1)*N0+1:q0*N0, (q1-1)*N1+1:q1*N1) = base;
end
end
The computation of the indices (where to place the base patterns) fulfills your requirement equations
(q0-1)*N0+1:q0*N0, (q1-1)*N1+1:q1*N1
Old Example (with mirroring)
Code (in Matlab)
% base pattern
N = 20;
base = rand(N) > 0.5; % pseudo-random
% multiplying the pattern
M = 4;
pattern = zeros(N*M);
for i = 1 : M
for j = 1 : M
b = base;
% mirroring the base
if mod(i, 2) == 1
flip(b, 2);
end
if mod(j, 2) == 1
flip(b, 1);
end
pattern((i-1)*N+1:i*N, (j-1)*N+1:j*N) = b;
end
end
% save
imwrite(pattern, 'test.jpg');
% display
imagesc(pattern);
axis image;
colormap(gray);
The patterns are flipped (mirrored) in one or two direction sometimes to simulates some kind of smoothness (symmetry) of the pattern.

What does the distance in machine learning signify?

In Neural networks, we regularly use the equation:
w1*x1 + w2*x2 + w3*x3 ...
We can interpret this as equation of a line with each x as a dimension. To make things more clearer, lets take an example of a simple perceptron network.
Imagine a single layer perceptron with 2 ip's/features (x1 & x2) and one output (y). (Sorry stackoverflow didn't allow me to post an additional image)
Let
R = w1*x1 + w2 * x2
y = 0 if R >= threshold
y = 1 if R < threshold
Scenario 1:
Threshold = 0
w1 = 2, w2 = -1
The line separating class 0 and 1 has the equation 2*x1 - x2 = 0
Suppose we get a test sample
P = (1,1)
R = 2*1 - 1 = 1 > 0
Sample P belongs to class 1
My questions is what is this R?
From the figure, its horizontal distance from the line.
Scenario 2:
Threshold = 0
w1 = 2, w2 = 1
The line separating class 0 and 1 has the equation 2*x1 + x2 = 0
P = (1,1)
R = 2*1 + 1 = 3 > 0
Sample P belongs to class 1
From the figure, its vertical distance from the line.
R is supposed to mean some form of distance from the classifying line. More the distance, more farther away from the line and we are more confident about the classification.
Just want to know what kind of distance from the line is R?

Runtime of while loop pseudocode

I have a pseudocode which I'm trying to make a detailed analysis, analyze runtime, and asymptotic analysis:
sum = 0
i = 1
while (i ≤ n){
sum = sum + i
i = 2i
}
return sum
My assignment requires that I write the cost/runtime for every line, add these together, and find a Big-Oh notation for the runtime. My analysis looks like this for the moment:
sum = 0 1
long i = 1 1
while (i ≤ n){ log n + 1
sum = sum + i n log n
i = 2i n log n
}
return sum 1
=> 2 n log n + log n + 4 O(n log n)
is this correct ? Also: should I use n^2 on the while loop instead ?
Because of integer arithmetic, the runtime is
O(floor(ln(n))+1) = O(ln(n)).
Let's step through your pseudocode. Consider the case that n = 5.
iteration# i ln(i) n
-------------------------
1 1 0 5
2 2 1 5
3 4 2 5
By inspection we see that
iteration# = ln(i)+1
So in summary:
sum = 0 // O(1)
i = 1 // O(1)
while (i ≤ n) { // O(floor(ln(n))+1)
sum = sum + i // 1 flop + 1 mem op = O(1)
i = 2i // 1 flop + 1 mem op = O(1)
}
return sum // 1 mem op = O(1)

Adaptive Median Filter

I am constructing code for adaptive median filter . When i execute it it gives me error at line No 12. Not enough arguments. and on line 28.Unexpected MATLAB Expression.
function f = adpmedian(g, Smax)
%ADPMEDIAN Perform adaptive median filtering.
% F = ADPMEDIAN(G, SMAX) performs adaptive median filtering of
% image G. The median filter starts at size 3-by-3 and iterates up
% to size SMAX-by-SMAX. SMAX must be an odd integer greater than 1.
% SMAX must be an odd, positive integer greater than 1.
**12>>**if (Smax <= 1) || (Smax/2 == round(Smax/2)) || (Smax ~= round(Smax))
error('SMAX must be an odd integer > 1.')
end
[M, N] = size(g);
% Initial setup.
f = g;
f(:) = 0;
alreadyProcessed = false(size(g));
% Begin filtering.
for k = 3:2:Smax
zmin = ordfilt2(g, 1, ones(k, k), 'symmetric');
zmax = ordfilt2(g, k * k, ones(k, k), 'symmetric');
zmed = medfilt2(g, [k k], 'symmetric');
`28>>` processUsingLevelB = (zmed > zmin) & (zmax > zmed) & ...
~alreadyProcessed;
zB = (g > zmin) & (zmax > g);
outputZxy = processUsingLevelB & zB;
outputZmed = processUsingLevelB & ~zB;
f(outputZxy) = g(outputZxy);
f(outputZmed) = zmed(outputZmed);
alreadyProcessed = alreadyProcessed | processUsingLevelB;
if all(alreadyProcessed(:))
break;
end
end
% Output zmed for any remaining unprocessed pixels. Note that this
% zmed was computed using a window of size Smax-by-Smax, which is
% the final value of k in the loop.
f(~alreadyProcessed) = zmed(~alreadyProcessed);

Lua Separation Steering algorithm groups overlapping rooms into one corner

I'm trying to implement a dungeon generation algorithm (presented here and demo-ed here ) that involves generating a random number of cells that overlap each other. The cells then are pushed apart/separated and then connected. Now, the original poster/author described that he is using a Separation Steering Algorithm in order to uniformly distribute the cells over an area. I haven't had much experience with flocking algorithm and/or separation steering behavior, thus I turned to google for an explanation (and found this ). My implementation (based on the article last mentioned) is as follows:
function pdg:_computeSeparation(_agent)
local neighbours = 0
local rtWidth = #self._rooms
local v =
{
x = self._rooms[_agent].startX,
y = self._rooms[_agent].startY,
--velocity = 1,
}
for i = 1, rtWidth do
if _agent ~= i then
local distance = math.dist(self._rooms[_agent].startX,
self._rooms[_agent].startY,
self._rooms[i].startX,
self._rooms[i].startY)
if distance < 12 then
--print("Separating agent: ".._agent.." from agent: "..i.."")
v.x = (v.x + self._rooms[_agent].startX - self._rooms[i].startX) * distance
v.y = (v.y + self._rooms[_agent].startY - self._rooms[i].startY) * distance
neighbours = neighbours + 1
end
end
end
if neighbours == 0 then
return v
else
v.x = v.x / neighbours
v.y = v.y / neighbours
v.x = v.x * -1
v.y = v.y * -1
pdg:_normalize(v, 1)
return v
end
end
self._rooms is a table that contains the original X and Y position of the Room in the grid, along with it's width and height (endX, endY).
The problem is that, instead of tiddly arranging the cells on the grid, it takes the overlapping cells and moves them into an area that goes from 1,1 to distance+2, distance+2 (as seen in my video [youtube])
I'm trying to understand why this is happening.
In case it's needed, here I parse the grid table, separate and fill the cells after the separation:
function pdg:separate( )
if #self._rooms > 0 then
--print("NR ROOMS: "..#self._rooms.."")
-- reset the map to empty
for x = 1, self._pdgMapWidth do
for y = 1, self._pdgMapHeight do
self._pdgMap[x][y] = 4
end
end
-- now, we separate the rooms
local numRooms = #self._rooms
for i = 1, numRooms do
local v = pdg:_computeSeparation(i)
--we adjust the x and y positions of the items in the room table
self._rooms[i].startX = v.x
self._rooms[i].startY = v.y
--self._rooms[i].endX = v.x + self._rooms[i].endX
--self._rooms[i].endY = v.y + self._rooms[i].endY
end
-- we render them again
for i = 1, numRooms do
local px = math.abs( math.floor(self._rooms[i].startX) )
local py = math.abs( math.floor(self._rooms[i].startY) )
for k = self.rectMinWidth, self._rooms[i].endX do
for v = self.rectMinHeight, self._rooms[i].endY do
print("PX IS AT: "..px.." and k is: "..k.." and their sum is: "..px+k.."")
print("PY IS AT: "..py.." and v is: "..v.." and their sum is: "..py+v.."")
if k == self.rectMinWidth or
v == self.rectMinHeight or
k == self._rooms[i].endX or
v == self._rooms[i].endY then
self._pdgMap[px+k][py+v] = 1
else
self._pdgMap[px+k][py+v] = 2
end
end
end
end
end
I have implemented this generation algorithm as well, and I came across more or less the same issue. All of my rectangles ended up in the topleft corner.
My problem was that I was normalizing velocity vectors with zero length. If you normalize those, you divide by zero, resulting in NaN.
You can fix this by simply performing a check whether your velocity's length is zero before using it in any further calculations.
I hope this helps!
Uhm I know it's an old question, but I noticed something and maybe it can be useful to somebody, so...
I think there's a problem here:
v.x = (v.x + self._rooms[_agent].startX - self._rooms[i].startX) * distance
v.y = (v.y + self._rooms[_agent].startY - self._rooms[i].startY) * distance
Why do you multiply these equations by the distance?
"(self._rooms[_agent].startX - self._rooms[i].startX)" already contains the (squared) distance!
Plus, multiplying everything by "distance" you modify your previous results stored in v!
If at least you put the "v.x" outside the bracket, the result would just be higher, the normalize function will fix it. Although that's some useless calculation...
By the way I'm pretty sure the code should be like:
v.x = v.x + (self._rooms[_agent].startX - self._rooms[i].startX)
v.y = v.y + (self._rooms[_agent].startY - self._rooms[i].startY)
I'll make an example. Imagine you have your main agent in (0,0) and three neighbours in (0,-2), (-2,0) and (0,2). A separation steering behaviour would move the main agent toward the X axis, at a normalized direction of (1,0).
Let's focus only on the Y component of the result vector.
The math should be something like this:
--Iteration 1
v.y = 0 + ( 0 + 2 )
--Iteration 2
v.y = 2 + ( 0 - 0 )
--Iteration 3
v.y = 2 + ( 0 - 2 )
--Result
v.y = 0
Which is consistent with our theory.
This is what your code do:
(note that the distance is always 2)
--Iteration 1
v.y = ( 0 + 0 + 2 ) * 2
--Iteration 2
v.y = ( 4 + 0 - 0 ) * 2
--Iteration 3
v.y = ( 8 + 0 - 2 ) * 2
--Result
v.y = 12
And if I got the separation steering behaviour right this can't be correct.

Resources