As the title says, I want to covert a line(or any equation) to 2D matrix.
For example: If I have a line equation y = x, then I want it to be like:
0 0 0 0 0 1
0 0 0 0 1 0
0 0 0 1 0 0
0 0 1 0 0 0
0 1 0 0 0 0
1 0 0 0 0 0
and the length of rows and columns can be variable.
Is there a function or method to implement that?
use meshgrid to get x-y grids:
% set resolution parameters
xmin = 1;
xmax = 100;
dx = 0.1;
ymin = 1;
ymax = 100;
dy = 0.1;
% set x-y grid
[xg, yg] = meshgrid(xmin:dx:xmax, ymin:dy:ymax);
% define your function
f = #(x) (x - 30).^2;
% apply it on the x grid and get close y values
D = abs(f(xg) - yg);
bw = D <= 1;
figure;
imshow(bw);
% flip y axis
set(gca,'YDir','normal')
you get:
and then you can further dilate/erode/skeletonize the output
Given x and y coordinates, how to fill in a matrix with those coordinates? As it is said, just do it in a for loop, or use the "sub2ind" function.
% x,y coordinates
x=0:.01:30;
y=10*sin(2*pi*.1*x);
% add offset so that (x,y)-coordinates are always positive
x=x+abs(min(x))+1;
y=y+abs(min(y))+1;
figure,plot(x,y,'.');axis tight
x=ceil(x); y=ceil(y);
im=zeros(max(y),max(x));
ind=sub2ind(size(im),y,x);
im(ind)=1;
figure,imagesc(im),axis image, axis xy;colormap gray;axis tight
xlabel('x'); ylabel('y')
Why not doing it on your own? You loop through all x-coordinates of the matrix that you (probably scaled) use as the x for your function and get an y out, that you (probably scaled) can round and then use as a y coordinate for your matrix to set the 1.
Related
I created random connectivity information matrix. From that I have plotted x,y and z axis points in 3D graph .Now I just want to apply the zaxis values in the corresponding connectivity such that where ever 1 is present in connectivity it should be multiplied by corresponding zaxis values (eg: if in conn matrix (1,3)place =1 then it should take particular zaxis values and multiply). But I getting the same values for all the places. Suggestions.
%Conncectivity Matrix
success = 0;
n = input('Enter the No. of Nodes'); %size of matrix
k = input('Enter the max connectivity'); %maximal number of 1s
p = 0.5;
Result_Matrix = zeros(n,n);
while (success == 0)
Result_Matrix = (rand(n,n) < p);
Result_Matrix(logical(eye(n))) = 0;
Result_Matrix = max(Result_Matrix, Result_Matrix');
s = sum(Result_Matrix,1);
success = 1;
if min(s) == 0
success = 0; p = p*2; % too few 1s, increase p
end
if max(s) > k
success = 0; p = p/2; % too many 1s, decrease p
end
end
m=Result_Matrix;
conn_mat=m;
disp('connection matrix');
disp(m);
[r,c] = find(m);
A = [r,c]
%3D-GRAPH
PlotSizex=100;
PlotSizey=100;
PlotSizez=-100;
x=PlotSizex*rand(1,n)
y=PlotSizey*rand(1,n)
z=PlotSizez*rand(1,n)
plot3(x(A).', y(A).',z(A).', 'O-')
%Zaxis values multiply with Connectivity
d=zeros(n,n);
z % values of zaxis
for i=1:n
for j=i+1:n
d(i,j)= z(i);
d(j,i)=d(i,j);
end
end
New matrix= d.*m %d is zaxis values and m is connectivity matrix.
I do obtain different values in new_matrix:
new_matrix =
0 -63.4303 -63.4303 0 0
-63.4303 0 0 -23.9408 0
-63.4303 0 0 -24.5725 0
0 -23.9408 -24.5725 0 -76.5436
0 0 0 -76.5436 0
My connection matrix is:
connection matrix
0 1 1 0 0
1 0 0 1 0
1 0 0 1 0
0 1 1 0 1
0 0 0 1 0
and z values are:
z =
-63.4303 -23.9408 -24.5725 -76.5436 -86.3677
I find it strange to multiply the elements in your connection matrix with a single z value, because each element in the connection matrix is related to two points in space (and thus two z values). So, it would make more sense to use the following:
for i=1:n
for j=i:n
d(i,j)= z(i)*z(j); % or another combination of z(i) and z(j)
d(j,i)=d(i,j);
end
end
I would like to generate a 3D binary mask which represents an ellipsoid with centers xc,yc,zc and radiuces xr,yr,zr.
I noticed that the function ellipsoid generates a mesh of points given these parameters. However, I want the data to be represented by a binary matrix (in my case, of size [100,100,100]), and not a mesh.
My Parameters are:
mask = zeros(100,100,100);
xc = 50; yc = 50; zc = 50;
xr = 15; yr = 15; zr = 15;
Thanks in advance!
To generate a binary mask of shapes which can use an equation you can follow the steps:
Generate a mesh (with ndgrid). Make sure the domain limits includes the volume/surface mask, and choose the mesh resolution according to your needs.
Use the volume/surface equation to generate a binary mask, by doing a simple logical comparison of the coordinates with the equation.
Simple 2D example:
Let's define a simple ellipse (in 2D).
%% // Simple 2D example
xc = 5 ; yc = 6 ; %// ellipse center = (5,6)
xr = 3 ; yr = 2 ; %// ellipse radiuses
xbase = linspace(0,10,11) ; %// temporary variable used to send to "ndgrid"
[xm,ym] = ndgrid( xbase , xbase ) ; %// generate base mesh
mask = ( ((xm-xc).^2/(xr.^2)) + ((ym-yc).^2/(yr.^2)) <= 1 ) %// get binary mask
Gives you the binary mask:
mask =
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 1 1 1 0 0 0
0 0 0 0 0 1 1 1 0 0 0
0 0 0 0 1 1 1 1 1 0 0
0 0 0 0 0 1 1 1 0 0 0
0 0 0 0 0 1 1 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 0 0 0 0 0 0
Granted you can hardly recognise an ellipse in the mask but I kept the resolution low to be able to display it as text. You can easily increase the resolution by defining a finer mesh.
3D Ellipsoid:
Well, it's exactly the same method, except we are going to add one dimension to the mesh, and use the 3D equation of the ellipsoid. So for your precise case:
%% // 3D ellipsoid
xc = 50; yc = 50; zc = 50;
xr = 15; yr = 15; zr = 15;
xbase = linspace(1,100,100) ;
[xm,ym,zm] = ndgrid( xbase , xbase , xbase) ;
mask = ( ((xm-xc).^2/(xr.^2)) + ((ym-yc).^2/(yr.^2)) + ((zm-zc).^2/(zr.^2)) <= 1 ) ;
I cannot show you a text output with these kind of 3D arrays, but your mask is now a 3D logical array containing true inside the ellipsoid and false elsewhere.
If I understood your question correctly, this should work:
mask = zeros(100, 100, 100);
%//your ellipsoid properties
xc = 50; yc = 50; zc = 50;
xr = 15; yr = 15; zr = 15;
for x=1:100
for y=1:100
for z=1:100
if ( ((x-xc)/xr)*((x-xc)/xr) + ((y-yc)/yr)*((y-yc)/yr) + ((z-zc)/zr)*((z-zc)/zr) < 1 )
mask(x,y,z) = 1; %//set elements within ellipsoid to 1
end
end
end
end
You can do this with Heaviside functions, this probably needs a bit more thought to get exactly what you want but as a start,
close all
clear all
%Setup Domain
maxdomain = 100;
mindomain = 0.;
step = 1.0;
X = mindomain:step:maxdomain;
Y = mindomain:step:maxdomain;
Z = mindomain:step:maxdomain;
[x,y,z] = meshgrid(X,Y,Z);
xc = 50; yc = 50; zc = 50;
xr = 15; yr = 15; zr = 15;
r2 = xr/2;
r = sqrt((x-xc).^2/xr + (y-yc).^2/yr + (z-zc).^2/zr);
u = heaviside(r-r2);
%Plot Surface of sphere
p = patch(isosurface(x,y,z,u));
isonormals(x,y,z,u,p)
set(p,'FaceColor','red','EdgeColor','none');
camlight ; alpha(0.6);
xlabel('x'); ylabel('y'); zlabel('z');
daspect([1,1,1]); view(3);
axis tight; camlight; camlight(-80,-10);
lighting gouraud;
which for your values above looks like,
and forxr = 15; yr = 45; zr = 15;,
The Heaviside function can be defined using,
function [out]=heaviside(x)
out=0.5.*(sign(x)+1.0);
end
if the Symbolic Math Toolbox is not available.
Show mask by meshc function
z = [0 0 0 0;0 1 1 0;0 0 0 0];
meshc(z)
Output is:
Desired output:
There is a lot of guessing on my side, and I guess you want something like this:
%// data
z = [0 0 0 0;0 1 1 0;0 0 0 0];
%// grid
[n,m] = size(z);
[x,y] = ndgrid(1:n,1:m);
%// finer grid
[xq, yq] = ndgrid(linspace(1,n,100),linspace(1,m,100));
%// interpolation
F = griddedInterpolant(x, y, z, 'cubic')
zq = F(xq, yq);
%// interpolated plot
figure(1)
meshc(xq,yq,zq)
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 been trying to label the edges of an undirected graph, also, i am using this matgraph tool! I succeeded in making a graph, i just want to assign weights to it... Please help!!
Here is what i tried,
clear all;
close all;
clc;
g=graph;
for k=1:6
add(g,k,k+1)
add(g,1,4)
add(g,5,7)
end
ndraw(g);
x=rand(1,1);
y=rand(1,1)
A =[0 x 0 x 0 0 0;
x 0 x 0 0 0 0;
0 x 0 x 0 0 0;
x 0 x 0 x 0 0;
0 0 0 y 0 x x;
0 0 0 0 x 0 x;
0 0 0 0 x x 0]
If I understood you correctly you can add this code after the code you wrote:
% get line info from the figure
lineH = findobj(gca, 'type', 'line');
xData = cell2mat(get(lineH, 'xdata')); % get x-data
yData = cell2mat(get(lineH, 'ydata')); % get y-data
% if an edge is between (x1,y1)<->(x2,y2), place a label at
% the center of the line, i.e. (x1+x2)/2 (y1+y2)/2 etc
labelposx=mean(xData');
labelposy=mean(yData');
% generate some random weights vector
weights=randi(21,length(labelposx),1);
% plot the weights on top of the figure
text(labelposx,labelposy,mat2cell(weights), 'HorizontalAlignment','center',...
'BackgroundColor',[.7 .9 .7]);