Vectorized formula for output layer in a neural network - performance

I have a neural network and want to use the trained neural network to solve for a set of test data. What I am struggling with is writing the formula for the hidden layer and for the output layer. I aim to have a vectorized formula but I will also be happy to implement a loop variation.
Now I believe I have the correct formula for the hidden layer and only need one for the output layer, but would appreciate it anyone confirm that it is the vectorized formula.
% Variables
% Xtest test training data
% thetah - trained weights for inputs to hidden layer
% thetao - trained weights for hidden layer to outputs
% ytest - output
htest = (1 ./ (1 + exp(-(thetah * Xtest'))))' ; % FORMULA FOR HIDDEN LAYER
ytest = ones(mtest, num_outputs) ; % FORMULA FOR OUTPUT LAYER

Below you can find both vectorized and loop implementations of the forward propagation. It is possible, that your input data have to be adapted to the code below, because of different notations and the way you store data in your matrices.
You need to add a bias unit to both input and hidden layer.
In order to simplify the work on the implementation and debugging I took some data from the open source machine learning repository and trained the network for the wine classification task.
Xtest - input data [178x13]
y - output class [178x1]
thetah - parameters of the hidden layer [15x14]
thetao -
parameters of the output layer [3x16]
The network separates the input data with rate 97.7%
Here is the code:
function [] = nn_fp()
load('Xtest.mat'); %input data 178x13
load('y.mat'); %output data 178x1
load('thetah.mat'); %Parameters of the hidden layer 15x14
load('thetao.mat'); %Parameters of the output layer 3x16
predict_simple(Xtest, y, thetah, thetao);
predict_vectorized(Xtest, y, thetah, thetao);
end
function predict_simple(Xtest, y, thetah, thetao)
mtest = size(Xtest, 1); %number of input examples
n = size(Xtest, 2); %number of features
hl_size = size(thetah, 1); %size of the hidden layer (without the bias unit)
num_outputs = size(thetao, 1); %size of the output layer
%add a bias unit to the input layer
a1 = [ones(mtest, 1) Xtest]; %[mtest x (n+1)]
%compute activations of the hidden layer
z2 = zeros(mtest, hl_size); %[mtest x hl_size]
a2 = zeros(mtest, hl_size); %[mtest x hl_size]
for i=1:mtest
for j=1:hl_size
for k=1:n+1
z2(i, j) = z2(i, j) + a1(i, k)*thetah(j, k);
end
a2(i, j) = sigmoid_simple(z2(i, j));
end
end
%add a bias unit to the hidden layer
a2 = [ones(mtest, 1) a2]; %[mtest x (hl_size+1)]
%compute activations of the output layer
z3 = zeros(mtest, num_outputs); %[mtest x num_outputs]
h = zeros(mtest, num_outputs); %[mtest x num_outputs]
for i=1:mtest
for j=1:num_outputs
for k=1:hl_size+1
z3(i, j) = z3(i, j) + a2(i, k)*thetao(j, k);
end
h(i, j) = sigmoid_simple(z3(i, j)); %the hypothesis
end
end
%calculate predictions for each input example based on the maximum term
%of the hypothesis h
p = zeros(size(y));
for i=1:mtest
max_ind = 1;
max_value = h(i, 1);
for j=2:num_outputs
if (h(i, j) > max_value)
max_ind = j;
max_value = h(i, j);
end
end
p(i) = max_ind;
end
%calculate the success rate of the prediction
correct_count = 0;
for i=1:mtest
if (p(i) == y(i))
correct_count = correct_count + 1;
end
end
rate = correct_count/mtest*100;
display(['simple version rate:', num2str(rate)]);
end
function predict_vectorized(Xtest, y, thetah, thetao)
mtest = size(Xtest, 1); %number of input examples
%add a bias unit to the input layer
a1 = [ones(mtest, 1) Xtest];
%compute activations of the hidden layer
z2 = a1*thetah';
a2 = sigmoid_universal(z2);
%add a bias unit to the hidden layer
a2 = [ones(mtest, 1) a2];
%compute activations of the output layer
z3 = a2*thetao';
h = sigmoid_universal(z3); %the hypothesis
%calculate predictions for each input example based on the maximum term
%of the hypothesis h
[~,p] = max(h, [], 2);
%calculate the success rate of the prediction
rate = mean(double((p == y))) * 100;
display(['vectorized version rate:', num2str(rate)]);
end
function [ s ] = sigmoid_simple( z )
s = 1/(1+exp(-z));
end
function [ s ] = sigmoid_universal( z )
s = 1./(1+exp(-z));
end

Assuming that your Xtest has dimensions N by M where N is the number of examples and M is the number of features, thetah is a M by H1 matrix where H1 is the number of hidden layers in the first layer and thetao is a H1 by O matrix where O is the number of output classes you do the following:
a1 = Xtest * thetah;
z1 = 1 / (1 + exp(-a1)); %Assuming you are using sigmoid units
a2 = z1 * thetao;
z2 = softmax(a2);
Read more about softmax here.

Related

how to combine two same scene images for image registration

I try to do image registration on two grayscale images where the images were taken twice with different views. The images were taking by myself using a Lifecam camera.
To register these images, I used template matching method and normalized cross correlation as similarity measure and found the right location. But the result after combination of these two images was not good as I wish. I don't know how to fix it. Do I need to do some rotation or translation first before combine it? If so, I have no idea how to get the real angle for rotation. Or do you have any idea how to fix the image result without applying any rotation?
Input image 1:
Input Image 2:
Result:
This my code:
A = imread('image1.jpg');
B = imread('image2.jpg');
[M1, N1] = size(A); % size imej A n B
[M2, N2] = size(B);
%% finding coordinated of (r2,c2)
r1 = size(A,1)/2; % midpoint of image A as coordinate
c1 = size(A,2
template = imcrop(A,[(c1-20) (r1-20) 40 40]);
[r2, c2] = normcorr(temp,B); % Normalized cross correlation
%% count distance of coordinate (r1,c1) in image A and (r2,c2)in image B
UA = r1; % distance of coordinate (r1,c1) from top in image A
BA = M1 - r1; % distance of coordinate (r1,c1) from bottom
LA = c1; % left distance from (r1,c1)
RA = N1 - c1; % right distance from (r1,c1)
UB = r2; % finding distance of coordinate (r2,c2) from top,
BB = M2 - r2; % bottom, left and right in image B
LB = c2;
RB = N2 - c2;
%% zero padding for both image
if LA > LB
L_diff = LA - LB; % value of columns need to pad with zero on left side
B = [zeros(M2,L_diff),B];
else
L_diff = LB - LA;
A = [zeros(M1,L_diff),A];
end
if RA > RB
R_diff = RA - RB; % value of columns need to pad with zero on right side
B = [B, zeros(M2,R_diff)];
else
R_diff = RB - RA;
A = [A, zeros(M1,R_diff)];
end
N1 = size(A, 2); % renew value column image A and B
N2 = size(B, 2);
if UA > UB
U_diff = UA - UB; % value of rows need to pad with zero on top
B = [zeros(U_diff,N2);B];
else
U_diff = UB - UA;
A = [zeros(U_diff,N1);A];
end
if BA > BB
B_diff = BA - BB; % value of rows need to pad with zero on bottom
B = [B; zeros(B_diff,N2)];
else
B_diff = BB - BA;
A = [A; zeros(B_diff,N1)];
end
%% find coordinate that have double value
if LA > LB
r = r1;
c = c1;
else
r = r2;
c = c2;
end
if UA >= UB
i_Start = r - UB + 1;
else
i_Start = r - UA + 1;
end
if BA >= BB
i_Stop = r + BB ;
else
i_Stop = r + BA;
end
if LA >= LB
j_Start = c - c2 + 1;
else
j_Start = c - c1 + 1;
end
if RA >= RB
j_Stop = c + RB;
else
j_Stop = c + RA;
end
%% add image A and B
A = im2double(A);
B = im2double(B);
final_im = A + B;
for i = i_Start:i_Stop
for j = j_Start:j_Stop
final_im(i,j) = final_im(i,j)/2;
end
end
final_im = im2uint8(final_im);
The answer from rayryeng in Ryan L's first link is quite applicable here. Cross-correlation likely won't provide a close enough match between the two images since the transformation between the two images is more accurately described as a homography than a 2D rigid transform.
Accurate image registration requires that you find this projective transformation. To do so you can find a set of corresponding points in the two images (using SURF, as mentioned above, usually works well) and then use RANSAC to obtain the homography's parameters from the corresponding points. RANSAC does a nice job even when some of the "corresponding" features in your two images are actually not correct matches. Once found, you can use the transformation to move one of your images to the other's point of view and fuse.
Here's a nice explanation of feature matching, RANSAC, and fusing two images with some Matlab code samples. The lecture uses SIFT features, but the idea still works for SURF.
Best published way to perform such a registration is based on fiducial points. You can choose the most clear edges or crossing points as a fiducial and then adjust the smoothness and regularization parameter to register them together.
look at the SlicerRT package. and let me know if you face any problem.

Implement Adaptive watershed segmentation in Matlab

I will like to implement "Adaptive Watershed Segmentation" in Matlab.
There are six steps in this algorithm. Input is figure(a) and result is figure(d).
Would you please to help me check is there any mistake in my code, and I don't know how to implement the sixth step.
Thank you so much!
Load image:
input_image = imread('test.gif');
Step 1 : Calculate D(x,y) at each (x,y), obtain the Euclidian distance map of the binary image and assign each value of M(x,y) as 0.
DT = bwdist(input_image,'euclidean'); % Trandform distance:Euclidian distance
[h,w]=size(DT);
M = zeros(h,w);
Step 2 : Smooth the distance map using Gaussian filter to merge the adjacent maxima, set M(x,y) as 1 if D(x,y) is a local maximum, and then obtain the marker map of the distance map.
H = fspecial('gaussian');
gfDT = imfilter(DT,H);
M = imregionalmax(gfDT); % maker map, M = local maximum of gfDT
Step3 : Scan the marker map pixel by pixel. If M(x0,y0) is 1, seek the spurious maxima in its neighbourhood with a radius of D(x ,y ).When M(x,y) equals 1 and sqr((x − x0)^2 + (y − y0)^2 ) ≤ D(x0, y0) , set M(x,y) as 0 if D(x,y) < D(x0,y0).
for x0 = 1:h
for y0 = 1:w
if M(x0,y0) == 1
r = ceil(gfDT(x0,y0));
% range begin:(x0-r,y0-r) end:(x0+r,y0+r)
xb = x0-r;
if xb <= 0
xb =1;
end
yb = y0-r;
if yb <= 0
yb =1;
end
xe = x0+r;
if xe > w
xe = w;
end
ye = y0+r;
if ye > h
ye = h;
end
for x = yb:ye
for y = xb:xe
if M(x,y)==1
Pos = [x0,y0 ;x,y];
Dis = pdist(Pos,'euclidean');
IFA = Dis<= (gfDT(x0,y0));
IFB = gfDT(x,y)<gfDT(x0,y0);
if ( IFA && IFB)
M(x,y) = 0;
end
end
end
end
end
end
end
Step 4:
Calculate the inverse of the distance map,and the local maxima turn out to be the local minima.
igfDT = -(gfDT);
STep5:
Segment the distance map according to the markers by the conventional watershed algorithm and obtain the segmentation of binary image.
I2 = imimposemin(igfDT,M);
L = watershed(I2);
igfDT (L==0)=0;
Step 6 : Straighten the watershed lines by linking the ends of the watershed lines with a straight line and reclassifying the pixels along the straight line.
I don't know how to implement this step
Try distance transform and then watershed transform.
im=imread('n6BRI.gif');
imb=bwdist(im);
sigma=3;
kernel = fspecial('gaussian',4*sigma+1,sigma);
im2=imfilter(imb,kernel,'symmetric');
L = watershed(max(im2(:))-im2);
[x,y]=find(L==0);
lblImg = bwlabel(L&~im);
figure,imshow(label2rgb(lblImg,'jet','k','shuffle'));

Matlab error in Backpropagation algorithm

Here is a matalab program for backpropagation algorithm-
% XOR input for x1 and x2
input = [0 0; 0 1; 1 0; 1 1];
% Desired output of XOR
output = [0;1;1;0];
% Initialize the bias
bias = [-1 -1 -1];
% Learning coefficient
coeff = 0.7;
% Number of learning iterations
iterations = 10000;
% Calculate weights randomly using seed.
rand('state',sum(100.*clock));
weights = -1 +2.*rand(3,3);
for i = 1:iterations
out = zeros(4,1);
numIn = length (input(:,1));
for j = 1:numIn
% Hidden layer
H1 = bias(1,1).*weights(1,1) + input(j,1).*weights(1,2)+ input(j,2).*weights(1,3);
% Send data through sigmoid function 1/1+e^-x
% Note that sigma is a different m file
% that I created to run this operation
x2(1) = sigma(H1);
H2 = bias(1,2).*weights(2,1)+ input(j,1).*weights(2,2)+ input(j,2).*weights(2,3);
x2(2) = sigma(H2);
% Output layer
x3_1 = bias(1,3).*weights(3,1)+ x2(1).*weights(3,2)+ x2(2).*weights(3,3);
out(j) = sigma(x3_1);
% Adjust delta values of weights
% For output layer:
% delta(wi) = xi*delta,
% delta = (1-actual output)*(desired output - actual output)
delta3_1 = out(j).*(1-out(j)).*(output(j)-out(j));
% Propagate the delta backwards into hidden layers
delta2_1 = x2(1).*(1-x2(1)).*weights(3,2).*delta3_1;
delta2_2 = x2(2).*(1-x2(2)).*weights(3,3).*delta3_1;
% Add weight changes to original weights
% And use the new weights to repeat process.
% delta weight = coeff*x*delta
for k = 1:3
if k == 1 % Bias cases
weights(1,k) = weights(1,k) + coeff.*bias(1,1).*delta2_1;
weights(2,k) = weights(2,k) + coeff.*bias(1,2).*delta2_2;
weights(3,k) = weights(3,k) + coeff.*bias(1,3).*delta3_1;
else % When k=2 or 3 input cases to neurons
weights(1,k) = weights(1,k) + coeff.*input(j,1).*delta2_1;
weights(2,k) = weights(2,k) + coeff.*input(j,2).*delta2_2;
weights(3,k) = weights(3,k) + coeff.*x2(k-1).*delta3_1;
end
end
end
end
But its showing error like -
??? Index exceeds matrix dimensions.
Error in ==> sigma at 95
a=varargin{1}; b=varargin{2}; c=varargin{3}; d=varargin{4};
Error in ==> back at 25
x2(1) = sigma(H1);
Please help me out. I am not able to understand the problem. Why there is an error saying index exceeds matrix dimension? Help is needed.

MATLAB program takes more than 1 hour to execute

The below program is a program for finding k-clique communities from a input graph.
The graph dataset can be found here.
The first line of the dataset contains 'number of nodes and edges' respectively. The following lines have 'node1 node2' representing an edge between node1 and node2 .
For example:
2500 6589 // number_of_nodes, number_of_edges
0 5 // edge between node[0] and node[5]
.
.
.
The k-clique( aCliqueSIZE, anAdjacencyMATRIX ) function is contained here.
The following commands are executed in command window of MATLAB:
x = textread( 'amazon.graph.small' ); %% source input file text
s = max(x(1,1), x(1,2)); %% take largest dimemsion
adjMatrix = sparse(x(2:end,1)+1, x(2:end,2)+1, 1, s, s); %% now matrix is square
adjMatrix = adjMatrix | adjMatrix.'; %% apply "or" with transpose to make symmetric
adjMatrix = full(adjMatrix); %% convert to full if needed
k=4;
[X,Y,Z]=k_clique(k,adjMatrix); %%
% The output can be viewed by the following commands
celldisp(X);
celldisp(Y);
Z
The above program takes more than 1 hour to execute whereas I think this shouldn't be the case. While running the program on windows, I checked the task manager and found that only 500 MB is allocated for the program. Is this the reason for the slowness of the program? If yes, then how can I allocate more heap memory (close to 4GB) to this program in MATLAB?
The problem does not seem to be Memory-bound
Having a sparse, square, symmetric matrix of 6k5 * 6k5 edges does not mean a big memory.
The provided code has many for loops and is heavily recursive in the tail function transfer_nodes()
Add a "Stone-Age-Profiler" into the code
To show the respective times spent on a CPU-bound sections of the processing, wrap the main sections of the code into a construct of:
tic(); for .... end;toc()
which will print you the CPU-bound times spent on relevent sections of the k_clique.m code, showing the readings "on-the-fly"
Your original code k_clique.m
function [components,cliques,CC] = k_clique(k,M)
% k-clique algorithm for detecting overlapping communities in a network
% as defined in the paper "Uncovering the overlapping
% community structure of complex networks in nature and society"
%
% [X,Y,Z] = k_clique(k,A)
%
% Inputs:
% k - clique size
% A - adjacency matrix
%
% Outputs:
% X - detected communities
% Y - all cliques (i.e. complete subgraphs that are not parts of larger
% complete subgraphs)
% Z - k-clique matrix
nb_nodes = size(M,1); % number of nodes
% Find the largest possible clique size via the degree sequence:
% Let {d1,d2,...,dk} be the degree sequence of a graph. The largest
% possible clique size of the graph is the maximum value k such that
% dk >= k-1
degree_sequence = sort(sum(M,2) - 1,'descend');
%max_s = degree_sequence(1);
max_s = 0;
for i = 1:length(degree_sequence)
if degree_sequence(i) >= i - 1
max_s = i;
else
break;
end
end
cliques = cell(0);
% Find all s-size kliques in the graph
for s = max_s:-1:3
M_aux = M;
% Looping over nodes
for n = 1:nb_nodes
A = n; % Set of nodes all linked to each other
B = setdiff(find(M_aux(n,:)==1),n); % Set of nodes that are linked to each node in A, but not necessarily to the nodes in B
C = transfer_nodes(A,B,s,M_aux); % Enlarging A by transferring nodes from B
if ~isempty(C)
for i = size(C,1)
cliques = [cliques;{C(i,:)}];
end
end
M_aux(n,:) = 0; % Remove the processed node
M_aux(:,n) = 0;
end
end
% Generating the clique-clique overlap matrix
CC = zeros(length(cliques));
for c1 = 1:length(cliques)
for c2 = c1:length(cliques)
if c1==c2
CC(c1,c2) = numel(cliques{c1});
else
CC(c1,c2) = numel(intersect(cliques{c1},cliques{c2}));
CC(c2,c1) = CC(c1,c2);
end
end
end
% Extracting the k-clique matrix from the clique-clique overlap matrix
% Off-diagonal elements <= k-1 --> 0
% Diagonal elements <= k --> 0
CC(eye(size(CC))==1) = CC(eye(size(CC))==1) - k;
CC(eye(size(CC))~=1) = CC(eye(size(CC))~=1) - k + 1;
CC(CC >= 0) = 1;
CC(CC < 0) = 0;
% Extracting components (or k-clique communities) from the k-clique matrix
components = [];
for i = 1:length(cliques)
linked_cliques = find(CC(i,:)==1);
new_component = [];
for j = 1:length(linked_cliques)
new_component = union(new_component,cliques{linked_cliques(j)});
end
found = false;
if ~isempty(new_component)
for j = 1:length(components)
if all(ismember(new_component,components{j}))
found = true;
end
end
if ~found
components = [components; {new_component}];
end
end
end
function R = transfer_nodes(S1,S2,clique_size,C)
% Recursive function to transfer nodes from set B to set A (as
% defined above)
% Check if the union of S1 and S2 or S1 is inside an already found larger
% clique
found_s12 = false;
found_s1 = false;
for c = 1:length(cliques)
for cc = 1:size(cliques{c},1)
if all(ismember(S1,cliques{c}(cc,:)))
found_s1 = true;
end
if all(ismember(union(S1,S2),cliques{c}(cc,:)))
found_s12 = true;
break;
end
end
end
if found_s12 || (length(S1) ~= clique_size && isempty(S2))
% If the union of the sets A and B can be included in an
% already found (larger) clique, the recursion is stepped back
% to check other possibilities
R = [];
elseif length(S1) == clique_size;
% The size of A reaches s, a new clique is found
if found_s1
R = [];
else
R = S1;
end
else
% Check the remaining possible combinations of the neighbors
% indices
if isempty(find(S2>=max(S1),1))
R = [];
else
R = [];
for w = find(S2>=max(S1),1):length(S2)
S2_aux = S2;
S1_aux = S1;
S1_aux = [S1_aux S2_aux(w)];
S2_aux = setdiff(S2_aux(C(S2(w),S2_aux)==1),S2_aux(w));
R = [R;transfer_nodes(S1_aux,S2_aux,clique_size,C)];
end
end
end
end
end

Fast computation of warp matrices

For a fixed and given tform, the imwarp command in the Image Processing Toolbox
B = imwarp(A,tform)
is linear with respect to A, meaning there exists some sparse matrix W, depending on tform but independent of A, such that the above can be equivalently implemented
B(:)=W*A(:)
for all A of fixed known dimensions [n,n]. My question is whether there are fast/efficient options for computing W. The matrix form is necessary when I need the transpose operation W.'*B(:), or if I need to do W\B(:) or similar linear algebraic things which I can't do directly through imwarp alone.
I know that it is possible to compute W column-by-column by doing
E=zeros(n);
W=spalloc(n^2,n^2,4*n^2);
for i=1:n^2
E(i)=1;
tmp=imwarp(E,tform);
E(i)=0;
W(:,i)=tmp(:);
end
but this is brute force and slow.
The routine FUNC2MAT is somewhat more optimal in that it uses the loop to compute/gather the sparse entry data I,J,S of each column W(:,i). Then, after the loop, it uses this to construct the overall sparse matrix. It also offers the option of using a PARFOR loop. However, this is still slower than I would like.
Can anyone suggest more speed-optimal alternatives?
EDIT:
For those uncomfortable with my claim that imwarp(A,tform) is linear w.r.t. A, I include the demo script below, which tests that the superposition property is satisfied for random input images and tform data. It can be run repeatedly to see that the nonlinearityError is always small, and easily attributable to floating point noise.
tform=affine2d(rand(3,2));
%tform=projective2d(rand(3));
fun=#(A) imwarp(A,tform,'cubic');
I1=rand(100); I2=rand(100);
c1=rand; c2=rand;
LHS=fun(c1*I1+c2*I2); %left hand side
RHS=c1*fun(I1)+c2*fun(I2); %right hand side
linearityError = norm(LHS(:)-RHS(:),'inf')
That's actually pretty simple:
W = sparse(B(:)/A(:));
Note that W is not unique, but this operation probably produces the most sparse result. Another way to calculate it would be
W = sparse( B(:) * pinv(A(:)) );
but that results in a much less sparse (yet still valid) result.
I constructed the warping matrix using the optical flow fields [u,v] and it is working well for my application
% this function computes the warping matrix
% M x N is the size of the image
function [ Fw ] = generateFwi( u,v,M,N )
Fw = zeros(M*N, M*N);
k =1;
for i=1:M
for j= 1:N
newcoord(1) = i+u(i,j);
newcoord(2) = j+v(i,j);
newi = newcoord(1);
newj = newcoord(2);
if newi >0 && newj >0
newi1x = floor(newi);
newi1y = floor(newj);
newi2x = floor(newi);
newi2y = ceil(newj);
newi3x = ceil(newi); % four nearest points to the given point
newi3y = floor(newj);
newi4x = ceil(newi);
newi4y = ceil(newj);
x1 = [newi,newj;newi1x,newi1y];
x2 = [newi,newj;newi2x,newi2y];
x3 = [newi,newj;newi3x,newi3y];
x4 = [newi,newj;newi4x,newi4y];
w1 = pdist(x1,'euclidean');
w2 = pdist(x2,'euclidean');
w3 = pdist(x3,'euclidean');
w4 = pdist(x4,'euclidean');
if ceil(newi) == floor(newi) && ceil(newj)==floor(newj) % both the new coordinates are integers
Fw(k,(newi1x-1)*N+newi1y) = 1;
else if ceil(newi) == floor(newi) % one of the new coordinates is an integer
w = w1+w2;
w1new = w1/w;
w2new = w2/w;
W = w1new*w2new;
y1coord = (newi1x-1)*N+newi1y;
y2coord = (newi2x-1)*N+newi2y;
if y1coord <= M*N && y2coord <=M*N
Fw(k,y1coord) = W/w2new;
Fw(k,y2coord) = W/w1new;
end
else if ceil(newj) == floor(newj) % one of the new coordinates is an integer
w = w1+w3;
w1 = w1/w;
w3 = w3/w;
W = w1*w3;
y1coord = (newi1x-1)*N+newi1y;
y2coord = (newi3x-1)*N+newi3y;
if y1coord <= M*N && y2coord <=M*N
Fw(k,y1coord) = W/w3;
Fw(k,y2coord) = W/w1;
end
else % both the new coordinates are not integers
w = w1+w2+w3+w4;
w1 = w1/w;
w2 = w2/w;
w3 = w3/w;
w4 = w4/w;
W = w1*w2*w3 + w2*w3*w4 + w3*w4*w1 + w4*w1*w2;
y1coord = (newi1x-1)*N+newi1y;
y2coord = (newi2x-1)*N+newi2y;
y3coord = (newi3x-1)*N+newi3y;
y4coord = (newi4x-1)*N+newi4y;
if y1coord <= M*N && y2coord <= M*N && y3coord <= M*N && y4coord <= M*N
Fw(k,y1coord) = w2*w3*w4/W;
Fw(k,y2coord) = w3*w4*w1/W;
Fw(k,y3coord) = w4*w1*w2/W;
Fw(k,y4coord) = w1*w2*w3/W;
end
end
end
end
else
Fw(k,k) = 1;
end
k=k+1;
end
end
end

Resources