Chapter 13. User-defined functions
100
function myfunc delete
function get_uhat clear
Note, however, thatifmyfunc isalready a definedfunction,providinga newdefinition automatically
overwrites the previous one, so it should rarely be necessary to delete functions explicitly.
13.4 Function programming details
Variables versus pointers
Series, scalar, matrix, bundle, as well as array arguments to functions can be passed in two ways:
“as they are”, or as pointers. For example, consider the following:
function series triple1(series x)
return 3*x
end function
function series triple2(series *x)
return 3*x
end function
These two functions are nearly identical (and yield the same result); the only difference is that you
need to feed a series into triple1, as in triple1(myseries), while triple2 must be supplied a
pointer to a series, as in triple2(&myseries).
Why make the distinction? There are two main reasons for doing so: modularity and performance.
By modularity we mean the insulation of a function from the rest of the script which calls it. One of
the many benefits of this approach is that your functions are easily reusable in other contexts. To
achieve modularity, variables created within a function are local tothat function, and are destroyed
when thefunction exits, unlessthey aremade available asreturn values andthese values are “picked
up” or assigned by the caller.
In addition, functions do not have access to variables in “outer scope” (that is, variables that exist
in the script from which the function is called) except insofar as these are explicitly passed to the
function as arguments.
By default, when a variable is passedto a function as an argument, what thefunction actually “gets”
is a copy of the outer variable, which means that the value of the outer variable is not modified by
anything that goes on inside the function. But the use of pointers allows a function and its caller
to cooperate such that an outer variable can be modified by the function. In effect, this allows a
function to “return” more than one value (although only one variable can be returned directly—see
below). The parameter in question is marked with a prefix of * in the function definition, and the
corresponding argument is marked with the complementary prefix & in the caller. For example,
function series get_uhat_and_ess(series y, list xvars, scalar *ess)
ols y 0 xvars --quiet
ess = $ess
series uh = $uhat
return uh
end function
# main script
open data4-1
list xlist = 2 3 4
# function call
scalar SSR
series resid = get_uhat_and_ess(price, xlist, &SSR)
In the above, we may say that the function is given the address of the scalar variable SSR, and it
assigns a value to that variable (under the local name ess). (For anyone used to programming in C:
Converting pdf to powerpoint online - Library SDK component:C# Create PDF from PowerPoint Library to convert pptx, ppt to PDF in C#.net, ASP.NET MVC, WinForms, WPF
Online C# Tutorial for Creating PDF from Microsoft PowerPoint Presentation
www.rasteredge.com
Converting pdf to powerpoint online - Library SDK component:VB.NET Create PDF from PowerPoint Library to convert pptx, ppt to PDF in vb.net, ASP.NET MVC, WinForms, WPF
VB.NET Tutorial for Export PDF file from Microsoft Office PowerPoint
www.rasteredge.com
Chapter 13. User-defined functions
101
note that it is not necessary, or even possible, to “dereference” the variable in question within the
function using the * operator. Unadorned use of the name of the variable is sufficient to access the
variable in outer scope.)
An “address” parameter of this sort can be used as a means of offering optional information to the
caller. (That is, the corresponding argument is not strictly needed, but will be used if present). In
that case the parameter shouldbe given a default value ofnull and the the function shouldtest to
see if the caller supplied a corresponding argument or not, using the built-in function isnull().
For example, here is the simple function shown above, modified to make the filling out of the ess
value optional.
function series get_uhat_and_ess(series y, list xvars, scalar *ess[null])
ols y 0 xvars --quiet
if !isnull(ess)
ess = $ess
endif
return $uhat
end function
If the caller does not care to get the ess value, it can use null in place of a real argument:
series resid = get_uhat_and_ess(price, xlist, null)
Alternatively, trailing function arguments that have default valuesmay be omitted, so the following
would also be a valid call:
series resid = get_uhat_and_ess(price, xlist)
Pointer argumentsmay also beuseful for optimizingperformance: even ifa variable isnot modified
inside the function, it may be a good idea to pass it as a pointer if it occupies a lot of memory.
Otherwise, the time gretl spends transcribing the value of the variable to the local copy may be
non-negligible, compared to the time the function spends doing the job it was written for.
Example13.1 takes this to the extreme. We define two functions which return the number of rows
of a matrix (a pretty fast operation). Function a() gets a matrix as argument; function b() gets a
pointer to a matrix. The functions are evaluated 500 times on a matrix with 2000 rows and 2000
columns; on a typical system floating-point numbers take 8 bytes of memory, so the total size of
the matrix is roughly 32 megabytes.
Running the code in example13.1 will produce output similar to the following (the actual numbers
of course depend on the machine you’re using):
Elapsed time:
a: without pointers (copy) = 3.3274 seconds,
b: with pointers (no copy) = 0.00463796 seconds,
Ifa pointer argument is used for thissort ofpurpose—andthe object to which the pointer pointsis
not modified(is treatedas read-only) by the function—one can signal thisto the user by adding the
const qualifier, as shown for function b() in Example13.1. When a pointer argument is qualified
in this way, any attempt to modify the object within the function will generate an error.
However, combining the const flag with the pointer mechanism is technically redundant for the
following reason: if you mark a matrix argument as const then gretl will in fact pass it in pointer
mode internally (since it can’t be modified within the function there’s no downside to simply mak-
ing it available to the function ratherthan copying it). So in the Example we couldgive the signature
of the b() function as simply
function scalar b(const matrix X)
Library SDK component:Online Convert PowerPoint to PDF file. Best free online export
Then just wait until the conversion from Powerpoint to PDF is complete and download the file Creating a PDF from PPTX/PPT has never been so easy Easy converting!
www.rasteredge.com
Library SDK component:C# powerpoint - PowerPoint Conversion & Rendering in C#.NET
This PowerPoint document converting library component offers reliable C#.NET PowerPoint document rendering APIs for developers PowerPoint to PDF Conversion.
www.rasteredge.com
Chapter 13. User-defined functions
102
Example 13.1: Performancecomparison: values versus pointer
function scalar a(matrix X)
return rows(X)
end function
function scalar b(const matrix *X)
return rows(X)
end function
set echo off
set messages off
X = zeros(2000,2000)
scalar r
set stopwatch
loop 500
r = a(X)
endloop
fa = $stopwatch
set stopwatch
loop 500
r = b(&X)
endloop
fb = $stopwatch
printf "Elapsed time:\n\
\ta: without pointers (copy) = %g seconds,\n \
\tb: with pointers (no copy) = %g seconds,\n", fa, fb
Library SDK component:VB.NET PDF- HTML5 PDF Viewer for VB.NET Project
NET Word, VB.NET Excel, VB.NET PowerPoint, VB.NET VB.NET PDF- HTML5 PDF Viewer for VB.NET Online Guide for Viewing, Annotating And Converting PDF Document with
www.rasteredge.com
Library SDK component:C# powerpoint - Convert PowerPoint to PDF in C#.NET
C# PowerPoint - Convert PowerPoint to PDF in C#.NET. Online C# Tutorial for Converting PowerPoint to PDF (.pdf) Document. PowerPoint to PDF Conversion Overview.
www.rasteredge.com
Chapter 13. User-defined functions
103
and call it via r = b(X), for the same speed-up relative to function a(). Nonetheless, the version
of b() shown in the example has the virtue of making clearer what is going on.
One limitation on the use of pointer-type arguments should be noted: you cannot supply a given
variable as a pointer argument more than once in any given function call. For example, suppose we
have a function that takes two matrix-pointer arguments,
function scalar pointfunc (matrix *a, matrix *b)
And suppose we have two matrices, x and y, at the caller level. The call
pointfunc(&x, &y)
is OK, but the call
pointfunc(&x, &x) # will not work
will generate an error. That’sbecausethe situation inside the function wouldbecometoo confusing,
with what is really the same object existing under two names.
List arguments
The use of a named list as an argument to a function gives a means of supplying a function with
aset of variables whose number is unknown when the function is written—for example, sets of
regressors or instruments. Within the function, the list can be passed on to commands such as
ols.
Alist argument can also be “unpacked” using a foreach loop construct, but this requires some
care. For example, suppose you have a list X and want to calculate the standard deviation of each
variable in the list. You can do:
loop foreach i X
scalar sd_$i = sd(X.$i)
endloop
Please note: a special piece of syntax is needed in this context. If we wanted to perform the above
task on a list in a regular script (not inside a function), we could do
loop foreach i X
scalar sd_$i = sd($i)
endloop
where $i gets the name of the variable at position i in the list, and sd($i) gets its standard
deviation. But inside a function, working on a list supplied as an argument, if we want to reference
an individual variable in the list we must use the syntax listname.varname. Hence in the example
above we write sd(X.$i).
Thisis necessary toavoidpossible collisions between the name-spaceofthe function andthe name-
space of the caller script. For example, suppose we have a function that takes a list argument, and
that defines a local variable called y. Now suppose that this function is passed a list containing
avariable named y. If the two name-spaces were not separated either we’d get an error, or the
external variable y would be silently over-written by the local one. It is important, therefore, that
list-argument variables should not be “visible” by name within functions. To “get hold of” such
variables you need to use the form of identification just mentioned: the name of the list, followed
by a dot, followedby the name of the variable.
Constancy of list arguments When a named list of variables is passed to a function, the function
is actually provided with a copy of the list. The function may modify thiscopy (for instance, adding
or removing members), but the original list at the level ofthe caller is not modified.
Library SDK component:VB.NET PDF Converter Library SDK to convert PDF to other file
This guide give a series of demo code directly for converting MicroSoft Office Word, Excel and PowerPoint document to PDF file in VB.NET application.
www.rasteredge.com
Library SDK component:VB.NET PowerPoint: Complete PowerPoint Document Conversion in VB.
Converting PowerPoint document to PDF file can be quite simple provided that this VB.NET PowerPoint Converting SDK is correctly installed and utilized.
www.rasteredge.com
Chapter 13. User-defined functions
104
Optional list arguments If a list argument to a function is optional, this should be indicated by
appending a default value of null, as in
function scalar myfunc (scalar y, list X[null])
In that case, if the caller gives null as the list argument (or simply omits the last argument) the
named list X inside the function will be empty. This possibility can be detected using the nelem()
function, which returns 0 for an empty list.
String arguments
String arguments can be used, for example, to provide flexibility in the naming of variables created
within a function. In the following example the function mavg returns a list containing two moving
averages constructed from an input series, with the names of the newly createdvariables governed
by the string argument.
function list mavg (series y, string vname)
list retlist = null
string newname = sprintf("%s_2", vname)
retlist += genseries(newname, (y+y(-1)) / 2)
newname = sprintf("%s_4", vname)
retlist += genseries(newname, (y+y(-1)+y(-2)+y(-3)) / 4)
return retlist
end function
open data9-9
list malist = mavg(nocars, "nocars")
print malist --byobs
The last line of the script will print two variables named nocars_2 and nocars_4. For details on
the handling of named strings, see chapter14.
If a string argument is considered optional, it may be given a null default value, as in
function scalar foo (series y, string vname[null])
Retrieving the names of arguments
The variables given as arguments to a function are known inside the function by the names of the
corresponding parameters. For example, within the function whose signature is
function void somefun (series y)
we have the series known as y. It may be useful, however, to be able to determine the names of
the variables provided as arguments. This can be done using the function argname, which takes
the name of a function parameter as its single argument and returns a string. Here is a simple
illustration:
function void namefun (series y)
printf "the series given as ’y’ was named %s\n", argname(y)
end function
open data9-7
namefun(QNC)
This produces the output
the series given as ’y’ was named QNC
Library SDK component:C# PDF Convert to Word SDK: Convert PDF to Word library in C#.net
Word in C#.NET. Online C#.NET Tutorial for Converting PDF to Word (.doc/ .docx) Document with .NET XDoc.PDF Library in C#.NET Class.
www.rasteredge.com
Library SDK component:VB.NET PDF - Convert PDF Online with VB.NET HTML5 PDF Viewer
Word, VB.NET Excel, VB.NET PowerPoint, VB.NET control as well as a powerful online PDF converter. file formats with high quality, support converting PDF to PNG
www.rasteredge.com
Chapter 13. User-defined functions
105
Please note that this will not always work: the arguments given to functions may be anonymous
variables, created on the fly, as in somefun(log(QNC)) or somefun(CPI/100). In that case the
argname function returns an empty string. Function writers who wish to make use of this facility
should check the return from argname using the strlen() function: if this returns 0, no name was
found.
Return values
Functions can return nothing (just printing a result,perhaps), or they can return a single variable—
ascalar, series, list, matrix,string, or bundle (see section10.7). The return value, ifany, is specified
via a statement within thefunction body beginningwith the keywordreturn, followedby either the
name ofa variable (which must be ofthe type announcedon the first line of the function definition)
or an expression which produces a value of the correct type.
Having a function return a list or bundle is a way of permitting the “return” of more than one
variable. For example, you can define several series inside a function and package them as a list;
in this case they are not destroyed when the function exits. Here is a simple example, which also
illustrates the possibility of setting the descriptive labels for variables generatedin a function.
function list make_cubes (list xlist)
list cubes = null
loop foreach i xlist --quiet
series $i3 = (xlist.$i)^3
setinfo $i3 -d "cube of $i"
list cubes += $i3
endloop
return cubes
end function
open data4-1
list xlist = price sqft
list cubelist = make_cubes(xlist)
print xlist cubelist --byobs
labels
Areturn statement causes the function to return (exit) at the point where it appears within the
body of the function. A function may also exit when (a) the end of the function code is reached (in
the case of a function with no return value), (b) a gretl error occurs, or (c) a funcerr statement is
reached.
The funcerr keyword—which may be followed by a string enclosed in double quotes, or the name
of a string variable, or nothing—causes a function to exit with an error flagged. If a string is
provided (either literally or via a variable), thisis printed on exit, otherwise a generic error message
is printed. This mechanism enables the author of a function to pre-empt an ordinary execution
error and/or offer a more specific and helpful error message. For example,
if nelem(xlist) = 0
funcerr "xlist must not be empty"
endif
Afunction may contain more than one return statement, as in
function scalar multi (bool s)
if s
return 1000
else
return 10
endif
end function
Library SDK component:C# PDF Convert to Jpeg SDK: Convert PDF to JPEG images in C#.net
Turn multiple pages PDF into single jpg files respectively online. Support of converting from any single one PDF page and multiple pages.
www.rasteredge.com
Chapter 13. User-defined functions
106
However, it is recommended programming practice to have a single return point from a function
unless this is very inconvenient. The simple example above would be better written as
function scalar multi (bool s)
return s ? 1000 : 10
end function
Error checking
When gretl first reads and “compiles” a function definition there is minimal error-checking: the
only checks are that the function name is acceptable, and, so far as the body is concerned, that you
are not trying to define a function inside a function (see Section13.1). Otherwise, if the function
body contains invalid commands this will become apparent only when the function is called and
its commands are executed.
Debugging
The usual mechanism whereby gretl echoes commandsandreportson the creation of new variables
is by default suppressed when a function is being executed. Ifyou want more verbose output from
aparticular function you can use either or both ofthe following commands within the function:
set echo on
set messages on
Alternatively, you can achieve this effect for all functions via the command set debug 1. Usually
when you set the value of a state variable using the set command, the effect applies only to the
current level of function execution. For instance, if you do set messages on within function f1,
which in turn calls function f2, then messages will be printedfor f1 but not f2. The debug variable,
however, acts globally; all functions become verbose regardless of their level.
Further, you can do set debug 2: in addition to command echo andthe printing of messages, this
is equivalent to setting max_verbose (which produces verbose output from the BFGS maximizer) at
all levels of function execution.
13.5 Function packages
Since gretl 1.6.0 there has been a mechanism to package functions and make them available to
other users of gretl.
Creating a package viathe command line
The mechanism described above, for creating function packages using the GUI, is likely to be con-
venient for small to medium-sized packages but may be too cumbersome for ambitious packages
that include a large hierarchy of private functions. To facilitate the building of such packages gretl
offers the makepkg command.
To use makepkg you create three files: a driver script that loads all the functions you want to pack-
age and invokes makepkg; a small, plain-text specification file that contains the required package
details (author, version, etc.); and (in the simplest case) a plain text help file. You run the driver
script andgretl writes the package (.gfn) file.
We first illustrate with a simple notional package. We have a gretl script file named foo.inp that
contains a function, foo, that we want to package. Our driver script would then look like this
include foo.inp
makepkg foo.gfn
Chapter 13. User-defined functions
107
Note that the makepkg command takes one argument, the name of the package file to be created.
The package specification file should have the same basename but the extension .spec. In this case
gretl will therefore look for foo.spec. It should look something like this:
# foo.spec
author = A. U. Thor
version = 1.0
date = 2011-02-01
description = Does something with time series
public = foo
help = foohelp.txt
sample-script = example.inp
min-version = 1.9.3
data-requirement = needs-time-series-data
As you can see, the format of each line in this file is key = value, with two qualifications: blank
lines are permitted (and ignored, as are comment lines that start with #).
All the fieldsincludedin the above example are required,with the exception of data-requirement,
though the order in which they appear is immaterial. Here’s a run-down of the basic fields:
 author: the name(s) of the author(s). Accented or other non-ASCII characters should be given
as UTF-8.
 version: the version number of the package, which should be limited to two integers sepa-
rated by a period.
 date: the release date ofthe current verson ofthe package,in ISO 8601 format: YYYY-MM-DD.
 description: a brief description of the functionality offered by the package. This will be
displayed in the GUI function packages window so it should be just one short line.
 public: the listing of public functions.
 help: the name of a plain text (UTF-8) file containing help; all packages must provide help.
 sample-script: the name of a sample script that illustrates use of the package; all packages
must supply a sample script.
 min-version: the minimum version of gretl required for the package to work correctly. If
you’re unsure about this, the conservative thing is to give the current gretl version.
The public fieldindicateswhich function orfunctions are to be made directly available to users(as
opposedto private “helper” functions). In the example above there is just one public function. Note
that any functions in memory when makepkg is invoked, other than those designatedas public, are
assumed to be private functions that should also be included in the package. That is, the list of
private functions (if any) is implicit.
The data-requirement field shouldbe specified if the package requires time-series or panel data,
or alternatively ifno dataset is required. If the data-requirement field isomitted, the assumption
is that the package needs a dataset in place, but it doesn’t matter what kind; if the packaged
functions do not use any series or lists this requirement can be explicitly relaxed. Valid values for
this fieldare:
needs-time-series-data
(any time-series data OK)
needs-qm-data
(must be quarterly or monthly)
needs-panel-data
(must be a panel)
no-data-ok
(no dataset is needed)
Chapter 13. User-defined functions
108
For a more complex example, let’s look at the gig (GARCH-in-gretl) package. The driver script for
building gig looks something like this:
set echo off
set messages off
include gig_mle.inp
include gig_setup.inp
include gig_estimate.inp
include gig_printout.inp
include gig_plot.inp
makepkg gig.gfn
In this case the functions to be packaged (of which there are many) are distributed across several
script files, each of which is the target of an include command. The set commands at the top are
included to cut down on the verbosity ofthe output.
The content of gig.spec is as follows:
author = Riccardo "Jack" Lucchetti and Stefano Balietti
version = 2.0
date = 2010-12-21
description = An assortment of univariate GARCH models
public = GUI_gig \
gig_setup gig_set_dist gig_set_pq gig_set_vQR \
gig_print gig_estimate \
gig_plot gig_dplot \
gig_bundle_print GUI_gig_plot
gui-main = GUI_gig
bundle-print = gig_bundle_print
bundle-plot = GUI_gig_plot
help = gig.pdf
sample-script = examples/example1.inp
min-version = 1.9.3
data-requirement = needs-time-series-data
Note that backslash continuation can be used for the elements of the public function listing.
In addition to the fields shown in the simple example above, gig.spec includes three optional
fields: gui-main, bundle-print and bundle-plot. These keywords are used to designate certain
functionsas playinga special role in the gretl graphical interface. A function picked out in this way
must be in the public list and must satisfy certain further requirements.
 gui-main: this specifies a function as the one which will be presented automatically to GUI
users (instead of users’ being faced with a choice of interfaces). This makes sense only for
packages that have multiple public functions. In addition,the gui-main function must return
abundle (see section10.7).
 bundle-print: thispicks out a function that should be used to print the contents of a bundle
returned by the gui-main function. It must take a pointer-to-bundle as its first argument.
The second argument, if present, shouldbe an int switch,with two or more valid values, that
controls the printing in some way. Any further arguments must have default values specified
so that they can be omitted.
 bundle-plot: selects a function for the role of producing a plot or graph based on the con-
tents of a returned bundle. The requirements on this function are as for bundle-print.
The “GUIspecial” tagssupport a user-friendly mode ofoperation. On a successful call to gui-main,
gretl opens a windowdisplaying the contentsofthe returnedbundle (formattedvia bundle-print).
Chapter 13. User-defined functions
109
Menus in this window give the user the option of saving the entire bundle (in which case it’s rep-
resented as an icon in the “icon view” window) or of extracting specific elements from the bundle
(series or matrices, for example).
If the package has a bundle-plot function, the bundle window also has a Graph menu. In gig, for
example, the bundle-plot function has this signature:
function void GUI_gig_plot(bundle *model, int ptype[0:1:0] \
"Plot type" {"Time series", "Density"})
The ptype switch is used to choose between a time-series plot of the residual and its conditional
variance, and a kernel density plot of the innovation against the theoretical distribution it is sup-
posed tofollow. The use ofthe value-labelsTime series andDensity means that the Graph menu
will display these two choices.
One other feature of the gig spec file is noteworthy: the help field specifies gig.pdf, documenta-
tion in PDF format. Unlike plain-text help, this cannot be rolled into the gfn (XML) file produced
by the makepkg command; rather, both gig.gfn and gig.pdf are packaged into a zip archive for
distribution. This represents a form of package which is new in gretl 1.9.4. More details will be
made available before long.
13.6 Memo: updating old-style functions
As mentioned at the start of this chapter, different rules were in force for defining functions prior
to gretl 1.8.4. It is straightforward to convert an old function to the new style. The only thing that
must be changed is the declaration of the function’s return type. Previously this was placed inline
in the return statement, whereas now it is placed right after the function keyword. For example:
# old style
function triple (series x)
y = 3*x
# note the "series" below: don’t do that any more!
return series y
end function
# new style
function series triple (series x)
y = 3*x
return y
end function
Note that if a function has no return value the keyword void must be used:
function void hello (string name)
printf "Hello from %s\n", name
end function
Note also that the role of the return statement has changed (and itsuse hasbecome more flexible):
 The return statement now causes the function to return directly, and you can have more
than one such statement, wrapped in conditionals. Before there could only be one return
statement, and its role was just to specify the type available for assignment by the caller.
 The final element in the return statement can now be an expression that evaluates to a value
of the advertised return type; before, it had to be the name of a pre-defined variable.
Documents you may be interested
Documents you may be interested