I have the situation like on this image below:
This plot is the result of two vectors:
fi = [41.309180589278, 41.8087915220215, 42.8081880760916
One way to find a zero crossing is to "turn the graph sideways", having fi
be a function of m
, and interpolate to find m=0
. But interp1
requires the m
input to be monotonic, which this is not. In fact, this function has two different values for each m
.
MATLAB knows the fzeros function, which finds a zero crossing of a function numerically. It requires a function as input. We can define an anonymous function using interp1
, which returns m-1
for any value of x
. Here, x
is defined by fi
and f(x)
by m
:
fi = [41.309180589278, 41.8087915220215, 42.8081880760916, ...
43.8078181874395, 44.8076823745539, 45.8077808710707, 46.3079179803177];
m = [1.00047608139868, 1.00013712198767, 0.999680989440986, ...
0.999524195487826, 0.999671686649694, 1.00012913666266, 1.00047608139868];
fun = @(x)interp1(fi,m,x)-1;
x1 = fzero(fun,42)
x2 = fzero(fun,46)
This gives me:
x1 = 42.109
x2 = 45.525
Note that we needed to know the approximate locations for these two zeros. There is no easy way around this that I know of. If one knows that there are two zero crossings, and the general shape of the function, one can find the local minimum:
[~,fimin] = min(m);
fimin = fi(fimin);
and then find the zero crossings between each of the end points and the local minimum:
x1 = fzero(fun,[fi(1),fimin])
x2 = fzero(fun,[fimin,fi(end)])
You need to use an anonymous function so that you can pass additional arguments to interp1.
Try this
fi = [41.309180589278, 41.8087915220215, 42.8081880760916, ...
43.8078181874395, 44.8076823745539, 45.8077808710707, 46.3079179803177];
m = [1.00047608139868, 1.00013712198767, 0.999680989440986, ...
0.999524195487826, 0.999671686649694, 1.00012913666266, 1.00047608139868];
fzero(@(x) 1-interp1(fi,m,x), 43)
fzero(@(x) 1-interp1(fi,m,x), 45)
The 43 and 45 are the initialization for x for fzero. You need to run the fzero twice to find the two solutions.