Matlab: creating a plot of a variable depending on one parameter - matlab

I have a 3x3 matrix in which some elements depend on a parameter called x which can attain values between 0 and 1.
I multiply the inverse of this matrix by a 3x1 vector, and I therefore obtain a 3x1 vector called optimal taxesin which each element depends on x.
I then create a variable called reinf which is equal to the first element of optimal taxes minus the other two elements.
I would like to plot the values of reinf depending on the parameter x in a range between 0 and 1.
I have tried used the following code, where H_V1x is the 3x3 matrix.
syms x positive real
optimal_taxes1x = inv(H_V1x)*inc_cons
reinf1x = optimal_taxes1x(1,1) - optimal_taxes1x(2,1) - optimal_taxes1x(3,1)
However when I run the last line it says I get the error "Index in position 1 exceeds array bounds (must not exceed 1)."
which is surprising since optimal_taxes1x is a 3x1 syms vector.
How could I solve this problem and create the plot?
Thank you
As requested, here are the matrix and the vector:
H_V1x = [ -5.9280e-07, 3.7066e-07,2.2215e-07; 3.7066e-07,(1537*x)/258614388 - 6736739427183417/2361183241434822606848,-(1537*x)/258614388;2.2215e-07,-(1537*x)/258614388,(1537*x)/258614388 - 6645950193052613/4722366482869645213696];
inc_cons = [0.823603356515493,
-0.219495869657492,
-0.0752767166225879]

I can run the code with no problem in 2016b. Here is my code:
clear variables; clc; close all
syms x real
assume(x > 0)
H_V1x = [ -5.9280e-07, 3.7066e-07,2.2215e-07; 3.7066e-07,(1537*x)/258614388 - 6736739427183417/2361183241434822606848,-(1537*x)/258614388;2.2215e-07,-(1537*x)/258614388,(1537*x)/258614388 - 6645950193052613/4722366482869645213696];
inc_cons = [0.823603356515493;
-0.219495869657492;
-0.0752767166225879]
optimal_taxes1x = inv(H_V1x)*inc_cons;
reinf1x = optimal_taxes1x(1,1) - optimal_taxes1x(2,1) - optimal_taxes1x(3,1)
x=0:0.02:1;
plot(x, subs(reinf1x))
And this is the plot result:
reinf1x =
(1040053994187210661864407040*(495592707753015189241062869767647395840x - 89156821447333517620228626174465662937))/(747(2815381160608336475815926275042762431495254208116923826176x - 445811259036595286456502337342890549874079624653932849201)) - (460318575875822254261534720(11210459727128231750210203484711869743104x - 2497571854516097684109652531721363759511))/(30627(2815381160608336475815926275042762431495254208116923826176x - 445811259036595286456502337342890549874079624653932849201)) - (42633524607347156989247488(162551666043359360378047950528322111275008x - 3799129388554029548248573922328032752851))/(30627(2815381160608336475815926275042762431495254208116923826176x - 445811259036595286456502337342890549874079624653932849201)) - (7258277284170644693450752(81275833021679680189023975264161055637504x - 35848130569758668835608493944994001436187))/(10209(2815381160608336475815926275042762431495254208116923826176x - 445811259036595286456502337342890549874079624653932849201)) + (402307845408630815045189632(495592707753015189241062869767647395840x - 73377230813429148255176338884456817971))/(249(2815381160608336475815926275042762431495254208116923826176x - 445811259036595286456502337342890549874079624653932849201)) - (7623637334217303404343984128(18254049353170950597767874357190897696768x - 2894673088146242304784596506648828329737))/(30627(2815381160608336475815926275042762431495254208116923826176*x - 445811259036595286456502337342890549874079624653932849201))

Related

How to determine eigenvalues for a matrix with one symbolic variable?

I am trying to find the eigenvalues of a matrix in which all the elements contain a symbolic variable 'w' in MATLAB. When using the eig function with a small matrix, for example 5x5, Matlab returns the answer in short time but for my case with 75x75 matrix there is no result even in a day.
For example, below are few elements of the matrix Wlbda_M from the first column:
(19532474732762832754894582760668901397*w^2)/2126764793255865396646091296448551321600 - 77109107202987061502201190106698982274469935551/713623846352979940529142984724747568191373312
(6440060630888147986147319697353091797*w^2)/1329227995784915872903807060280344576000 - 441341856681457924546721557987419671668917039305/2854495385411919762116571938898990272765493248
(7953990508504513613228552266816516309*w^2)/5316911983139663491615228241121378304000 - 993090640147003256075497986972973808296498643729/5708990770823839524233143877797980545530986496
- (7271843221507172811594735115331301459*w^2)/10633823966279326983230456482242756608000 - 28245878827613205686092124283481825395002044322201/182687704666362864775460604089535377456991567872
- (2565513214405907267970563627562325279*w^2)/5316911983139663491615228241121378304000 - 1233745715247789216300571967285405031051699895955/11417981541647679048466287755595961091061972992
(12880121261776288141689407588821663767*w^2)/2658455991569831745807614120560689152000 - 14122939413806629582719652926085181680332441367949/91343852333181432387730302044767688728495783936
(5577903399461689618556599053897735153*w^2)/1329227995784915872903807060280344576000 - 22284793286830406982057530040409776590196357698433/91343852333181432387730302044767688728495783936
(2974250232197768416038223182987456933*w^2)/2658455991569831745807614120560689152000 - 1611348533537140336395461230689378256028220143909/5708990770823839524233143877797980545530986496
- (9119615798509512940063368481418612157*w^2)/10633823966279326983230456482242756608000 - 11142396643415184739757301830243256383084598479265/45671926166590716193865151022383844364247891968
- (3080691908882112403687298624070229553*w^2)/5316911983139663491615228241121378304000 - 110335464170364107314736252830024866033040200773/713623846352979940529142984724747568191373312
To determine the eigenvalues I used the following command.
lbda_V=eig(Wlbda_M);

Matlab gives no result when I use the integral function

When trying to calculate the Integral of two variables, I got nothing!
Here is the code:
syms x;
a=0.4;
theta=(9 - 4*x*(5*x - 141/25))^(1/2)/2 - 3/2;
theta_prime=-(40*x - 564/25)/(4*(9 - 4*x*(5*x - 141/25))^(1/2));
g=(1/theta)*theta_prime
s=(1+a*(theta-1))*(g)^2
sgen = int(s,x,0.1,1) %x=0.1:0.1: 1
What was my mistake?
It supposed to be one value, such as '4.86'.
Please advise.
sgen is a symbolic object representing the integral of your function s. You can cast it to double to obtain a numerical value for your integral:
syms x;
a=0.4;
theta=(9 - 4*x*(5*x - 141/25))^(1/2)/2 - 3/2;
theta_prime=-(40*x - 564/25)/(4*(9 - 4*x*(5*x - 141/25))^(1/2));
g=(1/theta)*theta_prime;
s=(1+a*(theta-1))*(g)^2;
sgen = double(int(s,x,0.1,1)) % returns 4.8694
But if you're not interested in the symbolic equation for the integral, there really is no point in using the symbolic toolbox for this. It is much faster to compute the integral numerically. One way to do so is to create a function s(x) and then use integral to find the numerical integration. Do note that s(x) must be vectorized on the x variable for this to work (integral will call it with a vector of x values to save time). For vectorized computation, it is necessary to add dots in front of some of the *, / and ^ operators. This is the result:
a = 0.4;
theta = #(x) (9 - 4*x.*(5*x - 141/25)).^(1/2)/2 - 3/2;
theta_prime = #(x) -(40*x - 564/25)./(4*(9 - 4*x.*(5*x - 141/25)).^(1/2));
g = #(x) (1./theta(x)).*theta_prime(x);
s = #(x) (1+a*(theta(x)-1)).*g(x).^2;
sgen = integral(s,0.1,1.0) % returns 4.8694

How to find a condition to choose a specific number in the plot - matlab

i want a function that gives me every time i change g, the value of the select point the the data plot. How can i do that ?
function help = b0calc
s=0.319;
R= [0.319/0.6] ;
bb1 = linspace(0.01,10,600);
gg=0.5; % gg = g for many values of g
f2 = #(r,b,g) 1./(r.^2.*sqrt(1 - (b./r).^2 - (g^-2)*((2/15)*(s/R)^9 *(1./(r - 1).^9 - 1./(r + 1).^9 - 9./(8* r).*(1./(r - 1).^8 - 1./(r + 1).^8)) - (s/(R))^3 *(1./(r -1).^3 - 1./(r + 1).^3 - 3./(2* r).* (1./(r - 1).^2 - 1./(r + 1).^2)))));
X_scalar_b_scalar_g = #(b,g)real(pi - 2*b*quadgk(#(r)f2(r,b,g),rmin(g,b,R),Inf,'AbsTol',1e-4,'RelTol',1e-4,'MaxIntervalCount',5000));
for j=1:length(bb1)
Xg(j)=X_scalar_b_scalar_g(bb1(j),gg);
end
figure(1);
plot(bb1,Xg)
end
function r = rmin(g,b,R)
s=0.319;
f1 = #(r) 1 - (b./r).^2 - (g^-2)*((2/15)*(s/R)^9 *(1./(r - 1).^9 - 1./(r + 1).^9 - 9./(8*r).*(1./(r - 1).^8 - 1./(r + 1).^8)) -(s/R)^3 *(1./(r-1).^3 - 1./(r+1).^3 - 3./(2*r).*(1./(r-1).^2 - 1./(r+1).^2)));
r = fzero(f1,[1.0000001,9999999999999999999999999999999999999999999]);
end
for every change of gg=g , the graphic has a singularity in y coordinate ... i want the x value that gives this singularity every time.
You can use the sign change in the first derivative to track it
function [sng_pos, sng_val, dydx] = first_derivative(x,y)
% First derivative - first order forward difference
h = x(2)-x(1);
dydx = diff(y)/h;
% Find sign change then lowest function value in that range
ing = find(dydx <= 0);
sng_ind = find(y==min(y(max(ing)),y(max(ing)+1)));
sng_pos = x(sng_ind);
sng_val = y(sng_ind);
end
This assumes that the singularity is present in the first minima - global or local. It treats the singularity as the lowest function value between the two derivative values with opposite signs.
Note that this uses a first order, forward difference scheme - better results can be obtained with higher order schemes and a refined grid. Second order centered scheme may already be significantly superior.
Example of usage in the main function:
[s_pos, s_val, dydx] = first_derivative(bb1,Xg);
fprintf('Position of singularity: %f and value: %f \n', s_pos, s_val)
figure(2)
plot(bb1(1:end-1), dydx)
title('First derivative')

Calculate roots of characteristic equation of symbolic matrix

I have 3 data matrices A,B,C (all 3x3), with which I use the following code to calculate roots of D(p)X = 0
syms p
D = A + B*p + C*(p^2)
solP = double(solve(det(D)))
From this, I get 6 values for solP. But when I try substituting it back into the symbolic matrix D, as follows, I get non-zero values of det(D) sometimes
for i = 1:6
p = solP(i)
det(double(subs(D)) % Should be zero always as we are substituting roots
end
Please help me understand this behaviour.
EDIT ::
Example :
A =
1.0e+11 *
4.8976 7.0936 6.7970
4.4559 7.5469 6.5510
6.4631 2.7603 1.6261
B =
1.0e+11 *
3.9223 7.0605 0.4617
6.5548 0.3183 0.9713
1.7119 2.7692 8.2346
C =
1.0e+11 *
6.9483 0.3445 7.6552
3.1710 4.3874 7.9520
9.5022 3.8156 1.8687
solP =
0.1061 + 0.0000i
1.5311 + 0.0000i
-0.3432 + 0.9356i
-0.3432 - 0.9356i
0.4228 - 0.5465i
0.4228 + 0.5465i
det(D) =
2.2143e+19
-5.4911e+20
-8.6415e+19 + 4.5024e+19i
-8.6415e+19 - 4.5024e+19i
-1.4547e+19 + 9.1135e+19i
-1.4547e+19 - 9.1135e+19i
The problem is related to the relative accuracy of floating point values, typically 1e-16.
The input matrices are of the order 1e+11 - 1e+12, the solution is of the order 1e+0, so the elements of D are also of the order 1e+11 - 1e+12. To calculate a determinant of a 3x3 matrix, one should take products of three matrix elements and add/subtract them. So, each term is of the order of 1e+33 - 1e+36. If you subtract such a values to obtain the determinant, the expected accuracy is in the order of 1e+17 - 1e+20. Indeed, this corresponds with the values you get. Given the relative accuracy, you are not able to reach further to zero.
Note that if you scale your input matrices, i.e. divide it by 1e+11, the solutions are indeed the same, but the determinants are probably more what you would expect.

Use bsxfun function to find Max entry of matrix

For a given set of q and r, I want to find the maximum of Tp=x * log(1 + (q* r (1 - 1/y)* (2/x - y))/(1 + r* (1 - 1/y) + q* (2/x - y))) for x in (0,1) and y in (1,2).
I can calculate them using two for loops, but when I use really small steps sizes for x and y, e.g., 0.00001, this takes a long time. But I know that if I get Tp as a matrix for all x and y, i.e., Tp is matrix of size length(x) x length(y), it may easier and faster. As I read, bsxfun(#times,..) may be helped, but I don't know how I can apply it in my problem.
Here is what I have tried, but it doesn't give correct output. Here I used larger step size for understanding. Can someone fix this issue in my code?
function maxTp
hvar=0.1:0.2:1;
hl=length(hvar);
q=hvar; r=hvar;
stepx=0.2;stepy=0.1;
y0=1.1; x0=0.1;
x=x0:stepx:1; y=y0:stepy:2;
ox = zeros(hl,1); oy = zeros(hl,1);
MaxTp = zeros(hl,1);
for k=1:hl
Tp = bsxfun(#times,log(1 + (q(k)*r(k)*(1 - 1./y).*(2./x - y))./(1 + r(k)*(1 - 1./y) + q(k)*(2./x - y))).',x);
MaxTp(k,1)=max(max(Tp));
[p, q] = ind2sub(size(Tp),find(Tp==MaxTp(k,1)));
ox(k,1)=x0+(p-1)*stepx;
oy(k,1)=y0+(q-1)*stepy;
end
Try this inside your for loop:
Tp = bsxfun(#(x,y) log(1+(q(k)*r(k)*(1 - 1./y).*(2./x - y))./(1 + r(k)*(1 - 1./y) + q(k)*(2./x - y)))*x,x,y.'); %\\'
MaxTp(k,1)=max(max(Tp));
[p2, q2] = ind2sub(size(Tp),find(Tp==MaxTp(k,1)));
ox(k,1)=x0+(p2-1)*stepx;
oy(k,1)=y0+(q2-1)*stepy;
I changed the bsxfun to do the calculation in the function part rather than the vector inputs, and you were also overwriting p and q as the results of ind2sub.
You can also use fmincon (be aware the maximisation means we need to minimise the negative of the function). The following code goes inside the for loop:
f=#(x,y) log(1+(q(k)*r(k)*(1 - 1./y).*(2./x - y))./...
(1 + r(k)*(1 - 1./y) + q(k)*(2./x - y)))*x;
o(:,k)=fmincon(#(x) -f(x(1),x(2)),[0.5;0.5],[],[],[],[],[0;1],[1;2]);
o(:,k) gives the x and y coordinates of the maximum, I think it's different to your ox and oy variables though.