Related
I need to find an initial feasible solution for a network flow problem which is given by Nx = b, x >= 0. I used to the following OCTAVE code to do the job:
function [x,exitflag] = FIND_EXTREME_POINT(A,b)
%
% Function FIND_EXTREME_POINT
%
% Call: [x,fval] = FIND_EXTREME_POINT(A,b)
%
% MATLAB code for finding a extreme point of the set X = { x | Ax = b,
% x >= 0} by solving the auxiliary problem
%
% min 1'*y
% s.t. A*x + y = b
% x >= 0
% y >= 0
%
% either to receive a feasible basis solution or to return infeasibility
%
% Inputs:
% A - m*n matrix
% b = m*1 rhs
%
% Output:
% x - n*1 vector respresenting an extreme point
% exitflag - 0 if problem is infeasibile, 1 if the problem is feasible
%
% setup parameters for LP solver
[m,n] = size(A);
A_aux = [A eye(m)];
c_aux = [zeros(1,n) ones(1,m)]';
lb = [zeros(1,n+m)]';
ub = [];
ctype = repmat('S',1,m);
vartype = repmat('C',1,n+m);
% solve auxiliary LP
[xmin, fmin] = glpk(c_aux, A_aux, b, lb, ub, ctype, vartype, 1);
...% driving out artifical variables
The solution given by the glpk-solver matches to my handwritten notes.
For some reason I'm using MATLAB and I've got a problem with the following code:
function [x,exitflag] = FIND_EXTREME_POINT(A,b)
%
% Function FIND_EXTREME_POINT
%
% Call: [x,fval] = FIND_EXTREME_POINT(A,b)
%
% ....
%
% setup parameters for LP solver
[m,n] = size(A);
x = []; % output vector
A_aux = [A eye(m)];
c_aux = [zeros(1,n) ones(1,m)]';
lb = [zeros(1,n+m)]';
ub = [];
% solve auxiliary LP
[xmin,fval] = linprog(c_aux,[],[],A_aux,b,lb,ub);
... % driving out artifical variables
On the one hand the optimal solution xmin computed by the linprog-solver is feasible but on the other hand the function value fval is not zero but it should be so... Where is the mistake in my MATLAB code?
A little example:
N = [1 1 0 0 0 0 0;
-1 0 0 -1 0 0 0;
0 -1 1 0 0 -1 0;
0 0 -1 1 1 0 0;
0 0 0 0 0 1 1;
0 0 0 0 -1 0 -1];
b = [5 -5 0 0 0 0]';
OCTAVE gives me:
xmin =
5
0
0
0
0
0
0
0
0
0
0
0
0
fval =
0
MATLAB gives me:
xmin =
0.2184
4.7816
4.7816
4.7816
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
0.0000
fval =
5.8775e-016
I am trying to make a parity check matrix from non-systematic to systematic. Hence, I am attaching my code below. Somewhat it is correct, but there are some problems. It would be really great if someone could help me in this.
Subject: Information theory and coding. I am working on LDPC coding and decoding. Please check the code below
MATLAB CODE:
H = [1 0 1 1 0; 0 0 1 0 1; 1 0 0 1 0; 1 0 1 1 1]
[m,n] = size(H);
k = n-m;
for i = k+1:n
%H(:,i)
ind = find(H(:,i),1,'last');
% exchanging (ind)th row and (i-k)th row
if ind < i-k
continue;
end
if ind ~= i-k
temp = H(ind,:);
H(ind,:) = H(i-k,:);
H(i-k,:) = temp;
end
I = find(H(:,i));
% Guassian elimination
for j = 1:length(I)
if I(j) ~= i-k
H(I(j),:) = mod(H(I(j),:)+H(i-k,:),2);
end
end
end
Hsys = H
For e.g.
This is my H matrix:
H =
1 0 1 1 0
0 0 1 0 1
1 0 0 1 0
1 0 1 1 1
I want to have an identity matrix inside the matrix. The dimension on H matrix here is (mxn) which is (4x5).
Generally we use Gaussian elimination method to make the Identity matrix.hence, we make operations between rows. This is how we make it systematic.
I should have matrix as this in the result:
Hsys =
0 1 0 0 0
0 0 1 0 0
1 0 0 1 0
0 0 0 0 1
I should have an identity matrix of dimension m.
Here is how I'd do it (using Gauss-Jordan elimination):
% Not your matrix since it does not have any ones in the second column.
H=[1 1 0 1 1 0 0 1 0 0;
0 1 1 0 1 1 1 0 0 0;
0 0 0 1 0 0 0 1 1 1;
1 1 0 0 0 1 1 0 1 0;
0 0 1 0 0 1 0 1 0 1];
rows = size(H, 1);
cols = size(H, 2);
r = 1;
for c = cols - rows + 1:cols
if H(r,c) == 0
% Swap needed
for r2 = r + 1:rows
if H(r2,c) ~= 0
tmp = H(r, :);
H(r, :) = H(r2, :);
H(r2, :) = tmp;
end
end
end
% Ups...
if H(r,c) == 0
error('H is singular');
end
% Forward substitute
for r2 = r + 1:rows
if H(r2, c) == 1
H(r2, :) = xor(H(r2, :), H(r, :));
end
end
% Back Substitution
for r2 = 1:r - 1
if H(r2, c) == 1
H(r2, :) = xor(H(r2, :), H(r, :));
end
end
% Next row
r = r + 1;
end
Consider a set of points arranged on a grid of size N-by-M.
I am trying to build the adjacency matrix such that
neighboring points are connected.
For example, in a 3x3 grid with a graph:
1-2-3
| | |
4-5-6
| | |
7-8-9
We should have the corresponding adjacency matrix:
+---+------------------------------------------------------+
| | 1 2 3 4 5 6 7 8 9 |
+---+------------------------------------------------------+
| 1 | 0 1 0 1 0 0 0 0 0 |
| 2 | 1 0 1 0 1 0 0 0 0 |
| 3 | 0 1 0 0 0 1 0 0 0 |
| 4 | 1 0 0 0 1 0 1 0 0 |
| 5 | 0 1 0 1 0 1 0 1 0 |
| 6 | 0 0 1 0 1 0 0 0 1 |
| 7 | 0 0 0 1 0 0 0 1 0 |
| 8 | 0 0 0 0 1 0 1 0 1 |
| 9 | 0 0 0 0 0 1 0 1 0 |
+---+------------------------------------------------------+
As a bonus, the solution should work for both 4- and 8-connected neighboring points, that is:
o o o o
o X o vs. o X o
o o o o
This the code that I have so far:
N = 3; M = 3;
adj = zeros(N*M);
for i=1:N
for j=1:M
k = sub2ind([N M],i,j);
if i>1
ii=i-1; jj=j;
adj(k,sub2ind([N M],ii,jj)) = 1;
end
if i<N
ii=i+1; jj=j;
adj(k,sub2ind([N M],ii,jj)) = 1;
end
if j>1
ii=i; jj=j-1;
adj(k,sub2ind([N M],ii,jj)) = 1;
end
if j<M
ii=i; jj=j+1;
adj(k,sub2ind([N M],ii,jj)) = 1;
end
end
end
How can this improved to avoid all the looping?
If you notice, there is a distinct pattern to the adjacency matrices you are creating. Specifically, they are symmetric and banded. You can take advantage of this fact to easily create your matrices using the diag function (or the spdiags function if you want to make a sparse matrix). Here is how you can create the adjacency matrix for each case, using your sample matrix above as an example:
4-connected neighbors:
mat = [1 2 3; 4 5 6; 7 8 9]; % Sample matrix
[r, c] = size(mat); % Get the matrix size
diagVec1 = repmat([ones(c-1, 1); 0], r, 1); % Make the first diagonal vector
% (for horizontal connections)
diagVec1 = diagVec1(1:end-1); % Remove the last value
diagVec2 = ones(c*(r-1), 1); % Make the second diagonal vector
% (for vertical connections)
adj = diag(diagVec1, 1)+diag(diagVec2, c); % Add the diagonals to a zero matrix
adj = adj+adj.'; % Add the matrix to a transposed copy of
% itself to make it symmetric
And you'll get the following matrix:
adj =
0 1 0 1 0 0 0 0 0
1 0 1 0 1 0 0 0 0
0 1 0 0 0 1 0 0 0
1 0 0 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 0 0 1
0 0 0 1 0 0 0 1 0
0 0 0 0 1 0 1 0 1
0 0 0 0 0 1 0 1 0
8-connected neighbors:
mat = [1 2 3; 4 5 6; 7 8 9]; % Sample matrix
[r, c] = size(mat); % Get the matrix size
diagVec1 = repmat([ones(c-1, 1); 0], r, 1); % Make the first diagonal vector
% (for horizontal connections)
diagVec1 = diagVec1(1:end-1); % Remove the last value
diagVec2 = [0; diagVec1(1:(c*(r-1)))]; % Make the second diagonal vector
% (for anti-diagonal connections)
diagVec3 = ones(c*(r-1), 1); % Make the third diagonal vector
% (for vertical connections)
diagVec4 = diagVec2(2:end-1); % Make the fourth diagonal vector
% (for diagonal connections)
adj = diag(diagVec1, 1)+... % Add the diagonals to a zero matrix
diag(diagVec2, c-1)+...
diag(diagVec3, c)+...
diag(diagVec4, c+1);
adj = adj+adj.'; % Add the matrix to a transposed copy of
% itself to make it symmetric
And you'll get the following matrix:
adj =
0 1 0 1 1 0 0 0 0
1 0 1 1 1 1 0 0 0
0 1 0 0 1 1 0 0 0
1 1 0 0 1 0 1 1 0
1 1 1 1 0 1 1 1 1
0 1 1 0 1 0 0 1 1
0 0 0 1 1 0 0 1 0
0 0 0 1 1 1 1 0 1
0 0 0 0 1 1 0 1 0
Just for fun, here's a solution to construct the adjacency matrix by computing the distance between all pairs of points on the grid (not the most efficient way obviously)
N = 3; M = 3; %# grid size
CONNECTED = 8; %# 4-/8- connected points
%# which distance function
if CONNECTED == 4, distFunc = 'cityblock';
elseif CONNECTED == 8, distFunc = 'chebychev'; end
%# compute adjacency matrix
[X Y] = meshgrid(1:N,1:M);
X = X(:); Y = Y(:);
adj = squareform( pdist([X Y], distFunc) == 1 );
And here's some code to visualize the adjacency matrix and the graph of connected points:
%# plot adjacency matrix
subplot(121), spy(adj)
%# plot connected points on grid
[xx yy] = gplot(adj, [X Y]);
subplot(122), plot(xx, yy, 'ks-', 'MarkerFaceColor','r')
axis([0 N+1 0 M+1])
%# add labels
[X Y] = meshgrid(1:N,1:M);
X = reshape(X',[],1) + 0.1; Y = reshape(Y',[],1) + 0.1;
text(X, Y(end:-1:1), cellstr(num2str((1:N*M)')) )
I just found this question when searching for the same problem. However, none of the provided solutions worked for me because of the problem size which required the use of sparse matrix types. Here is my solution which works on large scale instances:
function W = getAdjacencyMatrix(I)
[m, n] = size(I);
I_size = m*n;
% 1-off diagonal elements
V = repmat([ones(m-1,1); 0],n, 1);
V = V(1:end-1); % remove last zero
% n-off diagonal elements
U = ones(m*(n-1), 1);
% get the upper triangular part of the matrix
W = sparse(1:(I_size-1), 2:I_size, V, I_size, I_size)...
+ sparse(1:(I_size-m),(m+1):I_size, U, I_size, I_size);
% finally make W symmetric
W = W + W';
Just came across this question. I have a nice working m-function (link: sparse_adj_matrix.m) that is quite general.
It can handle 4-connect grid (radius 1 according to L1 norm), 8-connect grid (radius 1 according to L_infty norm).
It can also support 3D (and arbitrarily higher domensional grids).
The function can also connect nodes further than radius = 1.
Here's the signiture of the function:
% Construct sparse adjacency matrix (provides ii and jj indices into the
% matrix)
%
% Usage:
% [ii jj] = sparse_adj_matrix(sz, r, p)
%
% inputs:
% sz - grid size (determine the number of variables n=prod(sz), and the
% geometry/dimensionality)
% r - the radius around each point for which edges are formed
% p - in what p-norm to measure the r-ball, can be 1,2 or 'inf'
%
% outputs
% ii, jj - linear indices into adjacency matrix (for each pair (m,n)
% there is also the pair (n,m))
%
% How to construct the adjacency matrix?
% >> A = sparse(ii, jj, ones(1,numel(ii)), prod(sz), prod(sz));
%
%
% Example:
% >> [ii jj] = sparse_adj_matrix([10 20], 1, inf);
% construct indices for 200x200 adjacency matrix for 8-connect graph over a
% grid of 10x20 nodes.
% To visualize the graph:
% >> [r c]=ndgrid(1:10,1:20);
% >> A = sparse(ii, jj, 1, 200, 200);;
% >> gplot(A, [r(:) c(:)]);
Your current code doesn't seem so bad. One way or another you need to iterate over all neighbor pairs. If you really need to optimize the code, I would suggest:
loop over node indices i, where 1 <= i <= (N*M)
don't use sub2ind() for efficiency, the neighbors of node i are simpy [i-M, i+1, i+M, i-1] in clockwise order
Notice that to get all neighbor pairs of nodes:
you only have to compute the "right" neighbors (i.e. horizontal edges) for nodes i % M != 0 (since Matlab isn't 0-based but 1-based)
you only have to compute "above" neighbors (i.e. vertical edges) for nodes i > M
there is a similar rule for diagonal edges
This would leed to a single loop (but same number of N*M iterations), doesn't call sub2ind(), and has only two if statements in the loop.
For each node in the graph add a connection to the right and one downwards. Check that you don't overreach your grid. Consider the following function that builds the adjacency matrix.
function adj = AdjMatrixLattice4( N, M )
% Size of adjacency matrix
MN = M*N;
adj = zeros(MN,MN);
% number nodes as such
% [1]---[2]-- .. --[M]
% | | |
% [M+1]-[M+2]- .. -[2*M]
% : : :
% [] [] .. [M*N]
for i=1:N
for j=1:N
A = M*(i-1)+j; %Node # for (i,j) node
if(j<N)
B = M*(i-1)+j+1; %Node # for node to the right
adj(A,B) = 1;
adj(B,A) = 1;
end
if(i<M)
B = M*i+j; %Node # for node below
adj(A,B) = 1;
adj(B,A) = 1;
end
end
end
end
Example as above AdjMatrixLattice4(3,3)=
0 1 0 1 0 0 0 0 0
1 0 1 0 1 0 0 0 0
0 1 0 0 0 1 0 0 0
1 0 0 0 1 0 1 0 0
0 1 0 1 0 1 0 1 0
0 0 1 0 1 0 0 0 1
0 0 0 1 0 0 0 1 0
0 0 0 0 1 0 1 0 1
0 0 0 0 0 1 0 1 0
I am new to MATLAB and I want to formulate the following lease square expression in Matlab. I have some codes that I am typing here. But the optimization problem solution seems not to be correct. Does anyone has an idea why?
First, I want to solve the heat equation
$$T_t(x,t) = - L_x . T(x,t) + F(x,t)$$
where L_x is Laplacian matrix of the graph.
then find y from the following least square.
$$ \min_y \sum_{j} \sum_{i} (\hat{T}_j(t_i) - T_j(t_i, y))^2$$
Thanks in advance!!
Here is my code:
%++++++++++++++++ main ++++++++++++++++++++
% incidence matrix for original graph
C_hat = [ 1 -1 0 0 0 0;...
0 1 -1 0 0 -1;...
0 0 0 0 -1 1;...
0 0 0 1 1 0;...
-1 0 1 -1 0 0];
% initial temperature for each vertex in original graph
T_hat_0 = [0 7 1 9 4];
[M_bar,n,m_bar,T_hat_heat,T_hat_temp] = simulate_temp(T_hat_0,C_hat);
C = [ 1 1 -1 -1 0 0 0 0 0 0;...
0 -1 0 0 1 -1 1 0 0 0;...
0 0 1 0 0 1 0 -1 -1 0;...
0 0 0 1 0 0 -1 0 1 -1;...
-1 0 0 0 -1 0 0 1 0 1];
%
% initial temperature for each vertex in original graph
T_0 = [0 7 1 9 4];
%
% initial temperature simulation
[l,n,m,T_heat,T_temp] = simulate_temp(T_0,C);
%
% bounds for variables
lb = zeros(m,1);
ub = ones(m,1);
%
% initial edge weights
w0 = ones(m,1);
% optimization problem
% w = fmincon(#fun, w0, [], [], [], [], lb, ub);
%++++++++++++++++++++ function++++++++++++++++++++++++++++
function [i,n,m,T_heat,T_temp] = simulate_temp(T,C)
%
% initial conditions
delta_t = 0.1;
M = 20; %% number of time steps
t = 1;
[n,m] = size(C);
I = eye(n);
L_w = C * C';
T_ini = T';
Temp = zeros(n,1);
% Computing Temperature
%
for i=1:M
K = 2*I + L_w * delta_t;
H = 2*I - L_w * delta_t;
%
if i == 1
T_heat = (K \ H) * T_ini;
%
t = t + delta_t;
else
T_heat = (K \ H) * Temp;
%
t = t + delta_t;
end
% replacing column of T_final with each node temperature in each
% iteration. It adds one column to the matrix in each step
T_temp(:,i) = T_heat;
%
Temp = T_heat;
end
end
%++++++++++++++++++ function+++++++++++++++++++++++++++++++++++++++++
function w_i = fun(w);
%
for r=1:n
for s=1:M_bar
w_i = (T_hat_temp(r,s) - T_temp(r,s)).^2;
end
end
To give a more clear answer, I need more information about what form you have the functions F_j and E_j in.
I've assumed that you feed each F_j a value, x_i, and get back a number. I've also assumed that you feed E_j a value x_i, and another value (or vector) y, and get back a value.
I've also assumed that by 'i' and 'j' you mean the indices of the columns and rows respectively, and that they're finite.
All I can suggest without knowing more info is to do this:
Pre-calculate the values of the functions F_j for each x_i, to give a matrix F - where element F(i,j) gives you the value F_j(x_i).
Do the same thing for E_j, giving a matrix E - where E(i,j) corresponds to E_j(x_i,y).
Perform (F-E).^2 to subtract each element of F and E, then square them element-wise.
Take sum( (F-E).^2**, 2)**. sum(M,2) will sum across index i of matrix M, returning a column vector.
Finally, take sum( sum( (F-E).^2, 2), 1) to sum across index j, the columns, this will finally give you a scalar.
I have the following equation:
((a^3)-(4*a^2))+[1 0 2;-1 4 6;-1 1 1] = 0
How do I solve this in MATLAB?
Here is one possibility:
% A^3 - 4*A^2 + [1 0 2;-1 4 6;-1 1 1] = 0
% 1) Change base to diagonalize the constant term
M = [1 0 2;-1 4 6;-1 1 1];
[V, L] = eig(M);
% 2) Solve three equations "on the diagonal", i.e. find a root of
% x^4 - 4*x^3 + eigenvalue = 0 for each eigenvalue of M
% (in this example, for each eigenvalue I choose the 3rd root,
% which happens to be real)
roots1 = roots([1 -4 0 L(1,1)]); r1 = roots1(3);
roots2 = roots([1 -4 0 L(2,2)]); r2 = roots2(3);
roots3 = roots([1 -4 0 L(3,3)]); r3 = roots3(3);
% 3) Build matrix solution and transform with inverse change of base
SD = diag([r1, r2, r3]);
A = V*SD*inv(V) % This is your solution
% The error should be practically zero
error = A^3 - 4*A^2 + [1 0 2;-1 4 6;-1 1 1]
norm(error)
(The error is actually of the order of 10^-14.)