Matlab Code for Linear System by Central Difference Method - matlab

I have a linear system Ay = b, which is created by matrix looks like this:
Here attempt to find the curves based on the matrix in the image description:
n = 10;
x0 = 0;
xn = 1;
h = 1/n;
y0 = 0;
y1 = 0;
x = zeros(1:n-1);
for i = 1:n-1;
x(i) = i*h
end
A =zeros(n-1);
for j = 1:n-2;
A(j,j+1) = (1+h/2);
A(j,j) = (h*exp(x(j))-2);
A(j+1,j) = (1-h/2);
end
A(n-1,n-1) = (h*exp(x(n-1))-2);
b = zeros(1,n-1); %Right-hand side vector
for i = 1:n-1
b(i)=h^2*((exp(x(i))-pi^2)*sin(pi*x(i))+pi*cos(pi*x(i)));
end
b=b';
y = zeros(1,n-1);
y = inv(A)*b % Solving for y
figure
plot(x,y,x,sin(x))
This is code that I create but the curves disappear, anyone can help me to check my code?

Related

Swapping fragments of matrices Matlab

I wrote a program implementing Gaussian Elimination with Complete Pivoting:
function x = gecp(A,b)
x = b;
n = length(A);
p = 1:n;
l = b;
for k = 1:n
[i,j] = find(A(k:n,k:n)==max(abs(A(k:n,k:n)),[],'all'));
i = i+k-1;
j = j+k-1;
[A(k,:),A(i,:)] = deal(A(i,:),A(k,:));
[A(:,j),A(:,k)] = deal(A(:,k),A(:,j));
[b(i),b(k)] = deal(b(k),b(i));
[p(k),p(j)] = deal(p(j),p(k));
temp = (k+1):n;
l(temp) = A(temp,k)/A(k,k);
b(temp) = b(temp)-l(temp).*b(k);
A(temp,temp) = A(temp,temp)-l(temp).*A(k,temp);
end
x(n) = b(n)/A(n,n);
for k = (n-1):-1:1
s = 0;
for h = (k+1):n
s = s+A(k,h)*x(h);
end
x(k) = (b(k)-s)/A(k,k);
end
x(p) = x;
And it is called like this:
N = 5; A = randn(N); b = randn(N,1); x = gecp(A,b)
Unfortunately all lines containing deal function (used for swapping rows of columns of matrices), give me following (or similar) error: "Unable to perform assignment because the size of the left side is 1-by-5 and the size of the right side is 0-by-5."
Unfortunately I have no idead why would the width of these vectors be changed to 0 as I wrote excatly the same thing on both sides.

Finding the distribution of '1' in rows/columns from a parity-check matrix

My question this time concerns the obtention of the degree distribution of a LDPC matrix through linear programming, under the following statement:
My code is the following:
function [v] = LP_Irr_LDPC(k,Ebn0)
options = optimoptions('fmincon','Display','iter','Algorithm','interior-point','MaxIter', 4000, 'MaxFunEvals', 70000);
fun = #(v) -sum(v(1:k)./(1:k));
A = [];
b = [];
Aeq = [0, ones(1,k-1)];
beq = 1;
lb = zeros(1,k);
ub = [0, ones(1,k-1)];
nonlcon = #(v)DensEv_SP(v,Ebn0);
l0 = [0 rand(1,k-1)];
l0 = l0./sum(l0);
v = fmincon(fun,l0,A,b,Aeq,beq,lb,ub,nonlcon,options)
end
Definition of nonlinear constraints:
function [c, ceq] = DensEv_SP(v,Ebn0)
% It is also needed to modify this function, as you cannot pass parameters from others to it.
h = [0 rand(1,19)];
h = h./sum(h); % This is where h comes from
syms x;
X = x.^(0:(length(h)-1));
R = h*transpose(X);
ebn0 = 10^(Ebn0/10);
Rm = 1;
LLR = (-50:50);
p03 = 0.3;
LLR03 = log((1-p03)/p03);
r03 = 1 - p03;
noise03 = (2*r03*Rm*ebn0)^-1;
pf03 = normpdf(LLR, LLR03, noise03);
sumpf03 = sum(pf03(1:length(pf03)/2));
divisions = 100;
Aj = zeros(1, divisions);
rho = zeros(1, divisions);
xj = zeros(1, divisions);
k = 10; % Length(v) -> Same value as in 'Complete.m'
for j=1:1:divisions
xj(j) = sumpf03*j/divisions;
rho(j) = subs(R,x,1-xj(j));
Aj(j) = 1 - rho(j);
end
c = zeros(1, length(xj));
lambda = zeros(1, length(Aj));
for j = 1:1:length(xj)
lambda(j) = sum(v(2:k).*(Aj(j).^(1:(k-1))));
c(j) = sumpf03*lambda(j) - xj(j);
end
save Almacen
ceq = [];
%ceq = sum(v)-1;
end
This question is linked to the one posted here. My problem is that I need that each element from vectors v and h resulting from this optimization problem is a fraction of x/N and x/(N(1-r) respectively.
How could I ensure that condition without losing convergence capability?
I came up with one possible solution, at least for vector h, within the function DensEv_SP:
function [c, ceq] = DensEv_SP(v,Ebn0)
% It is also needed to modify this function, as you cannot pass parameters from others to it.
k = 10; % Same as in Complete.m, desired sum of h
M = 19; % Number of integers
h = [0 diff([0,sort(randperm(k+M-1,M-1)),k+M])-ones(1,M)];
h = h./sum(h);
syms x;
X = x.^(0:(length(h)-1));
R = h*transpose(X);
ebn0 = 10^(Ebn0/10);
Rm = 1;
LLR = (-50:50);
p03 = 0.3;
LLR03 = log((1-p03)/p03);
r03 = 1 - p03;
noise03 = (2*r03*Rm*ebn0)^-1;
pf03 = normpdf(LLR, LLR03, noise03);
sumpf03 = sum(pf03(1:length(pf03)/2));
divisions = 100;
Aj = zeros(1, divisions);
rho = zeros(1, divisions);
xj = zeros(1, divisions);
N = 20; % Length(v) -> Same value as in 'Complete.m'
for j=1:1:divisions
xj(j) = sumpf03*j/divisions;
rho(j) = subs(R,x,1-xj(j));
Aj(j) = 1 - rho(j);
end
c = zeros(1, length(xj));
lambda = zeros(1, length(Aj));
for j = 1:1:length(xj)
lambda(j) = sum(v(2:k).*(Aj(j).^(1:(k-1))));
c(j) = sumpf03*lambda(j) - xj(j);
end
save Almacen
ceq = (N*v)-floor(N*v);
%ceq = sum(v)-1;
end
As above stated, there is no longer any problem with vector h; nevertheless the way I defined ceq value seemed to be insufficient to make the optimization work out (the problems with v have not diminished at all). Does anybody know how to find the solution?

Solving a system of 4 second order ODE's in matlab using ODE45

I need to solve this system of second order equations using ODE45 in matlab
I'm only familiar with using ODE45 with maybe one or two equations but not this many
Here is what I have but I'm not sure how to correct it:
function second_oder_ode
t = 0:0.001:3; % time scale
theta = pi/2;
phi = 0;
initial_t = 0;
initial_dtds = 0;
initial_r = 0;
initial_drds = 0;
initial_theta = 0;
initial_dthetads = 0;
initial_phi = 0;
initial_dphids = 0;
[t,x] = ode45( #(t,y) rhs(t,y,theta,phi), t, [initial_t initial_dtds initial_r initial_drds initial_theta initial_dthetads initial_phi initial_dphids] );
plot(t,x(:,1));
xlabel('t'); ylabel('r');
%%%%%%%%%%%%%% STATE VECTORS %%%%%%%%%%%%%%%%%%%%%
t = [t, dtds];
r = [r, drds];
theta = [theta, dthetads];
phi = [phi, dphids];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function dxds=rhs(t,r, theta, phi)
dxds_1 = t(2);
dxds_2 = -((2/3)*R0^(2)*((3*H0/(2*cv))^(4/3))*y(1)^(1/3))*(y(4)^(2)+abs(y(3))^(2)*y(6)^(2)+abs(y(3))^(2)*(sin(y(5)))^(2)*y(8)^(2));
dxds_3 = r(2);
dxds_4 = -(4/(3*y(1)))*y(2)*y(4)+abs(y(3))*(y(6)^(2)+(sin(y(5)))^(2)*y(8)^(2));
dxds_5 = theta(2);
dxds_6 = -(2/abs(y(3)))*y(4)*y(6)-(4/(3*y(1)))*y(2)*y(6)+((sin(2*y(5)))*(y(8)^(2))/2);
dxds_7 = phi(2);
dxds_8 = -2*y(8)*((2/(3*y(1)))*y(2)+(cot(y(5)))*y(6)+(1/abs(y(3)))*y(4));
dxdt=[dxdt_1; dxdt_2; dxdt_3; dxdt_4; dxdt_5; dxdt_6; dxdt_7; dxdt_8];
end
end
This isn't a full solution, but is longer than a comment.
You seem to be using t theta and phi each for two purposes.
For example, maybe change the timescale line to use s.
Looking at your odefun, here called rhs, I think it should have 2 arguments.
The first argument should be s (even if it is not used) and the second argument should be a vector input where the values y(1:8) correspond to [t; t_s; r; r_s; theta; theta_s; phi; phi_s].
The expressions for dxds_# should only contain terms of y and no t, r, theta or phi.
You have typos on the line dxdt= which should contain dxds terms.
Below I've made some changes. I've not tested this; I don't have the constants R0, H0 or cv and I think it will be uniformly zero.
Also I've removed the first occurrences of theta and phi. I'm not sure how these are supposed to feature in rhs.
function second_oder_ode
s = 0:0.001:3; % time scale
%theta = pi/2;
%phi = 0;
initial_t = 0;
initial_dtds = 0;
initial_r = 0;
initial_drds = 0;
initial_theta = 0;
initial_dthetads = 0;
initial_phi = 0;
initial_dphids = 0;
y0 = [initial_t, initial_dtds, initial_r, initial_drds, ...
initial_theta, initial_dthetads, initial_phi, initial_dphids];
[s,x] = ode45( #(s,y) rhs(s,y), s, y0);
plot(s,x(:,1));
xlabel('s'); ylabel('t(s)');
%%%%%%%%%%%%%% STATE VECTORS %%%%%%%%%%%%%%%%%%%%%
%t = [t, dtds];
%r = [r, drds];
%theta = [theta, dthetads];
%phi = [phi, dphids];
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function dxds=rhs(s,y)
dxds_1 = y(2);
dxds_2 = -((2/3)*R0^(2)*((3*H0/(2*cv))^(4/3))*y(1)^(1/3))*(y(4)^(2)+abs(y(3))^(2)*y(6)^(2)+abs(y(3))^(2)*(sin(y(5)))^(2)*y(8)^(2));
dxds_3 = y(4);
dxds_4 = -(4/(3*y(1)))*y(2)*y(4)+abs(y(3))*(y(6)^(2)+(sin(y(5)))^(2)*y(8)^(2));
dxds_5 = y(6);
dxds_6 = -(2/abs(y(3)))*y(4)*y(6)-(4/(3*y(1)))*y(2)*y(6)+((sin(2*y(5)))*(y(8)^(2))/2);
dxds_7 = y(8);
dxds_8 = -2*y(8)*((2/(3*y(1)))*y(2)+(cot(y(5)))*y(6)+(1/abs(y(3)))*y(4));
dxds=[dxds_1; dxds_2; dxds_3; dxds_4; dxds_5; dxds_6; dxds_7; dxds_8];
end
end

Function contourf, how i can get the area and centroid of the different objects

I am using contourf function with binary image. I am trouble how i can get the area and centroid of the different surface in the image, need this task to classify the objects.
You need to use the the Contour Matrix output
Here is an example:
function data = ContourInfo(C)
data = [];
if isempty(C)
return
end
k = 1;
j = 1;
while j < size(C,2);
data(k).numxy = C(2,j);
data(k).x = C(1,j+1:j+data(k).numxy);
data(k).y = C(2,j+1:j+data(k).numxy);
data(k).level = C(1,j);
[data(k).centroid(1) data(k).centroid(2) data(k).area] = ...
polycentroid(data(k).x, data(k).y);
data(k).area = polyarea(data(k).x, data(k).y);
data(k).centroid = polycentroid(data(k).x, data(k).y);
j = j + data(k).numxy + 1;
k = k+1;
end
function [x0,y0,a] = polycentroid(x,y)
[m1,n1] = size(x); [m2,n2] = size(y);
n = max(m1,n1);
x = x(:); y = y(:);
x2 = [x(2:n);x(1)];
y2 = [y(2:n);y(1)];
a = 1/2*sum (x.*y2-x2.*y);
x0 = 1/6*sum((x.*y2-x2.*y).*(x+x2))/a;
y0 = 1/6*sum((x.*y2-x2.*y).*(y+y2))/a;
Call as follow:
Z = peaks(20);
[C, h] = contourf(Z,10);
contourData = ContourInfo(C)
disp('Area of contour 1:');
disp(contourData(1).area
disp('Centroid of contour 1:');
disp(contourData(1).centroid);

Finding correct index value for matrix in Matlab using meshgrid

I'm trying to build make a code where an equation is not calculated for some certain values. I have a meshgrid with several values for x and y and I want to include a for loop that will calculate some values for most of the points in the meshgrid but I'm trying to include in that loop a condition that if the points have a specified index, the value will not be calculated. In my second group of for/if loops, I want to say that for all values of i and k (row and column), the value for z and phi are calculated with the exception of the specified i and k values (in the if loop). What I'm doing at the moment is not working...
The error I'm getting is:
The expression to the left of the equals sign is not a valid target for an assignment.
Here is my code at the moment. I'd really appreciate any advice on this! Thanks in advance
U_i = 20;
a = 4;
c = -a*5;
b = a*10;
d = -20;
e = 20;
n = a*10;
[x,y] = meshgrid([c:(b-c)/n:b],[d:(e-d)/n:e]');
for i = 1:length(x)
for k = 1:length(x)
% Zeroing values where cylinder is
if sqrt(x(i,k).^2 + y(i,k).^2) < a
x(i,k) = 0;
y(i,k) = 0;
end
end
end
r = sqrt(x.^2 + y.^2);
theta = atan2(y,x);
z = zeros(length(x));
phi = zeros(length(x));
for i = 1:length(x)
for k = 1:length(x)
if (i > 16 && i < 24 && k > 16 && k <= length(x))
z = 0;
phi = 0;
else
z = U_i.*r.*(1-a^2./r.^2).*sin(theta); % Stream function
phi = U_i*r.*(1+a^2./r.^2).*cos(theta); % Velocity potential
end
end
end
The original code in the question can be rewritten as seen below. Pay attention in the line with ind(17:24,:) since your edit now excludes 24 and you original question included 24.
U_i = 20;
a = 4;
c = -a*5;
b = a*10;
d = -20;
e = 20;
n = a*10;
[x,y] = meshgrid([c:(b-c)/n:b],[d:(e-d)/n:e]');
ind = find(sqrt(x.^2 + y.^2) < a);
x(ind) = 0;
y(ind) = 0;
r = sqrt(x.^2 + y.^2);
theta = atan2(y,x);
ind = true(size(x));
ind(17:24,17:length(x)) = false;
z = zeros(size(x));
phi = zeros(size(x));
z(ind) = U_i.*r(ind).*(1-a^2./r(ind).^2).*sin(theta(ind)); % Stream function
phi(ind) = U_i.*r(ind).*(1+a^2./r(ind).^2).*cos(theta(ind)); % Velocity potential