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);
Related
When trying to use the integral2 function, I get the following warning:
"Integrand function outputs did not match to the required tolerance when the same input values were supplied in two separate calls with different size input matrices. Check that the function is vectorized properly."
My code is:
z1=0; z2=5;
t1=0; t2=10;
a=1:500;
b=linspace(0.15,0.02,length(a));
c=[a;b];
d=4.9e-07;
func = #(z,t) my_func((z + t),c) .* exp(-d.*t);
int_x = integral2(func,z1,z2,t1,t2,'RelTol',1e-3,'AbsTol',1e-3) ./ (z2 - z1);
my_func is:
function out = my_func(z_in,c)
z=reshape(z_in,1,numel(z_in));
for i=1:length(z)
if (z(i)<0.0)
z(i)=0.0;
end
end
expfactor=exp(-z/150);
sB=5.5*0.9*4*expfactor;
mB=0.9*interpolate(c(1,:),c(2,:),z);
out=sB+mB;
out=reshape(out,size(z_in,1),size(z_in,2));
end
z1=0, z2=9.6, t1=0, t2=3000 (i.e. all have the size (1,1)), and I have used element-wise operations, so not sure what the problem is.
When debugging, my_func is called three times, with z and t having different sizes each time (although same as each other; (14,14), (2,3) and (14,14)). When sizes are (14,14), the values of z are unique for each column, but the same for each row (e.g. [3,2,1;3,2,1]), and vice versa for t (e.g. [4,4,4;5,5,5]). But when sizes are (2,3), all values in the z and t matrices are unique. The warning comes after the second and third call.
What could be the reasons for the warning?
Edit: to accommodate the dimension requirements in my_func, I've reshaped z to a vector at the start, then reshaped the output back to matrix at the end, copying a similar function I've seen. But this returns the warning:
"Non-finite result. The integration was unsuccessful. Singularity likely."
Thanks
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))
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
The code is
syms x;
v = #(x) (4 - x^2)^(1/2) - (2 - x)^(1/2)*(x + 2)^(1/2);
ezplot(v(x),[-2,2]);
which produce a plot
Should not v(x)
be zero for every x in [-2,2]?
If the idea is to replace "small" values in the output of your equation with zero, then some sort of if condition on the output data is needed. Unfortunately, you can't add an if to the anonymous function but you can do one of two things: define a standard function (in a program file) or wrap your anonymous function in another. The first way is more straightforward:
function [y] = v_func(x)
y = (4 - x.^2).^(1/2) - (2 - x).^(1/2).*(x + 2).^(1/2);
y(abs(y)<1e-10)=0;
end
The above performs the same calculation as before with second line of code replacing all values that are less than some tolerance (1e-10) with zero. Note how the equation is slightly different than your original one. It has been "vectorized" (see the use of the periods) to allow for an input vector to be evaluated rather than having to loop over each element in the vector. Note also that when we pass it to ezplot we must prefix the function name with the ampersand:
ezplot(#v_func,[-2,2]);
The second way requires wrapping your first anonymous function v in a couple of others (see anonymous functions and conditions). We start with your original function that has been vectorized:
v = #(x) (4 - x.^2).^(1/2) - (2 - x).^(1/2).*(x + 2).^(1/2);
and a (condition) function that replaces all values less than some tolerance with zero:
cond = #(y)(y*(1-(abs(y)<1e-10)))
We then wrap the two together as
func = #(x)cond(v(x))
so that the condition function evaluates the output of v. Putting it together with ezplot gives:
ezplot(func,[-2,2]);
and all output, as shown in the plot, should be zero.
The figure title will not be what you want, so it can be replaced with some variation of:
plotTitle = func2str(v);
title(strrep(plotTitle(5:end),'.','')); % as I don't want '#(x)' or periods to
% appear in the title
I've ignored the use of sym as I don't have the Symbolic Toolbox.
Say I have two column vectors of same size: P and Q. What I need to do is find the least squares-functional distance D = ||P - Q||^2. What does this mean and how do I implement it in matlab. Should I use the norm() function?
You can use
norm(P-Q)^2
or
sum((P-Q).^2)
A small test:
P = randn(1e7,1);
Q = randn(1e7,1);
tic
norm(P-Q)^2;
toc
tic
sum((P-Q).^2);
toc
Results:
Elapsed time is 0.130086 seconds.
Elapsed time is 0.098494 seconds.
So manually squaring and summing is a tad faster, and perhaps more intuitive.
If you are just trying to find the square of the Euclidian norm, or in other words sum((P(i) - Q(i))^2), then you can use sumsqr(P - Q).
EDIT: The Euclidian norm is defined as the square root of the sum of the squares, so in your case it would be sqrt(sum((P(i) - Q(i))^2)). That is what ||P - Q|| means. So ||P - Q||^2 would just be the sum of the squares of (P - Q), and MATLAB has a built-in function for that, as stated above.