

#Prosty przyklad implementacji pliku funkcyjnego z funkcja ktora implementuje
#metode Newtona znajdowania rozwiazania rownania nieliniowego skalarnego f(x)=0
#z argumentami funkcyjnymi (function handle) 
#ktore imituja w octavie wskazniki do funkcji
function [x,fval,info]=newton(f,x0=0,epsr=1e-7,epsa=1e-9,maxit=30) 
#Metoda Newtona skalarna
#
#Input:
#f - function handle do funkcji postaci y=f(x) ktorej zera szukamy
#przy czym zwracana wartosc y to skalar czyli wartosc f(x) albo 2 elementowy 
#wektor  taki ze y(1)=f(x) a y(2)=f'(x) - wartosc pochodnej w x
# w przypadku pierwszym wartosc f'(x) przyblizona jest przez (f(x+h)-f(x))/h dla  
#h=1e-8
#
#Pozostale parametry opcjonalne
#x - startowe przyblizenie (domyslnie 0) ale mocno polecamy podac lepsze!
#epsr = wzgledna tolerancje 
#epsa - bezwgledna tolerancja
#maxit = max ilosc iteracji
#Output:
#y - przyblizenie zera 
#fval - wartosc f(x)
#info - wynik 0 - zbieznosc; 
#             1   brak zbieznosci - przekroczyl max ilosc iteracji
#             2 - df(x) - zero nie mozna policzyc kolejnego  przyblizenia
# iteracje zatrzymuja sie jak
# zachodzi jedna z dwu
# |f(x)|>epsa + epsr*|f(x0)| lub ilość iteracji = maxit
#
# Przyklad:
# function y=f(x)
#  y=x*x-2;
# endfunction
#
# Wywolujemy:
# y=newton(@f,2) 
# [y,fy,info]=newton(@f,4,1e-2,1e-3) itd
#
#Przyklad z pochodna analityczna
# function y=f1(x)
#  y=[x*x-2;2*x];
# endfunction
#


fx=f(x0);
fx0=fx(1); 
it=0;
info=0;
eps=0.5*(epsr*abs(fx0)+epsa);


if(length(fx)==2) 
  der=0;#dokladna pochodna
else 
  der=1;#pochodna przyblizona
  #ustalamy epsdf - - parametr do obl przyblizonej pochodnej z [1e-7 1e-14]
  epsdf=1e-8;
endif

x=x0;
fval=fx(1);
while((abs(fval)>eps ) && (it<maxit))
  
#liczymy pochodna
 if(der)
  dfx=(f(x+epsdf)-f(x))/epsdf;
 else 
  dfx= fx(2);
 endif
 if(abs(dfx)>1e-12) 
  x=x - fval/dfx;
 else 
  info=2;
  printf("Pochodna df w punkcie x_%d=%g zero!\n",it,x);
  return;
 endif
 it++;
 fx=f(x);
 fval=fx(1);
endwhile

if((abs(fval)>eps ))
 info=1; #brak zbieznosci
 printf("Brak zbieznosci!Po %d iteracjach  |f(%g)|=%g>tol=%g!\n",it-1,x,fval,eps);
endif

endfunction



#Przykladowe funkcje do testow
 function y=sq(x)
  y=[x*x-2;2*x];
 endfunction


