11 svar
457 visningar
Cien 1188
Postad: 16 dec 2021 17:32

Skriv en function som löser f(x)=0 genom intervallhalvering.

Som rubriken säger så ska jag skriva en function som löser f(x)=0 genom intervallhalvering. Funktionen ska som indata ge en funktion som beräknar f(x), ett intervall [a,b] där f(x) växlar tecken samt den noggrannhet lösningen ska bestämmas med. Jag behärskar inte riktigt detta med functions än men jag har gjort ett program som har med intervallhalvering att göra så antar att jag kan göra mycket copy paste till denna. Programmet:

f=@(x)(x-2.5).*exp(-0.5*(x-2).^2)+0.2;   % Anonym funk
x=linspace(-2,7);                        % 100 punkter mellan -2 och 7
plot(x,f(x))
axis([-2 7 -1 1])
yline(0)                                 % horisontell linje y=0
hold on
plot([-1 -1],[-1 1],'r')                 % vertikal linje (x=-1)
text(-0.8,-0.75,'c')                     % intervallet c=[-1,-1/2]
plot([-0.5 -0.5],[-1 1],'b')             % vertikal linje (x=-1/2)
text(-0.3,-0.75,'d')                     % intervallet d=[-1/2,0]
plot([0 0],[-1 1],'g')                   % vertikal linje (x=0)
text(4.5,0.4,'y=f(x)')
hold off

a=-1;
b=0;

m=(a+b)/2;    % punkten exakt mellan -1 och 0, dvs -1/2.
c=[a,m];      % intervallet c=[-1,-1/2]
d=[m,b];      % intervallet d=[-1/2,0]
e=f(a)*f(m);  % Kunde lika gärna varit f(b)*f(m)

if e<0
    b=m;
    disp('Nollpunkt i intervallet c')
else 
    a=m;
    disp('Nollpunkt i intervallet d=[-1/2,0]')
end

Nu till de "nya" programmet där jag ska göra en function så har jag ett litet programskal som ska underlätta:


function m=min_bisect(f,I,tol)
% min_bisect - beräknar nollställe till f(x) på intervallet I.
%   Syntax:
%           x = min_bisect(f,I,tol)
%   Argument:
%           f   - funktionshandtag: pekar på namnet till en funktionsfil eller
%                 till en anonym funktion. T.ex. f=@funk eller f=@(x)cos(x)-x
%           I   - 1x2 matris, anger ett intervall I=[a,b]. Funktionen måste 
%                 växla tecken på intervallet.
%           tol - positivt tal som anger önskad noggrannhet för nollstället.
%   Returnerar:
%           x   - ett tal som ger approximativt nollställe.
%   Beskrivning:
%           Programmet beräknar ett approximativt nollställe till f(x) på
%           intervallet I med intervallhalveringsmetoden.
%   Exempel:
%           x = min_bisect(@(x)cos(x)-x,[0,1],1e-5)
	   
    a=I(1);
    b=I(2);

    msg=sprintf('??? Felaktig användning ==> min_bisect \n Funktionen måste växla tecken på intervallet.');
	     
    if ...
        disp(msg)
        m=[];
        return
    end

    while b-a > tol
        ...
    end

    m=(a+b)/2;

Vet inte riktigt hur jag ska börja, tips uppskattas :)

Dr. G 9479
Postad: 16 dec 2021 17:36

Räkna ut f(a), f(b) och f(m).

Vilka tecken har de?

Cien 1188
Postad: 16 dec 2021 17:38
Dr. G skrev:

Räkna ut f(a), f(b) och f(m).

Vilka tecken har de?

Den "första" koden jag posta är redan löst, det är den "andra" koden som är uppgiften som nu ska göras

Dr. G 9479
Postad: 16 dec 2021 17:49

Då börjar du med ett intervall där f(a) och f(b) har olika tecken. 

Beräkna f(m).

Vilket tecken har f(m)?

Om samma som f(a), så ...

eller

Om samma som f(b), så ...

Cien 1188
Postad: 16 dec 2021 18:23
Dr. G skrev:

Då börjar du med ett intervall där f(a) och f(b) har olika tecken. 

Beräkna f(m).

Vilket tecken har f(m)?

Om samma som f(a), så ...

eller

Om samma som f(b), så ...

Problemet är mer det här med function, hur ska jag skriva den delen?

Umbrella 299 – Fd. Medlem
Postad: 16 dec 2021 18:32 Redigerad: 16 dec 2021 18:34

.

Dr. G 9479
Postad: 16 dec 2021 19:07

Du kan t.ex använda feval.

t.ex

f = @(x) x.^2 - exp(x);

feval(f,2)

Bör räkna ut f(2).

Cien 1188
Postad: 16 dec 2021 21:25
Dr. G skrev:

Du kan t.ex använda feval.

t.ex

f = @(x) x.^2 - exp(x);

feval(f,2)

Bör räkna ut f(2).

Jag har gjort så här, har du någon aning varför inte satsen till if f(b)*f(m)<0 körs? Har ex satt f=x

f=input('Ange en funktion: '); % @(x)
a=input('Ange vänstra värdet av intervallet: ');
b=input('Ange högra värdet av intervallet: ');
%tol=input('Ange noggrannhet för nollstället: ');
%I=[a b];

m=(a+b)/2;    % punkten exakt mellan -1 och 0, dvs -1/2.
c=[a,m];      % intervallet c=[-1,-1/2]
d=[m,b];      % intervallet d=[-1/2,0]

grid on
x=linspace(-100,100);
plot(x,f(x))

if f(b)*f(m)<0
    disp('Nollpunkten är i intervallet d');
    a=m;
elseif f(a)*f(m)<0
        disp('Nollpunkten är i intervallet c')
else
    m=[];                          % Tomma mängden
    error('??? Felaktig användning ==> min_bisect Funktionen måste växla tecken på intervallet')
end    
Dr. G 9479
Postad: 16 dec 2021 22:00

Har du satt 

f = @(x) x

?

Cien 1188
Postad: 16 dec 2021 22:05
Dr. G skrev:

Har du satt 

f = @(x) x

?

yes

Dr. G 9479
Postad: 16 dec 2021 22:09

Aha, du har ju nollstället i kanten på intervallet, så produkten blir 0!

Cien 1188
Postad: 16 dec 2021 22:16
Dr. G skrev:

Aha, du har ju nollstället i kanten på intervallet, så produkten blir 0!

ah så klart dumma mig

Svara
Close