intersection of two line - matlab

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.

Related

How to find the intersections of two functions in MATLAB?

Lets say, I have a function 'x' and a function '2sin(x)'
How do I output the intersects, i.e. the roots in MATLAB? I can easily plot the two functions and find them that way but surely there must exist an absolute way of doing this.
If you have two analytical (by which I mean symbolic) functions, you can define their difference and use fzero to find a zero, i.e. the root:
f = #(x) x; %defines a function f(x)
g = #(x) 2*sin(x); %defines a function g(x)
%solve f==g
xroot = fzero(#(x)f(x)-g(x),0.5); %starts search from x==0.5
For tricky functions you might have to set a good starting point, and it will only find one solution even if there are multiple ones.
The constructs seen above #(x) something-with-x are called anonymous functions, and they can be extended to multivariate cases as well, like #(x,y) 3*x.*y+c assuming that c is a variable that has been assigned a value earlier.
When writing the comments, I thought that
syms x; solve(x==2*sin(x))
would return the expected result. At least in Matlab 2013b solve fails to find a analytic solution for this problem, falling back to a numeric solver only returning one solution, 0.
An alternative is
s = feval(symengine,'numeric::solve',2*sin(x)==x,x,'AllRealRoots')
which is taken from this answer to a similar question. Besides using AllRealRoots you could use a numeric solver, manually setting starting points which roughly match the values you have read from the graph. This wa you get precise results:
[fzero(#(x)f(x)-g(x),-2),fzero(#(x)f(x)-g(x),0),fzero(#(x)f(x)-g(x),2)]
For a higher precision you could switch from fzero to vpasolve, but fzero is probably sufficient and faster.

solve trig equation over boundary

Firstly, I'm sure a simple answer exists for this, maybe I'm just not wording it right in searching for an answer online.
I'm trying to solve an equation that looks like this:
a*x*cot(a*x) == b
Where a and b are constants. Using
solve(a*x*cot(a*x) == b, x)
I'm getting a result I know is wrong (with the values I'm using for the constants, I'm getting like -227, and it should be something around +160.) I plotted it up in Mathematica as two separate functions, and they do cross each other right around there, but since the cot part is periodic, they do so many times.
I want to constrain Matlab's search for the solution to a specific interval, such as 0 to 200; how do I do that?
I'm pretty new to Matlab (rather more experienced in Mathematica).
You can specify the bounds on x using fzero with only two requirements
The function must be in a "residual" form (i.e., r(x) = 0)
The residual values at the two bounds must have opposite sign (this guarantees that a root exists within the interval for continuous functions).
So we re-write the function in residual form:
r = #(x) a*x*cot(a*x) - b;
define the interval
% These are just random numbers; the actual bounds should come
% from the graph the ensures r has different signs a xL and xR
xL = 150;
xR = 170;
and solve
x = fzero(r,[xL,xR]);
I see you were trying to use the Symbolic Toolbox for a solution, but since the equation is a non-linear combination of a polynomial and a trigonometric function, there is more than likely no closed form solution. So I differed to a non-linear, numeric root-finder.
I tried some values and it seems solve returns a numeric solution. This is the documented behaviour if no analytic solution is found.
In this case, you may directly call the numeric solver with a matching start value
vpasolve(a*x*cot(a*x) == b, x,160)
It's not exactly what you asked for, but using your reading from the plot as a start value should do it.

What is the fastest method for solving exp(ax)-ax+c=0 for x in matlab

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.

vector valued limits in matlab integral

Is it possible to use vector limits for any matlab function of integration? I have to avoid from for loops because of the speed of my program. Can you please give me a clue on do
k=0:5
f=#(x)x^2
quad(f,k,k+1)
If somebody need, I found the answer of my question:quad with vector limit
I will try giving you an answer, based on my experience with quad function.
Starting from this:
k=0:5;
f=#(x) x.^2;
Notice the difference in your f definition (incorrect) and mine (correct).
If you only mean to integrate f within the range (0,5) you can easily call
quad(f,k(1),k(end))
Without handle function, you may reach the same results in a different way, by making use of trapz:
x = 0:5;
y = x.^2;
trapz(x,y)
If, instead, you mean to perform a step-by-step integration in the small range [k(i),k(i+1)] you may type
arrayfun(#(ii) quad(f,k(ii),k(ii+1)),1:numel(k)-1)
For a sake of convenince, notice that
sum(arrayfun(#(ii) quad(f,k(ii),k(ii+1)),1:numel(k)-1)) == quad(f,k(1),k(end))
I hope this helps.

MATLAB code help. Backward Euler method

Here is the MATLAB/FreeMat code I got to solve an ODE numerically using the backward Euler method. However, the results are inconsistent with my textbook results, and sometimes even ridiculously inconsistent. What is wrong with the code?
function [x,y] = backEuler(f,xinit,yinit,xfinal,h)
%f - this is your y prime
%xinit - initial X
%yinit - initial Y
%xfinal - final X
%h - step size
n = (xfinal-xinit)/h; %Calculate steps
%Inititialize arrays...
%The first elements take xinit and yinit corespondigly, the rest fill with 0s.
x = [xinit zeros(1,n)];
y = [yinit zeros(1,n)];
%Numeric routine
for i = 1:n
x(i+1) = x(i)+h;
ynew = y(i)+h*(f(x(i),y(i)));
y(i+1) = y(i)+h*f(x(i+1),ynew);
end
end
Your method is a method of a new kind. It is neither backward nor forward Euler. :-)
Forward Euler: y1 = y0 + h*f(x0,y0)
Backward Euler solve in y1: y1 - h*f(x1,y1) = y0
Your method: y1 = y0 +h*f(x0,x0+h*f(x0,y0))
Your method is not backward Euler.
You don't solve in y1, you just estimate y1 with the forward Euler method. I don't want to pursue the analysis of your method, but I believe it will behave poorly indeed, even compared with forward Euler, since you evaluate the function f at the wrong point.
Here is the closest method to your method that I can think of, explicit as well, which should give much better results. It's Heun's Method:
y1 = y0 + h/2*(f(x0,y0) + f(x1,x0+h*f(x0,y0)))
The only issue I can spot is that the line:
n=(xfinal-xinit)/h
Should be:
n = abs((xfinal-xinit)/h)
To avoid a negative step count. If you are moving in the negative-x direction, make sure to give the function a negative step size.
Your answers probably deviate because of how coarsely you are approximating your answer. To get a semi-accurate result, deltaX has to be very very small and your step size has to be very very very small.
PS. This isn't the "backward Euler method," it is just regular old Euler's method.
If this is homework please tag it so.
Have a look at numerical recipes, specifically chapter 16, integration of ordinary differential equations. Euler's method is known to have problems:
There are several reasons that Euler’s method is not recommended for practical use, among them, (i) the method is not very accurate when compared to other, fancier, methods run at the equivalent stepsize, and (ii) neither is it very stable
So unless you know your textbook is using Euler's method, I wouldn't expect the results to match. Even if it is, you probably have to use an identical step size to get an identical result.
Unless you really want to solve an ODE via Euler's method that you've written by yourself you should have a look at built-in ODE solvers.
On a sidenote: you don't need to create x(i) inside the loop like this: x(i+1) = x(i)+h;. Instead, you can simply write x = xinit:h:xfinal;. Also, you may want to write n = round(xfinal-xinit)/h); to avoid warnings.
Here are the solvers implemented by MATLAB.
ode45 is based on an explicit
Runge-Kutta (4,5) formula, the
Dormand-Prince pair. It is a one-step
solver – in computing y(tn), it needs
only the solution at the immediately
preceding time point, y(tn-1). In
general, ode45 is the best function to
apply as a first try for most
problems.
ode23 is an implementation of an
explicit Runge-Kutta (2,3) pair of
Bogacki and Shampine. It may be more
efficient than ode45 at crude
tolerances and in the presence of
moderate stiffness. Like ode45, ode23
is a one-step solver.
ode113 is a variable order
Adams-Bashforth-Moulton PECE solver.
It may be more efficient than ode45 at
stringent tolerances and when the ODE
file function is particularly
expensive to evaluate. ode113 is a
multistep solver — it normally needs
the solutions at several preceding
time points to compute the current
solution.
The above algorithms are intended to
solve nonstiff systems. If they appear
to be unduly slow, try using one of
the stiff solvers below.
ode15s is a variable order solver
based on the numerical differentiation
formulas (NDFs). Optionally, it uses
the backward differentiation formulas
(BDFs, also known as Gear's method)
that are usually less efficient. Like
ode113, ode15s is a multistep solver.
Try ode15s when ode45 fails, or is
very inefficient, and you suspect that
the problem is stiff, or when solving
a differential-algebraic problem.
ode23s is based on a modified
Rosenbrock formula of order 2. Because
it is a one-step solver, it may be
more efficient than ode15s at crude
tolerances. It can solve some kinds of
stiff problems for which ode15s is not
effective.
ode23t is an implementation of the
trapezoidal rule using a "free"
interpolant. Use this solver if the
problem is only moderately stiff and
you need a solution without numerical
damping. ode23t can solve DAEs.
ode23tb is an implementation of
TR-BDF2, an implicit Runge-Kutta
formula with a first stage that is a
trapezoidal rule step and a second
stage that is a backward
differentiation formula of order two.
By construction, the same iteration
matrix is used in evaluating both
stages. Like ode23s, this solver may
be more efficient than ode15s at crude
tolerances.
I think this code could work. Try this.
for i =1:n
t(i +1)=t(i )+dt;
y(i+1)=solve('y(i+1)=y(i)+dt*f(t(i+1),y(i+1)');
end
The code is fine. Just you have to add another loop within the for loop. To check the level of consistency.
if abs((y(i+1) - ynew)/ynew) > 0.0000000001
ynew = y(i+1);
y(i+1) = y(i)+h*f(x(i+1),ynew);
end
I checked for a dummy function and the results were promising.