File: broyden.e

package info (click to toggle)
euler 1.61.0-12
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 5,164 kB
  • sloc: ansic: 24,761; sh: 8,314; makefile: 141; cpp: 47; php: 1
file content (68 lines) | stat: -rw-r--r-- 1,616 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
comment
Broyden algorithm
endcomment

.. ### Broyden ###

function broyden (ffunction,xstart,A=0)
## broyden("f",x) or broyden("f",x,A;...) finds a zero of f.
## x is the starting value and A is a approximation of the jacobian.
## ... is passed to f(x,...)
## You can specify an epsilon eps with eps=... as last parameter.
	if (isvar("eps")); localepsilon(eps); endif;
	x=xstart; n=cols(x);
	delta=sqrt(epsilon());
	if A==0;
		A=zeros([n n]);
		y=ffunction(x,args());
		loop 1 to n;
			x0=x; x0[#]=x0[#]+delta;
			x1=x; x1[#]=x1[#]-delta;
			A[:,#]=(ffunction(x0,args())-ffunction(x1,args()))'/(2*delta);
		end;
	endif;
	y=ffunction(x,args());
	repeat
		d=-A\y'; x=x+d';
		y1=ffunction(x,args()); q=y1-y;
		A=A+((q'-A.d).d')/(d'.d);
		if d~=0; break; endif;
		y=y1;
	end;
	return x;
endfunction

function nbroyden (ffunction,xstart,nmax,A=0)
## broyden("f",x,n) or broyden("f",x,n,A;...) does n steps of the
## Broyden algorithm.
## x is the starting value and a is a approximation of the jacobian.
## if A is 0, it is neglected.
## ... is passed to f(x,...)
## You can specify an epsilon eps with eps=... as last parameter.
	if (isvar("eps")); localepsilon(eps); endif;
	x=xstart; n=cols(x); r=x;
	delta=epsilon();
	if A==0;
		A=zeros([n n]);
		y=ffunction(x,args());
		loop 1 to n;
			x0=x; x0[#]=x0[#]+delta;
			A[:,#]=(ffunction(x0,args())-y)'/delta;
		end;
	endif;
	y=ffunction(x,args());
	count=0;
	repeat
		count=count+1;
		d=-A\y'; xn=x+d';
		if xn~=x || count>nmax; r=r_xn; break; endif;
		x=xn;
		y1=ffunction(x,args()); q=y1-y;
		A=A+((q'-A.d).d')/(d'.d);
		y=y1;
		r=r_xn;
	end;
	return r;
endfunction