4TLCәp WOo  @`/#@%`')+-/1 3@5`=?/OEGIKMOQ S@U`WY[]_a c@gikmoq s@u`wy{} @` @ ` @ ` @ ` @ ` ǀ ɠ @ ` ׀ ٠  @` @`!Aa   !Aa/#A%a')+-/1!3A5a79;=?A!CAEaGIKMOQ!SAUaWY[]_a!cAeagikmoq!Ouy{}!Aa!AaOo  @`/#@%`')+-/1 3@5`=?/OEGIKMOQ S@U`WY[]_a c@gikmoq s@u`wy{} @` @ ` @ ` @ ` @ ` ǀ ɠ @ ` ׀ ٠  @` @`!Aa   !Aa/#A%a')+-/1!3A5a79;=?A!CAEaGIKMOQ!SAUaWY[]_a!cAeagikmoq!Ouy{}!Aa!AaOK_CREW1993mHPROGS HDOC HeEULER PRG 'N yEULER881PRG M!GEULER RSC {xsFEULER CFG /[OvE PRG PMw"READ_ME TXT!. H.. APPLE E "[BENCH E Xq DEMO E *wm`HELP E Fh8! VJULIA E Ki7KEPLER E btt9iLORENZ E G;yOPTI E {F<!RANDTESTE 6yFARENDITE E õ[C$ SPLINE E ӉF!UTIL E {YHrREAD_ME TXT!.. Show the apple set and investigate it, starts automatically or with .. >test(); function apple1 (z,z0) ## one iteration w=z0+z*z; return w endfunction function apple (z) ## compute 10 iterations w=z; loop 1 to 10; w=apple1(w,z); end: return w endfunction function showapple (a) ## show the apple set in 3D {x,y}=field(linspace(a[1],a[2],50),linspace(a[3],a[4],50)); z=x+1i*y; w=apple(z); view(5,3,-0.75,0.7); twosides(0); wa=abs(w); wa=max(wa,1); l=log(wa); l=2*l/max(max(l)'); framedsolid(x,y,-l,1); return wa; endfunction function showcontour(w) ## show the iterations global x; setplot(x); shrinkwindow(); xplot(); hold on; wl=log(w); contour(wl,linspace(1,max(max(wl)'),10)); title("Klicken Sie einen Punkt an! (Ende -> )"); r=0; repeat; m=mouse(); z=m[1]+1i*m[2]; if m[2]>x[4]; break; endif; {r,R}=iterate("apple1",z,20,z); color(2); plot(re(R),im(R)); color(1); end; hold off; return r endfunction function test() "Bitte einen Moment warten!", x=[-2,0.5,-1.25,1.25]; w=showapple(x); title("Bitte Taste drcken!"); wait(180); showcontour(w); return w; endfunction test();.. Bench function. leert=0; function leer return 0 endfunction function bench(ffunction) ## bench("f",...) returns the time needed by f in milliseconds. ## ... is passed to f. global leert; func=ffunction; t=time(); count=0; repeat; if (time()>t+5); break; endif; func(args(2)); count=count+1; end; argt=(time()-t)/count; return round(argt-leert,6); endfunction leert=bench("leer"); function f1 loop 1 to 1000; end; return 0; endfunction function f2 loop 1 to 1000; endif; end; return 0; endfunction function f3 x=0; loop 1 to 1000; x=3; end; return 0; endfunction function f4 x=0; loop 1 to 1000; x; end; return 0; endfunction function f5 A=zeros([2,2]); loop 1 to 1000; A=[1,2;3,4]; end; return 0; endfunction function f6 A=zeros([2,2]); loop 1 to 1000; A[1,1]=A[1,2]; end; return 0; endfunction function f7 loop 1 to 1000; v=1:10; end; return 0; endfunction function f8 v=1:10; loop 1 to 1000; v{4}=5; end; return 0; endfunction function f9 x=3; loop 1 to 1000; (x+x)*(x+x); end; return 0; endfunction function f10 v=1:10; x=0; loop 1 to 1000; x=v{4}; end; return 0; endfunction function f11 v=1:10; x=0; loop 1 to 1000; v*v; end; return 0; endfunction looptime=0; function musec (ffunction) global looptime; res=bench(ffunction,args(2))*1000-looptime; return {printf("%12.0f musec ",res),res}; endfunction function test global looptime; format(14,6); {text,looptime}=musec("f1"); text|" for one loop.", musec("f2")|" for: endif;", musec("f3")|" for: x=3;", musec("f9")|" for: (x+x)*(x+x);", musec("f4")|" for: x;", musec("f5")|" for: A=[1,2;3,4];", musec("f6")|" for: A[1,1]=A[1,2];", musec("f7")|" for: v=1:10;", musec("f8")|" for: v{4}=3;", musec("f10")|" for: x=v{4};", musec("f11")|" for: v*v;", looptime=0; return 0; endfunction comment ATARI ST values: 376 musecfor one loop. 253 musecfor: endif; 2317 musecfor: x=3; 5912 musecfor: (x+x)*(x+x); 1312 musecfor: x; 6397 musecfor: A=[1,2;3,4]; 7707 musecfor: A[1,1]=A[1,2]; 6362 musecfor: v=1:10; 3552 musecfor: v{4}=3; 3654 musecfor: x=v{4}; 4589 musecfor: v*v; endcomment test(); .. The Demo. Starts automatically. "" "Demo loading." "" demodelay=180; function delay global demodelay; return demodelay endfunction function warten wait(delay()); return 0; endfunction function cplot(z) ## cplot(z) plots a matrix of complex values, which contains the values ## of a function at some rectangular grid. plot(re(z),im(z)); hold on; plot(re(z'),im(z')); hold off; return 0; endfunction function fisch ## plots a fish global Pi; t=0:3; ph=interp(t,[0.05,0.3,0.2,1.2]); pb=interp(t,[0.05,0.5,0.2,0.2]); phi=Pi-linspace(0,2*Pi,20); l=linspace(0,3,40); psin=dup(sin(phi),length(l)); pcos=dup(cos(phi),length(l)); lh=dup(interpval(t,ph,l),length(phi))'; lb=dup(interpval(t,pb,l),length(phi))'; x=pcos*lb; z=psin*lh; y=dup(l-1.5,length(phi))'; view(2.5,1.5,0.3,0.1); solid(x,y,z); title("A solid fish (return)"); warten(); huecolor(1); solidhue(x,y,z,-y,1); title("A shaded fish (return)"); warten(); return 0; endfunction function grafikdemo ## grafikdemo shows the grafik capabilities of EULER fullwindow(); hold off; global Pi; "Demo of EULER's graphics." "" "These graphics have been programmed with a few lines." "Study demo for more information!" weiter(); ## Abbildungen von R nach R t=-Pi:Pi/20:Pi; shrinkwindow(); setplot(-Pi,Pi,-2,2); linewidth(4); plot(t,sin(t)); linewidth(1); hold on; color(2); style("."); plot(t,cos(t)); color(3); style("--"); plot(t,(sin(t)+cos(t))/2); xgrid(-3:1:3,1); ygrid(-1:1,1); title("2D plots (return)"); color(1); style(""); fullwindow(); hold off; warten(); ## Abbildungen von R nach R^2 in vier Fenstern t=-Pi:Pi/50:Pi; window(10,textheight()*1.5,490,490); plot(sin(3*t)/3+cos(t),sin(3*t)/3+sin(t)); hold on; title("Parametric curves (return)"); window(510,textheight()*1.5,1010,490); plot(sin(2*t)/3+cos(t),sin(2*t)/3+sin(t)); window(10,510,490,1010); plot(sin(2*t),sin(3*t)); window(510,510,1010,1010); t=t+2*Pi; plot(cos(t)*log(t),sin(t)*log(t)); hold off; warten(); ## x^2+y^3 als mesh und contour. fullwindow(); t=-1:0.1:1; t=t*Pi; {x,y}=field(t,t); mesh(x*x+y*y*y); title("x^2+y^3 (return)"); warten(); contour(x*x+y*y*y,-30:5:30); title("Contour plot of this function (return)"); warten(); t=-1:0.04:1; t=t*Pi; {x,y}=field(sin(2*t),cos(2*t)); huecolor(1); density(x*y,1); title("Density plot of a function (return)"); warten(); ## e^-r cos(r) als Drahtmodell. t=-1:0.1:1; t=t*Pi; {x,y}=field(t,t); r=x*x+y*y; f=exp(-r)*cos(r); view(2,1,0,0.5); ## [ Abstand, Zoom, Winkel rechts, Winkel hoch ] wire(x/Pi,y/Pi,f); title("Wire frame model (return)"); warten(); ## Der Fisch als solides Modell. fisch(); view(2,1,0.2,0.3); ## Eine complexe Abbildung w=z^1.3 setplot(-1, 2, -0.5, 1.5); t=0:0.1:1; z=dup(t,length(t)); z=z+1i*z'; color(1); style("."); cplot(z); hold on; color(2); style(""); cplot(z^1.3); color(1); xgrid(0); ygrid(0); title("Complex numbers w=z^1.3"); hold off; warten(); "End" return 0 endfunction function weiter "" "<< Press return to continue >>" warten(); "", return 120; endfunction function normaldemo ## Einfhrung in EULER global Pi; pi=Pi; "Hint for window versions:" "" "Use the scrollbars to see the complete text" "(or Shift+Cursorup or PageUp on some systems)," "if the text disappeared." weiter(); " Wellcome at EULER" "" "EULER has been designed to ease numerical computation." "Most of the time one has a tiny problem, to tiny to use a compiler" "language." "" "Besides, one may want to play with intermediate results, see a" "graphical representation, or simply have readily available" "numerical functions." "" "All this can be done with EULER." "It is like using a numerical laboratory." weiter(); "But EULER is not a symbolic algebra program. It uses numbers with" "finite accuracy as supplied by the C compiler used. It is therefore" "faster than a symbolic program, like MATHEMATICA." "" "All commands are entered by the keyboard. Old commands can be" "recalled with cursor up or down. ESC interrupts a computation," "and HELP shows the graphics screen." weiter(); ## Eingabe von Matrizen "With EULER one can enter matrices like this:" "" ">x=[5,6,7]" x=[5,6,7], ">A=[1,2,3;5,6,7;8,9,0]" A=[1 2 3;5 6 7;8 9 0], "The comma may be omitted." "These matrices are stored on the variables x and A." weiter(); "All computing is done element for element." ">x*x" x*x, ">A+A" A+A, weiter(); ## Complexe Zahlen. "Complex numbers and complex computations." ">1+2i", 1+2i, ">c=[1i 3 4+5i]", c=[1i 3 4+5i], "" ">1i*1i", 1i*1i, ">exp(1i*pi/2)", exp(1i*pi/2), weiter(); ## Matrixprodukt. "The dot multiplies two matrices." ">A.x'" A.x' "Note, that x had to be transposed!" "" ">x", x, weiter(); "" ">x'", x', "" ">x'.x" x'.x, weiter(); ## : "Generating vectors:" ">1:10", 1:10, ">-1:0.3:1", -1:0.3:1, weiter(); ">[1 2 3]|[4 5]", [1 2 3]|[4 5], ">[1 2 3]_[4 5 8]", [1 2 3]_[4 5 8], ">dup([1 2 3],4)", dup([1 2 3],4), weiter(); ## Funktionen. "Also all functions are applied to all elements of a matrix." "" ">sqrt([1,2,3,4])" sqrt([1,2,3,4]), "" "There are all the numerical functions." "See an overview with >list." weiter(); "It is easy to generate a table for a function, and with "the table, one can plot the function." "" ">t=0:pi/50:2*pi; s=sin(t); xplot(t,s);" t=0:pi/50:2*pi; s=sin(t); "plots the sine function in [0,2*Pi]", weiter(); shrinkwindow(); xplot(t,s); title("Please press return!"); fullwindow(); warten(); ## Untermatrizen. "Submatrices:" "" ">x=[11 12 13;21 22 23; 31 32 33]" x=[11 12 13;21 22 23; 31 32 33], ">x(1)" x(1), "One can write x[...] or x(...).", weiter(); ">x[1:2,2]", x[1:2,2], ">x[2:6,2:6]" x[2:6,2:6], ">x[:,3]", x[:,3], ">x[1,[2 2 1 3]]", x[1,[2 2 1 3]], weiter(); ## Numerische Integration. "An example:" "" ">sum(sin((1:100)/100))" sum(sin((1:100)/100)), "" "Let us integrate the sine in [0,pi] using the simpson method (but" "not the builtin functions). The exact value is 2." ">t=0:pi/50:pi; n=length(t);", t=0:pi/50:pi; n=length(t); ">f=2*mod((1:n)+1,2)+2; f[1]=1; f[n]=1;", f=2*mod((1:n)+1,2)+2; f[1]=1; f[n]=1; ">result=sum(sin(t)*f)/3*(t[2]-t[1])", longformat(); result=sum(sin(t)*f)/3*(t[2]-t[1]), shortformat(); "" "; surpresses output of intermediate results." weiter(); "By the way:" ">f[1:5]", f[1:5], ">f[n-4:n]", f[n-4:n], weiter(); ## Gleichungssysteme. "Solve linear systems:" "" ">a=hilb(10); b=a.dup(1,10); a\b" "" longformat(); a=hilb(10); b=a.dup(1,10); a\b, shortformat(); "" "The inaccuracy is unavoidable for the Hilbert matrix." weiter(); ## Kurvendiskussion. "A discussion" "" "The function:" ">x=1:0.02:10; y=log(x)/x;" x=1:0.02:10; y=log(x)/x; "The function looks like this (press any key)" warten(); shrinkwindow(); xplot(x,y); ygrid(0); title("(return)"); warten(); "" "The maximal value is: " ">m=max(y)", m=max(y), "" "it is obtained in" ">x(nonzeros(y>=m))", x(nonzeros(y>=m)), "" "The first derivative (numerically)" ">n=length(x); a=(y[2:n]-y[1:n-1])/(x[2:n]-x[1:n-1]);" n=length(x); a=(y[2:n]-y[1:n-1])/(x[2:n]-x[1:n-1]); xplot((x[2:n]+x[1:n-1])/2,a); ygrid(0); title ("(return)"); fullwindow(); warten(); weiter(); return 0 endfunction .. *** Approximations - Demo *** function apprdemo global Pi; pi=Pi; ## L_2-Approximation. "Some approximation problems." "" "First the x-values and the function values are computed:" "" ">x=0:0.02:1; y=sqrt(x);", x=0:0.02:1; y=sqrt(x); "" "Then the matrix of polynomial values:" "" ">n=length(x); p=polyfit(x,y,5),", n=length(x); p=polyfit(x,y,5), "" ">plot(x,y); hold on; color(3); "| .. "plot(x,polyval(p,x)); color(1); hold off;" weiter(); plot(x,y); hold on; color(3); plot(x,polyval(p,x)); color(1); hold off; title("sqrt(x) and its best L_2-approximation (return)"); warten(); plot(x,y-polyval(p,x)); ygrid(0); title("The error (return)"); warten(); "The maximal error in this interval is" "" ">max(abs(y-polyval(p,x)))", max(abs(y-polyval(p,x))), weiter(); ## Interpolation. "Interpolation:" "" ">t=equspace(0,1,5); s=sin(t); d=interp(t,s);", t=equispace(0,1,5); s=sin(t); d=interp(t,s); "" ">x=0:0.01:1; max(x,abs(interpval(t,d,x)-sin(x)))", x=0:0.01:1; max(abs(interpval(t,d,x)-sin(x))), "" ">plot(x,interpval(t,d,x)-sin(x)); ygrid(0); ", weiter(); plot(x,interpval(t,d,x)-sin(x)); ygrid(0); title("Interpolation error (return)"); warten(); ## Fourierreihe. "Discrete Fourier series:" "" ">n=64; t=0:pi/n:2*pi-pi/n; s=(tw[12:2*n-10]=zeros(1, 2*n-21); s1=re(ifft(w));" w[12:2*n-10]=zeros(1, 2*n-21); s1=re(ifft(w)); weiter(); setplot(0, 2*pi, -0.5, 1.5); plot(t,s); hold on; color(3); plot(t,s1); color(1); hold off; title("(return)"); warten(); ## Fourieranalyse. "Fourier analysis" "" "The signal:" ">t=(0:127)*2*pi/128; x=sin(10*t)+2*cos(15*t);" t=(0:127)*2*pi/128; x=sin(10*t)+2*cos(15*t); "" "Add some noise:" ">y=x+normal(size(x));" y=x+normal(size(x)); setplot(0,2*pi,-5, 5); plot(t,x); hold on; color(3); plot(t,y); color(1); title("Signal und signal with noise (return)"); warten(); hold off; "" "Now the Fourier analysis:" ">c=fft(y); p=abs(c)^2;" c=fft(y); p=abs(c); plot(0:64,p(1:65)); xgrid([10,15]); title("Spectral analysis (return)"); warten(); weiter(); return 0; endfunction .. *** Statistik - Demo *** function statdemo ## Statistikdemo. global Pi; pi=Pi; ## t-Test. "Statistics :" "" "Let us generate 10 simulated measurements:" "" ">x=1000+5*normal(1, 10)", x=1000+5*normal(1, 10), "" "Mean value:" ">m=sum(x)/10", m=sum(x/10), "" "Standart deviation:", ">d=sqrt(sum((x-m)^2)/9)," d=sqrt(sum((x-m)^2)/9), weiter(); "" "A 95-% confidence interval for the mean value:" "" ">t=invtdis(0.975,9)*d/3; [m-t,m+t]", t=invtdis(0.975,9)*d/3; [m-t,m+t], weiter(); ## xhi^2 "Statistical evaluation of dice throws." "" ">x=random(1, 600); t=count(x*6,6)'", x=random(1, 600); t=count(x*6,6), "Compute chi^2" ">chi=sum((t-100)^2/100)," chi=sum((t-100)^2/100), "We decide that the dice is unbiased, since" ">1-chidis(chi,5)" 1-chidis(chi,5), weiter(); "Now we simulate a biased dice:" ">x=(x<0.95)*x; t=count(x*6,6), chi=sum((t-100)^2/100);" x=(x<0.95)*x; t=count(x*6,6), chi=sum((t-100)^2/100); "Error probability:" ">1-chidis(chi,5)" 1-chidis(chi,5), weiter(); ## Binomialverteilung "The binomial distribution:" "" ">n=20; t=0:n; p=0.4; b=p^t*(1-p)^(n-t)*bin(n,t);" ">color(3); mark(t,b); color(1);" n=20; t=0:n; p=0.4; b=p^t*(1-p)^(n-t)*bin(n,t); "" ">d=sqrt(n*p*(1-p));" ">s=exp(-((t-20*p)/d)^2/2)/(d*sqrt(2*pi));" ">hold on; plot(t,s); hold off;" weiter(); color(3); mark(t,b); color(1); d=sqrt(n*p*(1-p)); s=exp(-((t-20*p)/d)^2/2)/(d*sqrt(2*pi)); hold on; plot(t,s); title("Binomial and normal distribution (press return)"); hold off; warten(); ## Mehrfeldertest "chi^2 test:" "" "Given the matrix:" ">a" format(5,0); a=[23,37,43,52,67,74;45,25,53,40,60,83]; a, shortformat(); "" "The matrix of expected values:" ">{k,l}=field(sum(a')',sum(a)'); s=totalsum(a); b=(k*l)/s;" {k,l}=field(sum(a')',sum(a)'); s=totalsum(a); b=(k*l)/s; weiter(); "Compute chi^2:" ">chi=totalsum((a-b)^2/b); 1-chidis(chi,5)," chi=totalsum((a-b)^2/b); 1-chidis(chi,5), "" "That means we decide that the columns do not depend of the rows." weiter(); ## Regression. "Regression analysis:" "" "A linear function with errors: " "" ">t=0:0.2:5; s=2*t+3+0.2*normal(size(t));", t=0:0.2:5; s=2*t+3+0.2*normal(size(t)); ">p=polyfit(t,s,1),", p=polyfit(t,s,1), ">color(3); mark(t,s); hold on; color(1); plot(t,polyval(p,t)); hold off;" weiter(); color(3); mark(t,s); hold on; color(1); plot(t,polyval(p,t)); hold off; title("The best fit (press return)"); warten(); return 0; endfunction function fibo(n) ## fibo(n) liefert einen Vektor mit den ersten n Finonaccizahlen. if (n<3) return [1 1]; endif; f=ones(1, n); for i=3 to n; f[i]=f[i-1]+f[i-2]; end; return f endfunction function itertest(x) ## itertest(x) konvergiert gegen sqrt(2). repeat; x=(x+2/x)/2; x, if x*x~=2; break; endif; end; return x; endfunction function multitest return {arg1,arg1*arg1} endfunction function hut (x,y) si=size(x,y); z=zeros(si); loop 1 to prod(si); r=x{#}^2+y{#}^2; if r<1; z{#}=exp(-1/(1-r)); endif; end; return exp(1)*z endfunction function udfdemo "EULER is programmable.", "" "As an example we list a function, which computes the first n" "fibonacci numbers when called with fibo(n):" weiter(); ">type fibo", type fibo; ">fibo(5)", fibo(5), weiter(); "As you can see, a function starts with" ">function name" "and ends with" ">end"|"function" "Every function must have a return statement, which stops it." weiter(); "Arguments are named arg1, arg2, arg3, ...," "unless they are given names in the function header." "argn() gives the number of arguments. All variables are local and" "cease to exist after function execution is finished." "But the command" ">global name" "allows acces of a global variable." weiter(); "There are:" "" "Conditionals:" ">if condition; ... { else; ... } endif;" "" "The condition can be any expression, especially a test like < > etc." "Logical connections are made with || (or) and && (and)." "!condition means: not condition." weiter(); "Repetitive statements:" ">for variable=start to end { step value }; ... end;" ">loop start to end; ... end;" ">repeat; ... end;" weiter(); "In loop's the index can be accessed with index() or #." "All these statements can be left with a break; or return ...;" weiter(); "" "Example:" "" type itertest "" ">longformat(); itertest(1.5), shortformat();", longformat(); itertest(1.5), shortformat(); weiter(); "A function can return multiple values and these values can be" "assigned to several variables." "" "Syntax:" ">return {variable,variable,...}" "The brackets { and } are part of the syntax here." "Then the multiple assignment looks like:" ">{a,b}=test(parameter)" weiter(); "An example:" "" type multitest "" "{a,b}=multitest(2); a, b,", {a,b}=multitest(2); a, b, weiter(); "Comments start with #"|"#. Comments are not listet with type." "If the first lines of a functions start with #"|"#," "they are considered help text. With help this text can be read." "" ">help field" "", help field, weiter(); "Since all EULER functions work for vector and matrix input," "user defined functions should be written the same way." "Most of the time, this is automatic. But sometimes a function" "uses a complicate algorithm or cases. Then there is the {} indexing" "which treats the matrix like a vector." weiter(); ">type hut", type hut "" v=view(5,2,0,0.4); ">{x,y}=field(-1.2:0.2:1.2,-1.2:0.2:1.2); framedsolid(x,y,hut(x,y));", {x,y}=field(-1.2:0.2:1.2,-1.2:0.2:1.2); framedsolid(x,y,hut(x,y)); title("(return)"); view(v); wait(delay()); "" shrinkwindow(); ">x=-2:0.05:2; xplot(x,hut(x,0));", x=-2:0.05:2; xplot(x,hut(x,0)); title("(return)"); wait(delay()); fullwindow(); weiter(); "Functions should be written with an external editor." "You can start an editor from within EULER, like any other program." "(Not for XWindow version)" "" ">exec string", weiter(); "The string must be in double quotes or must be a variable, which" "has been assigned a string. It consists of the program name and" "paramters to be passed to the program; e.g.," "" ">exec "|char(34)|"editor.prg testfile"|char(34), "" "or" "" "a="|char(34)|"editor.prg test"|char(34)|"; a", a="editor.prg test"; a, "" ">exec a" "(Calls Editor.prg)" weiter(); "You can echo output to a file" "" ">dump filename" "" "Again, filename must be string expression." weiter(); "With" ">dump" "echoing is stopped and the file closed." "" "Dumps are always appended to the file." "With" ">remove filename" "the file is removed (killed)." "" "By the way:" ">forget f; clear a;" "removes a function and the variable a." weiter(); return 0 endfunction function f(x) return exp(x)-1.5; endfunction function dgl(x,y) return -2*x*y; endfunction function specialdemo ## Simpson "Simpson integral : ", "" ">type f", type f; "" ">t=simpson("|char(34)|"f"|char(34)|",0,1)", t=simpson("f",0,1), "" "The error : " "" "t-(exp(1)-2.5)," t-(exp(1)-2.5), weiter(); ## Bisektion "Solutions of an equation : " "" ">type f", type f; "" ">t=bisect("|char(34)|"f"|char(34)|",0,1),", t=bisect("f",0,1), "" "Error : " "" ">t-log(1.5)", t-log(1.5), weiter(); ## Differentialgleichung "Differential equations : " "" ">type dgl", type dgl; "" ">t=0:0.05:2; s=heun("|char(34)|"dgl"|char(34)|",t,1); plot(t,s);" t=0:0.05:2; s=heun("dgl",t,1); plot(t,s); title("(return)"); warten(); "" "Maximal error : " "" ">max(abs(s-exp(-t^2)))", max(abs(s-exp(-t^2))), weiter(); ## Eigenwerte : "Eigenvalues and eigenvectors : " "" "Given the matrix" ">A=[0,1;1,1]", A=[0,1;1,1], "" "We compute the eigenvalues and eigenvectors of A." ">{l,V}=eigen(A); l=re(l)," {l,V}=eigen(A); l=re(l)," ">V=re(V)," V=re(V), weiter(); "Then V'.D.V=A." "" ">D=diag(size(A),0,l); V'.D.V," D=diag(size(A),0,l); V'.D.V, weiter(); return 0; endfunction function taste "<< Please press return >>", "", return wait(delay()); endfunction function grafiktutor ## Erklrt die Grafikfunktionen hold off; global Pi; "Explanation of some grafics functions." "" "First we compute a vector of x-values." ">x=-1:0.02:1;" x=-1:0.02:1; "Then we compute the function at these points." ">y=sin(4*Pi*x)*exp(-x*x);" y=sin(4*Pi*x)*exp(-x*x); "Finally we can plot the function." ">plot(x,y);" taste(); plot(x,y); wait(delay); "The plot can be given a title." ">title("|char(34)|"sin(4*Pi*x)*exp(-x*x),(return)"| .. char(34)|");" taste(); title("sin(4*Pi*x)*exp(-x*x),(return)"); wait(delay()); "For x- and y-grids, we use the following commands." ">xgrid(-0.5:0.5:0.5); ygrid(-1:0.5:1);" taste(); xgrid(-0.5:0.5:0.5); ygrid(-1:0.5:1); wait(delay); "To draw another plot above it, we use the hold command.", ">hold on; plot(x,cos(4*Pi*x)*exp(-x*x)); hold off;" taste(); hold on; plot(x,cos(4*Pi*x)*exp(-x*x)); hold off; wait(delay); "One can plot several curves wth a single plot command." "", "This time, the grid is to have labels." ">shrinkwindow();" shrinkwindow(); "", ">{x,n}=field(linspace(-1,1,50),1:5); T=cos(n*acos(x));" {x,n}=field(linspace(-1,1,50),1:5); T=cos(n*acos(x)); "This way we computed 5 rows of 5 functions cos(n*acos(x))." "", "First we set the plot region manually.", ">setplot(-1.5,1.5,-1.5,1.5);" "The we plot all functions." ">plot(x,T); xgrid(-2:2,1); ygrid(-2:2,1); wait(delay); hold off;" setplot(-1.5,1.5,-1.5,1.5); plot(x,T); xgrid(-2:2,1); ygrid(-2:2,1); wait(delay); hold off; "One can also mark a point on the screen with the mouse." ">title("|char(34)|"Click the left mouse button."|char(34)| .. "); c=mouse(); c," taste(); if delay>30; title("Click the left mouse button."); c=mouse(); c, "These are the coordinates, you choose." taste(); endif; "Now a function with a singularity." "" ">t=-1:0.01:1; setplot(-1,1,-10,10); xplot();" t=-1:0.01:1; setplot(-1,1,-10,10); xplot(); ">hold on; plot(t,1/t); plot(t,1/t^2); hold off;" hold on; plot(t,1/t); plot(t,1/t^2); hold off; "" taste(); title("1/t and 1/t^2 (return)"); wait(delay()); "Functions of two variables :" "" "First we compute a grid of x- and y-coordinates." ">{x,y}=field(-1:0.1:1,-1:0.1:1);" {x,y}=field(-1:0.1:1,-1:0.1:1); "", "Then we compute the function values at these grid points and" "draw them." ">z=x*x+x*y-y*y; mesh(z);" taste(); z=x*x+x*y-y*y; fullwindow(); mesh(z); wait(delay()); "The contour level lines of these function we can inspect with" ">contour(z,-3:0.5:3);" taste(); contour(z,-3:0.5:3); wait(delay); "A perspective view of the same surface." ">view(2.5,1,1,0.5); solid(x,y,z);" taste(); view(2.5,1,1,0.5); solid(x,y,z); wait(delay); "A wire fram model." ">wire(x,y,z);" taste(); wire(x,y,z); wait(delay); return 0 endfunction function abspann "As I think, this demo has given you a good impression. So" "EULER is well suited for many tasks in applied mathematics, as" "well as for viewing functions of one or two variables." "" "The author wishes you succes with mathematics and EULER!" return 0 endfunction function torus ## some torus type bodies. view([4,1,0,0.6]); global Pi; x=linspace(0,2*Pi,40); y=linspace(0,2*Pi,20); cosphi=dup(cos(x),length(y)); sinphi=dup(sin(x),length(y)); cospsi=dup(cos(y'),length(x)); sinpsi=dup(sin(y'),length(x)); ## faster than {phi,psi}=field(x,y); cosphi=cos(phi); ... ## a torus with a thick and a thin side. factor=1.5+cospsi*(cosphi/2+0.6); X=cosphi*factor; Y=sinphi*factor; Z=sinpsi*(cosphi/2+0.6); solid(X,Y,Z); title("(Return)"); wait(delay); ## a deformed torus factor=1.5+cospsi; X=cosphi*factor; Y=sinphi*factor; Z=sinpsi+dup(cos(2*x),length(y)); solid(X,Y,Z); title("(Return)"); wait(delay); ## the Moebius band t=dup(linspace(-1,1,20)',length(x)); x=linspace(0,Pi,40); cosphi1=dup(cos(x),length(y)); sinphi1=dup(sin(x),length(y)); factor=2+cosphi1*t; X=cosphi*factor; Y=sinphi*factor; Z=sinphi1*t; solid(X,Y,Z); title("Return"); wait(delay); return 0; endfunction function tube ## some tube like bodies. view([3,1,0,0.1]); global Pi; x=linspace(0,2*Pi,40); ## a atomic modell or so. y=0.1+(sin(linspace(0,Pi,15))| .. 1.5*sin(linspace(0,Pi,10))|sin(linspace(0,Pi,15))); cosphi=dup(cos(x),length(y)); sinphi=dup(sin(x),length(y)); f=dup(y',length(x)); solid(f*cosphi,f*sinphi,dup(linspace(-2,2,length(y)-1)',length(x))); title("(Return)"); wait(delay); ## a black hole t=linspace(0,1,20); cosphi=dup(cos(x),length(t)); sinphi=dup(sin(x),length(t)); f=dup((t*t+0.2)',length(x)); view([3,1.5,0,0.7]); solid(f*cosphi,f*sinphi,dup(t'*2-1,length(x))); title("(Return)"); wait(delay); return 0; endfunction function minimal (r,phi) R=dup(r',length(phi)); X=R*dup(cos(phi),length(r))+R*R/2*dup(cos(2*phi),length(r)); Y=-R*dup(sin(phi),length(r))-R*R/2*dup(sin(2*phi),length(r)); Z=4/3*dup((r^1.5)',length(phi))*dup(cos(1.5*phi),length(r))-1; view(9,1,-1.5,0.2); solid(X,Y,Z); title("A minmal surface (Return)"); wait(delay); return 0; endfunction function spiral {r,a}=field(0:0.1:1,0:pi()/8:6*pi()); z=a/8; x=r*cos(a)*(1-a/20); y=r*sin(a)*(1-a/20); z=z-1.5; view(4,1.5,0.5,0.3); framedsolid(x,y,z); title("(Return)"); wait(delay); return 0; endfunction function rings rr=0.2; t=linspace(0,2*pi,10); s=linspace(0,2*pi,41); n=length(s); r=dup(1+cos(t)*rr,n)'; m=length(t); x=dup(cos(s),m)*r; y=dup(sin(s),m)*r; z=dup(sin(t)*rr,n)'; view([4,1.5,0.3,0.3]); X=x_(x+1.3)_(x-1.3); Y=y_-z_-z; Z=z_y_y; solid(X,Y,Z,[m,2*m]); return 0; endfunction function startdemo {x,y}=field(-1:0.1:1,-1:0.1:1); z=x*x+y*y; mesh(z); title("(Return)"); wait(delay); return 0; endfunction function demo3d startdemo(); torus(); tube(); minimal(0.1:0.1:2.5,0:pi()/20:2*pi()); spiral(); rings(); return 0; endfunction function demos normaldemo(); grafikdemo(); apprdemo(); statdemo(); udfdemo(); specialdemo(); grafiktutor(); demo3d(); return 0; endfunction; function demo (del) global demodelay; if argn==1; demodelay=del; endif; repeat; shortformat(); style(""); fullwindow(); color(1); hold off; demos(); abspann(); weiter(); end; return 0 endfunction "" type demos "" "Use one of the above, or type demo() or demo(10)." "<< Demo will start after 10 seconds. Press Esc to stop it. >>" wait(10); demo();.. Help texts. comment *** Builtin functions: abs acos any arg argn args asin atan band bandmult bin cd ceil char charpoly chidis color complex conj contour cos count ctext cumprod cumsum diag diag dup epsilon error errorlevel eval exp extrema fak fdis fft find flipx flipy floor format framecolor free hb holding holding ifft im index input interp interpret interpval invnormaldis invtdis iscomplex isreal jacobi key lineinput linestyle log lu lusolve mark markerstyle matrix max max mesh meshfactor min min mod mouse name nonzeros normal normaldis ones pi plot plot polyadd polycons polydiv polymult polyroot polysolve polytrans polytrunc polyval printf prod project random re round scale scaling searchfile searchfile setdiag setepsilon setkey setplot shrink sign sin size solid sort sqrt stringcompare style sum symmult tan tdis text textcolor textsize time triangles twosides view view wait window window wire wirecolor zeros *** Commands: break clear clg cls comment do dump else end endif exec for forget function global help hexdump hold if list load loop memorydump meta output quit remove repeat return shg type *** Your functions: dir window view matrix zeros ones random normal format diag text ctext splineval spline iterate map broyden gauss gauss10 romberg simpson secant bisect heun arcosh arsinh cosh sinh totalsum field polyfit hilb eigennewton eigen1 eigenremove eigenspace1 eigen eigenspace eigenvalues det image kernel fit inv id framedwire framedsolid scaleframe frame2 frame1 framexmym framexmyp framexpym framexpyp framez1 framez0 getframe plotwindow cplot mark plot ygrid xgrid printscale fplot xmark xplot ticks setplot shrinkwindow fullwindow textwidth textheight title write writeform polydif length equispace linspace shortformat longformat reset endcomment function abs ## abs(x) returns the absolute value of x, |x|. error("Illegal argument number!"), endfunction function acos ## acos(x) returns the arcus cosine of x. ## Works for complex arguments also. error("Illegal argument number!"), endfunction function argn ## argn() returns the number of arguments of the active function. error("Illegal argument number!"), endfunction function args ## args(n) returns all arguments of a function from the n-th on. error("Illegal argument number!"), endfunction function asin ## asin(x) returns the arcus sine of x. ## Works for complex arguments also. error("Illegal argument number!"), endfunction function atan ## atan(x) returns the arcus tangens of x. ## Works for complex arguments also. error("Illegal argument number!"), endfunction function band ## band(A,c1,c2) sets all elements a(i,j) of A, for which ## c1 <= j-i <= c2 is not true, to 0. error("Illegal argument number!"), endfunction function bandmult ## bandmult(A,B) multiplies A with B, but is faster than A.B, if A or B ## contain many zeros. error("Illegal argument number!"), endfunction function sin ## sin(x) returns the sine of x. ## Works for complex arguments also. error("Illegal argument number!"), endfunction function cos ## cos(x) returns the cosine of x. ## Works for complex arguments also. error("Illegal argument number!"), endfunction function tan ## tan(x) returns the tangens of x. ## Works for complex arguments also. error("Illegal argument number!"), endfunction function bin ## bin(n,m) returns the "n over m", i.e., n!/(m!*(n-m)!). error("Illegal argument number!"), endfunction function cd ## cd("") shows the active directory. ## cd("Path") sets the active directory to Path. error("Illegal argument number!"), endfunction function ceil ## ceil(x) returns the smallest integer n>=x. error("Illegal argument number!"), endfunction function floor ## floor(x) returns the greatest integer n<=x. error("Illegal argument number!"), endfunction function char ## char(x) returns a string with a single character with ASCII code x. error("Illegal argument number!"), endfunction function chidis ## chidis(x,n) returns the chi^2 distribution of x with n degrees of ## freedom, i.e., the probability, that the sum of n normal distributed ## squared random variables is smaller than x. error("Illegal argument number!"), endfunction function color ## color(n) sets the plotting color to n, returns old color. error("Illegal argument number!"), endfunction function complex ## complex(a) returns 1, if a is complex. error("Illegal argument number!"), endfunction function conj ## conj(a) returns the complex conjugate of a. error("Illegal argument number!"), endfunction function contour ## contour(A,v) plots a contour plot of A at heights equal to the ## elements of v. error("Illegal argument number!"), endfunction function count ## count(v,n) counts the elements of the vector v in the intervals ## [0,1),[1,2),...,[n-1,n]. Thus a 1xn vector is returned. error("Illegal argument number!"), endfunction function cumprod ## cumprod(A) returns a matrix of the same size as A, containing ## the cumulative product of the rows of A, i.e., ## b(i,j) = prod(k=1 to j) a(i,k). error("Illegal argument number!"), endfunction function cumsum ## cumsum(A) returns a matrix of the same size as A, containing ## the cumulative sum of the rows of A, i.e., ## b(i,j) = sum(k=1 to j) a(i,k). error("Illegal argument number!"), endfunction function dup ## dup(v,n) returns a Matrix with n rows, each equal to v. error("Illegal argument number!"), endfunction function epsilon ## epsilon() returns the internally used epsilon. ## epsilon()=1e-8 is a correct assignment. ## The variable Epsilon is set in "util" to epsilon(). error("Illegal argument number!"), endfunction function pi ## pi() returns pi. The variable Pi is set in "util". error("Illegal argument number!"), endfunction function error ## error("s") aborts a function and prints the error text s. error("Illegal argument number!"), endfunction function errorlevel ## errorlevel("s") interprets "s" and returns the error code. ## The error is set to 0. This is a test function. error("Illegal argument number!"), endfunction function eval ## eval("f",...) evaluates the function f at the points ... ## f must be a user defined function! error("Illegal argument number!"), endfunction function exp ## exp(x) returns the exponential of x, i.e., e^x. error("Illegal argument number!"), endfunction function framecolor ## framecolor(n) sets the frame color to n, returns old color. error("Illegal argument number!"), endfunction function log ## log(x) return the natural logarithm of x. error("Illegal argument number!"), endfunction function sqrt ## sqrt(x) return the square root of x. error("Illegal argument number!"), endfunction function extrema ## extrema(A) returns a matrix, containing the rows [min imin max imax]. ## min and max are the minima and the maxima of the rows of A. ## imin and imax are the columns where these are obtained. error("Illegal argument number!"), endfunction function fak ## fak(n) returns n!. error("Illegal argument number!"), endfunction function fdis ## fdis(x,n,m) returns the F-distribution with n and m degrees of freedom. error("Illegal argument number!"), endfunction function fft ## fft(v) return the Fourier transform of v, obtained the fast way. error("Illegal argument number!"), endfunction function find ## find([v1,...,vn],x) finds the index i, such that v(i)<=xv(n). error("Illegal argument number!"), endfunction function flipx ## flipx(A) flips the matrix such that the last column becomes the first. error("Illegal argument nubmer!"), endfunction function flipy ## flipy(A) flips the matrix such that the last row becomes the first. error("Illegal argument nubmer!"), endfunction function free ## free() returns the number of free bytes. error("Illegal argument number!"), endfunction function ifft ## ifft(v) returns the inverse Fourier transform of v. error("Illegal argument number!"), endfunction function im ## im(z) returns the imaginary part of z. error("Illegal argument number!"), endfunction function re ## re(z) returns the real part of z. error("Illegal argument number!"), endfunction function index ## index() returns the looping index in loops. error("Illegal argument number!"), endfunction function input ## input("s") prints s and a prompt, than evaluates the user input. ## The input can be any EULER expression, and may contain variables. error("Illegal argument number!"), endfunction function interp ## interp(x,y,n) computes the polynomial interpolation of degree n ## at the points x with values y. The polynomial is returned in ## the form of divided differences. error("Illegal argument number!"), endfunction function interpval ## interpval(x,d,t) evaluates the divided differences d at the points t. ## E.g., interpval(x,interp(x,y),x) returns y. error("Illegal argument number!"), endfunction function invnormaldis ## invnormaldis(y) returns the inverse normal distribution. ## See normaldis. error("Illegal argument number!"), endfunction function normaldis ## normaldis(x) returns the normal distribution at x; i.e., ## the probability that a normal distributed unit random variable is ## less than x. error("Illegal argument number!"), endfunction function invtdis ## invtdis(x,n) returns the invers T-distribution with n degrees of ## freedom. See tdis. error("Illegal argument number!"), endfunction function tdis ## tdis(x,n) returns the T-distribution with n degrees of freedom, ## i.e. the probability, that a sample of n normal distributed ## unit random variables scaled with mean value and standard deviation ## of the sample is less than x. error("Illegal argument number!"), endfunction function isreal ## isreal(x) return 1 if x is real. error("Illegal argument number!"), endfunction function iscomplex ## iscomplex(x) return 1 if x is not real. error("Illegal argument number!"), endfunction function jacobi ## jacobi(A) uses the Jacobi algorithm to determine the eigenvalues ## of A. A must be symmetric and real. Returns the vector of eigenvalues. error("Illegal argument number!"), endfunction function lu ## lu(A) returns a LU-decomposition of A obtained by the Gauss method. ## The result is {lu,ri,ci,det}, where det is the determinant. ## lu contains the lu decomposition in a single matrix. ## ri contains the indices of the rows of lu, since these may have ## been swept. ## ci contains 1 or 0, where 1 marks the linar undependent rows of lu. ## See lusolve also. error("Illegal argument number!"), endfunction function lusolve ## lusolve(LU,b) solves A.x=b, if LU is a LU-decomposition of A. error("Illegal argument number!"), endfunction function max ## max(A) contains a column vector with the maxima of the rows of A. ## max(x,y) returns the maximum of x and y. error("Illegal argument number!"), endfunction function min ## min(A) contains a column vector with the minima of the rows of A. ## max(x,y) returns the maximum of x and y. error("Illegal argument number!"), endfunction function mesh ## mesh(A) plots a 3-D plot of the the matrix A. error("Illegal argument number!"), endfunction function mod ## mod(n,m) returns n modulo m. error("Illegal argument number!"), endfunction function mouse ## mouse() switches to graphics and shows a mouse cursor. ## When the user clicks with the left mouse button the (x,y)-coordinates ## at this point according to the last plot are returned. error("Illegal argument number!"), endfunction function nonzeros ## nonzeros(v) contains a vector, containing the indices of the nonzero ## elements of v. error("Illegal argument number!"), endfunction function hb ## hb(A) computes the Hessenberg form of A. Returns {B,r} such that ## band(B(r,r),-1,n) is the Hessenberg form. error("Illegal argument number!"), endfunction function polyadd ## polyadd(p,q) adds two polynomials p and q. error("Illegal argument number!"), endfunction function polycons ## polycons([z1,z2,...]) computes a polynomials with zeros in zi. error("Illegal argument number!"), endfunction function polydiv ## polydiv(p,q) divides two polynomials with remainder. Returns ## {result,remainder}. error("Illegal argument number!"), endfunction function polymult ## polymult(p,q) multiplies two polynomials. error("Illegal argument number!"), endfunction function polyroot ## polyroot(p,z) returns a zero of the polynomial p close to z. error("Illegal argument number!"), endfunction function polysolve ## polysolve(p) returns a vector with the zeros of p. error("Illegal argument number!"), endfunction function polytrans ## polytrans(x,d) transforms the divided differences form, return by ## interp to the usual polynomial form. error("Illegal argument number!"), endfunction function polytrunc ## polytrunc(p) truncates a polynomial to its smallest representation, ## i.e., its length is then the true degree plus 1. error("Illegal argument number!"), endfunction function polyval(p,x) ## polyval(p,x) returns the value of the polynomial p at x, i.e. ## p(1)+p(2)*x+...+p(n)*x^(n-1). error("Illegal argument number!"), endfunction function printf ## printf("format",value) returns a string, displaying the value ## with respect to the format in C syntax, e.g., ## "Zahl = "|printf("%16.10f",x), outputs x in a nice way. error("Illegal argument number!"), endfunction function project ## project(x,y,z) returns {x1,y1}, which is the projection of the ## coordinates x,y,z to the screen coordinates. error("Illegal argument number!"), endfunction function prod ## prod(A) returns a vector containing the products of the rows of A. error("Illegal argument number!"), endfunction function sum ## sum(A) returns a vector containing the sums of the rows of A. error("Illegal argument number!"), endfunction function symmult ## symmult(A,B) multiplies A with B, and returns a symmetric result. ## I.e., only the upper half of A.B is computed. error("Illegal argument number!"), endfunction function round ## round(x,n) rounds x to n digits. error("Illegal argument number!"), endfunction function searchfile ## searchfile("Pattern") searches for a file, matching the pattern. ## searchfile() searches another file matching this pattern. ## Returns "", if there is no (more) such file. error("Illegal argument number!"), endfunction function scale ## scale(s) scales the gaphic output so that it appears in a ## horizontal/vertical ratio of about s. If s is 0, then the full ## screen is used. error("Illegal argument number!"), endfunction function setdiag ## setdiag(A,k,v) sets the k-th diagonal of A to v (see diag). error("Illegal argument number!"), endfunction function setkey ## setkey(n,"text") sets the function key n to produce "text". error("Illegal argument number!"), endfunction function shrink ## shrink(n) shrinks the memory by n bytes to make space for editors etc. error("Illegal argument number!"), endfunction function sign ## sign(x) returns the sign of x. error("Illegal argument number!"), endfunction function size ## size(A) returns the size of the matrix A in form [rows,columns]. ## size(A,B,x,C,y,...) returns the size of A,B,C,.. which must agree. error("Illegal argument number!"), endfunction function solid ## solid(X,Y,Z) plots a solid three dimensional hyperplane with ## coordinates X,Y and Z. All these must be matrizes of the same ## dimensions. error("Illegal argument number!"), endfunction function sort ## sort(v) sorts the vector v. Returns {vs,i}, such that v(i)=vs; error("Illegal argument number!"), endfunction function style ## style("s") sets the style of plots and markers. ## For plots, there are ".", "-", "--", "i" (invisible). ## For markers, there are "mx", "m<>", "m.", "m+", "m[]", "m*". ## All other strings reset the default values. error("Illegal argument number!"), endfunction function markerstyle ## markerstyle("s") sets the style of markers. ## For markers, there are "mx", "m<>", "m.", "m+", "m[]", "m*". ## Return the old setting. error("Illegal argument number!"), endfunction function linestyle ## linestyle("s") sets the style of plots. ## For plots, there are ".", "-", "--", "i" (invisible). ## Return the old setting. error("Illegal argument number!"), endfunction function linewidth ## linewidth(n) sets the line width unless n==0. ## Returns the old line width. error("Illegal argument number!"), endfunction function stringcompare ## stringcompare("string1","string2") compares the two strings. ## Returns 0 if both are equal, 1 if string1 is bigger than string2, ## -1 else. error("Illegal argument number!"), endfunction function text ## text("string",[c,r]) displays the string at column c and row r error("Illegal argument number!"), endfunction function textcolor ## textcolor(n) sets the text color to n, returns old color. error("Illegal argument number!"), endfunction function textsize ## textsize() returns [width,height] of a single character in screen ## coordinates (0..1023,0..1023). error("Illegal argument number!"), endfunction function time ## time() returns a timer, running in seconds. error("Illegal argument number!"), endfunction function triangles ## triangles(flag) turns triangle meshing on and off. error("Illegal argument number!"), endfunction function twosides ## twosides(flag) turns shading in mesh and solid on and off. error("Illegal argument number!"), endfunction function wait ## wait(n) waits for n seconds, or until a key was pressed. error("Illegal argument number!"), endfunction function wire ## wire(X,Y,Z) works like solid, exept the plot is a wire frame. error("Illegal argument number!"), endfunction function wirecolor ## color(n) sets the wire color to n, returns old color. error("Illegal argument number!"), endfunction .. commands function break ## break -> breaks a current loop, for, or repeat. error("Illegal argument number!"), endfunction function clg ## clg -> clears the graphics screen. error("Illegal argument number!"), endfunction function cls ## cls -> clears the text screen. error("Illegal argument number!"), endfunction function clear ## clear -> clears the local variables. ## clear variable -> clears the variable. error("Illegal argument number!"), endfunction function comment ## comment -> searches for a line starting with "endcomment". error("Illegal argument number!"), endfunction function do ## do function -> does the commands of the function without parameters. ## return returns from do. error("Illegal argument number!"), endfunction function dump ## dump "file" -> dumps screen output also to a file. ## dump -> stops dumping to file. error("Illegal argument number!"), endfunction function if ## if ..; ..; else, ..; endif; -> EULER's if construction. error("Illegal argument number!"), endfunction function global ## global x -> allows the global variable x to be accessed in a function. error("Illegal argument number!"), endfunction function exec ## exec "file.prg strings" -> executes file.prg (may also be file.tos) ## with parameters in strings. error("Illegal argument number!"), endfunction function forget ## forget function -> kills the function from memory. error("Illegal argument number!"), endfunction function for ## for i=0 to 10 step 2; ..; end; -> EULER's for loop. error("Illegal argument number!"), endfunction function repeat ## repeat; ..; end; -> eternal loop. Abort with break! error("Illegal argument number!"), endfunction function help ## help function -> prints the help lines of a function. error("Illegal argument number!"), endfunction function type ## type function -> types the lines of a function. error("Illegal argument number!"), endfunction function hexdump ## hexdump variable -> prints the hexadecimal content of a variable, i.e. ## the internal representation. error("Illegal argument number!"), endfunction function hold ## hold on -> holds the current plot. ## hold off -> the next plot will delete the current plot. ## hold -> hold on and notices old holding state; next hold restores it. error("Illegal argument number!"), endfunction function list ## list -> list the functions. error("Illegal argument number!"), endfunction function memorydump ## memorydump -> displays all internal objects and their sizes. error("Illegal argument number!"), endfunction function meta ## meta "filename" -> aktiviert ein Metafile. ## meta; -> deaktiviert das Metafile. error("Illegal argument number!"), endfunction function output ## output on -> switches output of results on. ## output off -> switches it off. Useful in connection with dump. ## output -> toggles. error("Illegal argument number!"), endfunction function quit ## quit -> exits EULER (no verification!) error("Illegal argument number!"), endfunction function remove ## remove "file" -> kills the file from disk! error("Illegal argument number!"), endfunction function return ## return x -> exits a function with value x. error("Illegal argument number!"), endfunction function load ## load "filename" -> loads the commands in the file, as if they were ## input from the console. error("Illegal argument number!"), endfunction "Online help for builtin functions loading." "Enter" ">help sin" "for help on sin." .. Show the apple set and investigate it, starts automatically or with function apple1 (z) ## one iteration w=1i+z*z; return w endfunction function apple (z) ## compute 10 iterations w=z; loop 1 to 10; w=apple1(w); end: return w endfunction function showapple (a) ## show the apple set in 3D {x,y}=field(linspace(a[1],a[2],50),linspace(a[3],a[4],50)); z=x+1i*y; w=apple(z); view(5,3,-0.75,0.7); twosides(0); wa=abs(w); wa=max(wa,1); l=log(wa); l=2*l/max(max(l)'); framedsolid(x,y,-l,1); return wa; endfunction x=[-2,2,-2,2]; w=showapple(x); title("Bitte Taste drcken!"); wait(180); function test(w) ## show the iterations global x; setplot(x); shrinkwindow(); xplot(); hold on; wl=log(w); contour(wl,linspace(1,max(max(wl)'),10)); title("Klicken Sie einen Punkt an! (Ende -> )"); r=0; repeat; m=mouse(); z=m[1]+1i*m[2]; if m[2]>x[4]; break; endif; {r,R}=iterate("apple1",z,20); color(2); plot(re(R),im(R)); color(1); end; hold off; return r endfunction test(w);.. Demonstrates planet movements reset; function force (x,y) ## simple force of a single body at (0,0) r=x*x+y*y; r=r*sqrt(r); return {-x/r,-y/r} endfunction function dgl (t,p) {fx,fy}=force(p{1},p{2}); return [p{3},p{4},fx,fy]; endfunction function showcurve ## demonstrates the one body problem t=linspace(0,4,100); setplot(-1.5,1.5,-1.5,1.5); xplot(); hold on; s=heun("dgl",t,[1,0,0,1]); plot(s[1],s[2]); s=heun("dgl",t,[1,0,0,0.9]); plot(s[1],s[2]); s=heun("dgl",t,[1,0,0,0.8]); plot(s[1],s[2]); s=heun("dgl",t,[1,0,0,0.7]); plot(s[1],s[2]); hold off; return plot(); endfunction "showcurve defined" function showpotential ## demonstrates the Newton potential {x,y}=field(linspace(-0.9,1.1,23),linspace(-1,1,23)); p=max((-1)/sqrt(x*x+y*y),-10)+0.5; view(3,4,0.5,1.2); solid(x,y,p); hold on; t=linspace(0,3.5,150); s=heun("dgl",t,[1,0,0,0.7]); ps=-1/sqrt(s[1]*s[1]+s[2]*s[2])+0.5; color(2); wire(s[1],s[2],ps); hold off; return 0; endfunction "showpotential defined", "", "Make the screen look square and run showcurve or showpotential", .. EOF function lorenz (t,x) return [-3*(x[1]-x[2]),-x[1]*x[3]+26.5*x[1]-x[2],x[1]*x[2]-x[3]] endfunction function lorenza t=0:0.02:40; s=heun("lorenz",t,[0,1,0]); v=view(4,2,0.5,0.5); framedwire(s[1]/20,s[2]/20,s[3]/20-1); title("The Lorenz attractor"); wait(180); view(v); return s endfunction "The conputation takes a while, please wait!", lorenza(); .. Optimization routine function opti (A,b,z) ## Minimizes z.x' with contraints A.x'>=b and x'>=0. Works only, ## if z>=0. Returns {x,K}. si=size(A); m=si[2]; K=id(m); Kb=zeros(m,1); x=Kb; A1=A; b1=b; repeat r=A1.x-b1; if r>=0; break; endif; e=extrema(r'); i=e[2]; ir=nonzeros(r'~=e[1]); i=ceil(random(1,1)*length(ir)); i=ir[i]; v=A1[i]; mu=K'\v'; lambda=K'\z'; j=nonzeros(mu>epsilon()); if size(j)==[1,0]; error("No admissable point!"); else; q=lambda[j]/mu[j]; e=extrema(q'); jj=e[2]; j=j[jj]; endif; tt=K[j]; K[j]=v; A1[i]=tt; t=Kb[j]; Kb[j]=b1[i]; b1[i]=t; x=K\Kb; end; return {x',K} endfunction function game (A) ## Maximizes G such that A'.q>=G, sum q_i = 1, q_i>=0. ## Returns {q,G,flag}. flag is 1 if its a strongly unique solution. m=max(max(A)'); B=A'-m; si=size(B); M=(B|ones(si[1],1))_(ones(1,si[2])|0)_(-1*ones(1,si[2])|0); r=zeros(si[1],1)_1_-1; z=zeros(1,si[2])|1; {q,K}=opti(M,r,z); return {q[1:si[2]],m-q[si[2]+1],!any((K'\z')~=0)}; endfunction function knobeln (n=3) ## Berechnet die beste Strategie beim Knobeln. ## A und B nehmen insgeheim je 0 bis n Hlzer. ## A nennt eine Zahl und B eine davon verschiedene. ## Wer nher an der Summe ist gewinnt die Hlzer des Gegners plus 1. m=2*n+1; A=zeros((n+1)*m,(n+1)*(m-1)); for i=0 to n; for ik=0 to m-1; for j=0 to n; for jk=1 to m-1; if i+j==ik; A[i*m+ik+1,j*(m-1)+jk]=j+1; else if (i+j>ik && jk<=ik) || (i+jik); A[i*m+ik+1,j*(m-1)+jk]=j+1; else A[i*m+ik+1,j*(m-1)+jk]=-i-1; endif; endif; end; end; end; end; "Matrix berechnet", {q,G,flag}=game(A); "Gewinn fr zuerst ansagenden : "|printf("%10.5f",G), for i=0 to n; for ik=0 to m-1; if q[i*m+ik+1]~=0; else printf("%7.5f : Nimm ",q[i*m+ik+1])| .. printf("%2.0f, sage ",i)|printf("%2.0f",ik), endif; end; end; if flag; "Einzige Lsung!", endif; {p,G,flag}=game(-A'); "Gewinn fr zweiten : "|printf("%10.5f",G), for j=0 to n; printf("Nimm : %2.0f",j), for jk=1 to m-1; if p[j*(m-1)+jk]~=0; else printf("%7.5f : unterbiete ab ",p[j*(m-1)+jk])|.. printf("%2.0f",jk), endif; end; end; if flag; "Einzige Lsung!", endif; return {q,p}; endfunction function schere ## Berechnet die optimale Lsung fr das Schere-, Papier-, Brunnen- und ## Steinspiel. q=game([0,1,-1,-1;-1,0,1,1;1,-1,0,1;1,-1,-1,0]); "Whle mit Wahrscheinlichkeit", "Schere : ", q[1], "Papier : ", q[2], "Brunnen : ", q[3], "Stein : ", q[4], return q; endfunction function pokern (w=5,e=5) ## Lst ein einfaches Pokerspiel. A und B bekommen ein Karte im Wert ## 1 bis w. A passt oder setzt e. B kann dann passen ## oder halten. Der Grundeinsatz ist 1. A=zeros(w,w); for i=1 to w; ## Setze bei Karte i bis w for j=1 to w; ## Halte bei Karte j bis w if j<=i; A[i,j]=(w-i+1)*(j-1)+(e+1)*(w-i+1)*(i-j)-w*(i-1); else A[i,j]=(w-i+1)*(j-1)-(e+1)*(w-j+1)*(j-i)-w*(i-1); endif; end; end; A=A/(w*w); "Matrix erzeugt!", {p,G,flag}=game(A); "Gewinn : "|printf("%10.5f",G), "Strategie fr A:" for i=1 to w; if !(p[i]~=0); printf("%7.5f : ",p[i])|printf("Setze bei %2.0f bis ",i)|.. printf("%2.0f",w), endif; end; {q,G,flag}=game(-A'); "Gewinn : "|printf("%10.5f",G), "Strategie fr B:" for i=1 to w; if !(q[i]~=0); printf("%7.5f : ",q[i])|printf("Halte bei %2.0f bis ",i)|.. printf("%2.0f",w), endif; end; return {p,q}; endfunction function simulhelp (w,a,k1,b,k2) return -(a=k1)*((b=k2)*(w+1)*((a>b)-(a=pa) * (rb=pb) * simulhelp(w,a,k1,b,k4) + .. (ra>=pa) * (rb>=pb) * simulhelp(w,a,k2,b,k4)), return win endfunction "opti(A,b,z) definiert." "game(A) definiert." "knobeln, pokern, schere und simul definiert." .. Test the random number creator function randomtest (n=5000) ## perform various test on the random number creator t=random(2,n)*0.999999999; color(1); ## distribution test c=count(t[1]*100,100); histogram(t[1]*100,100); title("distribution of random numbers"); wait(); histogram(c,integer=1); title("distribution of distribution"); wait(); chi2=sum((c-n/100)^2/(n/100)); printf("chi^2 for distribution of numbers = %0.5f",chi2), printf("Probability for this: %0.2f%%",(1-chidis(chi2,99))*100), ## gap test f=nonzeros(t[1]<0.1); m=length(f); gaps=f[2:m]-f[1:m-1]; histogram(gaps,integer=1); title("distribution of gaps"); wait(); color(2); x=1:max(gaps); hold on; plot(x,0.9^(x-1)*0.1*m); hold off; color(1); wait(); c=count(gaps-1,20); p=0.9^(0:19)*0.1*m; chi2=sum((c-p)^2/p); printf("chi^2 for the gaps = %0.5f",chi2), printf("Probability for this: %0.2f%%",(1-chidis(chi2,20))*100), ## distribution of pairs test markerstyle("m."); xmark(t[1],t[2],grid=0); title("pairs of random numbers"); wait(); l=floor(t[1]*10)*10+floor(t[2]*10); histogram(l,integer=1); title("distribution of pairs"); wait(); c=count(l,100); histogram(c,integer=1); title("distribution of distribution of pairs"); wait(); chi2=sum((c-n/100)^2/(n/100)); printf("chi^2 for distribution of pairs = %0.5f",chi2), printf("Probability for this: %0.2f%%",(1-chidis(chi2,99))*100), return "" endfunction "randomtest", "test of the builtin random number generator." randomtest; .. Berechnet die Rendite eines Wertpapieres function rendite (x) ## berechnet die Rendite von Zahlungen x zu Perioden 0,1,2,3,... if sum(x)<0; error("Rendite negativ?"); endif; q=polydif(x); c=1; repeat cnew=c-polyval(x,c)/polyval(q,c); if c~=cnew; break; endif; c=cnew; end; return (1/cnew-1)*100; endfunction function rendite2 (x,n) ## berechnet die Rendite von Zahlungen x zu gebrochenen Perioden n. if sum(x)<0; error("Rendite negativ?"); endif; k2=x*n; n2=n-1; k2=k2[2:length(x)]; n2=n2[2:length(x)]; c=1; repeat cnew=c-sum(x*c^n)/sum(k2*c^n2); if c~=cnew; break; endif; c=cnew; end; return (1/cnew-1)*100; endfunction function effzins (kurs,laufzeit,zins) ## berechnet den effektiven Zins eines Wertpapieres. ## kurs und zins in %, laufzeit in Zinsperioden. ## z.B. effzins(104,8,8.75). si=size(kurs,laufzeit,zins); rend=zeros(si); loop 1 to prod(si); k=-kurs{#}|dup(zins{#},laufzeit{#})'; k[laufzeit{#}+1]=k[laufzeit{#}+1]+100; rend{#}=rendite(k); end; return rend endfunction function tilgung (darlehen,laufzeit,zins) ## berechnet die Tilgung eines Darlehens. p=1+zins/100; return p*(1/p-1)*darlehen/(1/p^laufzeit-1); endfunction function darlzins (darlehen,laufzeit,tilgung) ## berechnet den Zinssatz eines Darlehens. si=size(darlehen,laufzeit,tilgung); z=zeros(si); loop 1 to prod(si); k=-darlehen{#}|dup(tilgung{#},laufzeit{#})'; z{#}=rendite(k); end; return z endfunction function sparzins (rate,laufzeit,endkapital) ## berechnet den effektiven Zins eines Sparvertrages. si=size(rate,laufzeit,endkapital); z=zeros(si); loop 1 to prod(si); k=dup(-rate{#},laufzeit{#})'|endkapital{#}; z{#}=rendite(k); end; return z endfunction function endkap (rate,laufzeit,zins) ## berechnet das Endkapital eines Sparvertrages. p=1+zins/100; return p*rate*(p^laufzeit-1)/(p-1); endfunction "rendite(R) definiert." "rendite2(T,R) definiert." "effzins(W,T,Z) definiert." "tilgung(W,T,Z) definiert." "darlzins(W,T,R) definiert." "sparzins(R,T,W) definiert." "endkap(R,T,Z) definiert." "Benutzen Sie help ... fr weitere Informationen." .. Test the spline function. function test ## Demonstrates the spline functions in RMAT. "Klicken Sie eine Anzahl von Punkten (x,y) mit der Maus an.", "Das Programm berechnet dann den natrlichen Spline s(x) in einer", "Variablen durch diese Punkte, sowie das Interpolationspolynom.", "(Bitte Taste drcken)", wait(180); "" setplot(-1.1,1.1,-1.1,1.1); plot(-1.1,-1.1); xgrid(-1:0.5:1); ygrid(-1:0.5:1); hold on; title("Klicken Sie die Punkte mit der Maus an. Ende -> Hier! <-"); t=zeros(1,0); s=t; n=0; repeat; m=mouse(); if abs(m(1))>1.1 || abs(m(2))>1.1; break; endif; t=t|m(1); s=s|m(2); n=n+1; mark([m(1),m(1)],[m(2),m(2)]); end; {t,i}=sort(t); s=s(i); sp=spline(t,s); x=linspace(min(t),max(t),n*10); plot(x,splineval(t,s,sp,x)); color(2); plot(x,interpval(t,interp(t,s),x)); color(1); wait(180); hold off; return 0; endfunction function test2 ## Demonstrates the spline functions in RMAT. "Klicken Sie eine Anzahl von Punkten (x,y) mit der Maus an.", "Das Programm berechnet dann den natrlichen Spline s(x,y) in zwei", "Variablen durch diese Punkte, sowie das Interpolationspolynom.", "(Bitte Taste drcken)", wait(180); "" setplot(-1.1,1.1,-1.1,1.1); plot(-1.1,-1.1); xgrid(-1:0.5:1); ygrid(-1:0.5:1); hold on; title("Klicken Sie die Punkte mit der Maus an. Ende -> Hier! <-"); t=zeros(1,0); s=t; n=0; repeat; m=mouse(); if abs(m(1))>1.1 || abs(m(2))>1.1; break; endif; t=t|m(1); s=s|m(2); n=n+1; mark([m(1),m(1)],[m(2),m(2)]); end; spt=spline(1:n,t); sps=spline(1:n,s); x=linspace(1,n,600); plot(splineval(1:n,t,spt,x),splineval(1:n,s,sps,x)); color(2); plot(interpval(1:n,interp(1:n,t),x),interpval(1:n,interp(1:n,s),x)); color(1); wait(180); hold off; return 0; endfunction test(); test2(); .. The Utilities. "Loading utilities, Version 3.04, Apr 16, 1993." Epsilon=epsilon(); ResetEpsilon=epsilon(); ResetView=view(); Pi=pi(); E=exp(1); I=1i; function reset ## reset() resets espilon() and some other things global ResetEpsilon,ResetView; setepsilon(ResetEpsilon); style(""); hold off; color(1); shrinkwindow(); shortformat(); linewidth(1); view(ResetView); huecolor(1); return 0; endfunction function wait ## waits for a key (at most 5 min) return wait(300); endfunction function longformat ## longformat() sets a long format for numbers return format([20 12]); endfunction function shortformat ## shortformat() sets a short format for numbers return format([14 5]); endfunction; function linspace (a,b,n) ## linspace(a,b,n) generates n+1 linear spaced points in [a,b]. if a~=b; return a; endif; r=a:(b-a)/n:b; r[n+1]=b; return r; endfunction function equispace (a,b,n) ## equispace(a,b,n) generates n+1 euqidistribution (acos) spaced values ## in [a,b]. m=(1-cos(0:pi()/n:pi()))/2; return a+(b-a)*m; endfunction function length (v) ## length(v) returns the length of a vector return max(size(v)); endfunction function polydif (p) ## polydif(p) returns the polynomial p' n=cols(p); if (n==1); return 0; endif; return p[2:n]*(1:n-1); endfunction function writeform (x) if isreal(x); return printf("%25.16e",x); endif; if iscomplex(x); return printf("%25.16e",re(x))|printf("+%25.16ei",im(x)); endif; if isstring(x); return x; endif; error("Cannot print this!"); endfunction function write (x,s) if argn()==1; s=name(x); endif; si=size(x); if max(si)==1; s|" = "|writeform(x)|";", return 0; endif; s|" = [ .." for i=1 to si[1]; for j=1 to si[2]-1; writeform(x[i,j])|",", end; if i==si[1]; writeform(x[i,si[2]])|"];", else; writeform(x[i,si[2]])|";", endif; end; return 0 endfunction .. ### plot things ### function scalematrix(A) ## Scales a matrix A, so that its value are in the range from 0 to 1. e=extrema(A)'; mi=min(e[1]); ma=max(e[3]); if ma~=mi; ma=mi+1; endif; return (A-mi)/(ma-mi); endfunction function select ## Returns coordinates {x,y} of mouse clicks, until the user clicked ## above the plot window. p=plot(); x=[]; repeat m=mouse(); if m[2]>p[4]; break; endif; h=holding(1); mark(m[1],m[2]); holding(h); x=x_m; end; x=x'; return {x[1],x[2]} endfunction function title (text) ## title(text) plots a title to the grafik window. ctext(text,[512 0]); return text; endfunction function textheight ## textheight() returns the height of a letter. h=textsize(); return h[2]; endfunction function textwidth ## textwidth() returns the width of a letter. h=textsize(); return h[1]; endfunction function fullwindow ## fullwindow() takes the full size (besides a title) for the ## plots. h=textsize(); w=window(); window([12,textheight()*1.5,1011,1011]); return w; endfunction function shrinkwindow ## shrinkwindow() shrinks the window to allow labels. h=textheight(); b=textwidth(); w=window(); window([8*b,1.5*h,1023-2*b,1023-3*h]); return w; endfunction function setplot ## setplot([xmin xmax ymin ymax]) sets the plot coordinates and holds ## the plot. Also setplot(xmin,xmax,ymin,ymax). ## setplot() resets it. if argn()==4; return setplot([arg1,arg2,arg3,arg4]); else; if argn()==0; scaling(1); else; error("Illegal arguments!"); endif; endif; return plot(); endfunction function ticks (a,b) ## returns the proper ticks to be used for intervals [a,b] and ## the factor of the ticks. tick=10^floor(log(b-a)/log(10)-0.4); if b-a>10*tick; tick1=tick*2; else; tick1=tick; endif; if (tick>0.001) && (tick<1000); tick=1; endif; return {(floor(a/tick1)+1)*tick1:tick1:(ceil(b/tick1)-1)*tick1,tick} endfunction function xplot (x,y,grid=1,ticks=1) ## xplot(x,y) or xplot(y) works like plot, but shows axis ticks. ## xplot() shows only axis ticks and the grid. if argn()>0; if argn()==1; if iscomplex(x); y=im(x); xh=re(x); else y=x; xh=1:cols(y); endif; else; xh=x; endif; p=plotarea(xh,y); if !holding(); clg; frame(); endif; else p=plot(); endif; lw=linewidth(1); {t,f}=ticks(p[1],p[2]); xgrid(t,f,grid,ticks); {t,f}=ticks(p[3],p[4]); ygrid(t,f,grid,ticks); linewidth(lw); if argn()>0; ho=holding(1); plot(xh,y); holding(ho); endif; return p; endfunction function xmark (x,y,grid=1,ticks=1) ## xmark(x,y) or xmark(y) works like plot, but shows axis ticks. ## xmark() shows only axis ticks and the grid. if !holding(); clg; frame(); endif; if argn()==1; if iscomplex(x); y=im(x); xh=re(x); else; y=x; xh=1:cols(y); endif; else; xh=x; endif; p=plotarea(xh,y); {t,f}=ticks(p[1],p[2]); xgrid(t,f,grid,ticks); {t,f}=ticks(p[3],p[4]); ygrid(t,f,grid,ticks); ho=holding(1); p=mark(xh,y); holding(ho); return p; endfunction function setplotm ## The user may choose the plotting coordinates with the mouse. ## Returns the plot coordinates. h=holding(1); k1=mouse(); mark(k1[1],k1[2]); k2=mouse(); mark(k2[1],k2[2]); kl=min(k1,k2); ku=max(k1,k2); c=color(2); plot([kl[1],kl[1],ku[1],ku[1],kl[1]],[kl[2],ku[2],ku[2],kl[2],kl[2]]); color(c); setplot(kl[1],ku[1],kl[2],ku[2]); holding(h); return plot(); endfunction function fplot (ffunction,a=0,b=0,n=200) ## fplot("f",a,b,n,...) plots the function f in [a,b]. ## The arguments ... are passed to f. ## fplot("f") or fplot("f",,,n,...) plots f in the old interval. if a~=b; s=plot(); a=s[1]; b=s[2]; endif; t=linspace(a,b,n); s=ffunction(t,args(4)); return xplot(t,s) endfunction function histogram (d,n=10,grid=0,ticks=1,width=4,integer=0) ## Plots a histogram of the data d with n intervals. ## d must be a vector. mi=min(d); ma=max(d); if mi~=ma; ma=mi+1; endif; if integer; n=floor(ma-mi)+1; ma=ma+0.9999; endif; x=zeros(1,2*n+2); y=zeros(1,2*n+2); h=(d-mi)/(ma-mi)*n; c=count(h,n+1); c[n]=c[n]+c[n+1]; c=c[1:n]; y[2:2:2*n]=c; y[3:2:2*n+1]=c; xx=linspace(mi,ma,n); x[2:2:2*n]=xx[1:n]; x[3:2:2*n+1]=xx[2:n+1]; x[1]=mi; x[2*n+2]=ma; w=linewidth(width); xplot(x,y,grid,ticks); linewidth(w); return plot; endfunction function printscale (x) if (abs(x)>10000) || (abs(x)<0.00001); return printf("%12.5e",x); else return printf("%10.5f",x); endif; endfunction function niceform (x) ## Return a string, containing a nice print of x. y=round(x,10); return printf("%g",y); endfunction function xgrid(xx,f=1,grid=1,ticks=1,color=3) ## xgrid([x0,x1,...]) draws vertical grid lines on the plot window at ## x0,x1,... ## xgrid([x0,x1,...],f) additionally writes x0/f to the axis. c=plot(); n=cols(xx); s=scaling(0); h=holding(1); w=window(); st=linestyle("."); color(color); ht=textheight(); if argn()<2; ticks=0; endif; loop 1 to n; x=xx[index()]; if (x<=c[2])&&(x>=c[1]); if grid; plot([x,x],[c[3],c[4]]); endif; if ticks; col=w[1]+(x-c[1])/(c[2]-c[1])*(w[3]-w[1]); ctext(niceform(x/f),[col,w[4]+0.2*ht]); endif; endif; end; if ticks && !(f~=1); ctext("* "|printscale(f),[(w[1]+w[3])/2,w[4]+1.5*ht]); endif; linestyle(st); color(1); holding(h); scaling(s); return 0; endfunction function ygrid(yy,f=1,grid=1,ticks=1,color=3) ## ygrid([x0,x1,...]) draws horizontal grid lines on the plot window at ## x0,x1,... ## ygrid([x0,x1,...],f) additionally writes x0/f to the axis. c=plot(); n=cols(yy); s=scaling(0); h=holding(1); st=linestyle("."); color(color); w=window(); wd=textwidth(); ht=textheight(); if argn()<2; ticks=0; endif; loop 1 to n; y=yy[index()]; if (y>=c[3])&&(y<=c[4]); if ticks; row=w[4]-(y-c[3])/(c[4]-c[3])*(w[4]-w[2]); rtext(niceform(y/f),[w[1]-wd/2,row-ht/2]); endif; if grid; plot([c[1],c[2]],[y,y]); endif; endif; end; if ticks && !(f~=1); text("* "|printscale(f),[w[1]-6*wd,0]); endif; linestyle(st); color(1); holding(h); scaling(s); return 0; endfunction function plot (x,y) ## plot(x,y) plots the values (x(i),y(i)) with the current style. ## If x is a matrix, y must be a matrix of the same size. ## The plot is then drawn for all rows of x and y. ## The plot is scaled automatically, unless hold is on. ## plot(x,y) and plot() return [x1,x2,y1,y2], where [x1,x2] is the range ## of the x-values and [y1,y2] of the y-values. ## plot(x) is the same as plot(1:cols(x),x). if argn()==1; if iscomplex(x); return plot(re(x),im(x)); else return plot(1:cols(x),x); endif; endif; error("Illegal argument number!"), endfunction function mark (x,y) ## mark(x,y) plots markers at (x(i),y(i)) according the the actual style. ## Works like plot. if argn()==1; if iscomplex(x); return mark(re(x),im(x)); else return mark(1:cols(x),x); endif; endif; error("Illegal argument number!"), endfunction function cplot (z) ## cplot(z) plots a grid of complex numbers. plot(re(z),im(z)); s=scaling(0); h=holding(1); w=z'; plot(re(w),im(w)); holding(h); scaling(s); return plot(); endfunction function plotwindow ## plotwindow() sets the plot window to the screen coordinates. w=window(); setplot(w[1],w[3],w[2],w[4]); return plot() endfunction function getframe (x,y,z) ## gets a box around all points in (x,y,z). ex=extrema(x); ey=extrema(y); ez=extrema(z); return [min(ex[:,1]'),max(ex[:,3]'), min(ey[:,1]'),max(ey[:,3]'),min(ez[:,1]'),max(ez[:,3]')] endfunction function framez0 (f) wire([f[1],f[2],f[2],f[1],f[1]], .. [f[3],f[3],f[4],f[4],f[3]],dup(f[5],5)'); return 0 endfunction function framez1 (f) wire([f[1],f[2],f[2],f[1],f[1]], .. [f[3],f[3],f[4],f[4],f[3]],dup(f[6],5)'); return 0 endfunction function framexpyp (f) wire([f[2],f[2]],[f[4],f[4]],[f[5],f[6]]); return 0 endfunction function framexpym (f) wire([f[2],f[2]],[f[3],f[3]],[f[5],f[6]]); return 0 endfunction function framexmyp (f) wire([f[1],f[1]],[f[4],f[4]],[f[5],f[6]]); return 0 endfunction function framexmym (f) wire([f[1],f[1]],[f[3],f[3]],[f[5],f[6]]); return 0 endfunction function frame1 (f) ## draws the back part of the box (considering view) v=view(); y=sin(v[4])*v[1]; if y>f[5]; framez0(f); endif; if y=f[1]; framexmyp(f); framexmym(f); endif; if y<=f[4]; framexmyp(f); framexpyp(f); endif; if y>=f[3]; framexmym(f); framexpym(f); endif; return 0 endfunction function frame2 (f) ## draws the front part of the box (considering view). v=view(); y=sin(v[4])*v[1]; if y<=f[5]; framez0(f); endif; if y>=f[6]; framez1(f); endif; x=sin(v[3])*v[1]; y=-cos(v[3])*v[1]; if x>=f[2]; framexpyp(f); framexpym(f); endif; if x<=f[1]; framexmyp(f); framexmym(f); endif; if y>=f[4]; framexmyp(f); framexpyp(f); endif; if y<=f[3]; framexmym(f); framexpym(f); endif; return 0 endfunction function scaleframe (x,y,z,f,m) s=max([f[2]-f[1],f[4]-f[3],f[6]-f[5]]); xm=(f[2]+f[1])/2; ym=(f[4]+f[3])/2; zm=(f[6]+f[5])/2; ff=m/s*2; f=[f[1]-xm,f[2]-xm,f[3]-ym,f[4]-ym,f[5]-zm,f[6]-zm]*ff; return {(x-xm)*ff,(y-ym)*ff,(z-zm)*ff} endfunction function framedsolid (x,y,z,scale=0) ## works like solid and draws a frame around the plot ## if scale is specified, then the plot is scaled to fit into a cube of ## side length 2f centered at 0 frame=getframe(x,y,z); if !holding(); clg; endif; h=holding(1); if scale; {x1,y1,z1}=scaleframe(x,y,z,frame,scale); else; {x1,y1,z1}={x,y,z}; endif; color(2); frame1(frame); color(1); solid(x1,y1,z1); color(2); frame2(frame); color(1); holding(h); return frame endfunction function framedsolidhue (x,y,z,hue,scale=0,f=1) ## works like solidhue and draws a frame around the plot ## if scale is specified, then the plot is scaled to fit into a cube of ## side length 2f centered at 0 frame=getframe(x,y,z); if !holding(); clg; endif; h=holding(1); if scale; {x1,y1,z1}=scaleframe(x,y,z,frame,scale); else; {x1,y1,z1}={x,y,z}; endif; color(2); frame1(frame); color(1); if f; solidhue(x1,y1,z1,hue,f); else; solidhue(x1,y1,z1,hue); endif; color(2); frame2(frame); color(1); holding(h); return frame endfunction function framedwire (x,y,z,scale=0) ## works like framedsolid frame=getframe(x,y,z); if !holding(); clg; endif; h=holding(1); if scale; {x1,y1,z1}=scaleframe(x,y,z,frame,scale); else; {x1,y1,z1}={x,y,z}; endif; color(2); frame1(frame); color(1); wire(x1,y1,z1); color(2); frame2(frame); color(1); holding(h); return frame endfunction function density (x,f) ## density(x,1) makes density plot of the values in the matrix x ## scaled to fit into [0,f]. ma=max(max(x)'); mi=min(min(x)'); h=ma-mi; if h~=0; h=1; endif; xx=(x-mi)/h*f; density(xx); return xx; endfunction function solidhue (x,y,z,h,f) ## solidhue(x,y,z,h) makes a shaded solid 3D-plot of x,y,z. ## h is the shading and should run between 0 and 1. ## f determines, if h is scaled to fit in between 0 and f. ma=max(max(h)'); mi=min(min(h)'); delta=ma-mi; if delta~=0; delta=1; endif; hh=(h-mi)/delta*f*0.9999; return solidhue(x,y,z,hh); endfunction .. ### linear algebra things ### function id (n) ## id(n) creates a nxn identity matrix. return diag([n n],0,1); endfunction function inv (a) ## inv(a) produces the inverse of a matrix. return a\id(cols(a)); endfunction function fit (a,b) ## fit(a,b) computes x such that ||a.x-b||_2 is minimal. A=conj(a'); return symmult(A,a)\(A.b') endfunction function kernel (a) ## kernel(a) computes the kernel of the quadratic matrix a. {aa,r,c,d}=lu(a); n=size(a); nr=size(r); if nr[2]==n[2]; return zeros([1,n[2]])'; endif; if nr[2]==0; return id(n[2]); endif; c1=nonzeros(c); c2=nonzeros(!c); b=lusolve(aa[r,c1],a[r,c2]); m=size(b); x=zeros([n[2] m[2]]); x[c1,:]=-b; x[c2,:]=id(cols(c2)); return x endfunction function image (a) ## image(a) computes the image of the quadratic matrix a. {aa,r,c,d}=lu(a); return a[:,nonzeros(c)); endfunction function det (a) ## det(A) returns the determinant of A {aa,r,c,d}=lu(a); return d; endfunction function eigenvalues (a) ## eigenvalues(A) returns the eigenvalues of A. return polysolve(charpoly(a)); endfunction function eigenspace (a,l) ## eigenspace(A,l) returns the eigenspace of A to the eigenvaue l. k=kernel(a-l*id(cols(a))); if k==0; error("No eigenvalue found!"); endif; si=size(k); loop 1 to si[2]; x=k[:,index()]; k[:,index()]=x/sqrt(x'.x); end; return k; endfunction function eigen (A) ## eigen(A) returns the eigenvectors and a basis of eigenvectors of A. ## {l,x,ll}=eigen(A), where l is a vector of eigenvalues, ## x is a basis of eigenvectors, ## and ll is a vector of distinct eigenvalues. l=eigenvalues(A); s=eigenspace(A,l[1]); si=size(s); v=dup(l[1],si[2])'; vv=l[1]; l=eigenremove(l,si[2]); repeat; if min(size(l))==0; break; endif; ll=l[1]; sp=eigenspace(A,ll); si=size(sp); l=eigenremove(l,si[2]); s=s|sp; v=v|dup(ll,si[2])'; vv=vv|ll; end; return {v,s,vv} endfunction function eigenspace1 ## eigenspace1(A,l) returns the eigenspace of A to the eigenvalue l. ## returns {x,l1}, where l1 should be an improvement over l, and ## x contains the eigenvectors as columns. eps=epsilon(); repeat; k=kernel(arg1-arg2*id(cols(arg1))); if k==0; else; break; endif; if epsilon()>1 break; endif; setepsilon(100*epsilon()); end; if k==0; error("No eigenvalue found!"); endif; setepsilon(eps); {dummy,l}=eigennewton(arg1,k[:,1],arg2); eps=epsilon(); repeat; k=kernel(arg1-l*id(cols(arg1))); if k==0; else; break; endif; if epsilon()>1 break; endif; setepsilon(100*epsilon()); end; if k==0; error("No eigenvalue found!"); endif; setepsilon(eps); si=size(k); loop 1 to si[2]; x=k[:,index()]; k[:,index()]=x/sqrt(x'.x); end; return {k,l}; endfunction function eigenremove(l) ## helping function. return l(nonzeros(!(l[1]~=l))) endfunction function eigen1 ## eigen(A) returns the eigenvectors and a basis of eigenvectors of A. ## {l,x,ll}=eigen(A), where l is a vector of eigenvalues, ## x is a basis of eigenvectors, ## and ll is a vector of distinct eigenvalues. ## Improved version of eigen. l=eigenvalues(A); {s,li}=eigenspace1(A,l[1]); si=size(s); v=dup(li,si[2])'; vv=li; l=eigenremove(l,si[2]); repeat; if min(size(l))==0; break; endif; {sp,li}=eigenspace1(A,l[1]); si=size(sp); l=eigenremove(l,si[2]); s=s|sp; v=v|dup(li,si[2])'; vv=vv|li; end; return {v,s,vv} endfunction function eigennewton ## eigennewton(a,x,l) does a newton step to improve the eigenvalue l ## of a and the eigenvector x. ## returns {x1,l1}. a=arg1; x=arg2; x=x/sqrt(x'.x); n=cols(a); d=((a-arg3*id(n))|-x)_(2*x'|0); b=d\((a.x-arg3*x)_0); return {x-b[1:n],arg3-b[n+1]}; endfunction function hilb (n) ## hilb(n) produces the nxn-Hilbert matrix. {i,j}=field(1:n,1:n); return 1/(i+j-1); endfunction .. ### polynomial fit ## function polyfit (xx,yy,n) ## fit(x,y,degree) fits a polynomial in L_2-norm to (x,y). A=ones(size(xx))_dup(xx,n); A=cumprod(A'); return fit(A,yy)'; endfunction function field (x,y) ## field(x,y) returns {X,Y} such that the X+i*Y is a rectangular ## grid in C containing the points x(n)+i*y(m). x and y must be ## 1xN and 1xM vectors. return {dup(x,cols(y)),dup(y',cols(x))}; endfunction function totalsum (A) ## totalsum(a) computes the sum of all elements of a return sum(sum(A)'); endfunction function totalmin (A) ## Returns the total minimum of the elements of a return min(min(A)')' endfunction function totalmax (A) ## Returns the total maximum of the elements of a return max(max(A)')' endfunction function sinh ## sinh(x) = (exp(x)-exp(-x))/2 h=exp(arg1); return (h-1/h)/2; endfunction function cosh ## cosh(x) = (exp(x)+exp(-x))/2 h=exp(arg1); return (h+1/h)/2; endfunction function arsinh ## arsinh(z) = log(z+sqrt(z^2+1)) return log(arg1+sqrt(arg1*arg1+1)) endfunction function arcosh ## arcosh(z) = log(z+(z^2-1)) return log(arg1+sqrt(arg1*arg1-1)) endfunction function heun (ffunction,t,y0) ## y=heun("f",t,y0,...) solves the differential equation y'=f(t,y). ## f(t,y,...) must be a function. ## y0 is the starting value. n=cols(t); y=dup(y0,n); loop 1 to n-1; h=t[#+1]-t[#]; yh=y[#]; xh=t[#]; k1=ffunction(xh,yh,args(4)); k2=ffunction(xh+h/2,yh+h/2*k1,args(4)); k3=ffunction(xh+h,yh+2*h*k2-h*k1,args(4)); y[#+1]=yh+h/6*(k1+4*k2+k3); end; return y'; endfunction solveeps=epsilon(); function bisect (ffunction,a,b) ## bisect("f",a,b,...) uses the bisection method to find a root of ## f in [a,b]. global solveeps; if ffunction(b,args(4))<0; b1=a; a1=b; else; a1=a; b1=b; endif; if ffunction(b1,args(4))<0 error("No zero in interval"); endif; repeat m=(a1+b1)/2; if abs(a1-b1)0; b1=m; else a1=m; endif; end; endfunction function secant (ffunction,a,b) ## secant("f",a,b,...) uses the secant method to find a root of f in [a,b] global solveeps; x0=a; x1=b; y0=ffunction(x0,args(4)); y1=ffunction(x1,args(4)); repeat x2=x1-y1*(x1-x0)/(y1-y0); if abs(x2-x1)broydenmax) break; endif; y=y1; itercount=itercount+1; end; if (itercount>broydenmax) error("Iteration failed"); endif; return x; endfunction function map (ffunction,t) ## map("f",t,...) evaluates the function f at all points of the vector t. ## usually this is the same as f(t,...), but sometimes functions do not ## accept vectors as input. si=size(t); s=zeros(si); loop 1 to prod(si); s{#}=ffunction(t{#},args(3)); end; return s; endfunction itereps=epsilon(); function iterate (ffunction,x,n=0) ## iterate("f",x,n,...) iterate the function f(x,...) n times, ## starting with the point x. ## if n is missing or n is 0, then the iteration stops at a fixed point. ## Returns the value after n iterations, and its history. global itereps; if n==0; R=x; Rold=x; repeat Rnew=ffunction(Rold,args(4)); R=R_Rnew; if max(abs(Rold-Rnew))0); indnew[index()]=e[2]+ind[index()-1]; rr[index()]=e[1]; else indnew[index()]=e[4]+ind[index()-1]; rr[index()]=e[3]; endif; hh=-hh; end; ind=indnew; if (abs(hnew)<(1+remezeps)*abs(h)) break; endif; h=hnew; end; {t,d,h}=remezhelp(x[ind],y[ind],deg); if trace; xind=x[ind]; plot(x,y-interpval(t,d,x)); xgrid(xind); ygrid([-h,0,h]); title("Weiter mit Taste"); wait(180); endif; return {t,d,h,x[ind[deg+2]]}; endfunction .. ### Natural spline ### function spline (x,y) ## spline(x,y) defines the natural Spline at points x(i) with ## values y(i). It returns the second derivatives at these points. n=cols(x); h=x[2:n]-x[1:n-1]; s=h[2:n-1]+h[1:n-2]; l=h[2:n-1]/s; A=diag([n,n],0,2); A=setdiag(A,1,0|l); A=setdiag(A,-1,1-l|0); b=6/s*((y[3:n]-y[2:n-1])/h[2:n-1]-(y[2:n-1]-y[1:n-2])/h[1:n-2]); return (A\(0|b|0)')'; endfunction function splineval (x,y,h,t) ## splineval(x,y,h,t) evaluates the interpolation spline for ## (x(i),y(i)) with second derivatives h(i) at t. p1=find(x,t); p2=p1+1; y1=y[p1]; y2=y[p2]; x1=x[p1]; x2=x[p2]; f=(x2-x1)^2; h1=h[p1]*f; h2=h[p2]*f; b=h1/2; c=(h2-h1)/6; a=y2-y1-b-c; d=(t-x1)/(x2-x1); return y1+d*(a+d*(b+c*d)); endfunction .. ### use zeros,... the usual way ### function ctext ## ctext(s,[c,r]) plots the centered string s at the coordinates (c,r). ## Also ctext(s,c,r). if argn()==3; return ctext(arg1,[arg2,arg3]); endif; error("Illegal argument number!"), endfunction function text ## text(s,[c,r]) plots the centered string s at the coordinates (c,r). ## Also ctext(s,c,r). if argn()==3; return text(arg1,[arg2,arg3]); endif; error("Illegal argument number!"), endfunction function diag ## diag([n,m],k,v) returns a nxm matrix A, containing v on its k-th ## diagonal. v may be a vector or a real number. Also diag(n,m,k,v); ## diag(A,k) returns the k-th diagonal of A. if argn()==4; return diag([arg1,arg2],arg3,arg4); endif; error("Illegal argument number!"), endfunction function format ## format([n,m]) sets the number output format to m digits and a total ## width of n. Also format(n,m); if argn()==2; return format([arg1,arg2]); endif; error("Illegal argument number!"), endfunction function normal ## normal([n,m]) returns a nxm matrix of unit normal distributed random ## values. Also normal(n,m). if argn()==2; return normal([arg1,arg2]); endif; error("Illegal argument number!"), endfunction function random ## random([n,m]) returns a nxm matrix of uniformly distributed random ## values in [0,1]. Also random(n,m). if argn()==2; return random([arg1,arg2]); endif; error("Illegal argument number!"), endfunction function ones ## ones([n,m]) returns a nxm matrix with all elements set to 1. ## Also ones(n,m). if argn()==2; return ones([arg1,arg2]); endif; error("Illegal argument number!"), endfunction function zeros ## zeros([n,m]) returns a nxm matrix with all elements set to 0. ## Also zeros(n,m). if argn()==2; return zeros([arg1,arg2]); endif; error("Illegal argument number!"), endfunction function matrix ## matrix([n,m],x) returns a nxm matrix with all elements set to x. ## Also matrix(n,m,x). if argn()==3; return matrix([arg1,arg2],arg3); endif; error("Illegal argument number!"), endfunction function view ## view([distance, tele, angle1, angle2]) sets the perspective for ## solid and view. distance is the eye distance, tele a zooming factor. ## angle1 is the angle from the negativ y-axis to the positive x-axis. ## angle2 is the angle to the positive z-axis (the height of the eye). ## Also view(d,t,a1,a2). ## view() returns the values of view. if argn()==4; return view([arg1,arg2,arg3,arg4]); endif; error("Illegal argument number!"), endfunction function window ## window([c1,r1,c2,r2]) sets a plotting window. The cooridnates must ## be screen coordimates. Also window(c1,r1,c2,r2). ## window() returns the active window coordinates. if argn()==4; return window([arg1,arg2,arg3,arg4]); endif; error("Illegal argument number!"), endfunction .. *** directory *** function dir(pattern="*.*") ## dir(pattern) displays a directory. ## dir() is the same as dir("*.*"). s=searchfile(pattern), if stringcompare(s,"")==0; return 0; endif; repeat s=searchfile(), if stringcompare(s,"")==0; return 0; endif; end; endfunction . He.. EULER DOC IXfYEULER MAN ]{(EXAMPLESDOC rm'ZEXTEND DOC F %UPDATE DOC XREAD_ME TXT V_ EULER, The numerical Laboratory ====================================== Documentation ===================== Version 3.04 ================== INTRODUCTION ------------ EULER consists of the following files: EULER (the program, which may also have another name) EULER.CFG (is loaded after start of the program) UTIL.E (is loaded from EULER.CFG) There are some additional files, which help using the program: HELP.E (help texts) DEMO.E (a demo file, see the demo section) EULER.DOC (this file) EXPAMPLES.DOC (some example sessions) To load EULER, copy the above files in a directory, and start EULER. A startup screen indicating the version date will appear. The program will prompt for input, using a DOS-like text screen. The idea of EULER is a system with the following features: - Interactive evaluation of numerical expressions with real or complex values, vectors and matrices, including use of variables. - Built in functions that can take vectors as input and are then evaluated for each element of the vector or matrix. - Matrix functions. - Statistical functions and random numbers. - 2D- and 3D-plots. - A built in programming language with parameters and local variables. - An online help. - A tracing feature for the EULER programming language. These features make EULER an ideal tool for the tasks such as: - Inspecting and discussing functions of one real or complex variable. - Viewing surfaces in parameter representation. - Linear algebra and eigenvalue computation. - Testing numerical algorithms. - Solving differential equations numerically. - Computing polynomials. THE COMMAND LINE ---------------- If EULER is started from a shell, command line parameters for EULER can be entered. These parameter must be file names and those files are loaded after the start of EULER (See "loading a file"). Note, that the file EULER.CFG is always loaded as first file. The file EULER.CFG contains some commands to set up the EULER system, like defining the default file. It does in turn load the file UTIL.E. UTIL contains functions which are written in the EULER programming language and can be considered a part of EULER. But the user should feel free to change the content of UTIL to his own needs. THE DEMO AND THE ONLINE HELP ---------------------------- The best way to get a good idea of EULER is to run the demo. To do that issue the command >load "demo" Do not enter the prompt ">" and press the Return key. Of course, the file DEMO must be in the active directory. To get a print of the output of the demo, enter >dump "demo.txt"; load "demo"; dump; Then the file "demo.txt" will contain the demo texts. If the demo is interrupted (by the Escape key), the command >dump; must be entered to close the file "demo.txt". You can also learn to program EULER by studying the demo file. It is a good idea to make a print of the HELP file, since all functions are explained in that file. To load the online help, enter >load "help"; Then >help command will show the help text of the command (see "programming EULER"). THE LINE EDITOR --------------- Text can be entered after the prompt (>) using the keyboard. If a letter is mistyped, it can be cancelled with the Backspace key. The cursor keys -> and <- position the cursor back and forth in the line. The line editor is always in insert mode, so any character is inserted at the cursor position. Shift plus <- positions the cursor to the beginning of the line, and Shift plus -> to the end of the line. Clr-Home clears all input (Contrl-Up or Escape on some machines). Control plus -> or <- position the cursor one word to the right or left. Finally, the input is entered by pressing Return. Then EULER will start to interpret the command. Note, that the cursor can be at any position of the input line, when Return is pressed. Previous input can be recalled with the cursor-up and cursor-down keys. If a command is recalled this way and entered with Return, cursor-down recalls the next command; i.e., cursor-up and cursor-down are always based on the last recalled command. Pressing Clr-Home (see above) not only clears the input line, but also makes the last command the base for recalling. Thus Clr-Home plus cursor-up recalls the previous command. Pressing the Help key (or the insert key, depending on the version) extends incomplete commands. Pressing this key again gives another extension, if there is one. The search goes through the command history, the implemented functions, the user defined functions and the builtin commands in that order. There are some other special keys. The Tabulator (TAB, or some other key, depending on the program version) key switches to the Graphics screen and from there any key switches back. The Esc key stops any running EULER program and some internal functions, like the 3-dimensional plots, the linear equation solver and the polynomial root finder. Input can spread over several lines by the use of "..". The two dots are allowed at any place, where a space is acceptable. E.g. >3+ .. some comment >4 is equivalent to >3+4 Comments can follow the ".." and are skipped. The function keys may be programmed by the command >setkey(number,"text"); The number must be between 1 and 10 and the "text" may be any EULER string. Then the corresponding function key will produce the text, when it is pressed. If the function key text is to contain a ", one can use char(34) and the EULER string concatenation, as in the example >setkey(1,"load "|char(34)|"test"|char(34)|";"); which puts >load "test"; on the function key F1. THE DATA TYPES -------------- EULER uses the following data types - real numbers - complex numbers - real matrices - complex matrices - strings - references - programs The meaning of the first five data types should be clear. EULER tries to keep an evaluation real. But as soon, as complex data is involved the computation gets complex. That is why >sqrt(-1) results in NaN (not a number), but >sqrt(complex(-1)) gives 0+1*i. complex(x) is a way to turn a number complex. See the section on expressions for more information on how to enter these data types. Strings are only used for explaining output, file names and function key texts. There are only two string operators, the concetanation | and the function stringcompare. References are used internally for parameters of functions (see the programming section). Programs are the user defined programs including the functions in UTIL. All these data are kept on the stack. Usually, the user does not have to worry about the stack, since EULER uses normal mathematical notation for expressions. Internally, the evaluation of an expression uses the stack rather heavily. Programs are kept in the lower area of the stack. The stack is also used to pass parameters to builtin or user defined functions and to keep the local variables of these functions. Finally, we remark that the data explained in this section are different from builtin functions which can be used in the same places as user defined functions. There are also "commands", which cannot be used in expressions. Builtin functions and commands are part of the code of EULER. A complete list of builtin functions, commands and user defined functions is printed by >list If more information is needed, the command >memorydump is available. A hexdump of any data can be optained with >hexdump name but it will only be useful for insiders. >store("filename") stores the content of the EULER stack into a file. >restore("filename") loads that file. This is a short way of storing a session including the global variables and functions. ENTERING INPUT -------------- EULER input is either a "command", an "expression" or an "assignment". An example for a command is >quit which quits the EULER system. By and by, we will mention a few others. Another example is "load". An expression is a valid EULER expression, which has a resulting value. If it is entered on its own or followed by a comma, this value is printed. >3+4*5 prints the value 23.00000. The print is surpressed, if the expression is followed by a ";", like in the setkey example above. This makes sense, since some functions have side effects and their result is not needed, of since the user does not want to see the long output of an assignment (see below). The printing is done with a format determined by the function >format([n,m]) where n is the total width of print and m is the number of digits after the decimal dot. >format(n,m) does the same thing, but is a little bit slower since it is a function in UTIL. The output automatically switches to exponential format, if there is not enough space to display the number in fixed format. >longformat() is a function in UTIL, which sets a longer output format, while >shortformat() sets a shorter one. An assignment looks like >variablename=value It assigns the value to the variable, which is declared by the assignment, and prints the value. If the assignment is followed by a ";", then the printing is surpressed. An assignment may be followed by ",", which prints the right hand side of the assignment. There are also multiple assignments (see below). Expressions ----------- The most simple expressions are variables. Their value is the value of the variable, and their type is the type of the variable. If the variable is undefined, interpreting the expressions will stop with an error message. The basic constant expressions are numbers. Those are entered in the usual form 100, 100.0, 1e2, or 1.0e+2. The letter "small e" indicates powers of 10. An appendix "i" indicates multiples of the complex unit "i". "1+1i" is in fact a sum of 1 and 1i. A matrix is entered in the brackets "[" and "]" row by row. The columns are seperated by "," and the rows by ";". Example: >A=[1,2,3;4,5;6] This is equivalent with >A=[1,2,3;4,5,0;6,0,0] The matrix is real, if all entries are real, otherwise it is complex. If a row is shorter than the others, it is filled with zeros. A matrix constant can spread over several lines. A submatrix is a matrix, which is made up by the entries of another matrix. The simplest example is a matrix element >A[1,1] which gives the element in the first row and column of A. Note, that submatrices can be assigned values. Thus >A[1,1]=4.5 is a legal statement. If a submatrix gets complex, the matrix gets complex. If v is a 1xN or Nx1 matrix (i.e., a vector), then v[1] gives the first element of v; i.e., >v=[1.5,-2,0,4.8]; v[3] gives 0. Let us now assume, that A is a matrix, and r and c are vectors. Then A[r,c] results in a matrix, which consists of the rows r[1],r[2],... of A, and from these rows, only the columns c[1],c[2],... are taken. Example: >A[[1,2],[1,2]] is the upper left 2x2 submatrix of A. If a row or column does not exist, it is simply neglected. Thus, if A is a 4x4 matrix, then A[[4,7],[4,7]] results in the value A[4,4]. A special thing is A[1], which gives the first row of A. To be precise, if only one index is present, then the second index is assumed to be ":". A ":" indicates all rows or columns; i.e., A[:,1] is the first column of A, and A[:,:] is A itself. Another example: >v=[-1,-2,-3,-4,-5]; v[[5,4,3,2,1,1]] gives the vector [-5,-4,-3,-2,-1,-1]. If A is a 4x4 matrix, then A[[2,1]] gives a 2x4 matrix, which consists of the second row of A on top of the first row. Note, that there may be a 0xN or Nx0 matrix. For compatibility reasons, the square brackets can be replaced by round brackets. Thus, A(1,1) is the same thing as A[1,1]. But A[1,1] is faster. Furthermore, if there is a function A, then A(1,1) will result in a function call to A. A{i} gives the i-th element of the matrix A, as if the NxM Matrix A was a vector of length N*M. This is useful for making functions work for matrices, and is really the quickest way to access a matrix element. It works also, if the matrix A is to small or a real or complex variable. Then the result is the last element of A. String constants are enclosed in double quotes, like in >string="This is a text" The section on the line editor shows how to insert a double quote into a string. A single character with ASCII code n can be produced by >char(n) If A is a matrix expression (an expression of type matrix), then A' is the transposed matrix. The ":" serves to generate a vector quickly. Thus >1:10 generates the vector [1,2,3,4,5,6,7,8,9,10]. A step size may be given as in the example >5:-1.5:1 which yields [5,3.5,2]. By numerical reasons, one cannot expect to hit 1 exactly with 0:0.1:1. However, the program uses the internal epsilon to stop generating the vector, so that 0:0.1:1 yields the desired result. By default, the internal epsilon is set so that even >0:0.0001:1 works correctly. The binary operator "|" puts a matrix aside another; i.e., if A is a NxM matrix and B is a NxK matrix, then A|B is a Nx(M+K) matrix, which consists of A left of B. Analogously, A_B puts A atop of B. These operators work also for numbers, which are treated as 1x1 matrices. They do even work, if A is a Nx0 or 0xN matrix. The mathematical operators +,-,*,/ work as usual for numbers. For matrices they work elementwise. The matrix product of A and B is computed by "A.B". If a is a number and B a matrix, then a+B or B+a computes the sum of all elements of B with a. This also holds for the other operators. Of course, -A negates all elements of A. EULER knows the rule, to compute "*" and "/" before "+" and "-". One can also write ".*","./" for compatibility with MATLAB. If A has a different size as B, and neither A or B is a 1x1 matrix or a number, then A+B results in error. Of course, one can use the round brackets ( and ) to group expressions like in >(1+5)*(6+7^(1+3)) The power operator can be written "^" or "**" (or ".^"). It computes the power elementwise, like all the other operatos. So >[1,2,3]^2 yields [1,4,9]. The power may also be negative; i.e., the integer powers of all numbers are defined. For a matrix, inv(A) computes the inverse of A (not "A^-1"!). Note, that "^" has precedence, so >-2^2 gives -4. Comparison of values can be performed with >, >=, <, <=, != (not equal) or == (equal). They result in 1 or 0, where 1 is TRUE. Again, these operators work elementwise; i.e, >[1,2,3,4]>2 yields [0,0,1,1]. >!A (not A) gives a matrix, which is 1 on all zero elements of A, and 0 on all nonzero elements of A. >A && B gives a matrix, which is 1 whenever the corresponding elements of A and B are nonzero. >A || B is 1 whenever the corresponding element of A is nonzero or the corresponding element of B is nonzero. >any(A) yields 1 if any element of A is nonzero. If S and T are strings, then S|T consists of the string T appended to S. GENERATING A MATRIX ------------------- There are several builtin functions which generate matrices. The most elementary ones are zeros([N,M]) and ones([N,M]), which can also be written zeros(N,M) and ones(N,M). They produce a NxM matrix, which is filled with ones or zeros respectively. The first form, which gives the size in a 1x2 vector, is faster, since the second form is not a builtin function, but a user defined function from UTIL. The input for zeros and ones is the output of the "size" function, which gives [N,M] for size(A), if A is an NxM matrix. Note, that one can also generate 0xN and Nx0 matrices. So >zeros[0,5]_v_v is a legal statement, if v is a 1x5 vector. It is also possible to give size several arguments. Then >size(A,B,...) results in the size of the largest matrix of A,B,... However, all matrixes in the list must have the same size, unless their size is 1x1. The use of this feature will become apparent later on. Also >cols(A) >rows(A) return the number of columns and rows of a matrix A. >length(A) it the maximum of the number of columns and rows. More generally, >matrix([N,M],x) or matrix(N,M,x) returns a NxM matrix filled with x, which may be real or complex. >diag([N,M],K,v) produces a NxM matrix, which has the vector v on its K-th diagonal and is 0 everywhere else. If v is not long enough, the last element of v is taken for the rest of the diagonal. The 0-th diagonal is the main diagonal, the 1-st the one above, and the -1-st the one below. So >diag([5,5],0,1) produces the 5x5 identity matrix. The same can be achieved with >id(5) from UTIL. One can also write diag(N,M,K,v), as this is defined in UTIL. >diag(A,K) gives a vector, which is the K-th diagonal of A. >dup(v,N) duplicates the 1xM vector N times, such that a NxM matrix is generated, which has v in each row. If v is an Mx1 vector, then v is duplicated into the N columns of a MxN matrix. dup works also, if v is a number. Then it generates a column vector. >B=band(A,N,M) sets all elements of A[i,j] to 0, unless N <= i-j <= M. >B=setdiag(A,N,v) sets the N-th diagonal of A to v. v may be a number or a vector. >bandmult(A,B) multiplies to matrices A and B (like A.B), but is considerably faster, if A and B contain lots of zeros. >symmult(A,B) multiplies symmetric matrices A and B and saves half of the time. Furthermore, >flipx(A) flips the matrix, such that the last column becomes the first, the first column the last. >flipy(A) does the same to the rows. LOADING A FILE -------------- To abbreviate tedious input one may generate a file containing EULER commands. This file can be generated with any editor (like 1STWORD, TEMPUS or so). To load that file enter >load "filename" All lines of that file are then interpreted just as any other input from the keyboard. Also a loaded file may itself contain a load command. If an error occurs, the loading is stopped and an error message is displayed. There is a default extension ".e", which you should use for your files. You need not specify this extension in the load command. The best use of a load file is to define functions in that file (see "programming EULER"). BUILTIN FUNCTIONS ----------------- In this section some basic builtin functions are explained. There are the usual functions: abs, sqrt, exp, log, sin, cos, tan, asin, acos, atan, re, im, conj. They all work for complex values. In this case they yield the principle value. There are some functions which make sense only for real values: floor, ceil, sign, fak, bin. floor and ceil give integer approximations to a real number. "bin(n,m)" computes the binomial coefficient of n and m. >pi() (or simply ">pi") is a builtin constant. >epsilon() is an internal epsilon, used by many functions and the operator ~= which compares two values and returns 1 if the absolute difference is smaller than epsilon. This epsilon can be changed with the statement >setepsilon(value) >round(x,n) rounds x to n digits after the decimal dot. It also works for complex numbers. x may be a matrix. >mod(x,y) return x modulus y. >max(x,y) and min(x,y) return the maximum (minimum resp.) of x and y. >max(A) and min(A) return a column vector containting the maxima (minima resp.) of the rows of A. If A is a NxM matrix, then >extrema(A) is a Nx4 matrix, which contains in each row a vector of the form [min imin max imax], where min and max are the minima and maxima of the corresponding row of A, and imin and imax are the indices, where those are obtained. If v is a 1xN vector, then >nonzeros(v) returns a vector, containing all indices i, where v[i] is not zero. Furthermore, >count(v,M) returns a 1xM vector, the i-th component of which contains the number of v[i] in the interval [i-1,i). >find(v,x) assumes that the elements of v are ordered. It returns the index (or indices, if x is a vector) i such that v[i] <= x < v[i+1], or 0 if there is no such i. >sort(v) sorts the elements of v with the quicksort algorithm. If A is NxM matrix >sum(A) returns a column vector containing the sums of the rows of A. Analoguously, >prod(A) returns the products. >cumsum(A) returns a NxM matrix containing the cumulative sums of the columns of A. >cumprod(A) works the same way. E.g., >cumprod(1:20) returns a vector with faculty function at 1 to 20. The only string function in EULER is >stringcompare("string1","string2") which returns 0, if the strings are equal, -1 if string1 is alphabetically prior to string2, and 1 else. >time() returns a timer in seconds. It is useful for benchmarks etc. >wait(n) waits for n seconds or until a key was pressed. >key() waits for a keypress and returns the internal scan code. LINEAR ALGEBRA -------------- There are lots of builtin functions to perform linear algebra. The matrix product has already been discussed. The operation >A\b takes a NxN matrix A and a Nx1 vector b and returns the vector x such that Ax=b. If in >A\B B is a NxM matrix, then the systems A\B[:,i] are solved simultanuously. An error is issued if the determinant of A turns out to be to small relative to the internal epsilon. >inv(A) computes the invers of A. This is a function in UTIL defined as >A\id(cols(A)) There are also more primitive functions, like >lu(A) for NxM matrices A. It returns multiple values, which needs explaining. You can assign its return values to variables with >{Res,ri,ci,det}=lu(A) If you use only >Res=lu(A) all other output values are dropped. To explain the output of lu, lets start with Res. Res is a NxM matrix containing the LU-decomposition of A; i.e., L.U=A with a lower triangle matrix L and an upper triangle matrix U. L has ones in the diagonal, which are omitted so that L and U can be stored in Res. det is of course the determinant of A. ri contains the indices of the rows of lu, since during the algorithm the rows may have been swept. ci is not important if A is nonsingular. If A is singular, however, Res contains the result of the Gauss algorithm. ri contains 1 and 0 such that the columns with 1 form a basis for the columns of A. lu is used by several functions in UTIL. >kernel(A) gives a basis of the kernel of A; i.e., the vectors x with Ax=0. >image(A) gives a basis of the vectors Ax. The primitive function for computing eigenvalues currently implemented is >charpoly(A) which computes the characteristic polynomial of A. This is used by >eigenvalues(A) to compute the eigenvalues of A. Then >eigenspace(A,l) computes a basis of the eigenspace of l. >{l,X}=eigen(A) returns the eigenvalues of A in l and the eigenvectors in X. STATISTICAL FUNCTIONS --------------------- EULER supports statistical functions, such as distribution integrals and random variables. First of all, >random(N,M) or random([N,M]) generates an NxM random matrix with uniformly distributed values in [0,1]. It uses the internal random number generator of ANSI-C. The quality of this generator may be doubtful; but for most purposes it should suffice. The function >normal(N,M) or normal([N,M]) returns normally distributed random variables with mean value 0 and standart deviation 1. You should scale the function for other mean values or deviations. A function for the mean value or the standart deviation has not been implemented, since it is easily defined in EULER; e.g, >m=sum(x)/cols(x) is the mean value of the vector x, and >d=sqrt(sum((x-m)^2)/(cols(x)-1)) the standart deviation. Rather, some distributions are implemented. >normaldis(x) returns the probability of a normally dstributed random variable being less than x. >invnormaldis(p) is the inverse to the above function. These functions are only accurate to about 4 digits. However, this is enough for practical purposes and an improved version is easily implemented with the Romberg or Gauss integration method. Another distribution is >tdis(x,n) It the T-distrution of x with n degrees of freedom; i.e., the probability that n the sum of normally distributed random variables scaled with their mean value and standart deviation are less than x. >invtdis(p,n) returns the inverse of this function. >chidis(x,n) returns the chi^2 distribution; i.e., the distribution of the sum of the squares n normally distributed random variables. >fdis(x,n,m) returns the f-distribution with n and m degrees of freedom. Other functions have been mentioned above, like bin, fak, count, etc., which may be useful for statistical purposes. POLYNOMIALS ----------- EULER stores a polynomial a+bx+...+cx^n in the form [a,b,...,c]. It can evaluate a polynomial with the Horner scheme >polyval(p,x) where x can be a matrix, of course. It can multiply polynomials with >polymult(p,q) or add them with >polyadd(p,q) Of course, the polynomials need not have the same degree. >polydiv(p,q) divides p by q and returns {result,remainder}. >polytrunc(p) truncates a polynomial to its true degree (using epsilon). In UTIL >polydif(p) is defined. It differentiates the polynomial once. To construct a polynomial with prescribed zeros z=[z1,...,zn] >polycons(z) is used. The reverse is obtained with >polysolve(p) This function uses the Bauhuber method, which converges very stabelly to the zeros. However, there is always the problem with multiple zeros destroying the accuracy (but not the speed of convergence). Another problem is the scaling of the polynomial, which can improve the stability and accuracy of the method considerably. Polynomial interpolation can be done by >d=interp(t,s) where t and s are vectors. The result is a polynomial in divided differences (Newton) form, and can be evaluated by >interpval(t,d,x) at x. To transform the Newton form to the usual polynomial form >polytrans(t,d) may be used. Interpolation in the roots of unity can be done with the fast Fourier transform >p=fft(s) Then p(exp(I*2*pi*i/n))=s[i+1], 0<=is=ifft(p) GRAPHICS -------- The best part of EULER is its graphic capability. There are two screens, the text screen and the graphic screen. Text output automatically displays the text screen, and graphic output displays the graphic screen. One may also switch to the graphic screen by pressing TAB on input or with the command >shg; There are two coordinate systems. The screen coordinates are a 1024x1024 grid with (0,0) in the upper left corner. Furthermore, each plot generates plot coordinates mapping a rectangle of the plane on the screen with the smallest x value left and the smallest y value at the bottom. To be precise, the rectangle is mapped to the screen window, which may only cover a part of the display area. See below for more information on windows. If x and y are 1xN vectors, the function >plot(x,y) connects the points (x[i],y[i]) with straight lines and plots these lines. It first clears the screen and draws a frame around the screen window. The plot coordinates are chosen such that the plot fits exactly into the screen window. This behaviour is called autoscaling. You can set your own plot coordinates with >setplot(xmin,xmax,ymin,ymax) (or setplot([...])). The autoscaling is then turned off. To turn it on again, >setplot() or >scaling(1) is used. >s=scaling(0) does also turn off autoscaling and returns the old state of the scaling flag to s. By the way, the plot command returns the plot coordinates; i.e., a vector [xmin,xmax,ymin,ymax]. The screen window is a rectangle on the screen which can be set by >window(cmin,cmax,rmin,rmax) (or window([...])) in screen coordinates. If x is a 1xN vector and A MxN matrix, >plot(x,A) plots several functions. The same is true with >plot(B,A) if B is a MxN matrix. In this case, the plot is done for corresponding rows of A and B. The graphic screen is cleared by the plot command. This can be turned off with >hold on; or >holding(1); To turn holding off, >hold off; or >holding(0); is used. The function holding returns the old state of the holding flag. This is a way to draw several plots into the same frame. Combining window and holding is a way to draw several plots in several windows on the screen. >xplot(x,y) works like plot but does also show axis grids. Actually, xplot has default parameters grid=1 and ticks=1, which determine, if a grid is plotted and axis laballing is done. Thus >xplot(x,y,1,0) does no ticks. Also >xplot(x,y,ticks=0) may be used for the same purpose (see below in the section about EULER programming for details on default parameters). >xplot() plots the axis and ticks only. You should use >shrinkwindow() if you intend to use labels (ticks) on the axis. This leaves some space around the plot. >fullwindow() resizes the plots to the full size. You may also set the x axis grids on your own with >xgrid([x1,x2,x3,...]) or >xgrid([x1,x2,x3,...],f) the latter producing digits at the edge of the plot (ygrid(...) works respectively). Actually, these functions are defined in UTIL. >plotarea(x,y) sets the plot area for the next plot like plot(x,y), but it does not actually plot. >title("text") draws a title above the plot. It is a function in UTIL using >ctext("text",[col,row]) which plots the text centered at screen coordinates (col,row). >text("text",[col,row]) plots the text left justified. The width and height of the charcters can be asked with >textsize() returning the vector [width,height] in screen coordinates. If a color monitor is used, EULER can produce colored plots. The plot color can be modified with >color(n) where n=1 is black, and n=0 is white. Other colors depend on your system settings. The textcolor and framecolor can be set the same way. There is the possibility to use dotted and dashed lines, or even invisible lines erasing the background. This is done with the style one of the commands >style(".") >linestyle(".") ("-","--","i"). The function linestyle, also >linestyle("") returns the previous line style. The lines can have a width greater than 0. This is set with >linewidth(n) The function returns the previous setting. The command >mark(x,y) works like plot. But it does not connect the points but plots single markers at (x[i],y[i]). The style of the marker can be set with one of the commands >style("mx") >markerstyle("mx") for a cross. Other styles are "m<>" for diamonds, "m." for dots, "m+" for plus signs, "m[]" for rectangles and "m*" for stars. The function returns the previous marker style. >style("") resets the plot and marker styles. There is also the command >xmark(x,y) The easiest way to produce 3D-plots is >mesh(Z) If Z is a NxM matrix, its elements are interpreted as z-values of a function defined on a grid of points (i,j). The plot is a three dimensional plot with hidden lines of the points (i,j,Z[i,j]). It is autoscaled to fit onto the screen window. The point (1,1,z[1,1]) is the left foremost point. To improve the look of the plot, one uses >triangles(1) However, this way is considerably slower. Of course, >triangles(0) turns this feature off again. One can also turn off the different fill styles mesh uses for the two sides of the plot with >twosides(0) This function works also for solid plots described below. It is a faster way than the use of triangles to avoid the errors, that the mesh plot frequently makes. By the way, both functions return the old values of the flags. There is a function which produces matrices X and Y such that X[i,j] and Y[i,j] are the coordinates in the plane of a point in a rectangular grid parametrized by (i,j). This function is >{X,Y}=field(x,y) where x and y are row vectors. Then X[i,j] is equal to x[i] and Y[i,j] is equal to y[j]. So you can easily generate a matrix of function values; e.g., >Z=X*X+Y*Y Note that this is not the most economical way. The above Z would be generated by >Z=dup(x*x,cols(y))+dup(y*y,cols(x))' much more rapidly. A nicer way to plot a surface is >solid(x,y,z) or >framedsolid(x,y,z) where x, y and z are NxM matrices. The surface parameters are then (i,j) and (x[i,j],y[i,j],z[i,j]) are points on the surface. The surface should not self intersect; or else plot errors will occur. The surface is projected onto the screen in central projection, with the view centered to (0,0,0). You can set the viewing distance, a zooming parameter, the angles of the eye from the negative y- to the positive x-axis, and the height of the eye on the x-y-plane, by >view(distance,tele,angle,height) (or view([...])). view returns the previous values and view() merely returns the old values. framedsolid has a default parameter scale, which scales the image to fit into a cube with side length 2*scale, centered at 0, unless scale=0, which is the default value (no scaling). Thus >framedsolid(x,y,z,2) will scale the plot so that |x|,|y|,|z|<=2. >wire(x,y,z) and >framedwire(x,y,z) work the same way, but the plotting is not solid. If x, y and z are vectors, then a path in three dimensions is drawn. The color of the wires is set by >wirecolor(c) If you add an extra value to framedwire or framedsolid like in >framedwire(x,y,z,scale) the plot is scaled to fit into a cube of side length 2scale. The function >{x1,y1}=project(x,y,z) projects the coordinates x,y,z to the screen and is useful for 3D path plots. There is a function >scalematrix(A) which scale the matrix A linearly so that its entries are between 0 and 1. >solid(x,y,z,i) is a special form of solid. If i=[i1,...,in], then the ij-th row of (x,y,z) is not connected to the ij+1-st row. I.e., the plot consists of n+1 parts. A contour plot of a matrix is produced by >contour(A,[v1,...,vn]) The contour lines are then at the heights v1 to vn. The interpretation of A is the same as in mesh(A). A density plot is a plot of a matrix, that uses shades to make the values visible. It is produced with >density(A) The integer part of the values is cut off. So the shades run through the available shades, if A runs from 0 to 1. A can be scaled to 0 to f with >density(A,f) f=1 is the most important value. The shades can be controlled with >huecolor(color) if color=0, then the function uses the available colors for shading. One should set these colors to give a nice color scale from dark to light. This option is not available on B/W screens. Any positive color produces shades in that color using dithering. Any negative color cycles through colors 4 to 16 plus dithering. >solidhue(x,y,z,h) makes a solid view with shades. h are the shading values as in density. >framedsolidhue(x,y,z,h,scale,f) works like a mixture of framedsolid and solidhue. scale=0 and f=1 are the default values. The plotting of a user defined function f(x,...) can be done with >fplot("f",a,b) >fplot("f",a,b,n) >fplot("f",a,b,,...) The extra parameters ... are passed to f. n is the number of subintervals. Note the extra ',', if n is omitted. If a and b are omitted, as in >fplot("f",,,,...) or >fplot("f") then the plot coordinates of the last plot are used. You can zoom in with the mouse by >setplotm(); fplot("f"); This lets you select a square region of the screen. In any case, setplotm() sets the plot coordinates to the user selected square. It is possible to sample coordinates from the graphics screen with the mouse. >mouse() displays the graphics screen and a mouse pointer and waits for a mouse click. It returns a vector [x,y] which are the plot coordinates of the clicked spot. Using >{x,y}=select() returns several x coordinates and y coordinates at the points, which the user selected by the mouse. The selection stops, if the user clicks above the plot window. DIRECTORIES ----------- The active directory can be changed with >cd("path") where path is the new directory and may include a drive letter, like >cd("a:\progs") The command >dir("*.e") displays all files in the active directory, which fit with the pattern. This is not available on UNIX machines. THE META FILE ------------- For special purposes, you can keep a record of your graphic output on an external file called meta file. You turn on recording with >meta "filename"; and turn it off again with >meta; The content of the meta file looks like this. All commands start with a command number (a byte) and the number of arguments (a byte). Then several arguments follow (int or long or a string). The screen coordinates are multiplied by 1000 and are stored long, as is hue and scale. Note that int may be 16-bit or 32-bit depending on your machine. - 1 c0 r0 c1 r1 color style width Draws a line from (c0,r0 to (r1,c1). The style is none=0, solid=1, dotted=2, dashed=3. - 2 c r color type A marker at (c,r). dot=0, plus=1, start=2, square=3, cross=4, diamond=5. - 3 n c1 r1 f1 c2 r2 f2 c3 r3 f3 ... cn rn style A filled rectangle with the specified corners. fill style is solid=0, dotted=1. The corners are (ci,ri) and fi is a flag which determines if the point is to be connected to the next one on the boundary. n is the number of points. - 4 c r color centered Text+0(+0) A text at (c,r). The extra 0 makes the text have an even length. - 5 scale scales the plot window to 1 : (scale/1024). A 0 means rescaling to full screen. - 6 clears the screen. - 7 c1 r1 c2 r2 hue color Draws a rectangle with upper left corner (c1,r1) and lower right corner (c2,r2). hue is a value from 0 to 1 multiplied by 1000. color is as in the function huecolor(). - 8 c1 r1 c2 r2 c3 r3 c4 r4 hue color Draws a filled polygon with corner (ci,ri). The author has no use for the meta file right now. But clearly someone might write a program for printer output, film sequences etc. using the meta file. Sorry, but I was unable to use POSTSCRIPT commands. It should be trival to translate the above commands however. PROGRAMMING EULER ---------------- EULER would not be as powerful as it is, if there wasn't the possibility to extend it with user defined functions. A function can be entered from the keyboard or better from a load file. Since there may be errors in a function, it is best to call an editor, edit the function in a file and then load that file. Loading a file is done with >load "filename" as explained above. FUNCTIONS --------- A function is declared by the following commands >function name (parameter,...,parameter) >... >endfunction It can have several parameters or none. If the function is entered from the keyboard, the prompt changes to "udf>". "endfunction" finishes the function definition. An example: >function cosh (x) udf> return (exp(x)+exp(-x))/2 udf>endfunction Every function must have a return statement, which ends the execution of the function and defines the value it returns. A function can be used in any expression, just as the builtin functions. If a function is not used in an assignment and with surpressed output (followed by ";"), it is used like a procedure and its result is evidently lost. However, the function may have had some side effect. Inside a function one cannot access global variables or variables of the function which called the function. To use global variables use the command >global variablename in the function body. Of course, one can use other functions in expressions inside a function, one can even use the function inside itself recursively. All variables defined inside a function are local to that function and undefined after the return from the function. There is no way to define global variables or change the type or size of global variables from within a function, even if one defines these variables in a "global" statement. All parameters are passed as references. That means that a change of a parameter results in the change of the variable, which was passed as the parameter. For example >function test(x) > x=3; > return x >endfunction >a=5; >test(a); >a gives the value 3. There is an exeption to this. A submatrix is not passed by value. Thus >a=[1,2,3]; >test(a(1)); >a(1) gives the value 1. A function can have a variable number of parameters. The number of parameters passed to a function can be determined with the builtin function "argn()". If the parameters are not named in the function definition, they are given the names arg1, arg2 and so on. Parameters can have default values. The syntax ist parameter=value in the parameter definition; e.g., >function f(x=3,y,z=1:10) assigns the default value 3 to x and the vector 1 to 10 to z, if the function is called in the form >f(,4,) If the function is called >f(1,4) x has the value 1, y the value 4, and z the value 1:10. The function can even be given a named parameter. Consider the function >function f(x,y,z=4,w=4,t=5) Then >f(1,2,t=7) calls the function, as if >f(1,2,4,4,7) was entered. Actually the name needs not be a parameter name. Thus >f(1,2,s=7) defines a local variable s with value 7. A function can return multiple values. This is done with the return statement > return {x,y,...} You can assign all the return values of a function to variables, using >{a,b,...}=function(...); If the result of such a function is assigned to a number of variables smaller than the number of returned values, only the first values are used. If is is assigned to a larger number of variables, the last value is used more than once. Some builtin functions return multiple values. Comments can be included, starting with ##. Comments are not entered in the function definition and do not appear, when you type the function with >type functionname If the lines immediately after the function header start with ##, then those lines are considered to be help text. They can be displayed with >help functionname This is a good way to remember the parameters of the function. Also >list can be used to display the names of the user defined functions. A function or several functions can be removed with >forget name,... By the way, a variable can be removed with >clear name,... EULER PROGRAMMING LANGUAGE ------------------------- Like in any other programming language, in EULER there are commands for changing the flow of evaluation. These commands can only be used inside user defined functions. First there is the "if" command. >if expression; ...; else; ....; endif; The expression is any EULER numerical expression. If it is a matrix, and all its entries are different from zero, then the part from the ";" to the "else;" is evaluated. Else the part from "else;" to "endif" is evaluated. Of course "..." may spread over several lines. To work correctly, keywords like "if", "else", "endif" and others should be the first nonblank characters in a line, or should be preceded by "," or ";" (plus blanks or TABs). The "else" may be omitted. In this case the evaluation skips behind the "endif", if the matrix contains nonzero elements (resp. the number is nonzero). There is the function "any(A)", which yields 1, if there is any nonzero element in A, 0 otherwise. The function is useful in connection with the if statement. Next, there are several loops. >repeat; ...; end; >loop a to b; ...; end; >for i=a to b step c; ...; end; All loops can be aborted by the break command (usually inside an "if"), especially the seemingly infinite "repeat". "loop" loops are fast long integer loops. The looping index can be accessed with the function "index()" or with "#". In a "for" loop the looping index is the variable left of the "=". The step size can be omitted. Then it is assumed to be 1. As an example, the following loops count from 1 to 10: > i=1; > repeat; > i, i=i+1; > if i>10; break; endif; > end; and > loop 1 to 10; #, end; and > for i=1 to 10; i, end; DEBUGGING EULER PROGRAMS ------------------------ The command >trace on sets tracing of all functions on. Then any new line in a user defined function will be printed with the function name before it is executed. The uses has to press a key, before execution continues: F1 debugs every function. F2 debugs no function called in the current line. F3 will stop debugging until return of the current function. F4 will prompt for an expression and evaluate it. F9 aborts execution of the program. F10 ends tracing for this command. Any other key will display the available keys. >trace off switches tracing off. Note, that with F4 you can evaluate any expression, even if it contains local variables or subroutine calls. Tracing is switched off during evaluation of the expression. A single function can be traced with >trace function or >trace "function" Execution will stop only in this function. The same command switches the trace bit of this function off. >trace alloff switches tracing for all functions off. PROGRAMMING STYLE ----------------- All internal EULER functions can handle vector or matrix input. And so should user defined functions. To achieve this, sometimes nothing special needs to be done. E.g., the function >function kap (r,i,n) > p=1+i/100; > return p*r*(p^n-1)/(p-1) >endfunction is automatically capable to handle matrix intput. Thus >kap(1000,5:0.1:10,10) will produce a vector of values. However, if the function uses a more complicated algorithm, one needs to take extra care. E.g., >function lambda (a,b) > si=size(a,b); l=zeros(si); > loop 1 to prod(si); > l{#}=max(abs(polysolve([1,a{#},b{#},1]))); > end; > return l >endfunction shows the fastest way to achieve the aim. "si" will contain the size, of the matrix "a" or "b", and will yield an error message, if the sizes are different. However, if "a" is a real and "b" a matrix, "si" will contain the size of "b" and the program will still run properly. The loop will then be over all the elements of "a" or "b". the "{#}" indexing works correctly, if the vector is smaller than the index. It then yields the last element of a vector, which is OK in the case of a real or complex values. See also the function "map" in UTIL explained below. Forthermore, as a matter of good style, one should use the help lines extensively. One should explain all parameters of the function and its result. This is a good way to remember what the function really does. PASSING FUNCTIONS AS PARAMETERS ------------------------------- It is possible to pass functions to a function. E.g., the function "bisect" in UTIL finds the zero of a function using bisection. One uses this function in the following way: >function f(x) > return x*x-2 >endfunction >bisect("f",1,2) The result will be sqrt(2). If "f" needs extra paramters, those can also be passed to "bisect": >funtion f(x,a) > return x*x-a >endfunction >bisect("f",0,a,a) will result in sqrt(a) (for a>=0). The search interval is set to [0,a]. The way to write a function like "bisect" is to use the "args" function. >function bisect (function,a,b) >... > y=function(x,args(4)); >... >endfunction Then "function" will be called with the parameter "x" and all paramters from the 4-th on (if any) which have been passed to "bisect". Of course, "function" should be assigned a string, containing the name of the function which we want the zero of. USER INTERFACE -------------- Clearly, EULER is designed to run interactively. The user loads a file containing the functions he needs. The file may inform the user of its content by simply printing some messages with commands like >"The content of this file is:", >... Then the user can use the help facility to retrieve further information on the functions, its parameters and so on. He (or she) then calls the particular function with the parameters he desires. However, it is also possible to run a file as a standalone program. If you start EULER from a shell simply put the file into the command line. On the ATARI computer, you may also make EULER an application. Then all EULER files should have the same extension and clicking on such a file will start EULER and load the file. See the ATARI documentation for further information. If you wish a standalone application, the user will have to enter data. You can prompt him with >data=input("prompt"); The prompt prompt? > will appear and the user may enter any valid EULER expression, even if it uses variables. Errors are catched and force the user to reenter the input. If you wish the user to enter a string, use >string=lineinput("prompt"); The string may then be evaluated with >data=interpret(string); and if it does not consist of a valid EULER expression the result is the string "error". Output is printed to screen. All expressions and assignments produce output unless followed by ";". If formated output is wanted, use >printf("formatstring",realdata) The format string obeys the C syntax; e.g., "%15.10f" prints the data on 15 places with 10 digits after decimal dot, and "%20.10e" produces the exponential format. You can concatenate strings with | to longer output in a single line. Output is surpressed globally with >output off; and >output on; turns the output on again. This is useful if a dump file is defined by >dump "filename"; Then all output is echoed into the dump file. The command >dump; turns the dump off. Note that the dump is always appended to the file. Furthermore, that file may not be edited while dump is on! In UTIL the function >write(x,"x") is defined, which writes x in a format readable by EULER on input. If you omit the name "x", the name of x is used automatically. This is done with the help of the function >name(x) which gives a string containing the name of x. >cls; clears the screen. >clg; clears the graphics. Also to show graphics to the user, use >shg; Subsequent output will switch back to the text screen. Finally, an error can be issued with the function >error("error text") UTILITIES --------- In UTIL some fuctions are defined, which will to be of general use. First there are some functions for solving equations. >bisect("f",a,b,...) uses the bisetion method to solve f(x,...)=0. f must be a function of the real variable x which may have additional parameters "...". These parameters can be passed to bisect and are in turn passed to f. >secant("f",a,b,...) uses the secant method for the same purpose. >broyden("f",x) or >broyden("f",x,J,...) uses the Broyden method to find the roots of f(x,...)=0. This time, f may be a function f : R^n -> R^n. Then x is a vector. J is an approximation of the Jacobian at x, the starting point. If J==0 or J is missing, then the function computes J. Again, additional parameters are passed to f. >simpson("f",a,b) or >simpson("f",a,b,n,...) computes the Simpson integral with of f in [a,b]. n is the discretization and additional parameters are passed to f(x,...). f must be able to handle vector input for x. >gauss("f",a,b) or >gauss("f",a,b,n,...) performs gauss integration with 10 knots. If n is specified, then the interval is subdivided into n subintervals. f(x,...) must be able to handle vector intput for x. >romberg("f",a,b) or >romberg("f",a,b,n,...) uses the Romberg method for integration. n is the starting discretization. All other parameters are as in "simpson". The iteration goes on until the accuracy rombergeps is reached, which is epsilon() initially. There are some approximation tools. Polynomial interpolation has been discussed above. There is also spline interpolation >sp=spline(t,s) which returns the second derivatives of the natural cubic spline through (t[i],s[i]). To evaluate this spline at x, >splineval(t,s,sp,x) is available. >polyfit(t,s,n) fits a polynomial of n-th degree to (t[i],s[i]) in least square mode. This is an application of >fit(A,b) which computes x such that the L_2-norm of Ax-b is minimal. >iterate("f",x) or >iterate("f",x,n,...) iterates f starting at x n times and returns the vector of iterated values. If n is missing or 0, then the iteration stops at a fixed point and only this fixed point is returned. >map("f",x,...) evaluates the function f(x,...) at all elements of x, if f(x,...) does not work because the function f does not accept vectors x. HINTS ----- One can make all sorts of mistakes in EULER. This section tries to warn you of the more common ones, most os which the author has some experience with. As already mentioned, you should not assign to the parameter of a function. This will generally produce strange errors, which are difficult to debug. If you need default values for parameters, use a construction like >function f(a,x) > if argn()==2; xx=x; else xx=4; endif > ... which gives xx the value of the second parameter, with default 4. The next mistake is to produce matrices with 0 rows or columns. EULER can not do any computation with these matrices. Make sure that every index you use is in range. And use special handling, if there is nothing to do. Another subtlety concerns the use of multiple return values. The following simply does not work: >x=random(1,10); sin(sort(x)) The reason is that sort returns not only the sorted array but also the indices of the sorted elements. This works as if sin was passed two parameters and EULER will not recognize that use of sin. To work around this either assign the sorted array to a variable or put extra brackets around it: >x=random(1,10); sin((sort(x))) Also a return statement like >return {sort(x),y} really returns 3 (or more) values! Use >return {(sort(x)),y} One further misfortune results from the use of strings as functions, like in >function test(f,x) > return f(x*x) >endfunction >test("sin",4) This works well as long as there is no function by the name of "f". If there is, this function is called rather than the sine function. The only way to avoid this is to use really strange names for function parameters. I prefer "test(ffunction,x)" and used it throughout UTIL. VERSION CHANGES --------------- Here is a list of recent changes to EULER. The new version should be downward compatible in most cases. Minor error corrections are not listed here. - Named parameters and default values for paramters have been introduced. Many functions in UTIL.E have been redesigned using the new features. - Graphic primitives have been changed. Lines can have a width now. The density, huecolor and solidhue functions have been introduced. This changed the content of the meta file, which has also been simplified. - New functions in UTIL.E: scalematrix, select, framedsolidhue, setplotm. - The key function is defined. It waits for a key stroke. - The help/insert key extends incomplete commands. FINAL WORDS ----------- The author is interested in applications of EULER and will collect them. These applications will then be included in program updates (maybe in packed form). Some interesting applications are in the folder PROGS. The file EXAMPLES.DOC contains sample sessions with EULER and shows how to solve problems with this programming system. The author wishes anyone success in using EULER. Dr. R. Grothmann Grafenwerderstr. 14 W-8059 Wrth Germany EMail: mga010@ku-eichstaett.de .TH Euler 1 "" "" .SH NAME Euler - A numerical laboratory. .SH SYNTAX euler [-f font] [-g font] [-s KB] [-geom geometry] [-d display] [-0..15 color] [ files ] .SH OPTIONS .TP 8 -f font Specifies the font name for text output. .TP 8 -g font Specifies the font name for graphic text. .TP 8 -s number Specifies the number of KBytes for the user area of Euler. .TP 8 -geom geometry geometry is the geometry of the euler window in standard form. .TP 8 -number color Sets the color number to a color name. .TP 8 files Specifies input files for Euler. Default extension is ".e". .SH PURPOSE Euler is a Matlab(R) style numerical laboratory. It is capable of numerical mathematics with real or complex scalars, vectors or matrices. It can produce graphics in 2D or 3D. The built in programming language can be used to define functions, which can be loaded from external files. Many useful numerical algorithms are contained in the code. Others are contained in the setup file and written in the Euler language. .SH USAGE This version of Euler has a single window. The user can switch between the text and graphics output with the TAB key. Old text output may be accessed by the page up and pyge down key. Pointer usage is restricted to the mouse function. For details on the use of euler see the file euler.doc. .SH FILES .TP 12 euler The program. .TP 12 euler.cfg The configuration file, which in turn loads "util.e". .TP 12 *.e Euler language files. Important examples are "util.e" and "demo.e" .TP 12 euler.doc The documentation. .P On this system, euler is a shell script, which envokes the euler program and sets the directory to $HOME/euler/progs. Scan this directory for the "*.e" and "*.doc" files. Examples ======== Basic ideas ----------- EULER can do ordinary arithmetic like >(22+5)*(2^4-6) 270.00000 or >exp(-4) 0.01832 To get a longer output, we simply use the function >longformat 14.000000000000 5.000000000000 defined in UTIL. >exp(-4) 0.018315638889 Note, that the logarithm function computes the natural logarithm >log(exp(-4)) -4.000000000000 and the arcsine, arccosine a.s.o. are called asin,... >2*asin(1)-pi 0.000000000000 EULER can also handle vectors, like >[1,2,3,4,5] Column 1 to 3: 1.000000000000 2.000000000000 3.000000000000 Column 4 to 5: 4.000000000000 5.000000000000 All data can be assigned to a variable. Its name may consist of up to 15 letters >t=[1,2,3,4,5] Column 1 to 3: 1.000000000000 2.000000000000 3.000000000000 Column 4 to 5: 4.000000000000 5.000000000000 The important thing to know is that all functions are applied for each component of the vector. So >sqrt(t) Column 1 to 3: 1.000000000000 1.414213562373 1.732050807569 Column 4 to 5: 2.000000000000 2.236067977500 computes the square root of all elements of the vector. And >sqrt(t)*sqrt(t) Column 1 to 3: 1.000000000000 2.000000000000 3.000000000000 Column 4 to 5: 4.000000000000 5.000000000000 multiplies two vectors in each element. If one of the operators is a scalar (a real or complex number), the operation is applied on the scalar and each component of the vector. >5*t Column 1 to 3: 5.000000000000 10.000000000000 15.000000000000 Column 4 to 5: 20.000000000000 25.000000000000 >t*5 Column 1 to 3: 5.000000000000 10.000000000000 15.000000000000 Column 4 to 5: 20.000000000000 25.000000000000 It may be confusing to devide vectors, but EULER does it simly deviding each element of the vector. >t/t Column 1 to 3: 1.000000000000 1.000000000000 1.000000000000 Column 4 to 5: 1.000000000000 1.000000000000 An expression of the form a:h:b generates the vector [a,a+h,a+2h,...a+nh], where the n is the biggest n such that a+nh <= b+epsilon. Here, epsilon is a built in machine constant of small size. Example: >t=-1:0.01:1; The semicolon ";" suppresses the boring output of the vector. The elements of t are >t(1) -1.000000000000 >t(2) -0.990000000000 The size of this vector can be asked with >size(t) 1.000000000000 201.000000000000 The size function outputs a 1x2 vector containing the number of rows and columns of the matrix (we will soon see that vectors are special matrices). >t(201) 1.000000000000 It is better to use [...], because this notation evaluate faster. >t[201] 1.000000000000 Note, that >t[202] evaluates to a 1x0 vector. Let us do something useful with a vector. We like to plot a function. First of all, we use a graphics command to be explained later on. >shrinkwindow Column 1 to 3: 12.000000000000 38.000000000000 1011.000000000000 Column 4 to 4: 1011.000000000000 The 14 digit precission becomes boring, so we switch it off >shortformat; Next we plot a function >xplot(t,t*t*t-5*t*t+t) -1.00000 1.00000 -7.00000 0.05100 xplot(t,s) or plot(t,s) simply plot the points (t[i],s[i]) on the graphcis screen. You may even add a title to your plot. >title("t^3-5t^2+t"); Another function: >xplot(t,sin(2*pi*t)) -1.00000 1.00000 -1.00000 1.00000 We could have stored the values of our function into a vector. >s=t^3-5*t^2+t; Compute the maximum and minimum of this vector >max(s) 0.05100 >min(s) -7.00000 Vectors are really special matrices. You can enter a matrix with >A=[1,2,3;4,5,6;7,8,9] 1.00000 2.00000 3.00000 4.00000 5.00000 6.00000 7.00000 8.00000 9.00000 Compute the determinant of A. >det(A) 0.00000 A is singular. So let us change it a little bit >A[3,3]=10 1.00000 2.00000 3.00000 4.00000 5.00000 6.00000 7.00000 8.00000 10.00000 >det(A) -3.00000 Now we solve a linear system. >x=[1;1;1] 1.00000 1.00000 1.00000 gives a column vector, which can be multiplied with A. >b=A.x 6.00000 15.00000 25.00000 Then >A\b 1.00000 1.00000 1.00000 solves the linear system. The eigenvalues of A are all real. >eigenvalues(A) Column 1 to 2: 0.19825 0.00000 -0.90574 0.00000 Column 3 to 3: 16.70749 -0.00000 This is a complex vector, which we can make real with >re(eigenvalues(A)) 0.19825 -0.90574 16.70749 Zeros of a real-valued function of one variable ----------------------------------------------- The task is to compute the smallest positive zero of a function. First we define f. >function xi (g) udf> return (2-3*g^2)/(1-2*g^2)*g udf>endfunction >function l (g) udf> xi=xi(g); udf> return log(g)+8*xi/(1-xi^2) udf>endfunction In this case, we used an interactive definition. Of course, the functions could also be defined in a file. Let us print the functions. >type xi function xi (g) return (2-3*g^2)/(1-2*g^2)*g endfunction >type l function l (g) xi=xi(g); return log(g)+8*xi/(1-xi^2); endfunction Now we plot the functions, to see where the zeros are. >t=0:0.01:1; s=l(t); >setplot(0,1,-5,5); shrinkwindow(); >xplot(t,s); ygrid(0); xgrid(0:0.1:1); hold off; To locate the zero we use the mouse. >mouse() 0.11912 -0.15416 There should be a zero close to 0.12. We use bisection to compute it. >longformat(); bisect("l",0.1,0.2) 0.122366058965495 That solves our problem. The fibonacci numbers --------------------- Lets investigate the fibonacci numbers defined by f(1)=1, f(2)=1 and f(n+1)=f(n)+f(n-1). First we write a function computing the first n fibonacci numbers. >function fibo (n) udf>## computes the first n fibonacci numbers. udf> r=ones(1,n); udf> for i=3 to n; r[i]=r[i-1]+r[i-2]; end; udf> return r udf>endfunction Test: >fibo(5) 1.00000 1.00000 2.00000 3.00000 5.00000 Now we compute a 1000 of them. >f=fibo(1000); >plot(f) 1.00000 1000.00000 1.00000 4.34666e+0208 The plot shows a sharp increase of the numbers, probably exponetially. >plot(log(f)) 1.00000 1000.00000 0.00000 480.40711 Indeed the growth is of exponential nature. The growth rate is about 0.48 as can be seen with >plot(log(f)/(1:length(f))) 1.00000 1000.00000 0.00000 0.48041 The reason is the largest eigenvalue of the matrix >A=[0,1;1,1] 0.00000 1.00000 1.00000 1.00000 This matrix maps [f(n);f(n+1)] to [f(n+2);f(n+3)]. Let us compute the eigenvalues. >{l,V}=eigen(A); D=diag(size(A),0,l); Thus >V.D.V' 5.42101e-0020 0.00000 1.00000 0.00000 1.00000 0.00000 1.00000 0.00000 is A. V is a unitary matrix, since all eigenvectors are normed. Thus A^n = V . D^n . V': >V.(D^998).V'.[1;1] 2.68638e+0208 5.71486e-0226 4.34666e+0208 -3.53198e-0226 >f[1000] 4.34666e+0208 See! Thus the growth rate is >log(max(abs(l))) 0.48121 The exponential function for matrices ------------------------------------- This job will be solved in two versions. The first one evaluates exp(A) = I + A + A/2 + A/3! + A/4! + ... >type mexp function mexp (A) B=id(length(A)); S=B; n=1; repeat; if max(max(abs(B)))~=0; break; endif; B=A.B/n; S=S+B; n=n+1; end; return S endfunction The stopping criterion max(max(abs(B)))~=0 tests, if all elements of B are smaller than epsilon(). The second version uses eigenvalue decomposition. >type mexp1 function mexp1 (A) {l,v}=eigen1(A); return v.diag(size(A),0,exp(l)).inv(v) endfunction Let us test these functions. >A=[1,1,2;3,4,5;6,7,8] 1.00000 1.00000 2.00000 3.00000 4.00000 5.00000 6.00000 7.00000 8.00000 >eigenvalues(A) Column 1 to 2: 0.30420 0.00000 -0.73432 0.00000 Column 3 to 3: 13.43012 -0.00000 which means that A can be diagonalized. >mexp(A) 59292.72131 71084.03394 87292.04912 169351.28682 203035.19937 249326.53344 283826.55487 340276.98381 417861.71137 >mexp1(A) Column 1 to 2: 59292.72131 0.00000 71084.03394 0.00000 169351.28682 0.00000 203035.19937 0.00000 283826.55487 0.00000 340276.98381 0.00000 Column 3 to 3: 87292.04912 0.00000 249326.53344 0.00000 417861.71137 0.00000 Both functions work also for complex arguments. Solving a two point boundary equation ------------------------------------- We wish to solve the following differential equation y''(t)=t*y(t)*(y(t)-t)+1, y(0)=0, y(1)=0. First we define the differential equation; i.e., the system y1'=y2, y2'=ty1(y1-t)+1, >type dgl function dgl (t,x) return [x[2],t*x[1]*(x[1]-t)+1] endfunction Next we define a function which computes y(1) in dependence of y'(0). >type f function f (a,h) si=size(a); r=zeros(si); loop 1 to prod(si); l=heun("dgl",h,[0,a{#}]); r{#}=l[1,length(l)]; end; return r endfunction Let us get an idea, how solutions of this equation look like. >h=0:0.05:1; >xplot(h,heun("dgl",h,[0,0])); >xplot(h,heun("dgl",h,[0,1])); >xplot(h,heun("dgl",h,[0,-1])); Note, that heun returns a vector of function values and a vector of first derivatives. Now we solve the equation f(s)=0, which is equivalent to the shooting method. >a=-1:0.1:1; xplot(a,f(a,h)); >mouse -0.51456 0.01060 Thus the solution is close to -0.51. >s=secant("f",-0.52,-0.51,h) -0.51056 This is the solution. >xplot(h,heun("dgl",h,[0,s])); finally plots the solution and the derivative. Interest rates -------------- If you buy an investement for 108 (thousand or so) at year 0 and get payments of 8 at the end of the next 8 years. At the end of the 8th year you sell the investment for 100. The problem is to determine the interest rate of this investment. First of all, we enter the payments in a vector >K=[-108,8,8,8,8,8,8,8,108] Column 1 to 5: -108.00000 8.00000 8.00000 8.00000 8.00000 Column 6 to 9: 8.00000 8.00000 8.00000 108.00000 If the interest rate was i=(1+p/100), then a payment of a in n years is a/i^n today. Thus the interest rate is the solution of the equation K[0] + K[]/i + K[2]/i^2 + ... K[n]/i^n = 0. If we replace i with 1/x this becomes a polynomial. And we have polysolve at our hands to get the zeros of polynomials. >z=polysolve(K) Column 1 to 2: 0.93741 0.00000 -0.71379 -0.71358 Column 3 to 4: -0.71379 0.71358 0.71304 -0.71421 Column 5 to 6: 0.71304 0.71421 -0.00035 1.00929 Column 7 to 8: -0.00035 -1.00929 -1.00930 1.28498e-0019 Of these zeros the first one is the solution to our problem >r=(1/re(z[1])-1)*100 6.67698 Thus this investment has about 6.7% interest. However, this way is quite slow and therefore we should use another method. In this case the Newton method works very well. The following functions implements is. >type rendite function rendite (K) K1=polydif(K); x=1; repeat; xn=x-polyval(K,x)/polyval(K1,x); if xn~=x; return (1/xn-1)*1e+0002; endif; x=xn; end; endfunction Note, that the result is rediculously accurate. Instead of xn~=x, abs(xn-x)<0.0001 would fully suffice. Lets test it. >rendite(K) 6.67698 Now we can solve a lot of similar questions. A loan is a single payment made at year 0, and periodic payments over some years. E.g., >K=-104|dup(12,10)' Column 1 to 5: -104.00000 12.00000 12.00000 12.00000 12.00000 Column 6 to 10: 12.00000 12.00000 12.00000 12.00000 12.00000 Column 11 to 11: 12.00000 >rendite(K) 2.69021 is the interest rat of that loan. Lets test some other rates >K=-104|dup(13,10)'; rendite(K) 4.27750 >K=-104|dup(14,10)'; rendite(K) 5.80498 >K=-104|dup(15,10)'; rendite(K) 7.28074 We could make a function of it >type loanrate function loanrate (K,R,n) return rendite(-K|dup(R,n)') endfunction Including some help text helps. >help loanrate function loanrate (K,R,n) ## loanrate(K,R,n) computes the interest rate of a loan of K (including ## disaggio) and n periodic payments of R. endfunction >loanrate(104,12,10) 2.69021 But we are better of, if we make the function work for vector input. >type loanrate function loanrate (K,R,n) si=size(K,R,n); x=zeros(si); loop 1 to prod(si); x{#}=rendite(-K{#}|dup(R{#},n{#})'); end; return x endfunction Then we can plot various interest rates depending on the payments. >r=loanrate(104,12:0.1:17,10); shrinkwindow(); xplot(12:0.1:17,r); The Fast Fourier Transform -------------------------- The fast Fourier transform has many applications. Let us start with a first example involving complex numbers. We define the 512-th roots of unity with >z=exp(I*2*pi*(0:511)/512); and take the exponential function a these points >w=exp(z); To plot the image of the unit circle after the exp function has been applied, we use >shrinkwindow 12.00000 38.00000 1011.00000 1011.00000 >xplot(re(w),im(w)) 0.36788 2.71828 -1.32115 1.32115 This gives an oval shape. Of course, >xplot(re(z),im(z)) -1.00000 1.00000 -1.00000 1.00000 is the unit circle, which is a little deformed on the screen. Now, >p=fft(w); computes the interpolating polynomial; i.e. p(z[i])=w[i]. "ifft(p)" then evaluates this polynomial at the roots of unity z simultanuously. There is an error of course, but it is small. >max(abs(ifft(p)-w)) 1.38951e-0018 Let us truncate p to the first 16 coefficients >q=p[1:16] Column 1 to 2: 1.00000 -2.78697e-0020 1.00000 -3.27627e-0020 Column 3 to 4: 0.50000 -1.87865e-0020 0.16667 -6.79627e-0020 Column 5 to 6: 0.04167 -3.04213e-0020 0.00833 -3.16973e-0020 Column 7 to 8: 0.00139 -2.07105e-0020 0.00020 -2.05299e-0020 Column 9 to 10: 0.00002 -4.69085e-0020 2.75573e-0006 -3.18317e-0020 Column 11 to 12: 2.75573e-0007 -2.58004e-0020 2.50521e-0008 -9.53105e-0021 Column 13 to 14: 2.08768e-0009 -9.94706e-0021 1.60590e-0010 -8.97525e-0021 Column 15 to 16: 1.14707e-0011 -7.15237e-0021 7.64716e-0013 2.48211e-0021 Since q is a real polynomial, we may as well use >q=re(p[1:16]) Column 1 to 5: 1.00000 1.00000 0.50000 0.16667 0.04167 Column 6 to 10: 0.00833 0.00139 0.00020 0.00002 2.75573e-0006 Column 11 to 15: 2.75573e-0007 2.50521e-0008 2.08768e-0009 1.60590e-0010 1.14707e-0011 Column 16 to 16: 7.64716e-0013 These coefficients are in fact close to the Taylor series of exp >max(abs(q-1/fak(0:15))) 2.16840e-0019 The error of the approximating polynomial q is not very big >max(abs(polyval(q,z)-w)) 5.07712e-0014 >xplot(abs(polyval(q,z)-w)) 1.00000 512.00000 4.51316e-0014 5.07712e-0014 This is a typical error curve. Another use is signal processing. Let us first define equispaces values in [0,2pi] >t=0:pi/256:2*pi-pi/256; >size(t) 1.00000 512.00000 For the Fourier transform, optimal speed is achieved when the size is a power of 2. The signal is the mountain shaped function >s=pi-abs(s-pi); >xplot(t,s) 0.00000 6.27091 0.00000 3.14159 Then we add a little bit of noise >sn=s+normal(size(s))*0.05; >style("m."); mark(t,sn); This gives a cloud of values around the function. Then >xplot(abs(fft(s))); >fsn=fft(sn); >xplot(abs(fsn)); compares the Fourier transforms of the two functions. The noise can be seen clearly. To remove the noise, we might try >fsn1=fsn*(abs(fsn)>max(abs(fsn))/50); >xplot(t,re(ifft(fsn1))) 0.00000 6.27091 0.15441 2.99504 or even >fsn1=fsn*(abs(fsn)>max(abs(fsn))/100); >xplot(t,re(ifft(fsn1))) 0.00000 6.27091 0.10004 3.04940 This looks like the function and gives a smooth curve. However, it may sound quite different from the function. We could also remove high frequences with >fsn1=fsn[1:32]|zeros(1,512-64)|fsn(512-31:512); >xplot(t,re(ifft(fsn1))) 0.00000 6.27091 0.02219 3.14823 The apple set ------------- We like to plot the fractal set, defined as the set of all points z, such that the iteration w -> z+w*w is bounded when started at z. First we define a function, which performs this iteration 10 times. >type apple function apple (z) w=z; loop 1 to 10; w=z+w*w; end; return w; endfunction Next a rectangle in the complex plane is iterated >{x,y}=field(-2.5:0.05:1,-1.5:0.05:1.5); >z=x+I*y; >w=apple(z); This takes some time. To view the result, we use >view(5,1.5,0.5,0.5); twosides(0); >framedsolid(x,y,abs(w)<2,2); twosides(1); This looks quite nice, since we stopped EULER's backside detection. >contour(abs(w)<2,0.5); When abs(w[i,j])<2 is 1, we decide that the point z[i,j] should belong to the apple set. Iteration --------- Let us explore the function "iterate" defined in UTIL >help iterate function iterate (ffunction,x,n) ## iterate("f",x,n,...) iterate the function f(x,...) n times, ## starting with the point x. ## if n is missing or n is 0, then the iteration stops at a fixed point. ## Returns the value after n iterations, and its history. We try it out with the cosine function, which is a builtin function. However, we could as well use any user defined function. >iterate("cos",0) 0.73909 This is the fixed point of the cosine. >x=iterate("cos",0.73); x-cos(x) -2.83953e-0016 We can also iterate a vector x. >x=0:0.01:1; >{y,Y}=iterate("cos",x,10); >shrinkwindow(); xplot(x,Y') 0.00000 1.00000 0.00000 1.00000 You see a plot of the iterateted cosine functions, which approach a constant function with geometrical speed. Splines ------- To demonstrate the use of splines, we solve the differential equation y'' + sin(x)^2 *y' + y = cos(x)^2 with a very rough step size. The function f is defined as >type f function f (t,y) return [y[2],cos(t)^2-y[1]-sin(t)^2*y[2]] endfunction It represents the differential equation and maps (y,y') to its derivative. >t=0:20; >s=heun("f",t,[1,0]); >plot(t,s[1]) 0.00000 20.00000 0.21585 1.00000 This does not look smoothly. We smooth it out with spline interpolation >sp=spline(t,s[1]); >plot(x,splineval(t,s[1],sp,x)) 0.00000 20.00000 0.21224 1.00118 which looks much better. Since "sp" contains the second derivatives of the spline at the itnerpolation knots, we could as well compute "sp" ourselves from the differential equation. >sp=cos(t)^2-sin(t)^2*s[2]-s[1]; >plot(x,splineval(t,s[1],sp,x)) 0.00000 20.00000 0.21585 1.00022 There is not much difference. Now let us see if our grid size was to large. >t=0:0.1:20; >s=heun("f",t,[1,0]); >plot(t,s[1]) 0.00000 20.00000 0.18316 1.00000 This is the same picture, we already had. In fact, there is some difference. But the behaviour of the solution can be seen with the rough step size too. Complex numbers --------------- To visualize a complex mapping, there is the function cplot in UTIL. this functions takes a grid of complex values and connects them. >help cplot function cplot (z) ## cplot(z) plots a grid of complex numbers. To use this function, define a erctangular grid of complex numbers. >{x,y}=field(linspace(0,pi(),20),linspace(-1,1,20)); >z=x+1i*y; Now >cplot(z) 0.00000 3.14159 -1.00000 1.00000 plots just a rectangular pattern of lines. But >cplot(cos(z)) -1.54308 1.54308 -1.17520 1.17520 shows what the function cos does to the rectangle [0,pi]x[-1,1]. A pattern of elipses and hyperbola appears. Let us show some grids. >xgrid(-2:2) 0.00000 >ygrid(-2:2) 0.00000 To see the effect of the exponential function to the unit circle, we define >{r,phi}=field(0:0.1:1,0:pi()/10:2*pi()); >z=r*exp(I*phi); >cplot(z) -1.00000 1.00000 -1.00000 1.00000 This is just the unit circle a little distorted. >cplot(exp(z)) 0.36788 2.71828 -1.30249 1.30249 shows the image of the unit circle. With grids: >xgrid(1:2) 0.00000 >ygrid(-1:1) 0.00000 To see the real part of the function, i.e. a harmonic function, we use >twosides(0) 0.00000 >framedsolid(re(z),im(z),im(exp(z)),2) Column 1 to 5: -1.53552 1.53552 -1.53552 1.53552 -2.00000 Column 6 to 6: 2.00000 Also in EULER you need not be afraid of singularities. All one has to do is set the plot area accordingly. >{x,y}=field(-1:0.1:1,-1:0.1:1); >z=x+1i*y; >w=1/z; >setplot(-5,5,-5,5); >cplot(w) -5.00000 5.00000 -5.00000 5.00000 gives a nice picture of the inversion with respect to the unit circle. Another example: >{r,phi}=field(linspace(0.001,5,20),linspace(0,2*pi(),30)); >z=r*exp(1i*phi); >setplot(-2.5,5.5,-3,3.5); Now we can display the following Mbius transform >cplot((2*z-1i)/(z-1)) -2.50000 5.50000 -3.00000 3.50000 >xgrid(0); ygrid(0); INTRODUCTION ------------ This document describes how to extend EULER with own functions. Of course, you need a compiler capable of translating the source code. And you might probably need some good programming experience in C. Furthermore, it is necessary that you have some practice in using EULER. BASICS ------ EULER uses a stack for keeping the variables (local and global) and the parameters of functions. This stack starts with the user defined functions (udf). Next we have the global variables, and on top of them the parameters and variables of running functions. The stack grows from lower to higher memory. This description makes clear, why one cannot change the size of a global variable from within a function. The elements of the stack start with a header of data type typedef struct { LONG size; char name[16]; int xor; stacktyp type; } header; consisting of the total size of the stack element, its name and an index code of the name (to compare it easily), and the type of the data, which an enum type typedef enum { s_real,s_complex,s_matrix,s_cmatrix, s_reference,s_command,s_submatrix,s_csubmatrix,s_string,s_udf } stacktyp; The different data types will be explaned in detail below. Every stack element has a header, followed by a further description and the data. s_real : A double value. s_complex : Two double values (real and imaginary part). s_matrix : A matrix, consisting of the dimension of type typedef struct { int c,r; } dims; followed by r rows of c double values. s_cmatrix : A complex matrix, which differs from s_matrix by having r rows of c times two double values. s_reference : A reference to a variable, which consists of a pointer to the header of this variable. s_string : A string, which consists of the string followed by a 0. All other types are of no interest here. You can avoid to no many of the details, if you use the service makros, which we will describe now. "hd" is always a pointer to a header here. #define realof(hd) ((double *)((hd)+1)) computes the address of the value of a header of type s_real or the real part of a header of type s_complex. (note: it returns a pointer to the double value!). #define matrixof(hd) ((double *)((char *)((hd)+1)+sizeof(dims))) Computes address the (0,0)-element of a matrix (real or complex). #define dimsof(hd) ((dims *)((hd)+1)) Computes the addres of the dimension field of a matrix. I.e., dimsof(hd)->r is the number of rows. #define referenceof(hd) (*((header **)((hd)+1))) Computes a pointer to a pointer to a header for references. #define imagof(hd) ((double *)((hd)+1)+1) Gives a pointer to the imaginary part of a s_complex header. #define stringof(hd) ((char *)((hd)+1)) Computes a pointer to the string for s_string headers. #define nextof(hd) ((header *)((char *)(hd)+(hd)->size)) Computes the a pointer to the header of the next stack element. With these functions, you might get pointers to the details of stack elements. There are a few more functions and makros. void getmatrix (header *hd, int *r, int *c, double **m); Computes the size (rows and columns) and the start address of a matrix (real or complex). This works also for real and complex values. #define mat(m,c,i,j) (m+(LONG)(c)*(i)+(j)) Computes the address of the (i,j)-th element of a matrix starting at m. c is the number of rows of the matrix. #define cmat(m,c,i,j) (m+2*((LONG)(c)*(i)+(j))) The same for a complex matrix. There are two important variables char *newram,*ramend; The pointer newram indicates the start of the unused area of the stack. You may use the portion of memory between newram and ramend for own purposes, as long as you do not allocate new stack elements. DECLARING FUNCTIONS ------------------- Each function must be declared in "extend.c". First of all, you need to add a prototype to the long list of prototypes in that file. It simply has the form void myfunction (header *hd); Next, you need to append the function to the builtin_list array. You must add a line of the form "myname",2,myfunction, Here, "myname" is the name the function can be called in EULER. 2 (or any other number) is the number of parameters the function accepts. You may have two functions with the same name and a different number of arguments. "myfunction" is the name of the function in the source code. If the argument number is equal to 0, myname must be unique, and the function is called without regard for the number of arguments. Finally, you will have to program the function. You could simply add the function to the file "extend.c". FUNCTIONS OF ONE REAL OR COMPLEX VALUE -------------------------------------- This is easy. You define a function for the real and a function for the complex case. double real_case (double x) { ... return ...; } void complex_case (double *x, double *xi, double *z, double *zi) { *z=...; *zi=...; } void myfunction (header *hd) { spread1(real_case,complex_case,hd); } If you pass a 0 pointer, instead of complex_case, the complex case is undefined and a complex value issues an error message. Of course, the function "myfunction" will work for a matrix element by element. If the function has a real result for the complex case, you may use the function "spread1r" instead. Of course the complex case is then to be defined as void complex_case (double *x, double *xi, double *r) { ... } FUNCTIONS OF TWO REAL OF COMPLEX VALUES --------------------------------------- This is also easy. Again, you define a function for the real and the complex case. void complex_case (double *x, double *xi, double *y, double *yi, double *z, double *zi) { ... *z=...; *zi=...; } void real_case (double *x, double *y, double *z) { ... *z=...; } void myfunction (header *hd) { spread2(real_case,complex_case,hd); } There is also a function "spread2r". THE GENERAL CASE ---------------- This is more difficult. First of all you need to collect all parameters. Since some of them may be references, you need to compute the values of these references. This is done by the following code void myfunction (header *hd) { header *result,*hd1=hd,*hd2,*hd3,...; hd2=nextof(hd1); hd3=nextof(hd2); ... hd1=getvalue(hd1); hd2=getvalue(hd2); ... if (error) return; ... /* computations */ moveresult(hd,result); } Of course, you may not use more arguments than specified in builtin_list. If you specified 0 arguments, you need to test, if hd1, hd2, are bigger than newram, like in if ((char *)hd1 >= newram) ... Since an error may occur in a reference to a non-existing variable, you must check the variable error. Having done this, you should check the types of the arguments. if (hd1->type!=s_matrix) ... If you do not support the specific type, you should set error to 10000 (a value, reserved for this purpose) and return. Finally, it is a good idea to use getmatrix to get the size and address of any matrix involved. Now you have the parameters. You will need a place to put the return value (or values, if your function returns multiple values). This can be done with the "new_..." functions. All these functions have a parameter name, which you can set to "" simply. If there is no sufficient space, error is set to 1. header *new_matrix (int c, int r, char *name); Creates a matrix with r rows and c columns. header *new_cmatrix (int c, int r, char *name); The same for a complex matrix. header *new_real (double x, char *name); A real number with the value x. header *new_complex (double x, double y, char *name); A complex number with the value x+iy. header *new_string (char *s, size_t size, char *name); A string of size "size", to which s is copied. For example header *result; result=new_matrix(10,10,""); After you computed your result and copied it into the result variable, you need to move the result to the stack using "moveresult" (see above). In case of multiple results, use a code like header *result1,*result2; ... moveresult(hd,result1); hd=nextof(hd); moveresult(hd,result2); Lets give a simple example. We define a function, which flips a matrix along the second diagonal (from lower left to upper right). The changes in builtin_list are then "tflip",1,tflip, void tflip (header *hd) { header *st=hd,*result; int i,j,c,r; double *m1,*m2; hd=getvalue(hd); if (error) return; if (hd->type==s_real || hd->type==s_matrix) { getmatrix(hd,&r,&c,&m1); result=new_matrix(c,r,""); if (error) return; m2=matrixof(result); for (i=0; itype==s_complex || hd->type==s_cmatrix) { getmatrix(hd,&r,&c,&m1); result=new_cmatrix(c,r,""); if (error) return; m2=matrixof(result); for (i=0; i PURE-C < for ATARI-ST Version 1.0 (C)88-90 Borland Internat#al &H f&op`B@#Dr3x k # Ј<.@"#,Jy2g""@(I$k,"JfB// ?<@JNAO A<~kRrRAf6<HCBB`6 !jBJ)gHiRC` "fSI WSAk BSQƤ44Hyh`$ON]L0 J"L 8? 9g @N  ,uLNANVH BCEB`FBD`:BE<`T}$|@lV2AA:RF|m0H2AA5RDRC|mLxN^Nuh09fB@*0<$T"AD̃6/ $/ @j5@R@ 2ABrR@| m5|HjCAd0(PO<@4" JnHXOG K0*LP5Qk   "@HDr4. #&n$nH<68A(NJ@fB@`IKEHSHTHU"J n-!h::????"BgBBA^l! pn 4rB@^\HO08H"ҁҀ po n rL<%4T?!zx RH $2\r#f\ga"/ $@&$b1A?$C0p h$ P1Z`0TODRGl`<RC40E4S B0SD602 2otL '"l&0 tr'pRRRp!RrA!fY P`4(xqd%(z'j\$jj'djHr 2Ha~z!:  p.6F86$H1$Alf aR04f@lB@P`2H426C70c>mHT0h Kr0,bXOL1BP><85.Z$*`NPXP2Rr 0R3Q`j?"L M420aN @445T0US@` TSA0V) Js0rrDT@p p0$o@nTPxtv$,jCC``@62@ErPO &RN@ph`@R`J2d tBA<B0vAQXPLA0P0@0RC0k6mrk7A@8k7@"1gE6@H@$!0r2~z2(ؠ* p$ g("r~zR@!$ f7Gr.%H '@" Rw p^(m r{@ f`$`!T {@D7| pG0R37 @7 >"@Bk@B@4JJg$"{D|v|J@jh\^H/SZ\CCnP$TVRq(N П N` N\NN`NNA~ ""2ؐUj-`f'g"ATfp>hf5&p $p $^0$&H^' .:BC` RH@r̨RCfd0^H[@ P`Rgt`r cBkyTX^@~ Z697R@bp0S! 2:SA!(EdasfRvL^Qr0!`6Tp v z0W@j npZp!XD|r&Q ;3 lpH0l:@/ / ?R ,,Gа"rNn- ",,~,Z N0XXX z&Vк!x``$`PaPaJ"0``D0`f>Djm vQ>ԸSg:6084S `Q"`p$ rkg Xo2`0"kg2@Lv! a6 q@ y, * u8`$Ј ш$3J6. jKFFpd0>l@Pgl3đ0b^`;N>TJh2F&pZ`: .|ZHZZ<tg 23 h( V0<<*H:6$I| nBD`:2H ЁЀ A 5VR5VPS؜5V^RD0@@mTTdpTLT#a r2ҁ0NnTf!^Dpf(@P dʀV  n`F o 0 :` PZP>BDЀ`l(:3A9x4444 L2܃K1 Ug r: m`ԓ;80 r;Q,vB@D`B@:`"A4B;h :  RDREDo ffζDfvA;1h  0`N NE M2A*`RD\0HЀ22gDn$hЎ85?/ 6Z#S܂vN@p**,SH@otJCfpV*-pqXܝfu >b0lnVˀzQr|JCj}vzFB666zrl0HA 0ü6$ $2d`p nnVmdrs6..dfXpyIx}f}T}.Bt:ʑ'0Ц֤д "ةhضxP)0l4g4q\ ኉;Xjvor>ZSCJDp50DPfj@5RE   j@TC8GlM9CC9H qJDd8&H8::fgPqzPRC Bmpa>TVb rf8TX+/)Bt+ڢ,&L&2g64*#vA!V0 g BS2RjH`6 p *°$dr?tĀ?p?r'???<Xt? Bg?0 M/ /gp1`prt _"Rd@t.6r@g4| |blB4; &` `|`0-Q@g|g[@g`aB@1Jra `p4- jRL@Ajf^ T4Zg4JXTDb:@0;.  .P\ht8DAa"U .U:$$UvF00jRU<<^^HUHRjTTVFv``QXll.vAJX"j ^* R$`$F0-$:<9$.HB"DU lTO fn?- 4-aXO`~rrf PXOiVP@ЬfV2*=A4*=BjSAP"j(SB$(Hj BC`^ 0*rltX0r !b`@!*Rf܀JAgSAgRQ3l$R .!"ֵF >fPOd brtf ^V]氈4t*dW*h*h*hf5v&8:H+ rq bj*cdhlp fffHf` p@C0R8.|2A|B0hrn^ E<0rDn40|nnh| `Sd9*U *R$=L0FA2;@< hMghn(LCt0(0t<bn~PgdWAg1^Tsऌ0fEr 6U PrTPz8UPPUxP pPT(hQxPrP x `LP`FP`@P`:P`4P`.P`(P`"P`````` ` 1`` BH6` p BS"0p\J@g> l"t0"@`g` p`" NfP(`pa2`Pv/ g(g$ *BfHyT d |dҐx | J?hCp6J@k$`b g2Rj ` A26p/ %/ pA@45k F+kS@2+k 5A0r+BA&ʅ\_~\v BNR nÔ  0^1*HqܐXOLP^аvf@RV07@62@7AB 0p8SV@ Pz*SA"&PhXPhD KPdrUfT*`ҠxrмQHNXX\N (JnBBU` Ma0glPirj`fg`*6cH`DHRN š: :;r ;L; M6F>^!L$H&IbPZZMj"Jv1jlH\,K LT̒@ 눐Ё"<(~z ؠTOѾ@*XTT `T 67T02R"v`6T"p d&DV K"Y Z JNoH=n/(Xx0&J2ڢ6+k8+k0kPmhnPh2khmt4@knj @P J420+PЀ@P45ECpD 0fCL@P 2\CP@Tr@Dr L A=T68+UB<6D*4nm"pai"30eRpЄe3 JRY/ ,0o (fSR`5R$^^HDj$^04 8 jp jjjfRf]@f, cV)p g Hu(H@0L6*$j pRDk R4~(caF0rwb2:Ͼa>tg0(qlBjKCA0qX J@g6 fU$$ $6 $p`B@!f٢AlBC @JXO(;JC... `X?PD`8P-XO8jA"q:*`8p6a\8!1>Hm="rPOF?.4.r*X Ўܠ4!* T0h[Z<A|:@@A2qaCa Uj "PaȜ*$BA D2RT*j&` v!@\0aaAT(p#FǺ`&r0!bB@H`Nl@`RFFnb!&2r>@`n`j ̐^9Bl@. CE>`0g24&"p`J2   R=E|d 2To#=FRFvhV1Bh2Bl-N08l ppLnB&B#0$~1p@!@ 0"JP#0Xg0,D@9@A80!Ԃ" 3("2(RP7A7!5( 0 (&#$& T!"T#@#123`G0F&&6!/N/8x1#~/<4$CxG`|2/xvvA"@dB&VRDDn% TLRG`RGGn*Go#f%z)`B<@<0h#B0BA!B8\/pGJpa$H6-I8fB+{T 2J04n{rf($mÀTӭ`d@&n`JcJ%`HgH`HEn(@0b @o4|МXs)XXa(Y4Q"t(2Je&R#,|``YAԂ>20(2t2$`Ԃa^ &r!,#)BG`O U6p39AX"r` ӂP `r(86^F$00.DCRG lbb pbbDBQvC4DDv |Cpb\~F`Vo,,,,r2Tz@@.nB|F|`SFJFjREEnz2j(8&H86(Ie$q1h82h K#14n"( 0V n 2<0fI&&6Lp28rf%4&j6zXX(:';4*B4(7+@2$x6-2 R !B\TBhJU5"S £02?f2 uK("s1|tl?RsI((8?"s2?lv?0.?2?b3?Ƒ^? D?軠&\?,,,_8?@@?0d?`?0PrRH0$I1NdJ"N L|! &C ( u ffff(f ̠Jf* K( D⽦^P8FrxdN  ĴJ ʴHPz̔/ $H/  3A6I<6a!$npd/ ?/ 1 t T,(H=@6bePGt fZ'R/b0Hz}h"0"pӒ Rfʼ/** "L kv`'L&sZHt(&LdS!qqm'RHЀB2'H0(`"R$*I:$CJԂ|6ġ0k1lb0dF`YRĶFPvS vaXO꼫P"Thi :vf "O"z6d*H`  HI8\ Bk0D 2(@N BtE>BE `#&gJ& @XO`> &XO .=EzxxО xx~x0&XxB6o=FbdjђMh4BP$&ҁ :B^\@bvt"d1jHkf.3"`,XO0D@8a2(x80Ҋ 3("ʄ(4R4X8A$ޚ(/ ؂ t(&t#k$-6ºS#0ޓT1fRf X4 :6Aq8lb3j&/pHqsv3XOxG`fHR2?p/r@" 8 t"JjXORDDn%`DRG`n Go %lf%N)b`h<@0&#\B0Ap0\~B|0@ ( (D"Ҁ$BH8Ib^)B҂ J p|$l0ap`b 0B*.%..-@r B4*@4ЈCn!^ь BEK|* `$l4º@"qR RYf .zԂ4?20 t16!r< 8G(`HU >Pv"^/rT%YXVHP"M$$ nľZ þr9(2e"TCv(XOĜœl"KhRvªHXOHS"MHU3"KL8y1MFXOĂ2‚xH86&(IL$T$#1$0( @ptn 2<&nI(&&6[28`D*0`(I8fB%4^&j5DpB-&' ';J#L-HJH-WLF"64PJJ<$6-WM R^v31:"UPPS"42?( `?x4x_e,6?x&7x.xR?x3xvx&9x -A.BFtg&$[@*-\jpf".4z`Lz` "JfAPT  h8cJFg@*-@` *N-|24p0dN|`F0Hp2/TH$// Є2@h"$a b-DvGxa4^ ^/TTռ"SE`|HU.\:j/ /6N"І p0~"_aPJ% 'p>v4B'Gs4&vLb $hUjRN_jV>#(qtRZ)D\[Zv 8@Qt,DVUSve<o,$&8dk~2a2BV@ l l~RK /d H$d*pJprb#>afSpt/ R$@l7JJjHpBr{R:|ئA+cԀр-H-I&n*n (n$$nJ( \H$ԀԂj5Mn,BJA䢦 F A` aF4tڣ:D>|:pC@ l˜ JƲ70(̀<8(Ɔ.\N0P PsUP"K$t$MH K$֘BMN$Ѐ/_%Tb$d ppx&2\)2!2/RJп  tX>!p"_B+ zG%z$|/p3/r/r/Ltf/N4t3h//) p?rXSFSGFofq46anA`'Xz gLAzL=CA&pEAVD4Dn`./2HdD ,L<ӶŠQd>dh *Bܒ!`**v"j 0>LfB6Da4D^RD|ox#!~txN(!L~~7T .A0vt'1xDK JP: (`B@aG @V2U 2?3?5>?&fR&IZ&Q;CT(l@2h2Q~U<BgDvNQNtL Ma  SBD֨ (RFI"RONA 8P DK6//"q m 6 RCOlH-V/ff*'ڗ` ?4H:4.qLxhwNB((HTHUB8_.qb!~r|~*rDt{btB" B$ (Bq TBTYIX9QBG|L C\mԥA<<.2..|^QP222220a쀤"ojLLoD|n@o4Bo(&[@f 3Jr`"JEgNBNT08&H$Iv@02H ЁЀA ((6N ^Pg^  lSCC L @H<*H6: ޠ#TeC@H$ԀԂ y±DcN 3x&(IBD`82A2H$\ԂAC(>RDDlNJAu>`HRHUpK20F`tPOԻuh4\449!g ! 7rxv(b|0*`p@mT> :EH$n!5TE( $ $4Zn0^84^H<(H=@ ${T&JHbD:0'4.H"҂ҁ nm*J0:/4#4P  RЀ;"BBE%0<5jh sC /!/!?`!Q@g~ExE`P2G 4H s(C8e>A .G*>B4ah 04E@gH2H-s4r'('(52Hҁ4H;(H2(l>H sx4(: /"_ S~:0N0W6zzzvTBXzZ[> RG!Jx&@A6ҁ65.BG0j~  `v$RREp00 @f # fBadU0n80lPQ8{T(H$K1n*3n<7n%3nΐ5n4nm-K0p <_4pYP3p15tmBEIP.G0f3|$@1r"rx4r1a*XtOѺRđ"L 4"L66aR2V36S7" LaXOHpBKXXO2h4m5j02jHHiS JB"jzvj3 jj$4*2* P$#0,FL$8&(Ip"J0 Ka@LpfB R2"SNrL " xQ`"C\ R4 H RLL $ NzNJNNc"s: $R 20(hRZ"`"BFd`dڔ `::^ִR4 ZfRFFnLhREElz:H"sX~ XLXA FFn.z:r>8H"sH@r*ځ"څ XdF Fnʰ&H x!(P"K 0F(!F S'0T"( " %]<@`C(58Ԑn4Ad ˲Rl nPD`/@jHj.N dRUX\\P6 R2bOI<Ԕ,&zΡ*lDXvʨRƶ" FQpp&4^ָFgζ$/(./̺ڱڷ̀N.!)4R**?| 3 '" <G _ A((?OT*d^z7&OBGOBO EOOR\DL:_A*_QRLx H8$H-Hd$H09df(DL jfHS("L JpPO0g J Tl"eJ`420墀rC&` `c~0""C SrvzDNC`LxC`@Ȕ2lUpaHTmRCpT@mbNipm8Tt8o58S AfCTm6HH/ / &H$I BI qRbK&P$,HREGh R m4,0HCCAN@~|m4S0*jB "L0H*Rf%R RR F!F(nf ƈв2lf2#.`"#<??8:-BRCCn8.6.P\&I2!IfJ0/"П`dN0/A 2A"_a0"fJ#d/ a XOVT0H<0H&3x `&0H^"I4hВjrJ@f3,`SDJDjր0K&M(K`SLd$,Hrx4D`RLEK42hChbVb`Pr@jRPRMb "Lx3z ḰlxB1v`y 3BL< <$ABؗBK06Ua5!t5|F!D 6 n g @hl" HB$(J@ g> L3($.0CAa0RUC Z!n 2`t0.|bb@0;NV6HBBVht(4@L\0g4SU#`(04`bR< f` 4 .`-LJX)` 2fz4b@(SUa 3p=|Rpf&|`0g,SR `P$j2@lRRA hvLZ"0r BUpBUBt4 J>>a&5AX#.0€%m2*jA`"M L\XO@k# 40G / JD8g"1 b2,E d4f8(:4,2,>zK@̸EG Up^pl&&`:&$|GԪREEnF85̡**8DDВ8HSQVa|pCbOb@\ObObObObKbVlFhѼ{`BZhpB @RrJ@f @6BkV `H >!Tx` RHB{BtBm[@\36 ZREnmR=D0> !h h BDԬ`z0 g/BB 7HnrDpp~pF.R00.^6#d2ed/*V/F0/^F 2R恆> >0-mHpӢԐmqҺ"Jֶ2CN6#j\tu \"t.kړ* tJ($  n1"K3 Z!HVgRGHS183H02| (H5l’x(Hv0! izf, l$2)nf4, 0)Sf2,S'SN1A@*I $JOB^3r30hz7B *4V6 **hTT*T~XX(b CD$C!/!?!PJA@a-L@z"pSml d\ , SoaV(Ύ|d2PL0r4<pPH(RE`S` |n n*E0x~^sDqDzpnRrg,qTz`$ A"1Bz6•I@$HpC>$6  jH"vC@xI&HGC*2JO*O*O*O*O*O*OTO~M* B*P.O*O*9^a G4J&C($A(2PQFsQnn,~`2@U@Bm%aa! X:/ $I"P1XIHR/_XIp`РʐjH؈avusfrmr)ls}`pWpr|fr4tV5uʂ 6vup(rx(xۚ}1t8>)/t*HrSl(-r*r"ҁ(r$犔Ԃ$L-JЄЀAz,z_|~z*v*TTT~uqBFp̄8BB2zwN<Hx~2~aXq@l*Al" 89Fr~ РXÏ(jRF(1 b2"Cr b@_Ԏ8~E@"P:<)>֌> R<0 >>@(pۡFF2`< Fx8gA~~l.t1 "pP*FW(jtj`RfR`1THrZrB@J`p_ `8!tRb22RFvTTPVZ__X*```]X`p`jXqXU[~ZdpNXBqPђf4а4РЖf&l0PЖвЖfƑd fR[2n8 ԬX@Vhfdmc$McMgbdC`ovv **TTT~iboOjooP6Q0aRfo.i`ofTd4b8$Cbof ~roTXuoX< ޘZnRS9fzR`ZRXBvBiCUDvbDʿD2DଂD18H~Uf]~N_z\\QV\0`````*Pg,U@8Rf88hm>ʊ\1Bn*l.l#<SF/T.Ĕ-@(~z"ǰ$Pֈ"Aݿƻ``l **TTT~G&FfB Rh0.A|`vvSH~+v  U HpXzla L @l.ѮAl&JCf":;ElCFK.BCRGC.~|>:*< GZ <>>@ pÐ`68Wb.bl*XtXbR`ajjH:06e[v4H868$H&I(nC 0*,`ZZ( Z9 ;> Z ZE4. |0d@HQh  Cgeb"K dJpFbbbbeptI0Wv6ЁuXLD````tBD`RJ(N,|E`HT蜀"K J20a|m|mRDDn¦nĦ`<&Hкâ&HŠ06 kĠƠQhF&$F"2*$UAjgKHTHFU K +HSd r'aJBTCftZ[\\%haV\wT`,bC..0D` 0b J?.¸?"StU J02a2XORDU@D)RC<"4U8B<$H"J`!X$!X-?J!X$X% -X0 T$E0q*PX RrM*n MBCl԰`!.?:/./.E/./\F/^/.2/./^ b%.WK&Qv*[ ,@.~ND&&0 V𠠶z@0P<&r2ZNBCt0~XR2 .$27|tQ.4|1|"@̲2N:rG/0Ul8bP`RhgdVZLE J ¬@Edh$VT$^$0r/ /  3p G2Ƅr0627A>>7@^ @Npl p00+SldS`Ӱz7A|и&&nO?ⶑrs q:3Ѳ8nAz6.z}!zzzz.zz0 0n2nnnnw2nn>>)b2К7$6,zLN/z5d6p#rj7//H8GTD2j2DuM  I~4C1qXJ@fBl&P g. . 9|0JQf fBT0P~ ~8J 2`Qh`PE0`8H` ``BTо^6hxĻxHllKl0|b@0;p@ $:NbvpDq*&HVx,,b@q@NTT:hh&||nCU:`^J2`FbJ`.zb`kzжq4ƲJМD ~B&00S@g.> ~b~~~~;{~2:b2;z2;22r0&Htp"#-l20,,#_o,X@h[wD|E|Ƹۃ A[f(uށfApE@6 0.kR@ M D"dNs6PD Jd6TD޽vv<vB vLT4h xsxN zL__'m@zLEPbh& @fx`"a\bJ°8 &IA p pP {Hnp"K6(H*I$n&Jn*#H/"MA*4X#O*, "MwxBس&IC! /!?!B^=F0846m^3l l6^4BL\"_ D%R%hE*#<HUHSp0p PO MzP+RDĦKzzZ010V9@19a6p(@EHR"K L BXoOV#x){LD`%0V^'&/\BDF%VB4Vv 4Q*4Ί*H($ fHRHS/ / M\A"|\\ΘN $B*K^ $!t08 \!PeV&2A7 c( (P*Pa:8af:,,,|,,,,S2,&2&&&rf&&&&j av`싸?A삶yRva&&cZ 44΄ h A@h_Q|mWȣ^]C`vdxntI\<~^ PGFG.wtTZ^@@xv aBɯBBXدBB^s^w^},0F/ &Id(b{f.bV B""RL`L,(nVN28ǠL&B"rܪxAv'6{/LBʠp+JA_FX8pTTTTT;.b"Ƞ(B\J<#`0Z(XO0$HrDPBlzH2$64&// "n PO(0D0||" ~pf V m\d jfv`BC/ JCgO ؜G̸ ›*d*nPTd{]hdTJ***RyTТ`FƲK Jax|ҧ(7PO&B$8ob\D 2=*e mZdBop dbֶNb`}RN60HH@@hR.0AxX  ؂PP""pnPn8, / $"0oʌuԉgHRff$΃fތfff̢ 22n&22fvğxz$(. 8JaBBBaV`Bf//-jvt/,/2U/0V_ r~舵*N`gS@f|:`.** *`:*|no&  Cg.Dg*B@m`@FADFi칐Ѐ9xn^VRЀ`Rhx nm$$"bH<&HBC%^6D h D*4 % B&*&ȶ2k!޶dUjf>,(&B& "3Av`<XL$*$HE /0""ҁ cFv22"BE`P0DkHUlD2hE6D>:lBREm0Jc&J(9Ѐ$DD < ,6:V2J:J22>jr4N&8/&ֱpDp*Z2hA2,x2HS&n&&jK4C S^l.:,|`T S Z,o֛>:N l l8RFTm MKttpEZ ..D . ~D!dE R 4ԾFvVo0@ ~bTl$t`$ t&ZJm U0ZK" x@&/K"_ *RTmN<4 Wj`DFa2cqRN@zBf "LT:Tn |`PfR6K0Mo4&Pf^RnfVfNԠ82:`dm`j&n JAk|ofpT2@o:??p%?C"(`\a opT` B@?(((0D@,=Y(D0UW@rUSAAo`2UWA0VVV&d|pT3x2AbH3zAprs20&\%0 (N:"K𤒒dBr:D\R¬TvGUvKfB\m^ Kf@ޑ zp> z*!BF v|pӖ.6^:.X0&x.`2$^1RRb:nR,m¬vR6&,fmZʳUVT~HF,JFpP겤r6FTIj<(/urxƁ:MRDDl;(.6.H*Ba~H&I(4H}*`&JnX*PD`^(RғD z`8/h, 54R lđ`L08` >a@6H8$H(I&@0Ф_W{hL "AK J|"|v "hBܙd LJh`8e^2N;eZ<(Fw$2r1 vP JZJw~ J!ng2"uX2C ,Vx 3` pv1ƺ RPBfJB"k2$BT:S ޒf(. (.L<ZȔ(AJZ+ 'ڇL34fnSނ E^`(LBK,aJ^:6Z>"V*uaⶾOnr,J6Gw@ J$R|n oT<^?ʄb"T2r:F.|<:jJRI!VH!f`A.<<Z ZpxZVQdv[Tv0rR²8aƄ82~p(P2@pr~z*"& Upo*tL@vJҺڜ߂t J)f`bBcjIĥn`V$j{)ԙ"tBO&xn¦Zxxt&05t:&@|={HDR`0 @PNXzBT-|b JlYJ!v7h="Ν8!؊ ̒( pxb P6RXfJiP+ L8.<<Zڟj;WVբ?Q&2dR$~`HH L(H g &H! g p&H09 rfP2,f4+g3h↊@ : / 8aXOQ&H$}fN `h(p*AZ`# aR(H#B@x(pcgJQc{r` b2xT4ff kfHaGr6/ rF(q`_qt&`H@4@&n$nx<*FR*`HQPfl mF6QytR"("06"*H#F"gnbapL*HBSܒ7"A*8(20gUUA@@04^ MeCrgx) K00C`^9#vx`2 S#H L(G("FEҶn m` "Q:'20B$CEnz`0H r@12A7p| mL ԠrBBC gr>fZ~*LCfR"v/!/!5?!BzH VfƑ("pPT2*mʔڠB0B /@"_0nڤZjJTpȨd l)Ѐ+T,\3<!x8>? "D2;6,bI B`↲|(#(B 8f z~-(H`ʄ  N ~~Z2A  A ?P",|dLvA֦db`N .7jJ ,R nq8 &Ipaֱn 0^ $$Pq^>&H 2+ |JC"o$p lqCCs"^f>X\=^'/A Aȱ XO/̺"b"F:ps4\(C0!r2A&^d11T `hHUHTB&HG$>2H ЁЀE"BD`U"MJE& .+:, ]Vj *F DOfs4"Jrz./ pd&~0"pUѕ$ԁԂ¨ʐt P4 mo>dHd IqR䎚pHRS SooÎl L SoD($s H `80r,fR*HGC`^Ep$$40p%l*|` K@0rDn$`fRn ZZ4h$hhh" hxxڏR² yx t0BC8$E4sp`n&2G r"(zHЁT4JAbH°c pBC 6/2pl RR@1@P@*mLuI"Q @PXJ@g`. kg$ jpjlp`HopdB@o/ {*BRh4`RR2@W$3fC|  K&r _tN6$IDV=@HzFr *H"K$]XOtJCfpkN}Pb@BI L>{@@ H&"n'IP'HVT 2N'hIRfՒ *ג MpL"Lr pSXf"L"@Tp Uf >Nk |[ *vvR C At m* O0Pg"@ ( *&- R. PP>  R(tHB"R#ɡ$-&R#ˡ (m *̕*& p&n*nJfX&" |(Q"K6 n BPB^U I x`X RLrr"NNl>T0`a&,r`No ` :ZRbU@VpЄьЈ~l |202 Ч2*`XRLR&t{h !A0$?<RJcTO8 ^&: x5zDJ" "oN4"BC4p\ :V0l.>v@^SCJCjܺ"tp82gUAf u*&JѲ qg.!XLDN&HIb vrN:Z@(L xt0|T~\U%Bw(`/0P}Nh 0F|(I,1pT~p!F( Lq״Q& k?? {k"D,XΫRxq4. kq" $. xЂ rS/" "v/"."6C%"VYzfd%ʅz6J&L AlXflD<qX\AsRv0+zpT "/Rt DH<C`a   Ilܠ$C|gfH* f6#HSp"LG@eXfTg bgoHA 8g,`$~$HEyBv l2BEfETl,2dS U/"_PκTf2 U2 <.CdNn zT0DoJqzsz|mjp* Z8*6 2g 2+\|6HTqj.ȅ`hfGjD:`F0CarlBJ@k6RD/a`2rc22CHЁ$$ԀԂ RF 6m5D:"м.$j g œή\XL*T MK’^ MdΞ~ПCVJJV8VH!# 2%4Brl榠8A DBz&"@*,rB0FBF`<0E@n@m$b`h:VF Tm%Bzڃ@ (j$(@*lb.*: *rճ|HĚ4k"DDxLH4>B8 g\M.nC.B$ (Ū|-0w ²Ĵ vhfn8*`0ȔIP*H0>6ZI(ZG4H VLRREEnؤP<*0| h BG`@i8//0JL_AC(@DGGnREEn&H<,t/A &$Ap Q(R\0T VPFҐ`Wa.P6sr 0   $  t . 0   28'aC`"bK%N!zՎ qڥ  iTCL |/ AZ/r П3RSѪ2`*ZV@#d'/:"SA(&Ѥ)g> nR )D4UD:FX2N{ Gb!FbUIA'` Q>XXXJHAA^V`>l>TBat3vh4v>H~~~8~&~v~`~2vY䉬`jD `v.(`@6 7va.T`$54pn†`@  ItΖ<0p0|ҰC-I0 f6+8ƕvUBBDp$n0H(nB0"M󌰶 UJ8ü gN L!qf0 <^P X:N @< 2,RGRS0x2"M´FFn `~s(g2J<.r"V& df `T ":dXHl / /F OAGj"Ml8nXO,4XY:X?X1X?X?X?X:2Xy,=X?Z7Z"(Z2’?L<4jZ? F0:?"P Hj7?v4vl4:_gQQ.A,8W2_2_2^R2P_4?2Z:d<_(0mn?:x8܂:<????5TR`Yڔs"}z~O83}:<O8p~ezpC6|r"v"nv|"vI`6}s~|H8P&yPPf:P}^PP^Pw¾z~b"_ڱzv"vRS}yr86 .<)Џtf`Itnnnn@nn2ވ??ଐ#c# >_ /6֟////22Avh`X*\ZJ:Lߊrr2r@ ߤߤbLoOV#"#,r߸#6߯0*X@/X(vb.N&TLv/X*XOvr00OvOvOvOvόΌRNpDΏΊH<$H(H`$j g jg  fj*yT"HMШB^H J@fr"$H4"Mj MК"EvXO0 ᘊB(p",TBXvP*I<"0* |C+"@pPO l R T fL.HnA( / / ? "zF 020h,കl\BC&ZBBB/c2l@*BD`.2`2H($ |TKRDTmTRCl$ބ▂XXXX\fX`XX8ծ0^/!/!?! lW8Rll~lnn ,pDpl*r MK n MճRHhv0X,0`"f$f$(/~"~@064.4&X2$>P" Jú/ / $H&?10Hk??6^ ` &Hg v A:#AD1"*C&T $2A80&.\>A@lv0(򼰄D Dn$IH&jIh42@\7 (Hd6Hx` K N(XOМ Rbp .g@t5$HЀ**:(6nCN82"ZԀh,bbF@ *: D$2Qڹ @@g@@r@@RR6R RRtHRD$x!n* @@-M)2Rf 4(%@g:ԶVc 20)/$fd#"6$0'& /.#&NjbD*.q`w(Ĥ^rsBZK?Ң812)20HT15Vs2b24`!@&BHTHhh$1$*@3(4zs$@(@6*L9drJ(5ڀt/ "J LE @z A$B C I J&@&PPj2~D(PA,B"4~J0ڰ"jAxi"kH1vh4P5FQĔzʎH?HRRF1JrFFZ/lj/~FTj^E(pVq620QQ2@f$40-T66I;6qR:::djvuN$=2P`4PCPנbalPF+Lrj궢TvNPp~zĴxxzT|nNf=Zfg80B>nVf/6P/4"4\N#:RПRR/ $ZIİ JnNztЀ4 e&4/:_:J: K , ,ftfH8$H(I&Ha$H L(H>$/ppA8aPO1daL? Ffҙ1Pr<*H&vIq,L@&0X!<:M/dLVd L,$P/&#&됀.&"Aa&/&/&?R?Ę: :)2TK|J<.b>L6z31w4BZZ ZzZ1Z?a3=Aa&?.:!qzj :`"^UF*F(zq5pPAGaz( ^) ^'^L^^"EPZ T:"KޡH[8Q8a$nU ~Za6¶JƵPT@>D`fAFH`&J8 8T"LAq7lDJDg.`¡刁~"p*ăҡz7RFb< `8FRFF!ndGH%^87E`-@T#d:6( L$P##AT,,#`  S@tR g HmCt%B|ArdBb`P>C`0&[@ 4K5:2ng#Fk30i@*GV7(6>^7Dx[l|IJhdzREEnSFJFj:xUlr: / &/: & UmRT/ xp`p2&Ac`TBgD6@42 6FM7FRJH.JCpF8v .萋r@ v,"$Xpr@3TbRJ`z "r"v چЀ~ކ`4+ 1eC&  $Jf8CP"8A\"1|`&0n S@f||%|D Cʠ>RD@ 8 $$`  ,|m?<*rfdTā2DI0P<QBT01T UTvvvRV@$CЀ/^Ҽ` /p[ "Q #vv8pPgsHrB.f(HxAЬ S*g"*.R*! SctPOHѓ`rffR SLrif,Rx&݄` *٢rf2ºf`ĔVHBCJ{fFR*؈j}TgpP*pbRBaZ(g[f [fx@LxRa6I2:&f P.g@j*H (f \g& m rH0aĪ^Z8:6^fHTR\mh^M 6#f (#xR J؜+fp~Ɗ-fXKLJu#Ԕ AE`H`D@"f4R*S`e!gD $H"S 0 R{8f^'"af^gE*f6* H.fT pLFP4̵Pp*,"P0а0$$i@VVVU6jvHAZ="=!T FF#NZ~00v#~.$` `X##`NZ_f*B4#w`*~|2f"P:`g ,JV#y|+Z %*t~|2aj$Mn {J Lp~7&`H&H~(HR0ҨU@f2HUpPO n@f^p ;@J@kP;`L^gf8vuJJ J*BmHК&&/ CAr"XO4 zH(I&P*Qԃ:ꈦfA(r"R iag h0N>$gBu$(4XT@. 2u(p`B@HV!8BP:(:j!rКОn-RaжкW g|^|HX4o8`8.v.PA3,2 W6KBE`Pm"KKKG4rEK.H XO2:REEn |X|)~Q~ "M 4`  @  P//"_C ^*CzbD"8BHAƶ@ʺ6 B |TV:fU8 @H2.HЁSc/"$PSD-*fPLp&Hh@l  2eJHsC(HXO RE 8m|PJPH>F b>HR L H2p fJ'ZRERGBȺ@m4H"҂Hs0H&րCp>F mlv- H P$̴pc0 FЀ~pNv2p\s2 *sv.|zހl>s,pDl6H$Ԃp֘vos R ^4^pRxP22RtjT8V8%W8,ppTĪeG*bܪ pư-HS$j P*Sl:є'ה&הlc`Q2`0`0fT^ZSRPA8hnA*T8&H4'CDb Ԃ SMN27CS ~~Cf"F  @L`PS4(ĠH2DGAI#XOf2G6cV`jBHR"HXμ"B VEHtu0>J`"HrBtSm@D.r Mlh r4A"(CcZZNZr!`^BTAW*m@~P^RBд!$FrJAutOBj>j!p>t@ TXVSm:ְB4M "duNfrtQp HTq㒠w uwqȐDrN$Tp%pvspƨ:4xa4znڀVyd"dB6De$aC7(T0: 8288 F"z@h5B2Hag2ƎXEAFSBoR*DsBVlư^0*HF2rj8FFzTrFqjT@"_3?.w4|v|l|V~4ʋpbpDD~8)0GJ82+x$k JBk`ZA 2&St4QF`0xL x-I$n / r4H` &<0 rq2 4b8 KlN4İA^@L 4`]JzZ 8b,Nhf0@ hC32Ip0C1/ / \  K ^ӃXf.Z0 z ^^H<$H&BH(Hd*$fȈR2*UArHd⼨טh3!>J@kvH!T2,H"UAg lg ʼu`XdC0Ӝ[vlJSӼBHv68``"`葚wPvLv DTD|l|2bX<JRCh68ʪ m$m#V&TfXžXh2XDD CjTR\ e^KHg*>P|Lp||@fj |pz|$pb(è& KNȒH<2 RB(0"J@8&j.E< .܆ Aj(pH4.J0  @((v&`P2dZ X H1|0I6+F0+r#:a3`& B"L*80 \h2@SA8089p. vN 824ÒB~6Hb&I*n>fBP-2 08Pk"8`RI`A(.fx`8d* \=8.l R:- f4$EPB0qzzP( P:.`b@x)@FD<H܀܆1" n "0`Xh0j*@XMG@PG2.g6`6m@>`\BC`T5 LQbƌrXi\Àfrm "a0Ml2\N06RGRCCnBTD$xxmV0xJ`x+*p xz xxxDRCx;G:, #Q m<$Ba@D BB BW F!>z):&%::+:<`."> zTN$BUn$nd"D̑"<*"D$fX<pZ`D`Z|pZ`x2V#L0#L<.`%L%LcB00V\2ѤDc44n34f-J6DJAЀ*B&M2HҁA#dTBG=G4 g8` Ѐ;RDDn>``V6``` 0l4Rn$DƾP:f\ n0fT/ Hh2V@4$$ԀԂ( 0A saј`s20D0x0(g1Nj0`4HԂ0(V4ҁ45HЂ*ڀڅ K"2d @KnRCCnRDm6&Th`p3&Uh^`&:w,R`3&,0&Ђ".0,4&$85&43&P?&?&2>&?&Sr0&7&|8&?&?&4AH8&L&J$K3$(?"1"0"?"<"4"T؄>"l89"gj0d4|75069~\748EJ2fB2*p;7bC(j 5 p 0 8 aQ*5 :f8 P`Fr3 >23?37#hN""mfZb1(g / XO`/. / pxPyOƩ>>>R>: > <$$H{zfeL`zdDHSaHJp,Ablp aRC H*m @Al#^gK(M$k00 <2RJp "Ja6vqr* L.8.f4888XOJ/2<q`AcI`fzBHUbXO'a7tٌ$HBC(&H|hF8R@flB`8| g2|UmsX2B`< l Jk fRC`5BٌvG@K<<<<<<a3zE HT"b@ÃTP LH> 8TxTPTPr6PTBRTBP:"M(XKH<1"`P`(l g,g f+B*Pa*Td!n4 j @Њt6KL 0b!Рj-nP:v `$).NbJ80+0 :26POFSJ PO0- ^ \24 RbA"04, C("@F&*(((""ҁx/D &p, J2h@41l p@!\DUmQ mm`Fj8h0H8|ztz2dV<TTTRg3Fa)-f Cfffhh (j.1"Jf40DhUllj!Ӫ2`hH@rvXO lpГC f`v*D|J|aN@|`N EJgDEHXHBzPAG7l-@TD~L8BTJeNq.(AӠ0`GbCNn(( ((l8P00FHg@pAa-L88$f-J J8BnXIJH*kB'K`H  "g4+g g @k @C< K'M*r<BC-(` y~ a<|aP NVfR@UB@64p"( *H^n(lX-MTM S (PjRrj)g$MBR$bRCQK :T.<@bV=f>R4 n#Pn,Fq*z`,gbHa7|R0"Sfa@#fD (#f<` SRлd SfBaPXZ(gȠb^p7|^ M#H(M%$S.r!qN. S r8g-gBn .ѓzf"S  \)g\<"f&"-g XBܺp8z.Z (҂g,(4ghb  r~Jf Ƃ*. cQt.ѓP Mp * zX fBgb2pZTvXM .Rh" . `$S kAeA$al@ B1l2t0zR 'H!$Pa6:RB3.p^U 8A ,"d4aVlH0P>'k ЮPT"""U `A J f&'$ngL_XSXӆ[X[/7|dUz`\5b_0X<\ 0$"hB(R8@Zf*gp1@D6f*B z0HHJ/BRd$/ R·N&Gx KG /@jxRb`jbfPPB K/MfP@TlFL ̶aјorr$VHL2H( IN'*j /u/թzrx%F:ռ{t/ 6$2@\0/aҨ8@`RKg B$6NN0PPz&n׶1h{"Њ4Gv\9|*`lE aL6&lkf"J A҆Xnӷe(HRoƂXO 9|R&a l@bR`T2LȨ<L8gl a &`4)l"J KPtb&H C)I`*Xr\ `r R0B@CQ*A`"j]n|&{@`F kP @F8CT @"Abm B@C#aH(kXBXO.R@@feQ.0*<&H* \ `HTAvXOI06TL*LB D`2: / & μJE(g .4pC@g@P"RDD(nN(MD&D6 / fTrJh&$8 P(I`|(H! $ AeAaͺ` ୱZbG (H  lHSĀXO ,G 0 )Ͳ  * J   R   h r 0*# L~RLb`n<.( q ( $HBC` < dp_`B@\`TO RC&mL Y8BCxaqqJ6b` "fq &" м~$K$A(&H*/A pXO`2.RC aqB* Ֆgb8 " F.RD@m0H`!܉a:B`Ѹ(np3 RBSV`2X*h@ǴT`H rJA6ƋX&R1^{r g$ Lh:@`PLȷg"bR`p C m*IQv1(r SBUVp$\(k`l! dE BUrJP :*TRfW0":҈"тK" M \0+Pj(HJ a>7|"+ P< lp@@U .,Ɣ V @:Ɔ-XOT b 8$L8b`^0HD@0 r*2HЁT4AbH°c0BC0/2πА:@FB m@hR>"Q Pֹ BR"R20A@$3fC0H KEra8_txQ@``RpcܾB@ g`((-HHzXBrH:(WD]B4pRfR R&P-|`Y4PVATg&".Ӓ kN:&54^D~Pj2z0`ӄ0H#<(P< F=0R*(RB:(VPLR*"2:,@P0H -dQbmJ4$tdbBn`.0.4R n8<\e8"DTe@&oDodfd-Pz@Pf"n nP(DHBF.DN0H"v0H vńPFz(H*PgJ@&*k" g8pF`.2I&vC(:fe d 'HR@@nRFFnz!` x(>r00\h,+g 2;Έ6{`BpІ @Rp Sf 0RК<`@c%j`0*g Ь$BB>`ķ!rf@ .0*4`p@pbH@ 0; 8>8%0 RJ`<~.j*׎B@fJ` 2IB0(R@vm <8lŜ*zc:Vʑ/Hj Aa2POnƐ֐HҠ'A C""2^:$BHr'KC AKv`,Pq"t4.RCCn` a40jBU0+g| H8]O$H&I(o@&%p JR@g|f@HNBEvBA<b;k` |<*f<`&404 b C@pOl$Wb}Qx t8.f6@4`$>N >.>4><Lf `hg@Lr@d|J?'f> n ,"BXr",b*:@ b [0`|A`0@ 2"|=@ \ P[JJEj `p0?42<а2* 0H J *DDMDdd @DA : P0&j|#r0\OLxNup` Warning: use TCFLTLIB to get float suppo@ror printf. b0O!>68jx`p@c8?qX0|g* R@CDHoRh* Jg|-< `&о+g ( (. ?D62XAXAt0gJf$B RoDJDf Lf2SA`."SDQp X    m"to An ?B`ff ?VC $8@gE`e0/DS@j(D@-+/ 0r I"_ FpJWF@rSAkt0S@k.F"`)t@>$>x Jp~($||||:lDE0% |rBfSFDgedD"@6n8JEfp?@& XO5d?E:E:0SE ,1"pP@0EЈ@!jL>XO0@BEDEE!0tDj$aDR J'9VT<RF!h!/t0 !#!#~4k6$! SEj *0*F`!0&!Fn &:! &" 0Z?x0.a 16|`/F%Fk kx$`,PZNavP^NJfE JPt0Xa:P|XVHB?2_P|k:@k6Dkp@@ԈXOJfS 0gRژ8@0jDBDPD>0P\XO (VSBDB@f&6x0@P"@8L0 g` NZ00  N@f @60g!p.MHGGCr 0jD@`{NAװ8T(``>!v P?b C,6PA6"$@DoGn| Fo|`00CC?SFpԂ@ ` *(6ӄC0BJjR! :f4ɰ1R@PppAL0@pPHQa^|~trp  $ g -Wg+f0m9oX(.gh.6I@:DN@HF@Vvpp0 ]HXXn @lP`6h*f|$$d@JDg"LUR@vD&zRӅdR@`JfJf BYBBTO`.a%p2""#HACQb C׀0  JgPL$vG0ԇӃCNu4f#/:)xp?:)jHQCcn"_h t <G GG%*aK/%/%?%A~pKMaMQ*Ar21"@~`DiA*nAfIa<,FEEnL`Nu`?*Eq? `B?$r">?*¦?SK? ?%s7?x'? ߜ?P<?>m?H7+@H?;q?㤅 i?~HT?-!b2?JTB?Š[#?l F(kjqĎ?M Vv?F$?Z^ŝW?ɉl,~!?Փg?@&Nh?,n?zOUY =?Lu7?SB?l?zߚ:R?{Vi`?l\@?7 tn?d]J? Z0?zF?gw?4N|?[R?&)e:Ӻ?˙y0?6Y_5?;Oq3?e3ZK? ׬?}w_?8=4;﬋?]?Ƞu?HpGp"HQj. _AC $0l(asi4nE Gp00il?/Mјqr>wt1mf 2B Hz"pj`Juv Q?]AP0BaBAJ#B @$dVGVq,_>atan2JfFf@HV,oJfHVCpa <`C#<,JPlnA?\H// ? Q ŠVP_l<JPmnln`XH W`HkhHA#zC@vi]<dRc B450BLOԒEEF.BB?+1t?{]?΅RfA?U?q\qZGC ?A%I#ƽ?q$'d#Ϲ∢@0jXT?2(J@gAjb]r<2 V?mH@vX V@A nH bg/,QdJ g<:,C4HpP$A(@Jo nhkD@k@ @?br b  /` @ SdS¯Av@An/@ JBMP$l3Q?jDc0<?a2A@AC,0 ]HOgPrbC Od &JGf>J_kbPxf@ H @(P2$<s @ P4ɿ@Ziŭ+p@xIϦAGɀCQ~FMHvuu Z;]=]u%`R exp0h C6O璃cWmϫp ԥT/Xx6.=8Xlb?\>np?X?mKz?m?ZD?` +?y?ryXF$^?4 xدa@lJk fER'$H:@vbg0 -`<\S\C\C8DDD8 Ch zf> NKrcvxjJj pj̲j/| BoBe "IRW@Cò`]AHB.ATUD n(dڴ״δ8FC@,4:`V>>>>0|R~nm "Cl:>:xE@"E?kFg( Em bJGj SD&,FF`FBCF0<#? RDr0DHP2 _2 _Qj@DLd 8< DBD/D@x 2n |@fxܓAf 2 Ff CaA.l knef@rNuJ@j pv|Pr@Ӂj1^rdkg 2<@`D@2<\??"ڶ0Z&OHH b9C| :OH@Y:( : _6*H:z$ rd]nJ@kG,Vއe" n"_0УHB @l*W4: "`"_rQ2T\ ^VJӮa>p`B `6`*g!2 A`pQ"?`k(L2trbVBiB Wg>JWgjJQj4`$`@c&pf` "1&"0Qi`v|~ l@b`| ` &`P& D@Ƃz*(g4k`(`"څلgj `†fćg ևцdRQH TOcsqrtg(n0& \pH>T@aj 2ʀqvp *HEHe@E`@ ME@c.h~GME0 z`HG,<HF>HEBEڇ>,HFƔ.HG,HGBGBFHFj ԅӄS@kf Jf|&I"HA,h,BFHFԆ|`$BBHB6HClƖDjSFօDk.h.BGHGև~HC4BC`&BC2ǖ0G0փB2r2ҁSDSF(\HF<&( c2&j&``RJBjS` DkN.b:"HA.HABABGHGҁ߇D.ǒ D5 fBo RۄfHbR@r" ]I%&uareҘ8Lg#2#hn I$L聨RpTl @Pj|:8 † HAڃ:BDHDH&E&&p ؃݆6:8@2|ڂنR҄2kPS@$,ӆe2I\H" I`vxNu4T Hz8XZp Hz*Tv`H4آ`ةRBX408 @b0BBB`@P` ЀP !1C|mul0MHHTL@Z T X`U!ap̰4`ԷH@FtA1q B@pPTp``T * * 0```.>CG?/p<6>܇׀QQ>D?

UΠШ2,>``````  Η#0C 0bA`b R@Gd6|/|$F, "h.BGHҐH` "BAp"b024 6<?~Gj SWGd, @fPZ ZHA`\LBBJ|F҄FdHG>HG,⎜BbHFRF@Tpz`(cB~Hkb`lf`X"&03@B@4rЂׁ"$ @GNPuaZkf` Jf`,ddR& Zc"$EDDB!AB modAB!. ~qJ`tLr,Lą`b``f!` |@gJm CfxJGgLtdn@``DCC UCexd q6!eqiNf #!QQnJlJJ"#JJ$(0r@Ag8"(jNu f @a(f"Nu8*fNQu0&NuNu` r`r2.ap` aQ HQ aP2<@H@ >AHbQA @ Y(A ?UA@@SAHPԂQ0 @A(p"@ "ByA1@B3l 3@O("/F?<&NN\O$ @TXJ? ?ry@ڢ!h5? n$@ NaN-INF+(C)Xmath by d'ART:v(Se:*g6$H&I(o(,܄ "alM J"NNJ@gj(@0 `&Rcґ` NL\NSf@`*<&H&$I(pe$2"IH"L KNJ@o HpЃ"N"IxjK6M6 4M4"K H |``*^fp"M (K `K`c4BJk`n`n"AbX|j| \*crd "J M &`pK &ML<8ahg,H#2)2 8@PXYOM,P@ "a¾XOXO,@ޱ(H@@R>rad4pp.V08/ Q:-O, IP@~X%OP@"V<C8x` aBpJbF@?@g 2SAktaSb (Q2<@4/(jt@DB:g@f 0Ao$@Alp?B?D`hNB0AB(vCJBj4Cb@6JAkCc8C`Bf K020 JN` 0 Kap0D^x0/ @ JaPg@pN *g,, : 0pL\E6` 4&H6g8Kg SC JpN@< J0E|pN0` 4>HP(6@J0a(POJ.L2k?0 08a20d3b`J@g  <`0N:uQV67f"30P40p@g0NSQt8vBG8gLz BQI@XBFRG4`kI D b4SDgN փ"փ`NSGB@$2Lpp`pDzpRHJ> pp,p p`hhvzhRpؼ<0f,@P<߰< XgR0-`.:uErQjpdRE-Wg+f < .b< ބE$J D 2B@E<8z@`bnREJ4k| g@HJj$JD5gJШB& jh`0SDf`**opD(*B2QcA46g(8TJCjvJj@ r`SCf` Q C2C@<@^8BE$@$sn~F#b F4 Pg>X(  (CfBvqpB@(VHРt`F:S&gDf^+`Dg `bft@и,k x$ڹd SfRe`.&//@$",f4(hS8**fCH& FP ` "`&,A'JE#8 &lPHz\f"`xZVgX"$6g(f.lf'(SH`Ā"PdH@ (Rb*hg g/ _  kf"P`/tlXONlu4>"P Pz d6Nu?Bf _2 00tZC!I R `H&H( Ia6k g" L` |Jf(H < ")H``@0;6 K ((:`N^J| 9@{00l4(> `dБa!~b* 0/ b=NAP$_JkRV`VA(jRHfQC#L LLZ`p`p 3dLYOCBg r`THWu*"cr¸wɠir!w!"a!rbHwa r+ rb w $ w a a Ap`Arb h.VJ/ >ꀐ4*?!>*G46<6Gp+01&!_6/ &H4TD8H80+a"1@*^ kn tB@7@?B 0&>Q2&c  P*!tN Lh"+ RngF@@, L"St gSj`"HSISSk ögJg&"'LB䐂@@p`^$6rg0DtR$ XzZ"SIp ~*| P " 0 "@_P kNgPAp jH@$L *g,`0\1\| g&S6q"Pb~&Hp Cgp@CfFC0 4O0&8jaTp&F?ANBNA<>.`Br߲fNAAP>36@pc|1"2|**2ANA\p dNHR@W@e >? 2 PT@ @ X  D_(&HaS@@J90B kvf~<"g&B g06U(. & U(0PPdep€JfA@ `<|840,($  "H  SSeg  gb 1" fBPgSf! A0$HT$pGrt@(J3kSJtx"pA 0f:p bܶf(pf"`ENf&DP>$T.G NVd" &HCHCJCfԃԁd` & gSJ"R"T %0p$ "`!"&FZ"t!~X&N'`$?&8BCHC06H@0"&RBJf8%/%abcdefghijklmnopqrstuvwxyz &Q/A0HcJf Pg @ !Np RpPRf@\e a Ę!C2H "h`rD?L&S fB. a.j&@A`!|I'&.#4  )d I"Q f`rd ` #@#x"nA k |%Pڑ: 2/ oLQ x 8fpxJv`@6g,g"@  "P>Isvj`sxfgry gS0`LH8$C0 c &@ f`(@ ,gb*"Ҩeg  `p")@"2 H>g4" ҩ4eg `N"(>`" "Hef "r0eb&/K  f†B/Ƞ 2 4f!1```:" H?LxH  `8(2 Up(H2 nx@:fvLx2|HgS@!!Q|ЪSA!Q) 2PSꔀxHxx( Px(2< @hB(Ln x FSAp$ /$АeP40HB4 gxH_>"&(*,."B$B&B(B*B,BH>~(8L``HL|| 0 `AT10}tNu`HS~v$0$`Bp:A!0  !"#$%&'()*+,-./\:;<=>?@cc[\]^_`{|}~@ e:8U8:644Z@'9K]o /  ?QMo %70:?757  r2#0Pz8P"ЁP爐a(R#>H@|$HBJBf$NuHBЂ   (0 6AH@HB0@00 AH@B@tЀӁd҈ Fr" PNb A"HfABAtҁрNЈ N␀jD BJ "? `P" J"J4*?$ PD5"@ r.p l&&HRC?NMXOB/HP$J @8</NAT#NAX< V/HQZKRHO(?~<NNAP;J "G"N(HRt""2 "<x /ASewѿ+=Oasυϗϩϻ'9K]o߁ߓߥ߷#5GYk} 1CUgy_s_______ooo'o9oKo]oooooooooo#5GYk} 1CUgyӏ -?Qcuϟ);M_q˯ݯ%7I[mٿ!3EWi{ύϟϱ /ASew߉ߛ߭߿+=Oas'9K]o %d`r [3][Kein Fenster mehr frei][Abbruch] DialogHGraphics [1][Not enoug@h7mory!][Sorry]@   @ (?X:S@Zd?nn wWrite err"orOk]2  \*.*%s%s[2][File||will be delete@dJ|Abort]...3 9Could n?open that fF{clsglongformatshE listrese oad "help" d"/rinkwindowfu ll dumpexec edi?yI";& cd(")="ir"$); / .prg.app.PRG.APPEef\euler. rsc"Resource nicht gefu nden(OuVf M# Drminant zero*D<24ڢ!hk50R6\ 2nF4|9 zCF HE`? HZ6d/6N,ŬGG#Bauhuber-IPation fa@d0<p?(/?Z?WrP arguments?ra >ud/f>P0'g?  r@?Le?f Plp0columns must agreeh.needs a real vec tor `riix@ `. pgaLQ?L Marktoqyet impl`e"&offonIllegparamQumeshPT' p8?6n?xON".fg Ow(irMs di s0%l@)rojkk +9t!soli1B"& uhu4?th4*Cont;+6!Second(2zuDtyM2nfA:}vi!ew@e [d t alphGata] 02c0 r0 c1 r1 )2@71,A "{grP $styns@Cn@g!i-.--mxmom<>m.m+m[]m* FF&$Alinewid +!CtexG aF[x \yLT))uSebtQVP1x4'jHoldcQc0(Sca$TwosidesI$riangl%nXAPJfab ,  $pN^DP$A@ k(& jp12 34567#8(9-0:H/D@ f@0ЏϬ >n5 C;anmЦQh@ߘߪ߮(&LNbv$| B Vt %c%d.%d_f e22nUF3ÈlZFnJwƂ?x?߽{F?\ud?6ŎF?͇2~M4@; ?q2rC{?ϻ$?e /0d?? =pLrY?Z ?:uG?ɔPXhֆw @ )2T (dD  nDIx7 NQ 2JUET[&_@cPh o Rv L{ ܀ (42xFRpPZ"d 36x^YPdu mp(diskPll?St0}_ueiQJφϚ 3in: ^PgYAL! to lhRՠrePon(T@,eY Keys: F1 (cursor _dow SPĠ7 F2upN subrou0_es F@3Fright) Go unti`la) F4 (1-EEa1 F9 (escape(AborLt#eck"10BHPt0UIf7 eps7R|$W2ic, searchaƱ=5if% %laNQv)Iq4naPƣap?g UDF{%Ү9c`g`qаnon-loc jDAgJr1 L%d: +i Vyⴌloxa5w Sr.e@4BVglis_1!ҿch]i :pgpN ȁքavхa|SlFBK  z>@artܟto!M#5@epSULoo0E0 !2r&&$I[52l0.ygD߂ur8g& > Fe/oun *** Bui(e0Youhr (b (=...,) ## DefaFЍ@8P!ch9 H, ns9,e.g.: >( shPk 7 c"a20D0with=1hy5j1qaW}b`{B"e"wruQqdW#"( >quis-*wh{c/.!D:W aOOMgt]aMM MMbЈymf2uda̲K : 0 Ucl: R6 new1  %%6<16s, sijz%"c %5lx  offLWiutlQ! |QE6p9mPB!holdshga8a4ifa:b``k op`!%peatByg s8@globalnap\[doӑhEdRJd;OnRTxZ2_Xj^ xm;@oBi0%;qڤv4 |;{"%(J'b)" ,J6TX@; ;JFhPr;ݢ;n*̪xTq;J#R۞ <)<*<*$(." <5+jKm!&?Pq -Pd=1HIT1404=1\e2#1ff8)=(1p`=21zJQ0 =81fR =dD"P2>g,xM1i)=V1j@8=d1Jk=i1> :==zBj1S :=1SK1Uҍ FIW=1)}ZAJ1A8V=A@V=AA AjE@8=qAVTRA0= h"DP(>Bv BW@>AYS@AZ(h&P >*">J0A^F6A_"#Z>>IQx֖nQ2fAP>b1ixpitimp"p4sipnnpLstanaa`gsqrDt`imqvplFis `argssu)mdpnjrј!wsp`zerponesdi agbpt`@a`shvie wwaperomn$lt&.cr ^w@isolid plotaxelmarktpTpmypf8 LpstyleG8er o wid4thwdiUssv f bnctchi.maxmsv/c taceilc8umfifrehk e-polyadmdiv -p2ns< t%c8lulfft?ih^Lfgnl1h~b>}!LݐIe ro K etkeyHc$arcqh"4symrojec7 et"I#Ьtwad angl !fe-3.f lipxy U&j01bi#AWo0)r lev densityhu$f gr ">p@0BTf#<BBQUpȂ`<$|@ ~pr  P :4 ,, "$ 4 8,|6D. L $90 `  $  8 P .) h& fj*  Fl  xB &_ 8 E " f 8/ < "D :  : @   &   0$   .2lz^ $  HF  2   0  ,R ,0~* 0  PF. F(< 0,  8Yh+z m@(1 0 $ " d8*f2 Z 0> l<B  0+  CA  T M   w&C ("JD $HwTB2<2("L>b(0@ @0v0V6 RQH(Bb(>(>J B\B NVffj@ ~2 &mB0fhRJHJ B*I  2( @& 0Z$,*6T!p# . "20F' (< *6, ( .@0@&$$4  Z"H*PV<~ *0b( "P 4 X `P01,. $  *4.@P5 :pP 0FB:N ':< 0.7  2.1F  z0 0$@":^@? B&@|"D*`4.,2. @B>P`  6@, !"2&cc.  B$ fH` & $(<>2.6q+l0P@ EF p: 2Eh^@< >$<" \&Z0 V&Z&&V&+FR,r{dnL. 0q0kp pV $p$p8P,6T`   <b*("PV*2 ̠!" <" (:$D28*M*XS $dJ PV=4`D @ D0p@~&(o0""HP; $ cA (W4$PAv". 06R N&6WV@80J\ ,* P,8 ` npgrn$cq1b & ,E.J7 "ai  )p"6 "2$ "B s  Xl Fr v N    Q#jB" $ PRL( hD(:,82@@Э2BP8 LĀ!X(= 89^t@\n)^4`8.`;>0W$ :,> &aq0AjA@2L+aN9П(` 2x ,(. "RF.@.(  C8 zR@A𦰺"B[0xЄЇf<Aq& $*4 2 $2sb Mp% P .$200.$,) Pc#p" R , D!8p "!@(@@*1 ~$ ' ( (8N%R2$q& ~2" ,R5@(8fF *F8". ^$J,::X Pf@H pp!$  *@`>( .6D<< Pl(1 ``R(* "A@V:| @` Dn" aBpA`"N"8# Z 4``IB 0$$$R$*pB*: FB*:06D26 (> t F D (H`>26$H\:$0\>8 H(9Pd PA( x B\A.0&.0$,D&4n$&*"h(+aMb`p  .X&@pgd @(>"l0< `jX*> (4 68H 0#|@`_ cF H4$V4TpX@4"p >$^& `B_8" l0jr$2g@א ?p]:,&$0Rɡ#1`  A@2\@f8.0 ".,*( (8 ^ *285 PURE-C < for ATARI-ST Version 1.0 (C)88-90 Borland Internat#al &H f&op`B@#ˈrt3xx k #~ Ј<.@D#,zJy2g$""@(I$k,"JfB// ?<JNAO A<~kRrRAf6<HCBB`6 !jBJ)gHiRC` "f$SI WSAk BSQ4H4Hym`$ON`0 J"L oN? 9vg @N z , LNANV'H<-H=@6E~ I0fb)l/0.H2 Hp8""ҁҀ &48b/.. "n l`F)(Fd$ R*0BE`0 T!4H"@REnm$Ѐ J:)Hҁ *H:$ԅ c(Al3xh`t$vЀ 19 J0BF`,2H ЀЁ4H T"p(1I*8RF Fn<80P llH 2H5jE` 9|0Bl 4ļC!"BE>00g 4Nf"p`02 I=E| E`f^ ^JS^"J^@5J 4 =FRF9IP \P4BlRҁ #Bp2 ̃01^4.H,H#, h @>2,DA9A42Ԃ! 80(#$" $3(".@fB^$ > !.%L @ HAC!1v&!." T# *04Fp%H V9H!(dF&:3Hz1h"xG`>2J >!@O(FRDDnl4RG`RGGnBfGofa`*<0 ZB 2L,PL<.N^NuPP@Q$H6-I8KR+`HByQ2@Qfa09Afz$mnQPPT@ &n@C%T@G@En(@0B @OrCr&@X)XXP.I24A~"t+Z&R&/| Ij1 >d2 "Tt2$P,A $rPHHBG`V? U+V@~#&rP3H#3`,R0#80@h BRGGnR(Z `PZr<(4!|`Uv"U5&q!ZF0! |C0@>~F`@O"H2D (i4fSFJFj^REE n("  #H!8&06(Ip$!`$ Ka0#!$"($ `n 2B I&L 4.5.6M20882%40.&j&֪J(:';4*B4X(@7X+@2Xx$xu-n2Z fR!h2ܨ2`:`U5"Ssd2P/ au\b"s(36`HU >"/H|U J v4KH"M$ D|P2 "TCv0R4"VKX@P HXOHS"MHU"KL}i1M^XO020***`*0****8683`*0`(I00V0005D-К'';J#-HJzH-LF"64JJ@@7-M>2>1I3f:0"PPDa@?(R,?x4xV_Jf?xh7xxR?x3x"<x&9x-A.BFtg H][@f 3-2pf".4z`Lz`H "J fdT 88cJF g*`-@` *N-|2Djp0dN|`F0HRp2/Tl$//! Є2Č"$a@pb-DvGq!a& ^G/TT"S`|HU.T::j/ /6̜"І p0~"_aN'<܀H@G@|RpC@l8IJAP@P10nS(RJ!2PA@phRb"$HK0R LI4(Ҕ@@"`b1Hbv΢pl`Xa\0lL00eK0, 8zG\*.A|3`@."2 4N!Z3:@l hSFSGFo0x.P<#LxP|pEP#'`zfF9򚘤2%^>@< ^-IBC8:E!4Ѵ"JӴ@CPx@2j j0FS@f` n4/   C /!0IVS`.RO$`@hU@fhb hPPAzl`H1f$ 'aHtH`RADoxQ L."0XA3"K Jr"@ppa PAܐjp8V8n"^`j4." JQ^`iBf;"!\&\~j'RQ0v%$nBDA L MQ1 8b(aB!ؼPa# cJ0"` `$5$C,"N(XpFN`b.`\.8idLBeD2p "vR!0>HTHUHnW@4@8\@ c`pH"AQA0A(R33@ $^A`hb9H(dp!jpKq~r°.ClOKlEl_W  B&ڧZX4`A`$l (L @X|n2o&BC1RD][@f 3VJEgSkTkꢞH08&H$I&v@`CV3 #2 \33.3I.22SCCmL tt8t<*H#6:Ҋ"h#JH C@ ±ll>&( I BD`82A2H$ZAC(A CRDDl` jNP|HRHU@K20@zPO@0\V8 £%4"49g0L070szLA^8C1 hRDv`p@mv> v:EH$:̀^@gH2H-s'('(52Hҁ4HԂ;(1HH(ơd>H sxIԐක"1IL0i`F+0$6   氜"sp(B&4"0hRGX1.ҁ65BG`J@@JRc0@H\(0hP(h$R Ep  ж #@UTT$T8 P1H(H$K!B,b<'%#Ƶ@%m-K] !"rx$tar@xpXO0ܡT,`n,h "L"kV#6zS'N@"N La ۴XOgDHp"KJ0XFO"m%0"HHS J2"/jJj3 j(j$p$!P @<#pL56 t@s8&p@(I"J0 KVb R2w"tSa~v1qxp$t3 R4H .Nz...C"Is1I2 C 20(V1J8BF`hvHPH#HHHL"Qj jRFF4n iREEl X:H"sXQ(22>sXJ0Fnr^p:r|J8H"sHbH*څځAXsRFFn™>q 2xȒr䪔r!.(n@1"K 00(P S'0"T-0 1 xU̐x$TS)TRR" T!v(PP$vt'.P&qҁ0Da ~ HRf#f2f/XOV&0\06@~ \Hqv`& Ja֦@!lN a@@!\0^T$tX}n @ *ad $"( $tHPq*D qź<-hp4C0EԤ"|@ $6:/ȱ8Ё$Dd2I bRLOT/B B~Hp*.l2H(Ff>[ pX#P2"'jJJڡ4 d:R`ЪB A0Fg0P{"4K4&Zd$_,d,Z°A(?  &hhh3//!\|ϴ://(/R88/,"4 .,4!LxEF8$H-HB:$H0fZ AjfHS@PJnpPO0  T l"Jx`>202 rC&003""2C SЌ0b&BC`*xC`4 Sa00p@lTmRCpT@ʓMpTpd8? SF sRCTmırEABCED 6:BE< `H|@lp`B@2A A:|m0H2AA5Ax|m`U<ބHfB@@0RGl`<RC40E4SB0SD602 2!oTL ֈ "&0 tr'pRprRR`!Rr!f+ P F3H'Qj$jj`'pjHr 2trJ!:  p.ȁ6F86$H1$ܶlf a&ff@lB@z`2ҁ426C 70c>mHT0h Kr0,-XO1P><8.ZsP2Rr 0R3Q$`j?M420aPP @4450US@`A TSA0V Js0r:@p p0o@nE$Px$,jC"@62@rPOR@Wph`@KRJ2҈dtBA B0v@QL0`0@0RC0k6mrk7A8k 7@81(g6@+r2JrЈؼ b$ g"<#R!$ fdGr:%@HЗм'@" BRp^(m 2r#D4 f`$`T y87| p0R7 @7 >@Bk@Bp@4JJg$"8|0vLJ@XjYH9P.pXj`Z>.. .VJpCL`-`g"Aqp%` $p $0&JH: RHrvxRCf"0H@f Px6gtfr hcB6p_@( 67R@ p0\S2L:SAҡEa8cҠfvQ0! 6 $00j npp!FjXD|rQ4 3 xH08 .J,*:r8 6 RD! & - 0HJ"0$#8 8Pd6QF"0P0P~jm vXSg:60`S `"Fb>```L rkg@o2` rbvnk g20LF!6 0 1y0  86N tp8,"fxK~ab8v$001h.@`gl3"0Рb^P;N>T JR2&2*`: .>m*V *VJ*VP<t^g23 8 |<*H:6$I| n`C 2H @5H$X.>RD0@@mؒDTppD< : t>#(fҁ0>)RTV!~Bb%~Pf(l p Vn`F :o 0 :x` PZP>BD 2A94x,,, LD2^K1\Z Ug r:Dn mgI`;`0Jr;AF BD@`B@:`"A4B;4   RDREDoƥfζDf,A;1  0`N NE M2@`RD\0HЀ22gDnh8AP?/ 1K6׎0@`0:C@0oHJCfDFdpaPP< #<9H"PFp| plp*mހ>`APzJCjv˒FQ6hQ" 'h^H(p#PzRbHA0|>^#pT`J lZkjZ ZmT6LӠ"Sth6о@Uv`d,8E .K"HNIpc c0$c zc0rvBJPcl34`afرc3*c Zb33 JD`n5Rfj@["5Rlj fR`a^0RT3R87Rl=R93R3R98R J`$E`J^p8&HaL8:> :V>3X>pRRCm lp"Tv. 8R<ZTF/(*‘qq0p(r@BCR22A5AcvA6 *jDJEgR8"uZs$HRav(pIޓ J!ȑ J"|cdX5|S t$2 e J/X4`?Αx204 _PNXŒyS*$6"pH>EQhJH<-H-I%|BRZ p@a~`HSJ0XO0g0f0m- n 000B@ZJC𠆦l$H f 3vpHVV h`"&*.T"ǂ??. UD J٠ ڷ)"HDz&b$հ8@(Ҍbf,p<A|:B@ A ڠx""J aKbC XO0gN"Kz0A` \fRH` :gSHbBHk!AP O5zBkD PV8PjpuaI&bBp |D H srdp``/Cz U@gd <l&H g@FaF`/ <٠XO ALRLe$J`[ p%\?: @< (H g"Lr X8 +ފ’ <&"vaTf>2bg64*#vA!V0 gB$S2RjH`6 p *q~Uj000T00dr?t2V?p?r'???<Xt? Bg?Pn M/ /vTgp1`prt _"RPD0.6r4| |blB4; І &` `|`0-Q@g|g[@g`a,B@@raJ`0-xj(RLPAjbf^ T4ZHgJXTb:. ( .\ht8"DAЂ Ў֪К$Цv 0вj,<о^8HьDAшFP :\.hv$)"tj0.^<8QURHB$FTO$U:`[$.ldRZ"ZDR qv f?- 4-P `naRXO`~`3r PXOiVP fV2*=A4*=B@jSA"jSB$(HjBC`^0*ltXr !` !*Rf@JAgSA)gQi$UQj .!>F ffPOdZTrtf aT^Vp(p,p0p4bt*d*h*h*hf5.8`가H [rq b*cdUhlp ffffB` pC0R8.|@2A|B0hrn^ <0rD(n40|nnh| T``d9fU TR$=L0FA2;@<AhMghn(LTCt0(0tQ<bȈn~PgdWAg1^s0fr 6U PrPzQ8PUPUxPpPRhQxPrP "x `LP"`FP`@P"`:P`4P"`.P`(P"`"P``"```` $` 1`` B@D` p BS0p,J@g6 <"t0"`g`p`vA_ `pa`P0/ g(g$ *:f Hڀ|R\ܑtY&pB t JhJ?hCh6J@k`Ibdg!j d`AtdAP/ /I "p@2P@45k0+kS@X2+k 5A0rBWAR& BN@ XLBvDqHiҊ/rCZF#ABPQB@~[0H`O&ptPr ((JPBC` %L$Bj$5C$" RC LRqLbjHmҡ޲u>`8ؐ~ S9@xҀSA9At" 9B9T4,S 90,HkVCV XL`p\82"PӐ l+BTlXX'br$Bk$7$% (t*L $``, 8D 4.CZ2X+S6& k2L`lH| g S@gW@8!RK0 T|BC``.0HR@H2Tp RAAn 4`p RRR TB!FFcDjfd T00 +ı>A4 FqP$QgD0)f%QB@`&QgSc+fR@rRAm3lBiPa8<06@>J0f @!Fgl#2H ᘒ蓀FJCo K3A&He5BRQ%AR %KPVBV`@[aV,1Dg@B@C` Sd6RCq2@me Bk7d &P2akJRJ0g!BP1Pb0] 1~Tt0BgBgp'???<Xt0? Bg?C Jp02tDl.6r@gl4| g@`Q@ g g[@g`a|Ҝ@D`p``-P*QdP?* 4*  aXO`<4ШhaF0rHȄHτa>:gƘ,<$H&IS&"KAR@z%H@|lp`,X"HԮp0f0AhҠ*r0ZZ@东,: вplN:KjCA0(J@g6 f$$ $6C $p`!fhAfBC @JXO(JwC.l..۬ `P?Pa8DB-XO8j A `8Bp6a\8!1>Hm=rPOF?.4.rX Ўr4!* $0[Z<A|:@4@ArрBaCa *M: WPa̔*BA D2R$tj&X v!@\08ap(p#F<˲`rĒÐbB@a&H$I 4R'"Jcor ~ R m40HCC2ACRC@#m`4SjXjB "L03H*R&0RR֦$.0CA0<UC Zdn i,`t|bb@0;NV6HBBVht(4@L\0SU#ր*(04,`bHRd< f` 4 .`ZLJXR` 2fzhb@SUU3pi=Fpf&|`0g,SR`2@lRRA DBzLZ0E BU`BUBt4` I>>""]>T .6%$mJjv"M\XOˑk#d40G 8ptU#R&

ФP(-H(TB+ l,2& DPFr&|(W2@>1X1R1nT8V0XfA:o'02g5\>2XUBb@BCFHTC2Z2*?*4\0l0\2\2\8:^,2^:^0^ ;^,1^Bl*b`'&&C*4 E$U$L E B$NK$%/ $H$k%&n!4`tb(@HpXHpXvT .H#` .ha(H܀r2(hP$@.h@A\G@*"v?652?6o?:4FS" Fp3o?DV\????;F6ȁb/ H,T2@pȊ" R 6BkV`pȚo &H*K$ԂA(a*8cFUP|H<0*TP9I@ xj.QR9J@# v.R 2*j R,J,9K *K# S#҈0( BDd!BEjPt #"P" 2p2H$Ԁ力 2\2< 2j0Hj(&xxAI('i|xxxs[ ܐN@#,REnm&RDj   B@DƜ`z80 g /3 rD"*H.".PR|0^~.^9HV @b@0 550/<^b<T&1T"Lc ! qc./:p <$cj*gTrp(p(pJ8(.D*r#)I ( J0@iip5FZl8hܲi&H(0IE8d JahjjpN>H8hY"H~Iф0(h HC2(ԒhHIQI#!I#Q"в(P>>U>Q>>>ِL>"`PL5JgRnGЊ.HS0HdVf6(H%rdE ( i,f$2)Zf4, 0)Sf2,SSS!t!@j>T$>J>>?>hXXp< Ph$hI 49i"V0V Càx/ /ƿ$4IbȀ1 _"_aدPSxhȤ~ So܈x:( / 2h.20 r4v$Hz0RE@S@mt nBE/x4ψS@Q@,~frCX⋤1"1(2Z*J9$H$6@T j7d=4KHU Ja2R$H6"d?n8*260ְU4U4=E1c^2&]f`t6 DR`jC0I&HG???<:P4?= 0Q@362t'Јa*(3h`U2U:f*0>Q! $F>)|/ $P*"$Q8tp`$qsxHa^xQxf^xe^c^fbf%mbnlSȯmn*r`n`nbnlnfbn$a%breb&Rftet`t(btht(htmt1Hdt(/d|o|*bHrS(-b|*b"ҁ(b$$L-JpLЄAkm&ooohaBF`o ||6q|.6m0a.`39!(@l"*Al89FҐNdX\po&RFaF``6C$r SIDo^f~DP"P:<) "_Jx@@<0X̺ >@˼p.Fϼɼ`бɾƾqgDB0Z@(@:***0fCj°ap`0!R bLyrvrqxrrBȜTTZpDp0,pFOOHΒ<~vաbĔz~~Ђ!тBn~`! pSF*/44.44-@n6j*"ҁBPP.4".n$ԁs88lHHHHGFf8 芰Ap|`Hnv҄2ԄP@jt.tztRvtrٌh@l&AlJCf:;Ex-xKx|@,BBCRGmCzz|||||>:| R|p| |G <|>|>|@| p||`|ޤ|6|||||||n|B eJ~~f~~Bt'8H868$H&I(nHI2H,V "2H ЀЁ2I p f?2 @*@ @S0@& `H`\9Jb`& J(0  LL JL 33hP#"'h4 4I4I# 0HdBBPR 4HF4H(8H"0rvHzO L.*LP$ H<:6.*I>. 0"x:Zd`HPG@<@( B+$h 0pFPPPPIV I0\YЁX DPPPPA$BD`B*5I$|E`HT"K J20 aXAO|m|mRDDnXQ|0~<&H*H&H mkVQfF&$FV"2*r$UAjjҁr\NKHTHUP KNhHWSjhcbf^aBC`d PВ%|8A4ʚTg^,C..h0D`g 0bd! Jg~?.B?"StU J02 Ql D^U@BV`.RC<"X.P$H"JظTTT0"@R!F$F -F0UEa0*Ԧ RQBUQ4*xR^R BCLv!P//"K//2&// 2//4 bN+Hz"p@ $ X,a *P Qvq` 8ըH.QtDP &"<C` ""R``v"nN`'h%߾`2$h"hK8BZ*lbh6/ $pHEV(^üjg"^ӰZDLA"HC !F$U($46$#t g$&p2 Z3A*3@,,*l p02&QlT"QLb)3|j& ?jpPQ^^T4 T*V06.'^^^^3^xQxx xֳHp$<>R@.0F8P@X,He87DG2BD"P= AIVC0@(J@f BlpŅ g. . 9|0ЪJf̊ fBT~υ ~8b 2`h֊`P0(`8H` ``BTPȴ|hsrpHl$lKl0|b@0;N$:NbvC pD*&HNx,,b@@NTT:hh&||kCUx:`^J2`FbʎJ`.zb5`zaB(̽<  nR̈ 00S@g.> ~$~~~~;~2:b~2;z2;22Gf0&HT N2+eoe2BhgR `&Hd 5x/ &`HÈ" gd ø^zCffnf[fIBrQ*PPfqQъ&*¿$4BAr&@&~(2NPNrpЊ('P&B""Y$6JJ*$L>ByReBj2N`P"(H9H84 p`*B@QrA>3yjZ, > }F RDl x Ĕ ǎVr ÎRB٬'Q&AH"IXf, RNA"J~Ѧ#J")<+i*PDgP4h52#̿U(L ڀ*/ >h@c:CA&R|0.iH2)L P )HH #"hE$::UJ:N:J: )I(@(<> ;MDLJ"H$6rrX r($4rf],LQjDS5|C$p6ރJaU. &IH PNhBj(H*I$n"&J*#8/"MAHXO* "pMWfY3I~bi i?H/C  aVXOZFZ: r^^^a^ЁCZ$IHnE|2PO"J KzPO/. 00MO TtHH (/hH1*1"T00XOs0D@ #$P`@\h` Hta($EhN(APGG LK*p@"|.hE^Tj>HSHR@@POWR ̘$PR9H"!P,hҐ*L1TZ (H"&IHRL nXOdlR*QxIY#PPP`JV`!#i%`*(H(r0HRHS/ / DM"<8!<(1h,:`.H"0A R.H2!!#PO dz "T< l:|T2|Fa7 |a 2XB62 :dpi7rA|BTa05L5L(564IVFB^h@GAWBxZ 0jARtrh׎PJP\SDh 5$HZRPyWPooe;J^oo,X,\d,pB𕎒|"B9H F.`a8`~`6"0 hj A` !ahQ$I Bp `LP~i A`d_Rt$zr r n`eNw 4nxBޝA/L_ _d4$H` 8BD@`H(Irh0Rᦐٶ@N8A%ȇڂ<@" `ּ 8ñZHd:`H`NJg$ FJ @g8`(@2(`&AR4*H4b\ 8*z2‚"0PC\ P针@Bh!-Ip󤤞*H g>26&R/\"n LBPO(R&||Ԣ~pf V m jf"vC/ J#CgТt6H!XXؠkI*n(nT\@$bC9> ipi`Fa&V8PO{0~IXD1f,|hR0f"Pf2ȐRTf.Uf:"ULTf\FL1p0HH@0tPtxv.Vb,j2if4H8Rk ^o RR[j Rvo\ RVH o < H&"qVwf5p#\ffpx)f{̹̔ f/$ Rjn<&nHJ:HP* 6˅~РCBS~g*/$l,NZґ/ &D ȸRfXr~cdU8R@h?R0(Iz̖ N.ÚTIjY`r&J&$6z.PFBpTֆu$(H Hg:v K`a0E*``pPO rlb#ڀ8,8atn:0.DUl&S@p 24|02.(-H Hhdp 0 XO~r@gn sP2Ұ̐LlLzZVN ƋmDġĎ"Ip`f/+ⷠÂ0 3%I0HTzFw7:0J0p$H H8&tԂ"ҁGr҃ Ѐєp`& T"K bư GRb`*B@p,hb b*Ƞ'HvB@AgU@fpHUHTR rAzFX&HGBC0`*BD` UPRDTm K(`iRCP.mڲAx= B|AD e H"h`ߢ`U>. jp*!p< pG0-QFp"İ JMtVfhbAQ %X| T"^H#DfmP!|:jP-` `Rp E~.Y: n T` /"JfԚ5. M" J ~NqgS@f|:`.(T** *`:*v|no&  Cg.Dg*s:`BCl0`06Dl2`28ҵve@Fк+h+hq*ࢠxp0&H$02+|b:A2;NQ0"6+D.`($AG0&*0u$T"0v J ` nb*D `G `O&PP8> kbLfDf<@+Pr+JQ~.b& :9JFz R@`ZP:pt &&أ00Hr`"H@ DI1^"Rb0GP,/4jv~@ؚVH<@JHBCF B,0󮕦x Jl󶕾` ʀTq=ApR֤& x8 9$2î/pP#0VܔTàx*I NTT-@~ \ LI Td#@HRZ"`Ӛ\nЎf &\^L0FkD@o@ R//Pr2FHЁ$$ԂԀ _ C(胶l0rPm`0<1 >Ѐ rxn^VR7Ѐ2R1 sm&&"VRH<&H%RF hB XJ % n*6h'2V"@^fw(&&s> "3A``E<XbrJ$HE/0hh""b b2 <2PBE`P0DkHUlDF2 h6 D> : lHREKm0 J (Nr8$(D <,6:J2>:>22xjh4B8!XAU޼@ TFBA54X*dI,,48x2DUm`vBTr|tAP؎@m𜰸zߐ֐8㞕Ӟ> TlD`0\rZi&<0>Jm *ix`>NDmD_DJjJ Jjj.0u"$Fju7*/"9J _>B////////I/% .////(.x*' R U!(U f#(CP12 Th3 4 lO&/,@ЀH8((HG0fEjg6tR_VAPj f4P./\0 (5 _㮰L&&\jW.PTFф46K8il^ؐ@6TDB>f<(f4pP8*p:U@mP&n JAko@pT2@o:??p%?CVr\QP opT`B@?(`(@b(0D@P+Hj|9hLV0UW@rUSAAo`2UWA0v0H(0>8JpT$3F2𠿜H3Hpr +v{hІ`H)RRJBGprږUJ0V 1.b npxTB1|Ь0D0"&x&` PHzxbގ*DDP"tQl``t%`@J@U֣`P QP#wdnnp"tV0 'hPxHpI#","$.# : FRPĠ$d D9I ^Txpj d t ڗv$`!0ƗP(B5@/A:at%XO B@HlTȚĨTpڦX]k":F J@``  6a2О3l4 *^&6c`ffqr@@&R@lL8b<8/ $n`D`JnƘB"J`*"R@t` p@ 0Rl(hna1ن'J8BCVC`\qlN(J(mJx ZPv<3VfPrJ.i ,9J.~bp .h9KDQl |d.HpbD  l 9HB 011"LJC6 0P!b0da0`0>20 0| &2>"AJа`P)V`b`39nA2@ڙz2JCg 1H;a#r:x/% Q~2Hj1^a [N1Bpy PA¢ZB Qn1PnITST   DPKP8_.P, P, P,P $DP 0P"fknf 0r&.Ё[2a h H h2v0TE@b3faF TpЄJ*&@|B#Up oA 3 N`T``,`l NJf Ӓ%nPb,p RPRA"P֕R Fd`ƃ"pXA`AhL08JK"xGp@zps͒Qb(J@2s`tE`8CClBq`JIsI6OOBKNOO|Q`DfOOrK%~CGP` 󀛺OEƠDZP\<(`pPJVѲ$H(H L̤(H g 0&H g 4 KPf84+::.A's$s$/ BaXOҾ "/ vrH8RR I&J&؈nX f*1T# l(H#ͥB0>xg;90Rԍ2Qz&6Vf kVHQܼGb: / cJ K"C_&H0&nPF*6*Hh0fl mF6*jxR"(")"k #"gnJp*HBS6><'"9>F6"2QUA@BPPHTHU[C r_pZp&QHP8`N: Tr%QXrPdT 2!LAUm KPp@#@Tm`qcT'pdއ0B(CEqx 8`0H r@2A7 P\| mL H@2BC g>V>B*L3f"fJ5ҞPh pj 6J66pb* "pDA20z0@Z9RC f" g(( Jgqg H@䙒05rY8pfO`S5gdp"C\m2`U򆰾Rq /"H*H@$8""ҁҀ ΀(ppVp*^  fO hFtr.utµ >ns,B^N(nIp"pP"aLrTmހ֐0Q Pք2CUmU"~phb ppYttttfbtttlvvzzz2zzzzzh"4>Ӡ, B`./ۜ<B: f$X# (H` dԲz yl nJb` ppp|ppD'RL㶜n`ޣj2J6 N.H &IDa Phvr.Hp0 ~2`+JCoH$`F l@ECT8:`μ|9h/ C8Aa&kV:pX^ȓ*pA/668 (Hj2&XO3-mDIfh88NB6$BTTPr򋤻0t$"s4 6pt28fLK&)/ C M{a&&M&֌ :̼" Kh!f4Lf,+S!CI2H ЀЁEBD`UH"JsFERDTm .+D <RVҁ * DmfҶѶ."JrP./pі"0"Uѕ$Ԃԁ劗6ʣ0 P4 moXT!Hd Id4`)HS Sh~d(H'9Hv J PRP0fB 0*HG,I0P*| ` K0^iRn`p`.R J J,J&PPNPZjZ ǐyLxxRL0BC8EBc`n2AjЁЀ rHЁT4H°cR `ӼBC 6/'2` fR R@@@mlLgtI"Q P(J@g`. kg$ jpjlp`o`$B@o$/  BRqʲ`RR2$3 fz|  K)r D, 6$ID=@HzFr@ H"KAʨXORJCf`kNGбt`&urLrr~$4 <&"rܓ'ID'HHvd98lfŰ<ǰMrL"Lrp"L"dH p UN"@ڂ *tR jC A mv O0.„ᐲ"4 &- R.U P>  RҔ<B"R#ɀt$-&R#ˑp(m *̕,$&Jf& *I**@JBS(nBT`X(H" A r`@0H8 h6`ThHP82Rb̩,諚,,pU~"`20r* 8ܐS-m RQݗ 4 їF`,(B0d@f-6SxT:4phx (6I* @>IV李Jf f4-3|7!C|(*f -Ja9J2ЊZ"Dph ( 9K"6>\FJ ?<i4T@D}LL-PV)\Rw Tb,Pn0BC K2p0-I<8tpSCJCjtдpf8Җ2Af #&JJF nzz4Xh‹\I\rrbr$L 6Z\̠bxѾ0h| |DLE%@8fvH(>ID0@@8@ 0,cI" pD p P"LX QBL Զ\*g/6/0Ȋn|>xa 4|Z.a"$.hrrS/ ] / . 6C% 2&*,Fz Rd%84Xϰ$H& A,^f6h.L/CƤ`jP _*^"/D DH,  I8ٱgrXrHpf6>"LUdpTWv6~@nq@BD:`F0C` lBJ@k6RD/a~p6S2CB$$Ԃ UShnm7Dpм&SgW @qDd`T¡D}cfQ֖*؏C68W* (*,ڣڸ,) (.".1,2.08B&H@G!4E`FBF`<0E@n@mƸK"` 񜞊0 46FTmE"2m.y Ulb.* *ĢĚĎQxHδf! gĴRf$Z.|Hm9H( v2lfn18*`H2DIP<*HEKE`6IG4H vLREEn `|2V<*"0K| h BG`@Y//0JL_AC(DGGnREEn*B!0$(H`Z #UJ||r|:2XX|:|x~Ԃ«$( -*l/DqX~C/ ]A[`ldN,ZV"&Կ`6VHb&d*g,/Ap|&|)A B\0 PFl|BaP6̒ 0     $g. 0   28'a>`"Φ"NЌAlr|* Ѵ i6T6nLn6 AZ6/AF ПRgSFh2`*#d'/:"SA&A)gм ) )UFXy Gb!FbUIA'` Q>XXX&$AA^$m>l>TJa]DV3vh4v_>H~~~~:&~b~`~vY䉬`jD `v.`@6 7va(.T`~$24޵Ա Ab\n`,  It`0F\08ҜC-I0fx6+8|\LUBB P0$n0Hj(n!Ο"Mb6HêH( #H"(h0 2RGSmH͢2^"M ´FFn @¤2`-RRczRR&RRRRRRR>T,Tb8XdhTdD"0 fPv.\Hl / / L @MzNOA"yM³ OXO-`vR$j*fx/!/e// "-ـ/(htf @0%*II1 Hjǁ?SmP:&OxgrrrA18GrOO"2@O?BB:B:Bz8B[>BE8dy8T?Tm?T?T?T8T4TI`gocoom+hnpjboa36om oo <o`j`cfjVPb6KmIoooncָ$ Uĭ֠8/ * ?rƯ???zH<$H*H`$j g j  fr$-yHAB@ J@f,$H8$ Y8ܰXHmR&XOa &ܡp*&~J-KA"0* CU"|`rpPO @m'fN UfHb/.H~2n,1H( z(0dH20- BMC&N`/@BD`,2`2H $0C((TKRDUmTRCmmr6nzjRRRRTRNJ JծV)VH.h4XXXn<Zߌ\@\H^CX"L4 ppZ4``0B$0Jff#$X40nT*,",,b*22 J~~/ / $H&?10Hk??6^ ` &Hg  A#A!H*&DHA XA80&.\A~BL:: 0("n n$I&I4D0@(7(Hj6Hx` !K*NXO@ RbpZ .gqub$H*y s( dCN2Zp,bbF R*&h27 @@@?r@@RRy6R RRRD$xD* KPM)2Rf 4(@-gb2FFfV20)/$fd#"6P$0'&/.#&ND*.a`(rf8tsBZ?̱rXI"P412)&H~T15VDuNZ2X24V!&rT Hh&1$*@3&4Nz$@@6*mL9hK6 j/ "J6 LE@p AB `CI< K@&P / 2tDPA"Bֺ4t%C&"jAni"H1lh4B5Fd.H>qG8w?0R812888Z}/^Z/pFTZE(p>a6$ 0QQ2@fpЪg o6(I;(.:,+djvu6=2P`Z4P$P`޺0Xp*?3HА*0*2g0v.XgSDA*NrB"`fAF,`&J8 8T"LA z7l DJDg.$`‘ "p*~ 7R FJb<`h8FRFFn XG!8p(7E`n-@80#X:6 (@$5D##AH, #`B| S@lg -Hm4ErXBN`>C `0][@ zA.:2ڀng#ʣ k340@GB76>^B7Dx)ʦI &ì^$ ˨ REEnSFJFj:xUlr: / ҄/: UmRT/ xp`p2q&(D C KRD@ 8 $&$` Qx>|m?<*ROHTà2DkIʩB01T UTvvqvRV@$CЀ/^Ҽ` /p[ "Q #"Ԙ$pPgsHrB.f)(ПА Sg"R SDPOHѓ`rfRR SJZ0rif RA^.Hd,b`ohzrfrFFҢf`l,4BC6{fFRĈV}gppbRa(g[!f [fx@8xRa062&&ft(gPB*H f 4g& m BH@0aּ.Z8:n6|^fHTZ}yh^&XM|#f (#dJŌMؒ+fpj~z-fllK|ʤJrn"Fn AEx`PH`D,"f4R*S2`!g0 $H"S 0 h"^~b'"f^"g*f6* .fTl p`@fʵ

֔UP0$ Z$$@VVUV^LJ#Ⱥb="=!T PFJ#D.~00 v#tƪ|.$` `QpX^`NZ_f* v 4"%`*~|2f"P0`g ,J8,(F+<$D+"V8t~|2a`J$Mdb$ K"LV82`+< hTG`vHEVHR/ / "VM8OH"Jf\\hX J"MhSC JCjL'` !H&^(H%:Rd$U@f2HUXPZBpPO nf^t;@J@kP;8`^gPf84#JJ JBTmHzz/ CBAʻXJO%>rzH(I&P*QCQֆ,:(r"R ig hhiN$gS@ #$&(XrT@. #(p`Bj@8!ALJ( >RaU g^q .4o8`8.PVA2TL> *HKBE`!Pm"K G`4*E2K XO2:RE En @ (HIlQV"SL `J W * Ad J@t" Nh0"8(ܮAHAnڶڮN؄Īо:z*f8 .HЁSc*$PSDF-*fE&H\@rD  2UHsC( XORE ( m|P дHH> R>HR L H2 f'JRE RGB@m4H"ҁ҂Hs0H&փրC`FBmlN/z $H P$pI0 "`0H`#2h |ഊBI:2@6H$Ԃԃ4V(V`"Z4@8H&8\r`"RbU~rHpDUpPF`6@pG```VeXGb\0pHS$j| @Sl2CĆkÆpؒpTXBc$`"䎈 DRSRAHܒAATX&4'fC$8b ‚ Mp@27&CPbS<h8h(zz"~PS4FPp2D7ARVXFOpҸ271SPBHR"8"1rE8u"J` 2Sm@P7Dj F MNv "eR0Foғ"jȣjTc`DH^i5b5H()NNHa  5qzFfn8`|0,2`+&$kIE@vk`*2UHS0Bp(tH"p0DLL Pp1ؐ@@*$@@@0p rr tB:,tttttF:H(.hZH,H.hIt1/ =/ a`"f.H` "J+Z*fxR2UAHP$Q 32@, "UAg ^l P`Xd0B dppd~>l0 D 4B*jx nrr CArTMr<1*HbJ:*b0-@b hjr ĖL ~"T PhCA v=`h:@p La,8`(j30Z3BD|l"zRCmEFb m$m#%:&TtX ^n04H*h0RIH($vѦ^KfW`@XX,X `:,`$4Ѱ0p5H HҐB T@DPhH  Z Or "KjP:8(H$0,h0!hp¥#Ԃ>&trfE6lR \P6,``RZwd`Ÿ\0xr4C |*p‚ќڳK3t "`h0<$f6 yKr&2pf-Ipb9DJ!d`$cf-&`b.($$ځ484*8$⢌h(BAC4< "G<0+fgi, g:/ X @٠XO @SJ@gaBB&n$!F!B&vE`KANXOA,  2g62T"!6(GIBC$4>~(`L0H"S,J@f6*DJEo|l"S0HQxb8z fkR@t TAVlC@VVZҵZ0 X<.`aЈ)@d>H0HހއA" n "0.aH*H g XME@l@2.g6`4,m@0`DBC`D<@N 9 oP.8 <:.P8p4R@RCCnBD``C`m8`U``F`R`B `DRC`;@:. #0LHn tU|$&p` U $^bX\ h.#(# ,P&'`8:0($(PP#,@z". .r,r8r!HpIp`pGxp`6N#B#B|`%Bn%B r5*`TЀ:8c8^8V3Ơ8:N-KA,ЀI$LҁA#|HBF>4Pg6` @ҁ9RCCn<`2 p*$p"ppS@J@ k l4(RF6 g P7P x>*`: 20$PPl T"TRG"DP4fHB/U0>PV$$ԂԀ*0&8 -P H@s20T0NNg1|>K`XC`fBD`\r4HԂ230(W~T44HЂЀ**څڀ區 JE0MN "  J RDDnRCCnU2 TF*I(PF?";"jS:rQ:-R:S:-P:2.0Q:2(U:4S:2 U$U8Q T<U`DS S.`2TT/P:X)(N)AH-b(>$L7-J"G1$/'#$%/)k*#-5/// ,D">/60`7a(0H( _@V, )*Bp$du(!P F,\2.3#'a"L #""Tf*I$Q2Ng / XO`/. / pưPOҨh>>*>>l >D<$HpeL@pdDHSnarJplB⒬|aRC HmZ~AHAV@pK(M$kanf2RJp@A&A*0/ H LHO `.8f4888XJ/z2z<`AcI`fzB(HUrƌXO 740xb$HBC(&H|R8R@fBB`8| g2|Amcܓa@2B`< l Jk fRC `Bbv_G@K<<<<<<<<< K a4J!!d& Hh  VBRKh!@ W"|b@0;N༚6< <@$@6`jBS`f(m6BSCp aL0f""j #v:B"f+LL<`a:+`60T 0!8ּ / T4,`R Rff@BF`%R0oJ Rڶ`B S(f1g5 |ةZ` +Df@s@` F$p/ ~ "g g3f@.f (`.|@40*gF<X1T&RK THJ@g&S@g *Ua9|n$@t TRH$`d `R0T M4 U"h0Z>fR*@oB<`4g&Ӫ2`H@b}0,XO jpГCP f`v*(D|J|a,x@|`N EJgQDHXHcBzDAG 7l@TD~DL8ВBHeNq'/ 0r *H8  9 Ip'iA02q J 6.vH<*I,0HS"LQPOBCN@H18USDSmxS0UorD?tC0?jXOBE`T00Ё$$Ԁ励><`3H@RFFl<][@gRETmUS0rRRP=VbVVVVV f-z&* FNNJ8 NjJNjN|Na<d8HĉBCH2@oD?pC?ZЀ`U 20J@V/ $Hb@^08T@0aR `*&!B`&!`,`~ߢ> ߘ` JXרbl$JH$p jNT7|45d&j8PѪ-TsIl( fNKZ 0&Kӎq4Ӝ2Hj3"NDXO5 (pN z*kB'K`T@| "g4+g g @~@C< K'MѸոJR4 ng#Pܦ6z`L,gВ"la 7|R0"Sfa D#fD (#f<` SRлd SfB,02g"a7|@^ M@#H(M)$S28E" SFg-gB .Pzf"S"  )g\<"1f&"gm 0BܐH8بR.2(0l҂gD,(gh rf Jf ڠ2\D. Mp * zX fB I~g2p2,XM .“`J" . (`a$S 0Ae$Baھ@*B1:2t0JRЀr 'H~p16*B4b\`ИZA ,Ĭ0.Dq<00\Z,g 2;ΰ6TBj. Rp Sf 0КB`ac %j`0* g $B* `ķ!rf .0*6`p@pbH@0; 8#>8%02( R`<~4j*׎ B@0` 2IB0RP@vm <8Ŝ*pc:Vȑ/Hj Aab2POnԐА'A C"xaBtr'KC Kzv`,C q"tRCCn`$40jBU0+g|@<Nu1&$H&I(oNK.hBCBGx%BEggd5PgB fSJN:kRGN f oRNSG` xNJ@6pRGgRBEpV<*f F|<0< b Cp%$Wb <>>hgDlgJLJZ@Tr@A@U|?'n.  (2 ,z@ J0@vJk [0`N$RG*FtD( L."[02aJAADHRCBB LH"p* /r,R...A"Hpr QB/$A^f Pr,a ]gT-)f2f dP-,A*RBUrbdBB^V`JgrF D# F@Hot$/aPI2,I06!@$ [RCJEk0, 22Il 22Qddfr0U 0b0RfD^~ ^pyj DkfA!B00L<Nu0fp`?SAkBB F 6B 8O&H(I>?Av8z0| ~E*PN1@RG@kNSG@E 8SDe(N0+2v-f (fg`2N0b QHHc@ .f0 ` &T88l6<@.EfH<|$*v*TN6/RDDG`@ GB/f1|W~4R~|Lf Ux`QhgRU[> n ,"BXr"B,bV:@ bPzPz|Q `0J Pd"F6@P\ [@4JJEj `p0?4v TPO2* 0H  aD$MDdD @DA : P0&j|#r 0\O x" Warning: use TCFLTLIB to get float supporor printf. 0@Vb>68jx`p@c8?0|g J0R@CDPBa&* Jg|-@< `&+g ( (. ?D62XAXAt0g0f$B Ro DJDz2SA`."SDQ~ X*    m"to An ?B"` ff ?C $8@gE`e0/DS@jDP@-+/ r@ pJa<"@_pFpJWF@rPt0pS.@k.F"zt@>> x JpC~XO||t||:lDE0 |rBfSFDgeEdD"68JEfp?@& tXO05d?PE:E:SE ,1"p@@0E|8@"jL(XO0@EDEE!0Dj0$DR J'r T<RF!h!t^0 !#!#~kh6$! SE)j *0*F`!0&!F#n &!Q &" 0Z?x0. 16|`/F%Fk Tkx`,PD@Hp~ :@H?`_:|k:@k6DҊkpHfS 0gRL80jZ$BDT0\XO(VASBDB@P&.6x0j@:0@X& 0~ g,N0t 0  o(f @60gpU.<<06XW"X@f8fl06fL  HS@rJrfC6Tg 2@taS@b (L2/@4/(jtрJB4g: 0Ao$@Alph0`hNr6B( v`vˀCJBj4Cb6JCc8C> K0 JN`  0p0D @– J(aPHNՒ,b : |LPE 4&H6g8,KvC.(Q$|NV0 4>HP6@J00arPOJ.f2k?0 08Ba203bJ@g   p*p,p p`hhv*zhRpؼf,P<߰<XgR0`.:u*PErjpdRE-W'g+f A< b<t E$ J D2BP@E< 8z`bnREJ4k gHJj$JDgJ`Ю0&jh`0SDf`**opp(*B2QcA46g(8HfJCJ j r`SCfD` QC2C@A<@^8BEZ$@$snF#b F4Pg>X( p (C fBvqpB@(VH`F:S&gfp^+g`)Pft,k x$ڹd SfRe`.&//$"\,f4(S8*̄*fH&; F̰n n`p "`@&`S,A'JE8 5&lH\f"`*xZ\VX$,6gf.lf(SH`x"Pd| (@gH*Fg g"/l _И  kf"P`PHC/lXO>`4>"P Pz da6Nu?f _2 0tZC!IR `H&H( Ia6k g L` |J(H  )H``@0;6 K (:`N^J|9@{00l 4("> `dOaD!~b* / 0=NAP$_JkXRVVA2(jRHfQC#@z LL@``p`p 3 L@YOCBg Ar`THWf0נ"crFwLS$r!w!a!rbkw"a r+ $rb w w a a @Ap`Ar h.V/ *ʀ4 *DG46<6Gp+01&_6E &H4DP8080+a"1@*^ kn tB@7@?B 06&>Q2&c  P<*!tN Lh"+ nJgF@@, L"St gSj`"HSISSk gJg&"'LBD@@p`&$6rg0DtRD$ XzZ"SIp ~*| P " 0 "_P kNgPAp jH@$L@ *g,`0d\1\| g&S6q"Pb~&Hp Cgp@CfFC0 4O0&8jaTp&F`?ANjBN`A<>.`BrfNAAP>q36@pc1"2|**2ANA\pl dNHR@W@e >? 2 PT@ X  _(&HaS@@J9" kvf~<"g&B g06(. & (0PdeapJfA@U `<|84U0,($i  "H SSeg gb " fBPgSf A0$H$pGrt (J3 kSJtx@20f:p bܶf(pf"`Nf&D>$T.G N@Vd"  &HCHCJCfԃԁd` & gSJ""T %0p$"`!"&Z"t!~X&@N'`$?&8BCHC06H@ 0"&RBJ f8%/%abcdefghijklmnopqrstuvwxyz &/A0HcJf 9g @ NBp RP$Rf@\e a !C2( "h`rD,&S f. a.j&@A`!|'&.#4 @ )d I"Q f`rd ` #@#x"nA@k |JPڑ: 2/ oLQ1 x 8DfpxJv`6g,g"@  ">Isvj`sx%fgrEy gS0,`,H8$C%0 c &@ f`(@ ,gb*"Ҩeg  `p"@R"2 >g4" @4eg`N"(>`" "Hf "r0eb&/  fB/Ȱ@ 2 4f!1``:"@H?LxH U `8(J2 p(H2 nx:fvLx2|HgS@!!Q|ЪSA!QR ePSxHxx( PUx(2<* @h(Lnx ٍSAp$ /$ eP40HB4 gxH_>"&(*,."B$B&B(B*B,BH}~(8L``HL||0 ATc0}tNu`HyS~v$0$`Bp:AB0  !"#$%&'()*+,-./\:;<=>?@cc[\]^_`{|}~@r :88:644Z@'9K]o ^  ?QMo %70:?757  r2,#00z80"ЁЀ爐(R#>H@|$HBJBf$NuHBЂ   (0 6AH@HB0@$00 A H@B@tӁd3 FrG" PNb A"HfABAtҁрNЈ NjD B*J " `P" Jj"J4*$~ PD"k@ r.p l&&HR?NMXO/HP$J @8< /NATNFAX< V/ HQZKHO(?~< NNAP;J "G"N(HRt""2@"40<NBA 0d"< `HQ8#H 222" T 2 "<a" "_2E"Z2 $|Q#"<64`2"o) 2 ~<3F &3P2`X" Out of Memory! Determinant zero;M??Yk}H򿳿ſ׿@xڢ!h5$0 Budf>(:)F/j  @ |(%!& Pl0columns must agree! 2needs a real vector  Hrix=Wr Y argument's d pkxaLwMarhkxsAMyet implev0 offonIllegparam09@e%shOu0&fDz @@0?? @TF $>@fgcwirM di}sio@;r?ojmm +S!soliB&<yhcu4thP:Conpt@f;O6ESeco?nd( 2}ODtyM2/BA:view0e [d` t`g alpha`utax]@ 0c2c0 r0 c1 r1 )2@cA 8A7 "1gr\ $styzs@kng@i-.--mxmom<>m.m+m[]m* FF&$Alinewid "+!CtexW# aʅF[x yLT))uSetQ?Vx1!x4'vHoldcQ0=Sca&Twosid0esM &rian?gl't @i-APv?fab3 ,* ˪߫ $ppBu4@Zj P$@ k(5p12 U3456U7#8(9-0 Lڢ!h?5 pĴ  < /:ϖ<Tx/8 %c%d.%df e[Xv4@X<LU|3ÈlN~FnJwƂx? ж߽{Fܣ\uZxf?6ŎF2~M4qi; ?q2rC{lϻ$Ve Jo/&~oR Dj8!? =pMLrY?Z 0:uGɔPXz/~B֕ 0<%d|T H - <_62p_A6/|/|/|/|/|/|/|/|/|O,ZnB? Err"inputlyntax e!dψ_Zxa: %s۷/rs|%sxHpw f7 name. wbCould kopenyWri0te%rbRead (fatalEULER)T߿'fdef2dthis valuTheallows onlyжAep size!0 ?%5T: &_c anIhave O%leKVo bΙtM" overfmultipthes;M_q&8J\nVariab008\$Fehle`r Illeg00rat+?//C4funcBmreferen[cNA%R1/a@|A ndeHx*be=numberoO@em9pta?aprF typeR{}f`QUs)i"nt`fuptReturn missi``p1arP1 afQdQ>onyZ/i5VDOr%S6hGa:orePPIP?columnE""rPOlf%n`m`` us`0}+&/p, bwzClo}bracket )d|ow&Ne}mpl0!polynomial 4sta>rt!uTT, VerA 3.04Hd T1ohel,p(3B). pE1b!J: (%Bytes f@.) KJ$P@ֿzB %14.5e7f v ̺L.J2@<& F*P0Q >Z4 (@ld: Q<n?`x- D KNQQ UE:Y^e l *Fq v {(ȲJ2rFjP)Zz"Rdܱ6xXYPdump(di"sk` ll?nS{t0@_eiQ@߸̀in:E ^`gKL to lb3rePonT@dei Keys: F1 (cursor_dow S` F2uxp@ subrou0qes F3Fright) Go unt0ilVak F4 u(19EEa F9 (escape(Abo&rt#eck"1v0BHPt0aIX ep\sR$W2ic, searchqY=if% %l Na/v^Iqvna;P`apgg UDF$0%9cp%gp,non-loc j/ry R%d: +i~ 0Bl^oaQX[r.eӽ4BRlis[!)chÖ+zi D$g$N ґJR a'vSaJ!FFFB]  Syntax@srtⶦ/᪟to!#5@epSLoo@E0 !2,,?Ig5Nl@.C}sE fa(gADur8vg&>FÏo8unk݅ *** Bui(w0Your (9 (=...,) ## DefaЎn@8$`cBh9 H, Xns9Ʋg,e.g.: >P :shP^  oc"a20V0with=1h~y5j1qWb`! {B""ruQd#"( >quis4&ԈwhAcSRED^W2ta_ sMgtaMM MMbmxvdudaGG4*y : 0 c: RH new1  iy%67<16s, siz`%"c %5lx offt[iu0tlQ! QE6p9m8!G`^u!holdshgaYaFifaL(b`rk op=%peatByg s8@globala\ dohexx"ta›Oy 13 1993 "euler.cfg";s"?@fĕgŌ qð* R(x2ު ȳ! vn pD@ r tTT!x !v}bh1 |1R$"14B 0*!b1R( 0 1f*<F pP@Y<"ld1>"*E10%\ Ta1> YvrBjw1I~12K1,ȅ @ Z0RI,@$A2R10A.0A&A0* 2FA bZATߦA 0 F"DhB@A%@tA PE  P<h%:6""2T(A<.Az@6AJAQxPUIQP!LKe ro K et keyc$arch"4s ymrojec7 et"I"%Ю,twd an6gl !feA3.flipxdy Uj01bi#Ako0)r lev densityhu$f =gr "r``tWԑBQ $(&f@ r  ""J $< J$X@h L BTDB@7 @ Njz ~ b>DB>f?RJHNJ @*=  2 ( 0 &F0  *Z(( l~(*6<\N;&P@0<"4  0^"( AѨ:|*<6>8" *"  *&>*&B284F$ > 8 P :4 ,, "$ 4 8,|6D. L  $90 `   8 P < @& >.B*@  F\  h< 0' @2L 8 DJ  40 & "@    &   0$  s , .2l z^ $  HF @ s. ` _0 Q R*x  R0 PF. F( 0,  8Qh  e ( 0F"$ " d8o*f2 Z 0> l<B  0   D * "  " 0g&C $  *i"  * 02!9 0 ( ^ B @0 $  $=  >F(*,* (8&@"H) $D #$. C Ys `   & ( XM v*00 !R  "(  @ qP2F  **.. $:t:r :<0.t  2| NV &S 00,8:0c4**2*@E20> A2.0& "HWA 0,.  AZ.h &(< >2.6f0k ^ 9: p: . h H(&<6$P7" 7F&2* V .l * uLTT@L2QH0 l 0P.00\  "P& H>l@] 0!~05&(1 P02 D'$@ Ab*@. PT@"P19PA  Af   0 ! 3(0Z^T X0 .".""2p 0 ~F n%  f `;P@A @P 6  pP>  -0D P(8 ^ :<K6,B<YB@ 4@C!< x*("0_*`P""" <"p""P NL`$*lP[ ($d` @-V*HD` E3 02 pk`>Pj`& (6`[@"@4  *B@:N@H6HP_(Pڢ(ASzp-* 0oPpA&`  0T@\"f" ," = u p{@f8&$BC6d p=AC  bp  p( (*@s P$9x` "$< 0* q), !.07F$P/P;$8@PwP+"-"qVp appπB qs0TVn 2 q0A IP $ n!1!b@Lp!P J (,$` q@0,H0.0 ("p5x0ӧP  ` w@C !Jr(Qt!&>!0(,qڠ$  & PW$"4@ N&6a( q(A\ ppP$ *`Rn`V9D@`: P2"=P kPL 6#S  1` @pc  @000n2XdQX6@ TDJ@t*$"0< D( (6 n$0$0,,>+ &/PbA`tt`@}͠ON pГi( q ,(."RF.@.( ! Eh8 RA, @0~2kn<$& *4!2 $@ wA`pP@ .$200.$,V @@8F0@&F F18F @(](* @ $`1@( (A8о*$ @y2" ,AQ؞pO $h. `$`8 LHCNq9` `(0,v ,H(1J*` hЎ(* "A0$ J) \2&p_i $ 7B6  $$`*&B*: FB0:0@<26(B p@14 BT ( 21x*0Z>8 (@1$ P("b xJа.0&c. y$,40n$&"h(n b1q  .DG&pd @(>"q`C  X*4 4 *$*<8:> @_e 6F H4$`V|T@"]H!$t^jN6 "J&8 cी(& _Eo0P:@2\0Т8.0"(.,*(8 ^ *28(  1CUg'.U~P&8@K]o#5GY30@\\\\FF$6F0hZZ \ e m P x      /EXm    , !"#$%+&@'U(j) * + ,   )    &@ %  "B Euler File Options Program Information----------------------123456 load "..." dump "..." dump file="..." cd("...") dir("...") --------------------- Character height Save output to ... Save graphics ... Save configuration--------------------- Quit longformat shortformat shrinkwindow fullwindow list reset cls clg -------------------- load "demo" load "help" -------------------- exec edit load file EULERA numerical Lab by OK Rene GrothmannOKAbort___Height of grafic character: ___XXXshrink(300000); .. sollte fr alle Editoren ausreichen edit="p:\e.prg "; .. oder halt Ihr eigener Editor inklusive Pfad file="test"; command="p:\command.prg "; setkey(1," exec edit "); setkey(2," load file "); setkey(3," exec edit|file "); setkey(4,"function "); setkey(5,"endfunction"); setkey(6," return "); setkey(7," exec command "); setkey(8," reset "); setkey(9," cls "); setkey(10," quit "); cd("progs"); load "util" shortformat(); shrinkwindow(); `Fr`TPWM+C\"&Hf&o$k":",J"ҼR"A k +м<Sk L0H? QR@`,<(JA*A0<b:Q*ANvdDBEM*LDDDDN@ ݳl`ٽSbIP"[ I"&&"&& &0*rBQ"J@f$I$gtӐg BfA` AEG&'ZE FNBmNq`TH``>>>> TURBO-C @< for ATARI-ST@ Version 2.0 (C)88-90 Borland Interna@t#al &H f&op`B@"#r3x k #Ȁ Ј<.@=#,Jy2 g""@(I$k,"JfB// ?< JNAO A6<HCBB`6 !jBJ)gHiRC` "fzSI WJAk BSQƨ44H`$ON0 J"L )? 9|Vg @N Z , LNANV/ E??*BgB BAB@\""p"$_N^NuV>>5@R@gX 2ABrR@| m5| CAPO>B4&X JXeOz09ClDJ@f$H<68AB@H2²f(B@` GIKEHn"J n((0<????>> p 4r!B@^\O\(08H"ҁp7 n΅rL<4,r #,g!|0Al  N%  f &%H8(H$IBC @I!G`SKRCd \g :g| mRK"K@ "࢘L JrtBCG 0I@K@@0X230ָAN40gCT(1DP@x/. s/"s/ CZ<4B04 R p 1r "`^(2?/ l6J@mB0Jr 3z"P0p&P"!P"h<*"@VV,@62`l$_6<-H&HB2*RJPt`i0 ffR@K`{B@@22Jg&IK$`fPN&H`2RMf`*2AJ@2!*HgA@xBN`"RKDeJgrt&@6SK"`RbQ2 "R#HFKJ/ R0(2 hFQ3XO R1@B4 ` "`RXQvQ}SPQ<J K043\BCQ2G`AA5 7!mBC2`BA0"@7t*RL,**`,5,FB00C$B109! B@ 90pnrp N`Y@%fda~"8X1z0$ 0bz7Bj(JB`D@6f"%2D!@.BN`  R%fR ZP'NB<t4A: v&vv S"hJH V3 VI X X" @'|UHBkSJRH!t4$H0+ SJ"S`%(S"(S##J ( S/( (XS"(/(+(`RAL"j`"d%'<|5~21 0+5r|3 pjB3 jJBC(rp^z|$:ThT0Z1"@CX R!IpTr@4HH"*@*>3JG****T`d` *0000$```"`T N=@]qqZDS MS:r ThRg|Fph*g~GgrA=A$p@B=B8@( nfBD`8Duv0vfJDmb7274 BBs@`$* g4< `D7@0nGPV\ "RDp`~$C@Tx$5F5n 5E 5GDCm 043vpj$H` rRJf<0m9nH| 0$$J $` LptL+,XJ`dB\BdBTBNBHpgBHF8H8*p| pd42IBA.ZJ`ڂ(VB8LDEDa*dnnNlڠR 0 P"N8f 2z`| fQĢ Q8A&:Ġڠ#O48t Rhjp ff#$$0zR0V6(3lgCZEF иƀ0j~AB@ jv@s?@BAB42"8H4st"0 3~AʰxL? P|@g g,(` .g 4Cg HB*$ m n6&0& 8? _gnCDnvL Dxf^s\xK|&ZPh`SHKv nxdTR e 0;-KP@ж Clr?.|Hg" n BW@g`*zU@g`p|`Upp<Dp>|}Iar ~ A"BHӾ& Mz}B4blԐC2А^G15Ӻ,Bd""L`\r 4023 >à4-P`ŨA &Hnx Z0D9 Zgs> Q/BrHT 0PN!ttbHT(&_>18<68=B<.>. "D0&JQL`N/JQDCG/AhArBAzHk"BrcPO"#gr2j>m?.~|4.z2."xLXO L T"Bl$,tp"\,8!c, @԰e  @\$H L #PSp¸H8 :"Tj3 v*Ah: (ѹ!(Z AFѰCJѱa%J&@6m @(@.2*2ACA40m@ŽmJDm^¶5Ŷ#fDx3! p p 8t 8t T T0:$n &nPo6`6Qo88<B>RGl`<RC40E4SB0SD6020o2oVf ><t8d9hӌ GK2nQr &1$&0`t$(?nMR0TtX645T0US@5@ TSA5A J`r҆?z z0aHnj{4yHB@dX;0ulr Q &"ReVP4 0P63v4"S!$%" @lSVJ3xLJ~QRbY0 v>dCSDxND2p5p6pU8p9pаpH0@ڠCpH>pR` @N?BCpD$ҪF,G4ªH<ID"P^0@p(UPp LnPU$MvP6UNd<,\DUPTLVL|UWD\Q<d&4lS,tPT$88H.p_0~&t ^B2*pQ*>p(p#pY*p-8"pZFd86 JBAf@.KryǔN r G$NݖZ6Oj6bf.1|`&p!@$ @^pB gNU\@ " Ab``Ш N&`Nh`O(r D0?,, 4, q20~XOHf$& DR h Fڰz $GTbdjrHL\`@I"`4pCg 0.c`"*pdhd"gX!O0gdɰ5BCd 4 4 r4 ~?/ 6$`f I8ҤR84+@վR:R8`*`,`(0`JWB@$_66(0&rPj p lcB@ڷ pd * p"KAH¦pC`02@Aِ ٨ ٨FJ4(NgPT"R@mc2(mbِb>`h@AA "F0* mQv: vBzc5`x Hٲ p4pyp:0.&s *&Ъ *lr<&0 &Z'H hp"k hÓ&'I l,BBA47 AD1 CB3$k" pJ!FB#'  ms: r!Ap4sB@1 7 + hyf$&l2ǦC8&H(#"!@.KlJc$4*TeP j/Tr8Єc0"~!)%ڼ2|Q(xJ!\pd*\٪Fd A HJ`Jd %jp$JBjB< d lfA H@ HE`0@E@u f d RE<*Pf0ٷ(b(&a,*TPc4"Ҽ€P jT1t`f2( @"ѪT *P;4>FPPb Zn *" 0 T lj($ : uN&v RPP!f|N1J`H/J!>3)P&JPep J˸c(Jg!A`"H KCfB" b C@~d%K ` "J$ RH2 %HL "8," (Ad%KF(K&F` Z/ZB"P,A"T*j> b!lc+)K"l4*l$le r`%#%+&01b TdT!^! l5r3pЀo  8"%D3j$|Q!dc"0RR6!hWPh&tnn2VLn!(ttt21 J"~8~XerN:>3L,@&"JA2 E6+F*0T@ @c*P"AKq08{ sbEBja1DA|@6f0@6B@Cceqf3Yh fV "* Dq.%Ray$Q0)pTc$iT`  f iPGe ( fSHe iSH` SH  fRH`e Jz@8$H&,`"(l IPg8hT`RHb*BB`@b f6HÇRCCm4`R BR~ gcBn"n`X0&BA `@4HRB2BFҾ5оCB4H t(~RFѺpBCRDDnl=>6@2.":6ќlڑ6~ h PC $(DST"@:\T d Ԡ/ P@$t@tr  P^(D2x yHNro3;,g p` Bu@K,&BCv}Сh ~(f/@$>rnXOJ6|HjB2r 0Xdܘ 6@ִ B0<5C40R@5@ 2SA 5A @@pp J r 09l^XAO LP0;,g 0@ԯ``I n8,09ڢPH@T9UȋD L K4"`2pCg2X/0)&PBHH<(H-I<=A>K @ElBC8A =@@0HR@6P^RCR@L g dCnؼCl RE0F@m@6mz 2b@>&$$fBHn "J0pTAJXO0 ,2,,| CEnRL@` RCnmP @!Fnl:=R2P#AD4.CF1R=B=UH0'B0Xttp$I8 66 ??4*22*qV0pTFXOzf6LHp2vB:XO5@B:j0m@$B0j,Al 2gbD2v7$ 5@`4"5h$ h0&S1h(5B J3~#dr4\40  g p >f0`SAJAlpfh" ( 눐Ё`:R`n!JDoPpr'&Hg*(KREE n`   0D@pTT?0⡂ XO?€r0220lB NN402T2P?@rUb(DB4@2`؀JA2;N&:DNXblh.DAR`N!rr. `:"`0`&r`rH!`(`(2^A<*&Z$n 061@ ???4pp@8`2nP R@H]@,U@PbS@s\@SpV038T@Rwܵ垪G5pbh * &&(*A,r@HB`.vfP N8:P8&o"=D@`=j6 j8Wj<~:?*(&$C8Ao6qj@( 0V"PO?.* &r4$jj!`^<񘃌:,脃&RV, %wH?7Z7 zBzFrh2ޓВbp0p08֐=A4B 5 G@4!sgr\fnpTpr!f>J@lCxN`44XOBD:::::)HX10v $rJJAXr] $l 4f4x@`$@mBD0"PgR~ `RDDf+8$H&r(jBC`̰$`jCpbN8-GAHA T@Ph ڀB@3@@B@EA^Gp`N2A@I41|`2AA3U""" "UD D DfT D f|| B4; `| z`>T>4B@J41 2IBII# `bJ# L P@t6Q28`"PBAAfR`R"PfB@g&S @R&R *"R$_&lBh (gBpN0(g U@BfWIeHURBT2HrRfQX@ƙ6$H fԢrd`CtHnHq!?.Š2@6(H fPJC8X*fC*z***`&M`B"LA0 㤖 g8S 3 fB3B R@ 4B+Kp4XHA< zBn@BF=Ft$ bd$nЎ@6f=pR@ăĴ Kє;."= kF8xIblV-BD=DKpFgRDRn0+P.ŒR@m '0 7DCDp}`ZRR0ohB|` @zf-k@.쐮o "#&NIB g4". A\2т@.l  0R~0F f =k*BBkD\k$2f"2+Bk0m0Ӕо2D9T2X`pg2+2"L0X32XO7@B:6vgrppB`(2 ^ b2| gn^| n0| nR@.`|0^8V`*|:B:$2$ΰ|hn2|hn| |LB L|HD``|U |&@lnJCoSC~e U P D f0@42R@6TR0NH6<Ї@JCn}/ "..UGCp` ?c47%-n"rGHӮC$pp" JAs JGo0p( */0lS3XO,|@!.1xF=CzSC(0'.6:cX f-2614j@螮Ap0b82j "UH Usp GEp"URI" S0FSL(@vgN-UpX Uc ( g @Pc(gj"H@>D@>n-JE@gl4XO`BG=GA\pG@Ro"U UApDUR   4VJRƫRԴh!(L(J*\RQU U5:F"rBγ 3RIBa1vU`Pfr`BA7Ap$`Z A8nr A@9PcU\f HnBg 4:b&8 @,HRPL*Tp.PFf>RC` g^k4oX "@##"fA=|`d!@A"g @0 gb gR&=H0*rh` rvU\PQ44.0dA(1D;/el fU!RH`SRd @0@@.:cF@LpHZr0D@BPC3X#h^Ѐ< As ""2غ`o0`p0:?k?4``,`EA0@;tXO>2RA =A{^`@k&SB=Bslr ^BAw|DpOwB3q Ou&pr Am|3Lp(qZs@2 {f+~$ ph @f BФHh@ ТhRHs> b@0;N (< F%@* =p=|=p( 2ž$Bgp?4rp!hPO. r±Ԩ<1*|6g`B6AN` ᆄ`r n@0~g  n?lhd E`@4P EtXV@|gp*`0`4,QlQ R|` U~|gnn JBΘකn Q@nTȜY@ nژg~$`pdV~& Q*ЖJl"Dz.`NB@`t2Ŕ7@P:eC#aHkJVXXF4JF o,d0n@n)B`|J"*İ6޲n@Fd\I!,l@К2 'HF dr@v((>Dr_P.@St0FF 0pV. m@r\$k(?|`&?460CCRB>x0N.44c(0ѐBH7ABІ7nN'  8R 2 S'H x`8' `%  $$A2 FB@мTD?f4rB .DARAv) p.ޠNl<+ <0/n n )l7|/R!v"D@ )DBkB|-0e.g[ܒ&&, gT,`pNP Pdh2 2 f%`"gtQD\Ja3t/+JҖ,ՖNV5l2!|R C܈?&_|$A>*uf`N tL`  `@*`j6D*H8<:((f4.P^МB@rS HBCB4@DQEG6"7j$p<*"j,A7A4*$j(SB7B K<6`*I8&j 2FH :4j*H…<BG`DG(g\K,(Hf,&L%KF5GDHj*P*Xj*jh0*^5^` &LRGj( hJDm*.m$rD$0DPb0.j0.9 n f2Fpgb 33:mѪpft`BB3,LTH0~6hf*g'tjg&J,` *r}7C Se7|t2}L &iwh'r1CbL f8 ?@.p!@ 6(1JCm%8!@.0*m0_"($*gx!>0& A  Ђ45:R6" +~ rBPv&X@Z2*@6r5Np%$eV8 }qY (JoЏڇ(LcdNB|`T7" Lg: "R Lΐ f5C%L AH %H*CEr/ 3 P8NBoVE "J""28CO"A:1`zB$_84834$DBC&R`ALVp`@.CFebcC080:4A\Y&Rx`Hg&HRDDnABjBBE`F E|m%rK"4rhP0z8/ / 'lī:PS}YAf@fS.yg RL~Z&_.Ul@b<*lpS*}PllS6XOJ@f#P$Pr01*p"0 M&VJ "JMc~ f.pJ*@IB( A)H9@02` " MC Ft@ Bmĝt&H0\`pDBpL:g` 0SCJ@nB@;8-I&n6(n <$H3z@JFg N`f."0PJpP`0HP J`B@4eȧ@$H*I<>: . 0&#ؕzJC3A#SJRJnA0䶀NgPd y c P`*/. 2AMA0PO(H f@AAgj$kTSJ`$LRJ"KAkrA/B3XOrFPA0rGBnh'JJ'@F7^%xuC=9p`qA0^F"0xSJe*P. l*.POP JP$naXO:Apf)J@@U80.@'lrJRtr1x,z`^^l|jg$J"g ygY gngЀ Nfj`h$ 3*Eo2EH AP ` ElC0$JEgap"0RʵpE(f` p9@"E'06TA2A@A82(L4ŀv20 g:G "K0@C@ raF~@ԅr^~2`t Hz6J||CA14r0! 0J!8618z0FAR JDfB`^0Иfg:<`Egd 5A5E@5hB**@?J4 "0fXO <l̔1RBgBgHjBrB0tPO0rFIE46l8!=@rDn "`L`&DPO`B*?*(&$$4*"2@ֳOD5R6D8<:?.42XOԁij5F>lEprxrT $HB@ꩰj$TI`SLc.A\:f ,.Ja8 =@&6!r $XO0=$4P0h:`L0Bp"1<=@Z ZFdD~22fvGB|lBD` (/B "A" p9<4`XX0txed6ؐ / }.L6ӒCB:/JC2*P$f&Hr22XO`` P$_/ E@`T`AFj Zb:Z/HV/#4|tHrf,ZF<A|: B@rHn@~BfA\޴dDst`H0:gB" g>gs:5x0 S@lm 2\ g:f B2@ҡVh4g$_S XO Q?2bb r"zj&Ij(!lt`: K"gXP` 0|Ahn<|=rn|gf|,gh|g.|>p|Gg$n|Bgl4n`r|Hp |g `d8 MŔ M2B@B` A5R@0Lm :(g hQ&.`vPB5"M 0RCU`"gHCXH@05(jRAc#`(`"n 0<ΖvДB1 c !:#f"&0(Y" "lArphpJ 5~t~,2 bS&r 3`hp`b@l,~g@g:.~gh4źK e ||6RK@Jr% A(p"@ "~ A1B3!30"O"Nu/ Hz?<&NN\u/YOM,C Hza`%XOXO,H@B@H@ra&J@kNu.Vp`/Q:-O, I@@ XXOP@"Vx:zzV B~"VS@eQ,@8]O$@Ho&BCx%p JR@A2fж@HNB E>BA< <b;k`D1|<*f<(`&404 b Cp aR$W^ bQxAt8.f6@4`$>N >H>4><Lf T`hgrr@d p`C8jx0 pJ W0F@?@g 2SAktaSb (Q2/@4/(jt"@B: g@f 0Ao$@A@lp?B?D `h>1B(v`vCJBj4Cb6JAkCc8C\ K0@ކ0P` 0 Kap0Du6x0/@ @ JaAPg@ N g,, : !0L\E6` 4&H6g8K`JC JpNQA*gNX0 T~H PVJP0P~POJ.f2k?0 Pxa  20SP$J@g  A<`&0NuQVfW"d$Pd$P @g`NS@Q<&TNKBCBGx%BEQdg\Pf<gSJN:kT RGN g oRNSG` *N`"RGgc4RA0b|d_QvWҕSR `lDRRU[&2C 8\J 000@vJk(PPN$RG$aL> L."[0PaVJ hhhA h`` 2$`hzU`Rbȼ+fBXf .LELjJJdRE-Wg+f`T ^z"`t bbE$!J`&D2h<8zPnREJ4k| g@Jj$JDgJB&j``0SD**o ((*$B<806g(8JCjvJj@ "ZSCf` QC2s@^ 8BE$@$!j TF#< F4 Pg>X(  (CfBvB(V!H6H8x +Sg|2C'I&R UAe"S(kt d W`Y2FF@|LJ@f,gkg&B JNPu T`/ / B@JgB)g@fJ&Q(i ppe"// IP"_ _z&Q`B@"(_&ddD#H &HJfS#K, I(LB"L`:ҦS&gfJg^8`t,k x$d SfRe`.&//$"v,f4(S8**fJ& L\&"`&,A'JE#8 &lP\f"`"Pd (Lg*R g g/pDH Tkf"P`IJLj/fl XONu f4 n>"P z d6 ,Nu?Z _C2f 0( ZC!  `H&H66kl  gv`@(p\(H < a )ghNp\|gB9@{0`Q l,(6 C# Z LL\`p`p 03!4a V a!b@* YOCB g Шr`TH 0Xf0Rr/wB8r1Hw1a1rbTwa "r+ rb0 Iw w a a ADp`Ar $V/ TR HG46<6Gp+@F1"*J961g|8v&_q_TMP_XXX@./ &HD:4P.@8. 0+p"@@ kd B@7@0$95`Qv"c  Pª!2D L^"+ "JkRgFP @b,St gSj`"HSISSk ög@Jg&"'L@+x l@Pdp`Zl$6rg0DHt.zzZ"S"L Ip ~*| @> " 01"_@BkNgPAp jQ~$Rk*g,`0\1g3&CnB@$:6&Hp Cgp@CfFC0 ?<= NAЎk&8jaTp&F?A "BN@A& Jj.`Br߲fNAAVB3jGpc x&&AN%A\  "VNA\ |(lH```0xnQBg`? D@  _L`LJ&Hx&Sf2kpfxg gD6gJ e七dR@`JgSSKpPp  `Rp (pp0\`\6Xp`NxBz`Dx:6< fDaP"aB` p a<`0 Bx`\\\ .NAmT`@@@fXĀNu@2@?? ~)dSBg jX" -0p$`kxЁ"kr<$Ҁk8 $k0HzPcze/`2/  b `Јb'0<`///61N0,BC7V(BgP`0F6l*8~W*(&D@| ("b;aNu  !   ??B@CܐtJ1pB@B AC (g+fg"1b(A @8@D`#J@8ѰO4UEB"bB V fD@-CtH@B@H@&HC;0(R@BfQʣ@x _Z@!Z`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ Jg  JfSHg T f @TgHf8@U08(0U (  (U0P!epB|fA b<~U840,V($  "H !S Se gb Rf" f B`dgSf Av0*$HЌPД$GrtfJ3kSJt$"p <0f:!p b@(pf"`Nf&TD>$T.GBVd" &HCHCJCfԃd` & gSJ"ДԐ"dZ %2p$"`!"&Z "t!X&N'`$?&8BCHC06H@0"&RBJf8%`z"/%abcdefghijklmnopqrstuvwxyz@ PR6@Re:*/

r$vJ`4g*g"@ E"I j` $b#g/  gS.`L<0$C2 @c $@ f`p&@ gb*"Ҩeg  'z`p"@R". >g4" @4eg`(N"`" "Hf @"(.eb$ÒfQ xP` /= 2 4`Hf!!1``:"艁H?LxHU  `R8(2 p(H2 nx fvLx2|HgS@!!Q|@SA!Q ٙPS@xHxAx( UPx(2J< @h(Lnx # SAp` ,A(0jBABt0<  !"#$%&'()*+,-./wR:;<=>?@YuY[\]^_`yuy{|}~@r :88:644Z@! ' ,a2('0:/7%7  ;@$Nu$HBJBf$NuHB Ђ  $D BJT 8"8 $">D J"Jz4̀>$ PHB0@00@ AH@r2B@tЀӁd҈d FD/A//Ѥ&2N/JfB@J3pИ`TX <Ҋ&JB >G< q=w/Kd/ MXO$pN=M\x" HB @D/NMq $ NNW@,P ,<N NTAGBh2<aZ _0 r|<I$( o0L(1|!I!o@`1A"_A 00 r\m$@6r>\FrXk44hrNNZz l1Br'a@XIp"_2Nu. (GZ3^3C02~vNXL R r Pe0nA03B2pC@tRB2fBdr3/ 2dBi !

@ p[]{}()(:L^pς)4IBM 3.@3",p K  ;x  *d X8 ` `YDH PX\J#l0Uj @  V| 00 ^ 0$j(0P0 `%3 fAQ T08,  *쿕]bЬ0fdХ ^r"Jpfg@*z{ 8)) TF i @*0Jݠj?JȰN@JސZ0Jz@ AU5TX(!pCZ(ݰT(DZ@T(EZXU;V(FZXV(IZՠT(JZ@V(KZ݀DPLjDPMjUCFPNj0DFPOjH]E60PjH4Qjx]G6RjbSjPaTjvp2`j"bqV`x1p4Wz~tXz MvYz tZzPt[zhPv\zbt]zЮt^zSv_zt `zJdHUtFcHa:q `ԑ@X(ޕXYlҕpZp[{0\B]wАԊ^B@z_`bR  )֐\a.Zߒ. pb  xhx:j'ixjx%kpaʷ. l, إ Um-n ,woFp0wq*Hr`vs! x t u"ѱvp "+wJ?r& <xи.!mp0!z|w0}Ђ00~00%p^0%B$Ѿ` 2X\* B7Xz/L B ?H10;xB8ҘL5.2xK2xKxK2KxKxK6ݳKNA8+zۘ"2nژỘhۘhۘBߘhۘ"2ߘÐ`2Ð*p6`Ә5xRDӘ5]R\Ә56 l֘5NS:zfP<֘5~R+覰 QrJy{fc0'q8sK21b1o%sHfG8sbq sHw7s۬~uP~za!b ^$خq#BLAP#([C #E.oZCҶru!< Uc.o}0Z0#𰻛0(Q0(@kړHec^wZgSо%(cؿ00 0a\ 0V(sPeขXLR(%(cLȺrCH#RX)(sPHՒL jx!}xr4u8(ѲxҒӲ('Ԣvբ0֒0Hע`ؒ0x׳*R8]ے{ߒp@ 0HEȓ``+Af T%0R'80+wxH0hh&hh[hPh@hRV-|hPH ] 0H1`"B 14ts42EDIT.RS@C7Desk  FileOptionsBlock Sear ch#Print/Makros Info (--=23@566Load fm?Format di3 Exi"^@Qhow sizes8FParamkr)onfigjse editor.cfggtecuGEM[7T(OSp8Arguments?pAlways Vm.h?C yc BWindodw~Wafor key/$h ^k memor+ c" star^"-en$.^"Line b/pL/#BMo B*^F4ppy 3/#$k^F50 Hid T6? #)&?J%$&VShift le#lJrigh3+^K1>362}Replac'2SAgain86et 1)12)1*392?49)a4OF3GotojAlt-A:jA*j*A?j?i i"Q4B%h0c1CChe FGding b0k^B#E33!vRQ?^P(A_WS A:llel po3 ADon't DpZ1-8CTranslaQ t abR Help2-_T_Wc W`R Curs@Pa7QF`gAscii : $!XX`?=dd`|2Eolumn OkF6 :o|n_ X ofgfi ftva@r4h:\xA0 PS\d160 sr`RQfASCIIX .screenOt cwith CURSOR-UP,-DOWN,-LEFT,-RIGHT.Worp)SHIFTCONTROLp)so.UNDOinsera dr1dTPlP.6-BACKSPACEF8/9(HOME hoDmpthe.aT` CCLR-'hRETU=RN @7n2INSERTgglp mordh eps0EogpLMoreF` Stg/q/x////Ign Cas es$OnlyFrom 3px05>*100 0To!&Ca ncel"KW5n4S0G:y1yy2*yy3?yy4Tyy5iyy6~yy7AvailB:c5S@(+Re ve+ Gap)",1002*003?004Ti06~007AA:B:1"-sd280 tas4 @NlFastsSpi`G>"1.4Ab`OQ^Pair0o @`ck_b_Y_P_RRGd>FuC0O`sTh1is$TabM/S.i@ganVuHI8nde:lengP`/1pG%Pd wrapUiPlpepv{qs:+A a@`fqCsƒsheadeQP seco )fDQ<.EaеfollowUAtsoet~oR{reofRSsҳmay zt\x??b\d? heOxci `b c@cPcs.\ mWubn`2Х>\\Q뇥!v)hens.T?BLRm~3by~ooooooo`0c Multi purpOt/myVБGrothmannVer1.01,31.12.199jOkq r^Douclidef`.ALT-1-6-0#?s^X=^Q=Quit, ^C=BɞW=0Sf=0R=0Fd=q9G=.#SHbF10`,KEY+STR ING+!)&run #) :%7I[m!3EWi{/ ////A/S/e/w///////???+?=?O?a?s???????OOO'O9OKO]OoOOOOOOOO__#_5_G_Y_k_}_______o oo1oCoUogoyooooooo -?Qcu)9\*.MAKBTfxҏ,N`rޟ&8[1][%ld|d][Ok] E@Д[2]j[|.!?][Yes|OIro]w_Could nopen|...7%si+r+ +Bs|thaong! , %c Urcopy#elf!NoId!(y/n/ESC) <-- 3][ȿڿ"4FXj|ώϠϲG - G7 KMHPs t H8P2K4M6b a S r .-5 R,!"& +$ )% *&5-56708;<=>9@?@:A,BCD !"#$;5T%U&V(W'PZZ[Z\D]V1234@xy.z/{0 #HTBL"4FXj V+ieg1 mh$s sij!DUPF95y@0no|c]BXChang0xnalBI nameD_NMo(De@I|@{Ok|@GGed%BA.2^AsSor ry] `*Error onu0ectionQA O!2wh0avGcl'osP*heMMreadNNTc3fgPbR^n'!reneQ92a %d   `  1 %s 6'K3ld-%d-zs r Illegormat|inP{nfi]%dlS(:.5qPr"bcys cUna a\b%s.s+q?Ou`f me05$f!lear `TU#No|Lo ad ap(pL]:P0BGHpL$II>r  "( (2 "B0 T 2 n"  $"L 0 `R 0" |T  2 "  \v8 &(( "   5 0d9"&"       &  ( P ,0V (   =,"*X M W jD0  8(&N ;` &,-  @`1 , @& X ( "h$2Bl h<$n V 44.&@4,V twr """ ($, 0 , 0$lf<^n F   $ " "$"< 0^$",O@&4d0*4L4&  2P (&("F*H60 A,b$@$ `*"8"2"""` :$  "& 2 E @ $g0  :0*7  : 2>4""FDl(L0A  @B f8" 0 c A>  J 0 { | *. W&  R"*0!& $J"  <#7$< 0`< 4@`*  !&0P0(  D 1f0! 0/ +0~Z  62*p,< "6 >DbC Q, p!8&0-F F@{B d*14V0$07(@F0"~ 0 <0OT@ (K 5 &*$0B j,0] |AA\P( &@_T "   P_@"x@  &$ ,P@!@AO@|& 0 dZ "h& (>\H@Y,hV* ~p4R*:*< 6 "e0K @ j ,$ @ P> $4 .V);M_q  y} *********************************************** Program ten zostal sprowadzony do Polski przez Krata Soft z Krakowa w pazdzierniku 1993. Jesli chcesz miec najnowsze oprogramowanie na Atari ST,STE,TT,FALCON 030 to przyjdz do nas.Stoimy na gieldzie Elbud ul.Wadowicka 12 w Krakowie w kazda sobote i niedziele. Czesc! Krata Soft ############################################### * * | \___/ | | \ | | \ | \ /\ / * * \_____/ | \ \______ | \ \______ \/ \/ * * * * If you want to order the latest GAM- PROFSSIONAL- or * * MIDI software, or the latest SUPR NINTNDO games, or a * * Copier for the SS then just do the following thing... * * * * Send a 3" disk to the following address, and write * * down your name and address, you will get the latest * * lists and i*************************************** * ATARI ST/STE/MEGA STE/TT/FALCON * * * * - MIDI * * - MUZYCZNE * * - UZYTKI, DTP * * - GRAPHISC * * - GRY * * - DEMOSY, KODY ZRODLOWE * * i co ci na mysl przyjdzie * * prosto z Holandii * * * * KRATA & PASKUD * * Katowice sobota: Dom zwiazkow L1,L2 * * niedziela: Baildon 70,71 * * tel. (katowice) 87-94-32 * *************************************** *************************************** * ATARI ST/STE/MEGA STE/TT/FALCON * * * * - MIDI * * - MUZYCZNE * * - UZYTKI, DTP * * - GRAPHISC * * - GRY * * - DEMOSY, KODY ZRODLOWE * * i co ci na mysl przyjdzie * * prosto z Holandii * * * * KRATA & PASKUD * * Katowice sobota: Dom zwiazkow L1,L2 * * niedziela: Baildon 70,71 * * tel. (katowice) 87-94-32 * ***************************************