I have code as below to implement a sparse matrix:
close all
n=10;
p = 1/11;
term13 = -(1 / p^2);
term2 = (2 / p^2);
e=ones(n,1);
z=sparse(n,n);
for j=1:n
vval(j) = barrier(j*p);
z(j)=term2 + vval(j);
end
h = spdiags([term13*e z(j)*e term13*e], -1:1, n,n);
t=full(h)
and barrier is a function that has the value of 600 if 0.4<= j*p <=0.6, otherwise it is zero.
Naturally, I expect the matrix to be as bellow:
242 -121 0 0 0 0 0 0 0 0
-121 242 -121 0 0 0 0 0 0 0
0 -121 242 -121 0 0 0 0 0 0
0 0 -121 242 -121 0 0 0 0 0
0 0 0 -121 842 -121 0 0 0 0
0 0 0 0 -121 842 -121 0 0 0
0 0 0 0 0 -121 242 -121 0 0
0 0 0 0 0 0 -121 242 -121 0
0 0 0 0 0 0 0 -121 242 -121
0 0 0 0 0 0 0 0 -121 242
but surprisingly it has the form
242 -121 0 0 0 0 0 0 0 0
-121 242 -121 0 0 0 0 0 0 0
0 -121 242 -121 0 0 0 0 0 0
0 0 -121 242 -121 0 0 0 0 0
0 0 0 -121 242 -121 0 0 0 0
0 0 0 0 -121 242 -121 0 0 0
0 0 0 0 0 -121 242 -121 0 0
0 0 0 0 0 0 -121 242 -121 0
0 0 0 0 0 0 0 -121 242 -121
0 0 0 0 0 0 0 0 -121 242
To be exact, I expect h(5,5) = h(6,6) = 842 i.e. 242+600.
but it takes barrier =0.
Why is this value incorrect?
I'm not sure:
why the for loop is needed,
why you allocate a nxn sparse matrix z, and then use it with a single index z(j),
where vval is allocated, or used for that matter,
and why you create a sparse diagonal matrix, only to call full in the next line.
But regardless, the issue you asked about is caused by the line
h = spdiags([term13*e z(j)*e term13*e], -1:1, n,n);
which should be
h = spdiags([term13*e, z*e, term13*e], -1:1, n,n);
instead (note z instead of z(j)).
Related
Suppose I define the following simple matrix in MATLAB:
myImage3 = zeros(10,10);
for i=1:10
for j=i:2:10
myImage3(i,j) = 20;
end
end
Then myImage is a 10x10 matrix that looks like:
myImage3 =
20 0 20 0 20 0 20 0 20 0
0 20 0 20 0 20 0 20 0 20
0 0 20 0 20 0 20 0 20 0
0 0 0 20 0 20 0 20 0 20
0 0 0 0 20 0 20 0 20 0
0 0 0 0 0 20 0 20 0 20
0 0 0 0 0 0 20 0 20 0
0 0 0 0 0 0 0 20 0 20
0 0 0 0 0 0 0 0 20 0
0 0 0 0 0 0 0 0 0 20
How do I write a function that tracks or traces through all connected nonzero elements of the matrix? For example, if I start at (1,1), we have the following trace:
(1,1) --> (2,2) --> (3,3) ---> ... --> (10,10).
But if I start at (1,3), we have the following trace:
(1,3) --> (2,4) -> (3,5) ---> ... --> (8,10).
Similarly, if I start at (1,5), we have the following trace:
(1,5) --> (2,6) --> (3,7) ---> ... --> (6,10).
The elements do not need to be "20", but rather could be any non-zero number. Also, the elements do not have to be perfectly diagonal. They could be a zig zag like shown below:
myImage2 =
10 0 0 0 0 0 0 0 0 0
0 5 0 0 0 0 0 0 0 0
0 0 20 0 0 0 0 0 0 0
0 0 21 0 0 0 0 0 0 0
0 0 14 15 20 0 0 0 0 0
0 0 0 0 0 20 0 0 0 0
0 0 0 0 0 0 20 0 0 0
0 0 0 0 0 0 0 20 0 0
0 0 0 0 0 0 0 0 20 0
0 0 0 0 0 0 0 0 0 20
But notice that if I start at (1,1) again, every neighboring pixel has another non-zero neighboring pixel (i.e. connected).
The trace, starting at (1,1) would now look like:
(1,1)--> (2,2)--> (3,3) --> (4,3) --> (5,3)--> (5,4)--> (5,5)--> (6,6)--> (7,7)--> (8,8)--> (9,9)--> (10,10)
I think I need to use Depth First Search, but all the algorithms I see apply to adjacency matrices, not the type of matrices shown above.
I've been doing some experimenting with PostGIS, and here's what I've noticed:
Suppose I have a table defined as follows:
CREATE TABLE IF NOT EXISTS geomtest (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
geom geometry(POLYGON, 4326) NOT NULL
);
And I add the following polygon:
SRID=4326;POLYGON((0 0,0 10,10 10,10 0,0 0))
If I query the geom column on its own, I get a Hex representation of the geometry. If I instead call ST_AsBinary(geom), I get a binary representation.
However, when I convert both the hex and binary representations to an array of bytes, the results I get are slightly different. The first comment is the result I get by converting the hex into binary, and the next is straight from ST_AsBinary()
//[1 3 0 0 32 230 16 0 0 1 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
//[1 3 0 0 0 1 0 0 0 5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 36 64 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
As you can see, the first 4 bytes are identical; representing whether it's in big or little endian, and the type of geometry (3, in this case a Polygon). The rest of the bytes are the same too. The only difference is there are a few extra bytes added after the first 4.
I wondered if this had to do with representing the projection (SRID=4326), but I haven't found any evidence to that.
If someone could shed some light on this, I'd greatly appreciate it.
I didn't examine the bytes, but I am sure that the difference is the SRID that's not included in the WKB format.
Try st_asewkb instead.
I have a folder with pictures. For each picture, I want to take the maximum value and add it to a new matrix (I created a zeros-matrix, so the zeroes will be replaced with the new values).
This is my code:
function handles = original(hObject, eventdata, handles)
handles.weed=handles.selected;
pic=imread(handles.me);
handles.pic=pic;
axes(handles.axes1)
imshow(pic);
num=max(pic(:))
zeroMat = zeros(1,70);
handles.zeroMat = zeroMat;
for i =1:3
if zeroMat(1,i)~= 0;
i=i+1
else
zeroMat(1,i)=num
break
end
end
zeroMat(1,i)=num
Every time I select a new picture, the zeromat restarts itself to a new zeros-matrix. I know why it happens, but unfortunately I don't know how to overcome it.
This is the output:
pic1:
zeroMat =
Columns 1 through 20
255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 21 through 40
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 41 through 60
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 61 through 70
0 0 0 0 0 0 0 0 0 0
pic2:
Columns 1 through 20
203 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 21 through 40
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 41 through 60
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Columns 61 through 70
0 0 0 0 0 0 0 0 0 0
I can't tell how this function is being invoked, so can't advice how to change up the logic. A rough fix could be to include the line
if ~isfield(handles,'zeroMat')
handles.zeroMat = zeros(1,70);
end % if
which should create handles.zeroMat the first time the function is run. You could then do something like
firstNonzero = find(handles.zeroMat > 0, 1, 'first'); % 'first' not needed, default
handles.zeroMat(firstNonzero) = max(pic(:));
I am new to matlab coding and I would like to know how to plot a tour visiting all points in a minimum spanning tree (yes, TSP/TSM). I was given a set of points a matrix of 20x2 and I was able to find out the MST of these points and I need help figuring out how to plan a tour of these points of minimum possible distance?
my adj matrix for the MST is,
X_st =
0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0
1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 0 1
0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0
0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0
0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0
0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0
1 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0 0 1 0 1 0 0 0 1 0 0 0 0
0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Obtained from kruskal algorithm to plot a MST of a complete graph.
My, neighbouring weighted matrix obtained from kruskal function is,
1 3
7 17
5 20
6 14
1 17
6 20
16 19
2 14
7 11
6 18
12 19
14 16
10 19
8 11
2 8
3 15
9 18
4 19
13 15
Any guidance would be much appreciated.
once you have extracted the points for the MST using krushkals algorithm u need to use f=figure then for each (x,y) point it has to be like f = f + plot(x1,y1,x2,y2,[options]) plot and the plot code should be surrounded by hold on hold off please let me know if the answer was helpful the complete snippet will be like
f = figure;
hold on
f = f + plot(x1,y1,x2,y2) //put this in a loop for all points
hold off
I have a matrix (A) in the form of (much larger in reality):
205 204 201
202 208 202
How can I tally the co-incidence of numbers on a column-by-column basis and then output this to a matrix?
I'd want the final matrix to run from min(A):max(A) (or be able to specify a specific range) across the top and down the side and for it to tally co-incidences of numbers in each column. Using the above example:
200 201 202 203 204 205 206 207 208
200 0 0 0 0 0 0 0 0 0
201 0 0 1 0 0 0 0 0 0
202 0 0 0 0 0 1 0 0 0
203 0 0 0 0 0 0 0 0 0
204 0 0 0 0 0 0 0 0 1
205 0 0 0 0 0 0 0 0 0
206 0 0 0 0 0 0 0 0 0
207 0 0 0 0 0 0 0 0 0
208 0 0 0 0 0 0 0 0 0
(Matrix labels are not required)
Two important points: The tallying needs to be non-duplicating and occur in numerical order. For example a column containing:
205
202
Will tally this as a 202 occurring with 205 (as shown in the above matrix) but NOT 205 with 202 - the duplicate reciprocal. When deciding what number to use as the reference, it should be the smallest.
EDIT:
sparse to the rescue!
Let your data and desired range be defined as
A = [ 205 204 201
202 208 202 ]; %// data. Two-row matrix
limits = [200 208]; %// desired range. It needn't include all values of A
Then
lim1 = limits(1)-1;
s = limits(2)-lim1;
cols = all((A>=limits(1)) & (A<=limits(2)), 1);
B = sort(A(:,cols), 1, 'descend')-lim1;
R = full(sparse(B(2,:), B(1,:), 1, s, s));
gives
R =
0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Alternatively, you can dispense with sort and use matrix addition followed by triu to obtain the same result (possibly faster):
lim1 = limits(1)-1;
s = limits(2)-lim1;
cols = all( (A>=limits(1)) & (A<=limits(2)) , 1);
R = full(sparse(A(2,cols)-lim1, A(1,cols)-lim1, 1, s, s));
R = triu(R + R.');
Both approaches handle repeated columns (up to sorting), correctly increasing their tally. For example,
A = [205 204 201
201 208 205]
gives
R =
0 0 0 0 0 0 0 0 0
0 0 0 0 0 2 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
See if this is what you were after -
range1 = 200:208 %// Set the range
A = A(:,all(A>=min(range1)) & all(A<=max(range1))) %// select A with columns
%// that fall within range1
A_off = A-range1(1)+1 %// Get the offsetted indices from A
A_off_sort = sort(A_off,1) %// sort offset indices to satisfy "smallest" criteria
out = zeros(numel(range1)); %// storage for output matrix
idx = sub2ind(size(out),A_off_sort(1,:),A_off_sort(2,:)) %// get the indices to be set
unqidx = unique(idx)
out(unqidx) = histc(idx,unqidx) %// set coincidences
With
A = [205 204 201
201 208 205]
this gets -
out =
0 0 0 0 0 0 0 0 0
0 0 0 0 0 2 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
Few performance-oriented tricks could be used here -
I. Replace
out = zeros(numel(range1));
with
out(numel(range1),numel(range1)) = 0;
II. Replace
idx = sub2ind(size(out),A_off_sort(1,:),A_off_sort(2,:))
with
idx = (A_off_sort(2,:)-1)*numel(range1)+A_off_sort(1,:)
What about a solution using accumarray? I would first sort each column independently, then use the first row as first dimension into the final accumulation matrix, then the second row as the second dimension into the final accumulation matrix. Something like:
limits = 200:208;
A = A(:,all(A>=min(limits)) & all(A<=max(limits))); %// Borrowed from Divakar
%// Sort the columns individually and bring down to 1-indexing
B = sort(A, 1) - limits(1) + 1;
%// Create co-occurrence matrix
C = accumarray(B.', 1, [numel(limits) numel(limits)]);
With:
A = [205 204 201
202 208 202]
This is the output:
C =
0 0 0 0 0 0 0 0 0
0 0 1 0 0 0 0 0 0
0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
With duplicates (borrowed from Luis Mendo):
A = [205 204 201
201 208 205]
Output:
C =
0 0 0 0 0 0 0 0 0
0 0 0 0 0 2 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0