Reputation: 1901
Consider a general vector which represent some non-linear function
for example:
x = [1 2 3 4 5 6 7 8 9 10];
f = [-1 6 8 7 5 2 0.1 -2 -3];
Is there a method in matlab that can find the solutions of f(x)=0
? with some given accuracy
Upvotes: 1
Views: 105
Reputation: 102241
Maybe you can try interp1
in arrayfun
like below (linear interpolation was adopted)
x0 = arrayfun(@(k) interp1(f(k:k+1),x(k:k+1),0),find(sign(f(1:end-1).*f(2:end))<0));
such that
x0 =
1.1429 7.0476 9.5000
DATA
x = [1 2 3 4 5 6 7 8 9 10];
f = [-1 6 8 7 5 2 0.1 -2 -3 3];
Upvotes: 1
Reputation: 1901
I've made a function that does it, but feel it is something quite "regular" that matlab must have built in answers...so if someone has any write it down and I will accept it as an answer.
function sol = find_zeros(x,f)
f_vec = round(f*10^2)/10^2;
ind=find(diff(sign(f_vec))~=0);
K = length(ind);
if (K>0)
sol = zeros(1,K);
for k=1:K
if (f_vec(ind(k))<f_vec(ind(k)+1))
df = f_vec(ind(k)):0.01:f_vec(ind(k)+1);
else
df = flip(f_vec(ind(k)+1):0.01:f_vec(ind(k)));
end
dx = linspace(x(ind(k)),x(ind(k)+1),length(df));
j = find(df==0);
sol(k) = dx(j);
end
else
sol=[];
end
sol=unique(sol);
end
Upvotes: 0
Reputation: 1293
If you think about it, when you have a random distribution f
, finding zeros can only be done with linear interpolation between the data points:
For your example, I would define a function myFunc
as:
function y = myFunc(val)
x = [1 2 3 4 5 6 7 8 9 10];
f = [-1 6 8 7 5 2 0.1 -2 -3 3];
P = griddedInterpolant (x, f, 'linear', 'linear');
y = P(val);
end
and apply a root searching algorithm via something like fzero
:
val = 0;
x = [1 2 3 4 5 6 7 8 9 10];
x = [-inf x inf]; % Look outside boundary too
fun = @myFunc;
sol = zeros(1, numel(x)-1);
cnt = 0;
for i = 1:length(x)-1 % fzero stops at the 1st zero hence the loop over each interval
bound = [x(i) x(i+1)];
try
z = fzero(fun, bound);
cnt = cnt+1;
sol(cnt) = z;
catch
% No answer within the boundary
end
end
sol(cnt+1:end) = [];
Upvotes: 1