I have a equation like this:
2^n * exp((-p*k*n*(k*n-(k+1)*2^t)))/((k+1)^2*2^(2*t+1))- 1=0.
I tried using the follwing code, but it gives me a warning that "Explicit solution could not be found".
syms n k t p positive;
S=solve(2^n * exp((-p*k*n*(k*n-(k+1)*2^t)))/((k+1)^2*2^(2*t+1))- 1,n,'IgnoreAnalyticConstraints', true);
S
Is there a way to solve the equation in terms on n?
Thanks in advance
Short answer: NO
MATLAB tries to find an "Explicit" solution, one in which variable n is expressed in terms of the other variables. In your case, the solution is "Implicit", meaning that variable n cannot be isolated and thus appears on both sides of the equation.
I used a different tool and here is what I got.
[e^((-k^2-k)np2^t+k^2n^2p)=2^(-2t+n-1)/(k^2+2*k+1)]
As you can see, n appears on both sides.
You might want to take a look at this post
Related
I have a problem when computing the derivative of a first order function as below:
syms x(t)
xd = diff(x);
y = xd*xd;
how to compute derivative of y by xd;
functionalDerivative(y,xd);
Then, it raises an error as below:
Error using symengine
The variable 'diff(x(t), t)' is invalid.
The result should be:
2*diff(x,t)
I also think about name xd as a symbolic variable, then use diff(y,xd) but this way is not good for some situation. Do we have any method can directly compute the derivative of a differential function?
Please suggest me some solutions.
Thank in advance!
I find it a little odd that the Symbolic Engine can't handle that, lacking a better word I'll borrow one from the TeX world, unexpandable expression. However, you can get around the limitation by subs-ing in a temporary variable, taking the derivative, and subs-ing it back in:
>> syms u(t)
>> dydxd = subs(functionalDerivative(subs(y,xd(t),u(t)),u),u(t),xd(t))
dydxd(t) =
2*diff(x(t), t)
Hopefully this subs approach will work in most cases, but more complex expressions for y may make it not work.
What is the least computational time consuming way to solve in Matlab the equation:
exp(ax)-ax+c=0
where a and c are constants and x is the value I'm trying to find?
Currently I am using the in built solver function, and I know the solution is single valued, but it is just taking longer than I would like.
Just wanting something to run more quickly is insufficient for that to happen.
And, sorry, but if fzero is not fast enough then you won't do much better for a general root finding tool.
If you aren't using fzero, then why not? After all, that IS the built-in solver you did not name. (BE EXPLICIT! Otherwise we must guess.) Perhaps you are using solve, from the symbolic toolbox. It will be more slow, since it is a symbolic tool.
Having said the above, I might point out that you might be able to improve by recognizing that this is really a problem with a single parameter, c. That is, transform the problem to solving
exp(y) - y + c = 0
where
y = ax
Once you know the value of y, divide by a to get x.
Of course, this way of looking at the problem makes it obvious that you have made an incorrect statement, that the solution is single valued. There are TWO solutions for any negative value of c less than -1. When c = -1, the solution is unique, and for c greater than -1, no solutions exist in real numbers. (If you allow complex results, then there will be solutions there too.)
So if you MUST solve the above problem frequently and fzero was inadequate, then I would consider a spline model, where I had precomputed solutions to the problem for a sufficient number of distinct values of c. Interpolate that spline model to get a predicted value of y for any c.
If I needed more accuracy, I might take a single Newton step from that point.
In the event that you can use the Lambert W function, then solve actually does give us a solution for the general problem. (As you see, I am just guessing what you are trying to solve this with, and what are your goals. Explicit questions help the person trying to help you.)
solve('exp(y) - y + c')
ans =
c - lambertw(0, -exp(c))
The zero first argument to lambertw yields the negative solution. In fact, we can use lambertw to give us both the positive and negative real solutions for any c no larger than -1.
X = #(c) c - lambertw([0 -1],-exp(c));
X(-1.1)
ans =
-0.48318 0.41622
X(-2)
ans =
-1.8414 1.1462
Solving your system symbolically
syms a c x;
fx0 = solve(exp(a*x)-a*x+c==0,x)
which results in
fx0 =
(c - lambertw(0, -exp(c)))/a
As #woodchips pointed out, the Lambert W function has two primary branches, W0 and W−1. The solution given is with respect to the upper (or principal) branch, denoted W0, your equation actually has an infinite number of complex solutions for Wk (the W0 and W−1 solutions are real if c is in [−∞, 0]). In Matlab, lambertw is only implemented for symbolic inputs and thus is very slow method of solving your equation if you're interested in numerical (double precision) solutions.
If you wish to solve such equations numerically in an efficient manner, you might look at Corless, et al. 1996. But, as long as your parameter c is in [−∞, 0], i.e., -exp(c) in [−1/e, 0] and you're interested in the W0 branch, you can use the Matlab code that I wrote to answer a similar question at Math.StackExchange. This code should be much much more efficient that using a naïve approach with fzero.
If your values of c are not in [−∞, 0] or you want the solution corresponding to a different branch, then your solution may be complex-valued and you won't be able to use the simple code I linked to above. In that case, you can more fully implement the function by reading the Corless, et al. 1996 paper or you can try converting the Lambert W to a Wright ω function: W0(z) = ω(log(z)), W−1(z) = ω(log(z)−2πi). In your case, using Matlab's wrightOmega, the W0 branch corresponds to:
fx0 =
(c - wrightOmega(log(-exp(c))))/a
and the W−1 branch to:
fxm1 =
(c - wrightOmega(log(-exp(c))-2*sym(pi)*1i))/a
If c is real, then the above reduces to
fx0 =
(c - wrightOmega(c+sym(pi)*1i))/a
and
fxm1 =
(c - wrightOmega(c-sym(pi)*1i))/a
Matlab's wrightOmega function is also symbolic only, but I have written a double precision implementation (based on Lawrence, et al. 2012) that you can find on my GitHub here and that is 3+ orders of magnitude faster than evaluating the function symbolically. As your problem is technically in terms of a Lambert W, it may be more efficient, and possibly more numerically accurate, to implement that more complicated function for the regime of interest (this is due to the log transformation and the extra evaluation of a complex log). But feel free to test.
I have to analyze 802.11 saturation throughput using matlab, and here is my problem. I'm trying to solve parametric equations below (parameters are m,W,a) using solve function and i get
Warning: Explicit solution could not be found
How could I solve above equations using matlab?
I guess you were trying to find an analytical solution for tau and p using symbolic math. Unless you're really lucky with your parameters (e.g. m=1), there won't be an analytical solution.
If you're interested in numerical values for tau and p, I suggest you manually substitue p in the first equation, and then solve an equation of the form tau-bigFraction=0 using, e.g. fzero.
Here's how you'd use fzero to solve a simple equation kx=exp(-x), with k being a parameter.
k = 5; %# set a value for k
x = fzero(#(x)k*x-exp(-x),0); %# initial guess: x=0
how can one obtain coordinates of intersections of two line diagrams with given expression or equation?
for example:
L1= sin(2x) , L2= Ln(x); or anything else.
Amazingly, nobody has yet suggested using the function designed to do this in matlab. Use fzero here. Fzero is a better choice than fsolve anyway, which requires the optimization toolbox. And, yes, you could do this with Newton's method, or even bisection or the secant method. But reinventing the wheel is the wrong thing to do in general. Use functionality that already exists when it is there.
The problem at hand is to find a point where
sin(2*x) == log(x)
Here log(x) refers to the natural log. Do this by subtracting one from the other, then looking for a zero of the result.
fun = #(x) sin(2*x) - log(x);
Before you do so, ALWAYS plot it. ezplot can do that for you.
ezplot(fun)
The plot will show a single root that lies between 1 and 2.
fzero(fun,2)
ans =
1.3994
Since you tagged with matlab, you can do it with fsolve(#(x)sin(2*x)-log(x),1) which gives 1.3994 (1 is the initial starting point or guess). The y-coordinate is log(1.3994) = 0.3361.
That is, you use fsolve, pass it the function you want to solve for the zero of, in this case sin(2*x) == log(x) so you want sin(2*x) - log(x) == 0 (log is the natural log in matlab).
If you already have functions set up like, e.g. L1 = #(x)sin(2*x) and L2 = #(x)log(x) (or in functions L1.m and L2.m) you can use fsolve(#(x)L1(x)-L2(x),1).
In general, you have to solve the equation L1(x) = L2(x). If you don't know from the beginning what L1 and L2 are (linear, polynominal...) then the only solution is numeric solving for example with Netwon algorithm. The problem is then reduced to finding roots (zeros) of function f(x) = L1(X) - L2(X).
This is not a trivial question: what you're asking for is a general method for solving any mathematical equation.
For instance, you could consider using the bisection method, or Newton's method.
There is no general answer.
As a general non-analytic solution, when you have any 2 curves described by 2 sets of points, there is great submission at File Exchange - Fast and Robust Curve Intersections.
I'm talking about Volterra integral equations of second order:
In my case g is an ugly integral also between a and x, also a=0 (for both g and the integral above). K is equal to 1.
I found some information about Fredholm equations, but they are not exactly the same (fixed intervals, they don't have x on the integral sign), I wonder if maybe I can reconduct my analysis to a Fredholm equation? And if so, how can I solve it in Matlab?
You have a Volterra equation of the second kind, and in the case when the kernel takes the form k(x-t) it can be solved an operational way(method).
Since your task is not unique, will be convenient to use a ready solution:
http://www.mathworks.com/matlabcentral/fileexchange/49721-volterra-integral-equations-solver
Solve your equation (if I understood correctly problem statement):
isolve(1,10*x,1)
ans =
10*exp(x) - 10
Will check the correctness of the solution by substituting in the source:
10*x + int(y,0,x)
ans =
10*exp(x) - 10
Solved correctly.
P.S. Sorry for my English.