jarhead
jarhead

Reputation: 1901

Find intersections of a general vector with zeros MATLAB

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

Answers (3)

ThomasIsCoding
ThomasIsCoding

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

jarhead
jarhead

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

If_You_Say_So
If_You_Say_So

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

Related Questions