Pregunta

I have a function f(t) and want to get all the points where it intersects y=-1 and y=1 in the range 0 to 6*pi. The only way I cold do it is ploting them and trying to locate the x-axis pt where f(t) meets the y=1 graph. But this doesn't give me the exact point. Instead gives me a near by value. This is how I am getting the points.

clear;
clc;
f=@(t) (9*(sin(t))/t) + cos(t);
fplot(f,[0 6*pi]);
hold on; plot(0:0.01:6*pi,1,'r-');
         plot(0:0.01:6*pi,-1,'r-');
         x=0:0.2:6*pi; h=cos(x); plot(x,h,':')
¿Fue útil?

Solución

You are essentially trying to solve a system of two equations, at least in general. For the simple case where one of the equations is a constant, thus y = 1, we can solve it using fzero. Of course, it is always a good idea to use graphical means to find a good starting point.

f=@(t) (9*(sin(t))./t) + cos(t);
y0 = 1;

The idea is if you want to find where the two curves intersect, is to subtract them, then look for a root of the resulting difference.

(By the way, note that I used ./ for the divide, so that MATLAB won't have problem for vector or array input in f. This is a good habit to develop.)

Note that f(t) is not strictly defined in MATLAB at zero, since it results in 0/0. (A limit exists of course for the function, and can be evaluated using my limest tool.)

limest(f,0)
ans =
           10

Since I know the solution is not at 0, I'll just use the fzero bounds from looking there for a root.

format long g
fzero(@(t) f(t) - y0,[eps,6*pi])
ans =
          2.58268206208857

But is this the only root? What if we have two or more solutions? Finding all the roots of a completely general function can be a nasty problem, as some roots may be infinitely close together, or there may be infinitely many roots.

One idea is to use a tool that knows how to look for multiple solutions to a problem. Again, found on the file exchange, we can use research.

y0 = 1;
rmsearch(@(t) f(t) - y0,'fzero',1,eps,6*pi)
ans =
          2.58268206208857
          6.28318530717959
          7.97464518075547
          12.5663706143592
          13.7270312712311

y0 = -1;
rmsearch(@(t) f(t) - y0,'fzero',1,eps,6*pi)
ans =
          3.14159265358979
          5.23030501095915
          9.42477796076938
          10.8130654321854
           15.707963267949
          16.6967239156574

Otros consejos

Try this:

y = fplot(f,[0 6*pi]);

now you can analyse y for the value you are looking for.

[x,y] = fplot(f,[0 6*pi]);
[~,i] = min(abs(y-1));
point = x(i);

this will find one, nearest crossing point. Otherwhise you going through the vector with for

Here is the variant with for I often use:

clear;
clc;
f=@(t) (9*(sin(t))/t) + cos(t);
fplot(f,[0 6*pi]);
[fx,fy] = fplot(f,[0 6*pi]);
hold on; plot(0:0.01:6*pi,1,'r-');
         plot(0:0.01:6*pi,-1,'r-');
         x=0:0.2:6*pi; h=cos(x); plot(x,h,':')

k  = 1; % rising 
kt = 1; % rising
pn = 0; % number of crossings
fy = abs(fy-1);
for n = 2:length(fx)
    if fy(n-1)>fy(n)
        k = 0; % falling
    else
        k = 1; % rising
    end

    if k==1 && kt ==0 % change from falling to rising
        pn = pn +1;
        p(pn) = fx(n);
    end
    kt = k;
end

You can make this faster, if you make an mex-file of this...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top