I'm trying to write some code which would find the limit of a function as x approaches positive and negative infinity. The code I have so far is as follows:
pos = limit(exp(atan(x)), x = infinity)
neg = limit(exp(atan(x)), x = -infinity)
However, it gives me an error saying "invalid syntax at =. Possibly, a ), }, or ] is missing. When I looked at the Matlab documentation for how to compute a limit, they had this as their example:
limit((1 + 1/n)^n, n = infinity)
and this returned an answer of e. When I put this into my own Matlab, it gave me the same error, could anyone help? Is it possibly an error with my Matlab?
You've been looking at the wrong help. Such notation (and limit function) is used in MuPAD interface, not in the simple Matlab Command Window.
To use limit() in Matlab environment, you have to use symbolic variables and this is the correct help page.
In other words, to compute
limit((1 + 1/n)^n, n = infinity)
you have to declare a symbolic variable n
syms n
and then provide the correct syntax (ref. help)
limit((1 + 1/n)^n, n, inf)
and the result is (of course) exp(1), that is e.
Related
I'm using Matlab 2014b. I've tried:
clear all
syms x real
assumeAlso(x>=5)
This returned:
ans =
[ 5 <= x, in(x, 'real')]
Then I tried:
int(sqrt(x^2-25)/x,x)
But this still returned a complex answer:
(x^2 - 25)^(1/2) - log(((x^2 - 25)^(1/2) + 5*i)/x)*5*i
I tried the simplify command, but still a complex answer. Now, this might be fixed in the latest version of Matlab. If so, can people let me know or offer a suggestion for getting the real answer?
The hand-calculated answer is sqrt(x^2-25)-5*asec(x/5)+C.
This behavior is present in R2017b, though when converted to floating point the imaginary components are different.
Why does this occur?
This occurs because Matlab's int function returns the full general solution when you ask for the indefinite integral. This solution is valid over the entire domain of of real values, including your restricted domain of x>=5.
With a bit of math you can show that the solution is always real for x>=5 (see complex logarithm). Or you can use more symbolic math via the isAlways function to show this:
syms x real
assume(x>=5)
y = int(sqrt(x^2-25)/x, x)
isAlways(imag(y)==0)
This returns true (logical 1). Unfortunately, Matlab's simplification routines appear to not be able to reduce this expression when assumptions are included. You might also submit this case to The MathWorks as a service request in case they'd consider improving the simplification for this and similar equations.
How can this be "fixed"?
If you want to get rid of the zero-valued imaginary part of the solution you can use sym/real:
real(y)
which returns 5*atan2(5, (x^2-25)^(1/2)) + (x^2-25)^(1/2).
Also, as #SardarUsama points out, when the full solution is converted to floating point (or variable precision) there will sometimes numeric imprecision when converting from exact symbolic form. Using the symbolic real form above should avoid this.
The answer is not really complex.
Take a look at this:
clear all; %To clear the conditions of x as real and >=5 (simple clear doesn't clear that)
syms x;
y = int(sqrt(x^2-25)/x, x)
which, as we know, gives:
y =
(x^2 - 25)^(1/2) - log(((x^2 - 25)^(1/2) + 5i)/x)*5i
Now put some real values of x≥5 to check what result it gives:
n = 1004; %We'll be putting 1000 values of x in y from 5 to 1004
yk = zeros(1000,1); %Preallocation
for k=5:n
yk(k-4) = subs(y,x,k); %Putting the value of x
end
Now let's check the imaginary part of the result we have:
>> imag(yk)
ans =
1.0e-70 *
0
0
0
0
0.028298997121333
0.028298997121333
0.028298997121333
%and so on...
Notice the multiplier 1e-70.
Let's check the maximum value of imaginary part in yk.
>> max(imag(yk))
ans =
1.131959884853339e-71
This implies that the imaginary part is extremely small and it is not a considerable amount to be worried about. Ideally it may be zero and it's coming due to imprecise calculations. Hence, it is safe to call your result real.
I am trying to numerically solve an equation using fzero in Matlab. It is part of a bigger exercise. I haven't posted much here so not sure how much background information you need about this exercise so will try to keep it short.
This is my code:
fun = #(a)log(a/xBar) + (1/n) * log(dataProd) + diff(gamma(a))/gamma(a);
x0 = 0.8014;
x = fzero(fun,x0)
These are the values:
n = 209
xBar is 0.6078
dataProd = 3.1554e-77
I get the following error message in Matlab:
Operands to the || and && operators must be convertible to logical
scalar values.
Error in fzero (line 306)
elseif ~isfinite(fx) || ~isreal(fx)
Any idea why I get this error message?
I would guess that, during the search for a solution, fzero tries to evaluate your function at a=0, leading to an infinity. To check if this is the case, either look and see if you can set the optimization parameter 'display' to 'iter', or something similar in your version of Matlab. Otherwise, you can simply move your function to a separate m-file and call disp(a) on the first line. That way you will be able to see what fzero is doing and which value of a is causing the problem.
I am trying to perform a numerical triple integral over s, gamma1, gamma2. The limits are (-inf +int), (0,+inf) and (gamma1,+inf) respectively. Please dont be scared from the shape of my function (its just a function of gamma1, gamma2, s)
The following is my code
syms s
syms gamma1
syms gamma2
fun=-(exp(-(28035689158432973*pi*gamma2^(2/3))/2305843009213693952)*
exp(-(pi*s*7120816246010697*i)/112589990684262400)*
(1/((pi*s*(4194304/gamma1^2 + 4194304/gamma2^2)*i)/(50*
(6144/gamma1 + 6144/gamma2)) + 1)^((3*(2048/gamma1 + 2048/gamma2)^2)
/(4194304/gamma1^2 + 4194304/gamma2^2)) - 1)
*(exp(-(pi^2*s*(log((-(gamma2*25*i)/(1024*pi*s))^(1/3) + 1)/3;
y=#(s,gamma1,gamma2)fun;
gamma2min=#(s,gamma1) gamma1;
prob=integral3(y,-inf,+inf,0,+inf,gamma2min,+inf)
I get the following error
Error using integralCalc/finalInputChecks (line 511)
Input function must return 'double' or 'single' values. Found 'sym'.
Any advice?
Thank you very much!
You can use quadgk to numerically integrate functions defined like
y=#(a,b,c) 1/abs(a^2+b^2+c^2+1);
(which I used to test my answer).
It's tricky because quadgk expects a function that takes vector input and returns a vector of function values, but you can get around it by using a lot of arrayfun's:
R=#(s,gamma1) quadgk(#(gamma2) arrayfun(#(k) y(s,gamma1,k),gamma2),gamma1,Inf)
S=#(s) quadgk(#(gamma1) arrayfun(#(k) R(s,k),gamma1),0,Inf)
T=quadgk(#(s) arrayfun(#(k) S(k),s),-Inf,Inf)
But! It's very slow, I wasn't patient enough to wait for the answer. So, replace the Inf and -Inf limits with 100 and -100, for example, and you will get an answer. Maybe try with 50 and -50 and see how much the solution changes by, if it changes very little then you can be confident the answer is quite accurate, otherwise you'll have to increase the number and wait longer! The faster your function decays the smaller the bounds you will be ale to get away with.
I wanted to solve the following equation in MATLAB R2013a using the Symbolic Math Toolbox.
(y/x)-(((1+r)^n)-1)/r=0 where y,x and n>3 are given and r is the dependent variable
I tried myself & coded as follows:
f=solve('(y/x)-(((1+r)^n)-1)/r','r')
but as the solution for r is not exact i.e. it is converging on successive iterations hence MATLAB is giving a warning output with the message
Warning: Explicit solution could not be found.
f =
[ empty sym ]
How do I code this?
There are an infinite number of solutions to this for an unspecified value of n > 3 and unknown r. I hope that it's pretty clear why – it's effectively asking for a greater and greater number of roots of (1+r)^n. You can find solutions for fixed values of n, however. Note that as n becomes larger there are more and more solutions and of course some of them are complex. I'm going to assume that you're only interested in real values of r. You can use solve and symbolic math for n = 4, n = 5, and n = 6 (for n = 6, the solution may not be in a convenient form):
y = 441361;
x = 66990;
n = 5;
syms r;
rsol = solve(y/x-((1+r)^n-1)/r==0,r,'IgnoreAnalyticConstraints',true)
double(rsol)
However, the question is "do you need all the solutions or just a particular solution for a given value of n"? If you just need a particular solution, you shouldn't be using symbolic math at all as it's slower and has practical issues like the ones you're experiencing. You can instead just use a numerical approach to find a zero of the equation that is near a specified initial guess. fzero is the standard function for solving this sort of problem in a single variable:
y = 441361;
x = 66990;
n = 5;
f = #(r)y/x-((1+r).^n-1)./r;
r0 = 1;
rsol = fzero(f,r0)
You'll see that the value returned is the same as one of the solutions from the symbolic solution above. If you adjust the initial guess r0 (say r0 = -3), it will return the other solution. When using numeric approaches in cases when there are multiple solutions, if you want specific solutions you'll need to know about the behavior of your function and you'll need to add some clever extra code to choose initial guesses.
I think you forgot to define n as well.
f=solve('(y/x)-(((1+r)^n)-1)/r=0','n-3>0','r','n')
Should solve your problem :)
I'm attempting to get a nonlinear least squares fit for the following function:
Nloc = 250;
d = 1 / Nloc;
m = 0.5; %Initial guess
ncmfun = #(m, p) arrayfun(#(p) betainc(d, Nloc*m .* p, Nloc*m .* (1 - p), 'upper'), p);
Where m is the parameter being fit, Nloc and d are constants, and p and freq are vectors of positive real numbers and of the same length (I triple checked). When I use lsqcurvefit everything works fine:
[mfit,resnorm,] = lsqcurvefit(ncmfun, m, p, freq, 0, 1)
Also, if I use any m to evaluate the function, everything works fine as well. However when I use nlinfit:
[mfit,R,Jac,CovB,MSE,ErrorModelInfo] = nlinfit(p, freq, ncmfun, m)
I get the following error(s):
Error using betainc
Z must be real and non-negative.
Error in #(p)betainc(d,Nloc*m.*p,Nloc*m.*(1-p),'upper')
Error in
#(m,p)arrayfun(#(p)betainc(d,Nloc*m.*p,Nloc*m.*(1-p),'upper'),p)
Error in nlinfit>#(b,x)w.*model(b,x) (line 206)
modelw = #(b,x) w.*model(b,x);
Error in nlinfit>LMfit (line 486)
yfit = model(beta,X);
Error in nlinfit (line 207)
[beta,J,~,cause,fullr] = LMfit(X,yw,
modelw,beta,options,verbose,maxiter);
Error in Sloan_NCM_Parameterize_Nm (line 37)
[mfit,R,Jac,CovB,MSE,ErrorModelInfo] = nlinfit(p, freq,
ncmfun, m);
What's especially frustrating was this same script was working a couple weeks ago. I then tried to use it again and it no longer works. I tried to go through and see if I accidentally changed something and didn't remember, but I can't find any errors. Furthermore, I'm confused as to why lsqcurvefit works but not nlinfit. I'd like to use nlinfit because it provides me with more statistical information about the error.
Thanks in advance for any help you can provide!
They both use the same algorithm to identify a solution, however, you are explicitly stating an upper and lower bound for your solution in lsqcurvefit which ensures your incomplete beta function behaves. You don't have this option in nlinfit. I'm not sure what you did before (you can always look at the command history)
You have a few options from this point:
1 - programatically intercept every value that goes to ncmfun, by either expending your anonymous functions in what my nightmares are made of, or creating your own m-file for it. If the value is outside of [0,1] return progressively higher error value (with the boundaries being >>> then any possible value within the set)
2 - Try to force a quicker convergence by playing with some of the parameters (perhaps by using a robust fitting option (cf documentation))