Subroutines are similar to mathematical functions (see Section 4.3), and once defined, can be used anywhere in algebraic expressions, just as functions can be. However, instead of being defined by a single algebraic expression, whenever a subroutine is evaluated, a block of Pyxplot commands of arbitrary length is executed. This gives much greater flexibility for implementing complex algorithms. Subroutines are defined using the following syntax:
subroutine <name>(<variable1>,...) { ... return <value> }
Where name is the name of the subroutine, variable1 is an argument taken by the subroutine, and the value passed to the return statement is the value returned to the caller. Once the return statement is reached, execution of the subroutine is terminated. The following two examples would produce entirely equivalent results:
f(x,y) = x*sin(y) subroutine f(x,y) { return x*sin(y) }
In either case, the function/subroutine could be evaluated by typing:
print f(1,pi/2)
If a subroutine ends without any value being returned using the return statement, then a value of zero is returned.
Subroutines may serve one of two purposes. In many cases they are used to implement complicated mathematical functions for which no simple algebraic expression may be given. Secondly, they may be used to repetitively execute a set of commands whenever they are required. In the latter case, the subroutine may not have a return value, but may merely be used as a mechanism for encapsulating a block of commands. In this case, the call command may be used to execute a subroutine, discarding any return value which it may produce, as in the example:
pyxplot> subroutine f(x,y) { print "%s - %s = %s"%(x,y,x-y) ; }
pyxplot> call f(2,1)
2 - 1 = 1
pyxplot> call f(5*unit(inch), 10*unit(mm))
127 mm - 10 mm = 117 mm
Newton fractals are formed by iterating the equation subject to the starting condition that If set numerics complex root1 = exp(i*unit( 0*deg)) tolerance = 1e-2 subroutine newtonFractal(x,y) # Plot Newton fractal
, where
is any complex number
and
is any mathematical function. This series is the Newton-Raphson method for numerically finding solutions to the equation
, and with time usually converges towards one such solution for well-behaved functions. The complex number
represents the initial guess at the position of the solution being sought. The Newton fractal is formed by asking which solution the iteration converges upon, as a function of the position of the initial guess
in the complex plane. In the case of the cubic polynomial
, which has three solutions, a map might be generated with points colored red, green or blue to represent convergence towards the three roots.
is close to one of the roots, then convergence towards that particular root is guaranteed, but further afield the map develops a fractal structure. In this example, we define a Pyxplot subroutine to produce such a map as a function of
, and then plot the resulting map using the colormap plot style (see Section 1.12). To make the fractal prettier – it contains, after all, only three colors as strictly defined – we vary the brightness of each point depending on how many iterations are required before the series ventures within a distance of
of any of the roots
.
set unit angle nodimensionless
root2 = exp(i*unit(120*deg))
root3 = exp(i*unit(240*deg))
{
global iter
z = x+i*y
iter = 0
while (1)
{
z = z - (z**3-1)/(3*z**2)
if abs(z-root1)tolerance { ; return 1 ; }
if abs(z-root2)tolerance { ; return 2 ; }
if abs(z-root3)tolerance { ; return 3 ; }
iter = iter + 1
}
}
set size square
set key below
set xrange [-1.5:1.5]
set yrange [-1.5:1.5]
set sample grid 250x250
set colmap hsb(c1*0.667,0.8+0.2*c2,1.0-0.8*c2)
set nocolkey
set log c2
plot newtonFractal(x,y):iter+2 with colormap