$$ \renewcommand{\vec}[1]{\mathbf{#1}} $$

Reference

This chapter contains the reference sheet for wasora version 0.3.96 automatically generated from specially-marked comments in the source code. Please bookmark this page for future reference.

Keywords

This section lists all the primary keywords that wasora understands in the input file, along with the secondary keywords and the arguments that may be passed. Throughout the section, the following typographic convention is used:

construction description
KEYWORD a keyword that is recognized by wasora (case insensitive)
identifier a generic identifier
var a variable identifier
vector a vector identifier
matrix a matrix identifier
function a function identifier
file a file identifier
filepath a file path
expr an algebraic expression that may involve any valid object
num_expr an algebraic expression that may involve only constants and NUMBER s
string a text string
printf_format a C printf-like format string expecting a floating point argument (i.e. %g)
[ xxx ] the construction xxx is optional and may or may not be given
{ xxx | yyy } either xxx or yyy

A primary keyword must start a new line. Leading blanks are allowed. Keywords are case insensitive, they are shown here capitalized because of style. Identifiers are case sensitive. Algebraic expressions work as expected, i.e. basic operators are +, -, * and /. The exponentiation operator is ^ and brackets ( & ) change operator hierarchies as usual:

# expressions can contain variables and functions, whose
# arguments may be expressions themselves, and so on
c = (1 + sin(pi/4)^(5/2))/(1 - log(abs(a-b)))

Logical operators <, >, | (or) and & (and) can be used. The equal sign = is an operator within an algebraic expression. Keep in mind that they operate on floating point arithmetic:

a = 1
b = 2
IF (a+eps)<1&(b+eps)>1
 PRINT "both a and b are less than one"
ENDIF

Comments start with a hash # and last until the end of the line. If an argument to a keyword needs to include a space, double quotes should be used. The following snippets illustrates the behavior of wasora's parser:

# this file shows some particularities about the wasora parser

# there are primary and secondary keywords, in this case
# PRINT is the primary keyword and TEXT is the secondary, which
# takes a single token as an argument, in this case the word hello
PRINT TEXT hello

# if the text to be printed contains a space, double quotes should be used:
PRINT TEXT "hello world"
# if the text to be printed contains quotes, they should be escaped:
PRINT TEXT "hello \"world\""

# it does not matter if the argument is a string or an expression, whenever
# a certain argument is expected, either spaces are to be remove or
# the arguments should be enclosed in double quotes:
PRINT 1 + 1
PRINT "1 + 1"
PRINT 1+1

# to insert comments, the hash `#` character is used
PRINT sqrt(2)/2     # comments may appear in the same line as a keyword

# in case a hash character is expected to appear literally in an argument
# it should be escaped to prevent wasora to ignore the rest of the line:
PRINT TEXT "\# this is a commented output line"  # this is a wasora comment 

# secondary keywords and/or arguments can be given in different lines either by
# a. using a continuation marker composed of a single backslash:
PRINT sqrt(2)/2 \
      sin(pi/4) \
      cos(pi/4)
# b. enclosing the lines within brackets `{` and `}`
PRINT sqrt(2)/2 \ {
      sin(pi/4) \
      # comments may appear inside brackets (but not within continued lines)
      cos(pi/4) }

# arguments may be given in the command line after the input file
# they are referred to as $1, $2, etc. and are literally used
# i.e. they can appear as arguments or even keywords
# if a $n expressions appears in the input file but less than n
# arguments were provided, wasora complains
# this behavior can be avoided by giving a default value:
DEFAULT_ARGUMENT_VALUE 1 world
DEFAULT_ARGUMENT_VALUE 2 2

PRINT TEXT "hello $1"
PRINT sqrt($2)/$2

# try executing this input as
# $ wasora parser.was WORLD
# $ wasora parser.was WORLD 3

# if a literal dollar sign is to part of an argument, quote it with a backslash:
PRINT TEXT "argument \$1 is $1"

The rest of the section contains all the keywords that wasora understands.

=

Usage

<var>[ [<expr_tmin>, <expr_tmax>] | @<expr_t> ] = <expr> <vector>(<expr_i>)[<expr_i_min, expr_i_max>] [ [<expr_tmin>, <expr_tmax>] | @<expr_t> ] = <expr> <matrix>(<expr_i>,<expr_j>)[<expr_i_min, expr_i_max; expr_j_min, expr_j_max>] [ [<expr_tmin>, <expr_tmax>] | @<expr_t> ] = <expr>

.=

Usage

{ 0[(i[,j]][<imin:imax[;jmin:jmax]>] | <expr1> } .= <expr2>

ABORT

Catastrophically abort the execution and quit wasora.

Usage

ABORT

Whenever the instruction ABORT is executed, wasora quits without closing files or unlocking shared memory objects. The objective of this instruction is, as illustrated in the examples, either to debug complex input files and check the values of certain variables or to conditionally abort the execution using IF clauses.

Example #1, abort1.was

# a complex problem definition
# [...]
# 

NUMBER nrefl1  4
NUMBER nrefl2  24
NUMBER nz      30
VECTOR deltaz SIZE nz

deltaz(i)<1:nrefl1-1> = 48.2/(nrefl1-1)
deltaz(i)<nrefl1:nrefl2> = 530.7/(nrefl2-nrefl1+1)
deltaz(i)<nrefl2+1:nz> = 34.4/(nz-nrefl2)

# check if we built the deltaz vector correctly
PRINT_VECTOR i deltaz
ABORT

# more complex problem definitions follow
# [...]
# 

Example #2, abort2.was

PHASE_SPACE n c
VAR rho

beta = 550e-5
Lambda = 5e-4
lambda = 0.15

n_0 = 1
c_0 = beta/(lambda*Lambda)

SEMAPHORE rho_ready WAIT
READ SHM_OBJECT rho_shm rho

n_dot .= (rho - beta)/Lambda * n + lambda*c
c_dot .= beta/Lambda * n - lambda*c

WRITE SHM_OBJECT pow_shm n
SEMAPHORE pow_ready POST

PRINT t n rho c

# if power is greater than 150% quit
IF n>1.5
 PRINT TEXT "unacceptable power"
 ABORT
ENDIF

ALIAS

Defines a scalar alias of an already-defined indentifier.

Usage

ALIAS <name> <identifier>

CALL

Executes a previously dynamically-loaded user-provided routine.

Usage

CALL <name> [ expr_1 expr_2 ... expr_n ]

CLOSE

Usage

CLOSE

CONST

Marks a scalar variable, vector or matrix as a constant.

Usage

CONST name_1 [ <name_2> ] ... [ <name_n> ]

DEFAULT_ARGUMENT_VALUE

Give a default value for an optional commandline argument.

Usage

DEFAULT_ARGUMENT_VALUE <num_expr> <string>

If a $n construction is found in the input file but the commandline argument was not given, the default behavior is to fail complaining that an extra argument has to be given in the commandline. With this keyword, a default value can be assigned if no argument is given, thus avoiding the failure and making the argument optional.

DIFFERENTIAL

Usage

DIFFERENTIAL { <vars> | <vectors> | <matrices> }

FILE

Defines a file, either as input or as output, for further reference.

Usage

< FILE | OUTPUT_FILE | INPUT_FILE > <name> <printf_format> [ expr_1 expr_2 ... expr_n ] [ INPUT | OUTPUT | MODE <fopen_mode> ] [ OPEN | DO_NOT_OPEN ]

FIT

Usage

FIT <function_to_be_fitted> TO <function_with_data> VIA <var_1> <var_2> ... <var_n> [ GRADIENT <expr_1> <expr_2> ... <expr_n> ] [ RANGE_MIN <expr_1> <expr_2> ... <expr_n> ] [ RANGE_MAX <expr_1> <expr_2> ... <expr_n> ] [ DELTAEPSREL <expr> ] [ DELTAEPSABS <expr> ] [ MAX_ITER <expr> ] [ VERBOSE ] [ RERUN | DO_NOT_RERUN ]

FUNCTION

Defines a function of one or more variables.

Usage

FUNCTION <name>(<var_1>[,var2,...,var_n]) { [ = <expr> ] | [ FILE_PATH <file_path> ] | [ ROUTINE <name> ] | [ VECTOR_DATA <vector_1> <vector_2> ... <vector_n> <vector_n+1> ] } [COLUMNS <num_expr_1> <num_expr_2> ... <num_expr_n> <num_expr_n+1> ] [ INTERPOLATION_THRESHOLD <expr> ] [ INTERPOLATION { linear | polynomial | spline | spline_periodic | akima | akima_periodic | nearest | rectangle } ] [ DATA <num_expr_1> <num_expr_2> ... <num_expr_N> ]

HISTORY

Record the time history of a variable as a function of time.

Usage

HISTORY <variable> <function>

IF

Begins a conditional block.

Usage

IF expr
<block_of_instructions_if_expr_is_true>
[ ELSE ]
[block_of_instructions_if_expr_is_false]
ENDIF

IMPLICIT

Defines whether implicit declaration of variables is allowed or not.

Usage

IMPLICIT { NONE | ALLOWED }

By default, wasora allows variables (but not vectors nor matrices) to be implicitly declared. To avoid introducing errors due to typos, explicit declaration of variables can be forced by giving IMPLICIT NONE. Whether implicit declaration is allowed or explicit declaration is required depends on the last IMPLICIT keyword given, which by default is ALLOWED.

Example #1, implicit.was

# implicit declaration is allowed by default
a = 1

# from now on, explicit declaration is needed
IMPLICIT NONE
VAR b
b = 2

# we now go back to implicit declarations
IMPLICIT ALLOWED
c = 3

PRINT %g a b c

INCLUDE

Include another wasora input file.

Usage

INCLUDE <file_path> [ FROM <num_expr> ] [ TO <num_expr> ]

Includes the input file located in the string file_path at the current location. The effect is the same as copying and pasting the contents of the included file at the location of the INCLUDE keyword. The path can be relative or absolute. Note, however, that when including files inside IF blocks that instructions are conditionally-executed but all definitions (such as NUMBERS) are processed at parse-time independently from the evaluation of the conditional. The optional FROM and TO keywords can be used to include only portions of a file.

Example #1, include1.was

VAR a
# the input file compute.was should compute 
# the value of variable a
INCLUDE compute.was
PRINT a

Example #2, included2.was

# this file is included2.was
b = 1
PRINT "a is greater than a certain threshold"

Example #3, include2.was

a = 0.2

IF a>0.5
 INCLUDE included2.was
ENDIF

# although b is set to one only if a>0.5, it is properly defined
# and can be used in a PRINT because the definitions are not
# influenced by conditional blocks
PRINT %g b

Example #4, include3.was

# include a file that depends on the commandline argument
VAR a
INCLUDE case-$1.was
PRINT TEXT "result for case $1:" a

INITIAL_CONDITIONS_MODE

Defines how initial conditions of DAE problems are computed.

Usage

INITIAL_CONDITIONS_MODE { AS_PROVIDED | FROM_VARIABLES | FROM_DERIVATIVES }

In DAE problems, initial conditions may be either:

  • equal to the provided expressions (AS_PROVIDED)
  • the derivatives computed from the provided phase-space variables (FROM_VARIABLES)
  • the phase-space variables computed from the provided derivatives (FROM_DERIVATIVES)
In the first case, it is up to the user to fulfill the DAE system at \( t = 0 \). If the residuals are not small enough, a convergence error will occur. The FROM_VARIABLES option means calling IDA's IDACalcIC routine with the parameter IDA_YA_YDP_INIT. The FROM_DERIVATIVES option means calling IDA's IDACalcIC routine with the parameter IDA_Y_INIT. Wasora should be able to automatically detect which variables in phase-space are differential and which are purely algebraic. However, the DIFFERENTIAL keyword may be used to explicitly define them. See the SUNDIALS documentation for further information.

LOAD_PLUGIN

Loads a wasora plug-in from a dynamic shared object.

Usage

LOAD_PLUGIN { <file_path> | <plugin_name> }

A wasora plugin in the form of a dynamic shared object (i.e. .so) can be loaded either with the LOAD_PLUGIN keyword or from the command line with the -p option. Either a file path or a plugin name can be given. The following locations are tried:

  • the current directory ./
  • the parent directory ../
  • the user's LD_LIBRARY_PATH
  • the cache file /etc/ld.so.cache
  • the directories /lib, /usr/lib, /usr/local/lib
If a wasora plugin was compiled and installed following the make install procedure, the plugin should be loaded by just passing the name to LOAD_PLUGIN.

LOAD_ROUTINE

Loads one or more routines from a dynamic shared object.

Usage

LOAD_ROUTINE <file_path> <routine_1> [ <routine_2> ... <routine_n> ]

M4

Calls the m4 macro processor with definitions from wasora variables.

Usage

M4 { INPUT_FILE <file_id> | FILE_PATH <file_path> } { OUTPUT_FILE <file_id> | OUTPUT_FILE_PATH <file_path> } [ MACRO <name> [ <format> ] <definition> ] }

MATRIX

Defines a matrix.

Usage

MATRIX <name> ROWS <num_expr> COLS <num_expr> [ DATA num_expr_1 num_expr_2 ... num_expr_n ]

MINIMIZE

Usage

MINIMIZE <function> [ METHOD { conjugate_fr | conjugate_pr | vector_bfgs2 | vector_bfgs | steepest_descent | nmsimplex2 | nmsimplex | nmsimplex2rand } [ GRADIENT <expr_1> <expr_2> ... <expr_n> ] [ GUESS <expr_1> <expr_2> ... <expr_n> ] [ MIN <expr_1> <expr_2> ... <expr_n> ] [ MAX <expr_1> <expr_2> ... <expr_n> ] [ STEP <expr_1> <expr_2> ... <expr_n> ] [ VERBOSE ] [ NORERUN ] [ MAX_ITER <expr> ] [ TOL <expr> ] [ GRADTOL <expr> ]

NUMBER

Defines a named number.

Usage

NUMBER <name> [ = ] <num_expr>

PARAMETRIC

Sistematically sweeps a zone of the parameter space.

Usage

PARAMETRIC <var_1> [ ... <var_n> ] [ TYPE { linear | logarithmic | random | gaussianrandom | sobol | niederreiter | halton | reversehalton } ] [ MIN <num_expr_1> ... <num_expr_n> ] [ MAX <num_expr_1> ... <num_expr_n> ] [ STEP <num_expr_1> ... <num_expr_n> ] [ NSTEPS <num_expr_1> ... <num_expr_n> ] [ OUTER_STEPS <num_expr> ] [ MAX_DAUGHTERS <num_expr> ] [ OFFSET <num_expr> ] [ ADIABATIC ]

PHASE_SPACE

Usage

PHASE_SPACE { <vars> | <vectors> | <matrices> }

PRINT

Prints plaint-text data to the standard output or to an output file.

Usage

PRINT [ FILE <file_id> | FILE_PATH <file_path> ] [ NONEWLINE ] [ SEP <string> ] [ NOSEP ] [ HEADER ] [ SKIP_STEP <expr> ] [ SKIP_STATIC_STEP <expr> ] [ SKIP_TIME <expr> ] [ SKIP_HEADER_STEP <expr> ] [ <object_1> <object_2> ... <object_n> ] [ TEXT <string_1> ... TEXT <string_n> ]

Each argument object that is not a keyword is expected to be part of the output, can be either a matrix, a vector, an scalar algebraic expression. If the given object cannot be solved into a valid matrix, vector or expression, it is treated as a string literal if IMPLICIT is ALLOWED, otherwise a parser error is raised. To explicitly interpret an object as a literal string even if it resolves to a valid numerical expression, it should be prefixed with the TEXT keyword. Hashes # appearing literal strings have to be quoted to prevent the parser to treat them as comments within the wasora input file. Whenever an argument starts with a porcentage sign '%', it is treated as a printf-compatible format definition and all the objects that follow it are printed using the given format until a new format definition is found. All the objects are treated as double-precision floating point numbers, so only floating point formats should be given. The default format is '%e'. Matrices, vectors, scalar expressions, format modifiers and string literals can be given in the desired order, and are processed from left to right. Vectors are printed element-by-element in a single row. See PRINT_VECTOR to print vectors column-wise. Matrices are printed element-by-element in a row-major fashion if mixed with other objects but in the natural row and column fashion if it is the only given object. If the FILE keyword is not provided, default is to write to stdout. If the NONEWLINE keyword is not provided, default is to write a newline '\\n' character after all the objects are processed. The SEP keywords expects a string used to separate printed objects, the default is a tab '\\t' character. Use the NOSEP keyword to define an empty string as object separator. If the HEADER keyword is given, a single line containing the literal text given for each object is printed at the very first time the PRINT instruction is processed, starting with a hash # character. If the SKIP_STEP (SKIP_STATIC_STEP)keyword is given, the instruction is processed only every the number of transient (static) steps that results in evaluating the expression, which may not be constant. By default the PRINT instruction is evaluated every step. The SKIP_HEADER_STEP keyword works similarly for the optional HEADER but by default it is only printed once. The SKIP_TIME keyword use time advancements to choose how to skip printing and may be useful for non-constant time-step problems.

PRINT_FUNCTION

Prints one or more functions as a table of values of dependent and independent variables.

Usage

PRINT_FUNCTION <function_1> [ { function_2 | expr_1 } ... { function_n | expr_n-1 } ] [ FILE <file_id> | FILE_PATH <file_path> ] [ HEADER ] [ MIN <expr_1> <expr_2> ... <expr_m> ] [ MAX <expr_1> <expr_2> ... <expr_m> ] [ STEP <expr_1> <expr_2> ... <expr_m> ] [ NSTEPs <expr_1> <expr_2> ... <expr_m> ] [ FORMAT <print_format> ]

PRINT_VECTOR

Prints one or more vectors.

Usage

PRINT_VECTOR [ FILE <file_id> ] FILE_PATH <file_path> ] [ { VERTICAL | HORIZONTAL } ] [ ELEMS_PER_LINE <expr> ] [ FORMAT <print_format> ] <vector_1> [ vector_2 ... vector_n ]

READ

Reads data (variables, vectors o matrices) from external objects.

Usage

[ READ | WRITE ] [ SHM <name> ] [ { ASCII_FILE_PATH | BINARY_FILE_PATH } <file_path> ] [ { ASCII_FILE | BINARY_FILE } <identifier> ] ///kw+READ+usage [ IGNORE_NULL ] [ object_1 object_2 ... object_n ]

SEMAPHORE

Performs either a wait or a post operation on a named shared semaphore.

Usage

[ SEMAPHORE | SEM ] <name> { WAIT | POST }

SHELL

Executes a shell command.

Usage

SHELL <print_format> [ expr_1 expr_2 ... expr_n ]

SOLVE

Solves a non-linear system of \( n \) equations with \( n \) unknowns.

Usage

SOLVE <n> UNKNOWNS <var_1> <var_2> ... <var_n> RESIDUALS <expr_1> <expr_2> ... <expr_n> ] GUESS <expr_1> <expr_2> ... <expr_n> ] [ METHOD { dnewton | hybrid | hybrids | broyden } ] [ EPSABS <expr> ] [ EPSREL <expr> ] [ MAX_ITER <expr> ] [ VERBOSE ]

Example #1, solve1.was

# solves the system of equations
#    y = exp(x)
#  x+y = 2
#
SOLVE 2 UNKNOWNS x y RESIDUALS exp(x)-y x+y-2
PRINT " x = " %f x
PRINT " y = " %f y

Example #2, solve2.was

# solves the system of equations
#  y = exp(-f(z)*x)
#  x = integral(f(z'), z', 0, z)
#  2 = x+y+z
# where f(z) is a point-wise defined function

FUNCTION f(x) INTERPOLATION akima DATA {
0    0
0.2  0.2
0.5  0.1
0.7  0.8
1    0.5
}

# the initial guess (may be given with the GUESS keyword also)
x = 0.5
y = 0.5
z = 0.5

VAR z'
SOLVE 3 UNKNOWNS x y z METHOD hybrids RESIDUALS {
 y-exp(-f(z)*x)
 integral(f(z'),z',0,z)-x
 x+y+z-2 
}

PRINT " x = " %f x
PRINT " y = " %f y
PRINT " z = " %f z

TIME_PATH

Forces transient problems to pass through specific instants of time.

Usage

TIME_PATH [ expr_1 ] [ expr_2 ] ... [ expr_n ]

The time step dt will be reduced whenever the distance between the current time t and the next expression in the list is greater than dt so as to force t to coincide with the expressions given. The list of expresssions should evaluate to a sorted list of values.

VAR

Defines one or more scalar variables.

Usage

VAR <name_1> [ <name_2> ] ... [ <name_n> ]

VECTOR

Defines a vector.

Usage

VECTOR <name> SIZE <num_expr> [ DATA <num_expr_1> <num_expr_2> ... <num_expr_n> ] [ FUNCTION_DATA <function> ]

WRITE

Writes data (variables, vectors o matrices) to external objects. See the READ keyword for usage details.

Special variables

done

Flag that indicates whether the overall calculation is over.

done_outer

Flag that indicates whether the parametric, optimization of fit calculation is over or not. It is set to true (i.e. \( \neq 0 \)) by wasora whenever the outer calculation is considered to be finished, which can be that the parametric calculation swept the desired parameter space or that the optimization algorithm reached the desired convergence criteria. If the user sets it to true, the current step is marked as the last outer step and the transient calculation ends after finishing the step.

done_static

Flag that indicates whether the static calculation is over or not. It is set to true (i.e. \( \neq 0 \)) by wasora if step_static \( \ge \) static_steps. If the user sets it to true, the current step is marked as the last static step and the static calculation ends after finishing the step.

done_transient

Flag that indicates whether the transient calculation is over or not. It is set to true (i.e. \( \neq 0 \)) by wasora if t \( \ge \) end_time. If the user sets it to true, the current step is marked as the last transient step and the transient calculation ends after finishing the step.

dt

Actual value of the time step for transient calculations. When solving DAE systems, this variable is set by wasora. It can be written by the user for example by importing it from another transient code by means of shared-memory objects. Care should be taken when solving DAE systems and overwriting t. Default value is 1/16, which is a power of two and roundoff errors are thus reduced.

end_time

Final time of the transient calculation, to be set by the user. The default value is zero, meaning no transient calculation.

i

Dummy index, used mainly in vector and matrix row subindex expressions.

infinite

A very big positive number, which can be used as end_time = infinite or to define improper integrals with infinite limits. Default is \( 2^{50} \approx 1 \times 10^{15} \).

in_outer_initial

Flag that indicates if the current step is the initial step of an optimization of fit run.

in_static

Flag that indicates if wasora is solving the iterative static calculation. Flag that indicates if wasora is in the first step of the iterative static calculation. Flag that indicates if wasora is in the last step of the iterative static calculation.

in_transient

Flag that indicates if wasora is solving transient calculation.

in_transient_first

Flag that indicates if wasora is in the first step of the transient calculation.

in_transient_last

Flag that indicates if wasora is in the last step of the transient calculation.

j

Dummy index, used mainly in matrix column subindex expressions.

max_dt

Maximum bound for the time step that wasora should take when solving DAE systems.

min_dt

Minimum bound for the time step that wasora should take when solving DAE systems.

ncores

The number of online available cores, as returned by sysconf(_SC_NPROCESSORS_ONLN). This value can be used in the MAX_DAUGHTERS expression of the PARAMETRIC keyword (i.e ncores/2).

on_gsl_error

This should be set to a mask that indicates how to proceed if an error ir raised in any routine of the GNU Scientific Library.

on_ida_error

This should be set to a mask that indicates how to proceed if an error ir raised in any routine of the SUNDIALS IDA Library.

on_nan

This should be set to a mask that indicates how to proceed if Not-A-Number signal (such as a division by zero) is generated when evaluating any expression within wasora.

pi

A double-precision floating point representaion of the number \( \pi \), equal to math.h 's M_PI constant.

realtime_scale

If this variable is not zero, then the transient problem is run trying to syncrhonize the problem time with realtime, up to a scale given. For example, if the scale is set to one, then wasora will advance the problem time at the same pace that the real wall time advances. If set to two, wasora's time wil advance twice as fast as real time, and so on. If the calculation time is slower than real time modified by the scale, this variable has no effect on the overall behavior and execution will proceed as quick as possible with no delays.

rel_error

Maximum allowed relative error for the solution of DAE systems. Default value is is \( 1 \times 10^{-6} \). If a fine per-variable error control is needed, special vector abs_error should be used.

static_steps

Number of steps that ought to be taken during the static calculation, to be set by the user. The default value is one, meaning only one static step.

step_outer

Indicates the current step number of the iterative outer calculation (parametric, optimization or fit). Indicates the current step number of the iterative inner calculation (optimization or fit).

step_static

Indicates the current step number of the iterative static calculation.

step_transient

Indicates the current step number of the transient static calculation.

t

Actual value of the time for transient calculations. This variable is set by wasora, but can be written by the user for example by importing it from another transient code by means of shared-memory objects. Care should be taken when solving DAE systems and overwriting t.

zero

A very small positive number, which is taken to avoid roundoff errors when comparing floating point numbers such as replacing \( a \leq a_\text{max} \) with \( a < a_\text{max} + \) zero. Default is \( (1/2)^{-50} \approx 9\times 10^{-16} \) .

Built-in functions

Function names are case sensitive.

abs

Returns the absolute value of the argument \( x \).

Usage

y = abs(x)

$$ \begin{equation*} y = |x| \end{equation*} $$

Example #1, abs.was

PRINT %g sqrt(abs(-2))

# exercise: remove the absolute value from the sqrt argument

$ wasora abs.was
1.41421
$

acos

Computes arc in radians whose cosine is equal to the argument \( x \). A NaN error is raised if \( |x|>1 \).

Usage

y = acos(x)

$$ \begin{equation*} y = \arccos(x) \end{equation*} $$

asin

Computes arc in radians whose sine is equal to the argument \( x \). A NaN error is raised if \( |x|>1 \).

Usage

y = asin(x)

$$ \begin{equation*} y = \arcsin(x) \end{equation*} $$

atan

Computes, in radians, the arc tangent of the argument \( x \).

Usage

atan(x)

$$ \begin{equation*} \arctan(x) \end{equation*} $$

atan2

Computes, in radians, the arc tangent of quotient \( y/x \), using the signs of the two arguments to determine the quadrant of the result, which is in the range \( [-\pi,\pi] \).

Usage

atan(y,x)

$$ \begin{equation*} \arctan(y/x) \in [-\pi,\pi] \end{equation*} $$

Example #1, atan.was

PRINT atan(-0.5)  mod(atan(-0.5),2*pi)-pi

Example #2, atan2.was

PRINT atan2(1,-2) mod(atan(-0.5),2*pi)-pi

ceil

Returns the smallest integral value not less than the argument \( x \).

Usage

ceil(x)

$$ \begin{equation*} \lceil x \rceil \end{equation*} $$

clock

Returns the value of a certain clock in seconds measured from a certain (but specific) milestone. The kind of clock and the initial milestone depends on the optional flag \( f \). It defaults to zero, meaning wall time since the UNIX Epoch. The list and the meanings of the other available values for \( f \) can be checked in the clock_gettime (2) system call manual page.

Usage

clock([f])

Example #1, clock.was

VAR x y
t1 = clock()
y = 4*integral(integral((x^2+y^2)<1, x, 0, 1), y, 0, 1)
t2 = clock()

PRINT "approximate result = " %g y " took " %.1f t2-t1 " seconds to compute" NOSEP

# exercise: read the clock_gettime manual page and
# compute t2-t1 with other parameters to clock()

$ wasora clock.was
approximate result = 3.14167 took 0.1 seconds to compute
$

cos

Computes the cosine of the argument \( x \), where \( x \) is in radians. A cosine wave can be generated by passing as the argument \( x \) a linear function of time such as \( \omega t+\phi \), where \( \omega \) controls the frequency of the wave and \( \phi \) controls its phase.

Usage

cos(x)

$$ \begin{equation*} \cos(x) \end{equation*} $$

cosh

Computes the hyperbolic cosine of the argument \( x \), where \( x \) is in radians.

Usage

cosh(x)

$$ \begin{equation*} \cosh(x) \end{equation*} $$

d_dt

Computes the time derivative of the signal \( x \) using the difference between the value of the signal in the previous time step and the actual value divided by the time step. For \( t=0 \), the return value is zero. Unlike the functional derivative, this function works with expressions and not with functions. Therefore the argument \( x \) may be for example an expression involving a variable that may be read from a shared-memory object, whose time derivative cannot be computed with derivative.

Usage

d_dt(x)

$$ \begin{equation*} \frac{x(t) - x(t-\Delta t)}{\Delta t} \approx \frac{d}{dt} \Big( x (t) \Big) \end{equation*} $$

Example #1, d_dt.was

end_time = 5
dt = 1/10
t0 = 0.5
r = heaviside(t-t0)

PRINT t r lag(r,1) d_dt(lag(r,1)) r*exp(-(t-t0)) HEADER

# exercise: plot output for different values of dt

$ wasora d_dt.was | qdp -o d_dt
$

deadband

Filters the first argument \( x \) with a deadband centered at zero with an amplitude given by the second argument \( a \).

Usage

deadband(x, a)

$$ \begin{equation*} \begin{cases} 0 & \text{if $| x | \leq a$} \\ x + a & \text{if $x < a$} \\ x - a & \text{if $x > a$} \end{cases} \end{equation*} $$

equal

Checks if the two first expressions \( a \) and \( b \) are equal, up to the tolerance given by the third optional argument \( \epsilon \). If either \( |a|>1 \) or \( |b|>1 \), the arguments are compared using GSL's gsl_fcmp, otherwise the absolute value of their difference is compared against \( \epsilon \). This function returns \textsl{exactly} zero if the arguments are not equal and one otherwise. Default value for \( \epsilon = 10^{-16} \).

Usage

equal(a, b, [eps])

$$ \begin{equation*} \begin{cases} 1 & \text{if $a = b$} \\ 0 & \text{if $a \neq b$} \end{cases} \end{equation*} $$

exp

Computes the exponential function the argument \( x \), i.e. the base of the natural logarithms raised to the \( x \)-th power.

Usage

exp(x)

$$ \begin{equation*} e^x \end{equation*} $$

Example #1, exp.was

end_time = 1

PHASE_SPACE x
CONST alpha

alpha = 1.8

x_0 = 1.2
x_dot .= -alpha*x

y = x_0*exp(-alpha*t)

PRINT t x y y-x 

expint1

Computes the first exponential integral function of the argument \( x \). If \( x \) equals zero, a NaN error is issued.

Usage

expint1(x)

$$ \begin{equation*} \text{Re} \left[ \int_1^{\infty}\! \frac{\exp(-xt)}{t} \, dt \right] \end{equation*} $$

Example #1, expint1.was

VAR u 

E1(x) := expint1(x)
Def(x) := integral(exp(-x*u)/u,u,1,99)

PRINT_FUNCTION E1 Def MIN 1e-2 MAX 2.0 STEP 1e-2 HEADER

expint2

Computes the second exponential integral function of the argument \( x \).

Usage

expint2(x)

$$ \begin{equation*} \text{Re} \left[ \int_1^{\infty}\! \frac{\exp(-xt)}{t^2} \, dt \right] \end{equation*} $$

Example #1, expint2.was

E2(x) := expint2(x)
guesswho(x) := exp(-x) - x * expint1(x)

PRINT_FUNCTION E2 guesswho MIN 1e-2 MAX 2.0 STEP 1e-2 HEADER

# exercise: which is the limit of guesswho(x) as x approaches to zero?

expint3

Computes the third exponential integral function of the argument \( x \).

Usage

expint3(x)

$$ \begin{equation*} \text{Re} \left[ \int_1^{\infty}\! \frac{\exp(-xt)}{t^3} \, dt \right] \end{equation*} $$

expintn

Computes the \( n \)-th exponential integral function of the argument \( x \). If \( n \) equals zero or one and \( x \) zero, a NaN error is issued.

Usage

expintn(n,x)

$$ \begin{equation*} \text{Re} \left[ \int_1^{\infty}\! \frac{\exp(-xt)}{t^n} \, dt \right] \end{equation*} $$

Example #1, expintn.was

n = 4

En(x) := expintn(n,x)
guesswho(x) := (1/(n-1)) * (exp(-x) - x * expintn(n-1,x))

PRINT_FUNCTION En guesswho MIN 0.01 MAX 2.0 STEP 1e-2 HEADER

# Try this for different values of n > 1.

floor

Returns the largest integral value not greater than the argument \( x \).

Usage

floor(x)

$$ \begin{equation*} \lfloor x \rfloor \end{equation*} $$

heaviside

Computes the zero-centered Heaviside step function of the argument \( x \). If the optional second argument \( \epsilon \) is provided, the discontinuous step at \( x=0 \) is replaced by a ramp starting at \( x=0 \) and finishing at \( x=\epsilon \).

Usage

heaviside(x, [eps])

$$ \begin{equation*} \begin{cases} 0 & \text{if $x < 0$} \\ x / \epsilon & \text{if $0 < x < \epsilon$} \\ 1 & \text{if $x > \epsilon$} \end{cases} \end{equation*} $$

Example #1, heaviside.was

end_time = 1

PRINT t heaviside(t-0.5,0.25)

# exercise: what happens if the second argument is negative?

if

Performs a conditional testing of the first argument \( a \), and returns either the second optional argument \( b \) if \( a \) is different from zero or the third optional argument \( c \) if \( a \) evaluates to zero. The comparison of the condition \( a \) with zero is performed within the precision given by the optional fourth argument \( \epsilon \). If the second argument \( c \) is not given and \( a \) is not zero, the function returns one. If the third argument \( c \) is not given and \( a \) is zero, the function returns zero. The default precision is \( \epsilon = 10^{-16} \). Even though if is a logical operation, all the arguments and the returned value are double-precision floating point numbers.

Usage

if(a, [b], [c], [eps])

$$ \begin{equation*} \begin{cases} b & \text{if $a \neq 0$} \\ c & \text{if $a = b$} \end{cases} \end{equation*} $$

integral_dt

Computes the time integral of the signal \( x \) using the trapezoidal rule using the value of the signal in the previous time step and the current value. At \( t = 0 \) the integral is initialized to zero. Unlike the functional integral, this function works with expressions and not with functions. Therefore the argument \( x \) may be for example an expression involving a variable that may be read from a shared-memory object, whose time integral cannot be computed with integral.

Usage

integral_dt(x)

$$ \begin{equation*} z^{-1}\left[ \int_0^t x(t') \, dt' \right] + \frac{x(t) + x(t-\Delta t)}{2} \, \Delta t \approx \int_0^{t} x(t') \, dt' \end{equation*} $$

Example #1, integral_dt.was

end_time = 2*pi
dt = end_time/100

y = sin(t) + random_gauss(0,0.05)

PRINT t y integral_dt(y)

# exercise: compute also  the instantaneous 
# mean value of the signal y(t)

integral_euler_dt

Idem as integral_dt but uses the backward Euler rule to update the integral value. This function is provided in case this particular way of approximating time integrals is needed.

Usage

integral_euler_dt(x)

$$ \begin{equation*} z^{-1}\left[ \int_0^t x(t') \, dt' \right] + x(t) \, \Delta t \approx \int_0^{t} x(t') \, dt' \end{equation*} $$

is_even

Returns one if the argument \( x \) rounded to the nearest integer is even.

Usage

y = is_even(x)

$$ \begin{equation*} y = \begin{cases}1 &\text{if $x$ is even} \\ 0 &\text{if $x$} is odd} \end{cases} \end{equation*} $$

is_in_interval

Returns true if the argument \( x \) is in the interval \( [a,b) \), i.e. including \( a \) but excluding \( b \).

Usage

is_in_interval(x, a, b)

$$ \begin{equation*} \begin{cases} 1 & \text{if $a \leq x < b$} \\ 0 & \text{otherwise} \end{cases} \end{equation*} $$

is_odd

Returns one if the argument \( x \) rounded to the nearest integer is odd.

Usage

y = is_odd(x)

$$ \begin{equation*} y = \begin{cases}1 &\text{if $x$ is odd} \\ 0 &\text{if $x$} is even} \end{cases} \end{equation*} $$

j0

Computes the regular cylindrical Bessel function of zeroth order evaluated at the argument \( x \).

Usage

j0(x)

$$ \begin{equation*} J_0(x) \end{equation*} $$

lag

Filters the first argument \( x(t) \) with a first-order lag of characteristic time \( \tau \), i.e. this function applies the transfer function $$ G(s) = \frac{1}{1 + s\tau} $$ to the time-dependent signal \( x(t) \), by assuming that it is constant during the time interval \( [t-\Delta t,t] \) and using the analytical solution of the differential equation for that case at \( t = \Delta t \) with the initial condition \( y(0) = y(t-\Delta t) \).

Usage

lag(x, tau)

$$ \begin{equation*} x(t) - \Big[x(t) - y(t-\Delta t) \Big] \cdot \exp\left(-\frac{\Delta t}{\tau}\right) \end{equation*} $$

lag_bilinear

Filters the first argument \( x(t) \) with a first-order lag of characteristic time \( \tau \), i.e. this function applies the transfer function $$ G(s) = \frac{1}{1 + s\tau} $$ to the time-dependent signal \( x(t) \) by using the bilinear transformation formula.

Usage

lag_bilinear(x, tau)

$$ \begin{equation*} y = y(t-\Delta t) \cdot \left[ 1 - \frac{\Delta t}{2\tau} \right] + \left[ \frac{x(t) + x(t - \Delta t)}{1 + \frac{\Delta t}{2\tau}}\right] \cdot \frac{\Delta t}{2\tau} \end{equation*} $$

lag_euler

Filters the first argument \( x(t) \) with a first-order lag of characteristic time \( \tau \), i.e. this function applies the transfer function $$ G(s) = \frac{1}{1 + s\tau} $$ to the time-dependent signal \( x(t) \) by using the Euler forward rule.

Usage

lag_euler(x, tau)

$$ \begin{equation*} y(t-\Delta t) + \Big[ x(t) - x(t - \Delta t) \Big] \cdot \frac{\Delta t}{\tau} \end{equation*} $$

last

Returns the value the signal \( x \) had in the previous time step. This function is equivalent to the \( Z \)-transform operator "delay" denoted by \( z^{-1}\left[x\right] \). For \( t=0 \) the function returns the actual value of \( x \). The optional flag \( p \) should be set to one if the reference to last is done in an assignment over a variable that already appears insi expression \( x \). See example number 2.

Usage

last(x,[p])

$$ \begin{equation*} z^{-1}\left[ x \right] = x(t-\Delta t) \end{equation*} $$

Example #1, last1.was

end_time = 1
PRINT t last(t) last(last(1-t))

# exercise: plot the two signals

Example #2, last2.was

end_time = 1

y = y + 1
z = last(z,1) + 1

PRINT t %g y z

# exercise: compute z = last(z)+1 and see what happens

limit

Limits the first argument \( x \) to the interval \( [a,b] \). The second argument \( a \) should be less than the third argument \( b \).

Usage

limit(x, a, b)

$$ \begin{equation*} \begin{cases} a & \text{if $x < a$} \\ x & \text{if $a \leq x \leq b$} \\ b & \text{if $x > b$} \end{cases} \end{equation*} $$

limit_dt

Limits the value of the first argument \( x(t) \) so to that its time derivative is bounded to the interval \( [a,b] \). The second argument \( a \) should be less than the third argument \( b \).

Usage

limit_dt(x, a, b)

$$ \begin{equation*} \begin{cases} x(t) & \text{if $a \leq dx/dt \leq b$} \\ x(t-\Delta t) + a \cdot \Delta t & \text{if $dx/dt < a$} \\ x(t-\Delta t) + b \cdot \Delta t & \text{if $dx/dt > b$} \end{cases} \end{equation*} $$

log

Computes the natural logarithm of the argument \( x \). If \( x \) is zero or negative, a NaN error is issued.

Usage

log(x)

$$ \begin{equation*} \ln(x) \end{equation*} $$

Example #1, log.was

end_time = 1
dt = 1e-2

x = d_dt(log(1+t))
y = 1/(1+t)

PRINT t x y y-x 

# exercise: why does this example gives a bigger error than
# the exp.was example?

mark_max

Returns the integer index \( i \) of the maximum of the arguments \( x_i \) provided. Currently only maximum of ten arguments can be provided.

Usage

mark_max(x1, x2, [...], [x10])

$$ \begin{equation*} i / \max \Big (x_1, x_2, \dots, x_{10} \Big) = x_i \end{equation*} $$

mark_min

Returns the integer index \( i \) of the minimum of the arguments \( x_i \) provided. Currently only maximum of ten arguments can be provided.

Usage

mark_max(x1, x2, [...], [x10])

$$ \begin{equation*} i / \min \Big (x_1, x_2, \dots, x_{10} \Big) = x_i \end{equation*} $$

max

Returns the maximum of the arguments \( x_i \) provided. Currently only maximum of ten arguments can be provided.

Usage

max(x1, x2, [...], [x10])

$$ \begin{equation*} \max \Big (x_1, x_2, \dots, x_{10} \Big) \end{equation*} $$

min

Returns the minimum of the arguments \( x_i \) provided. Currently only maximum of ten arguments can be provided.

Usage

min(x1, x2, [...], [x10])

$$ \begin{equation*} \min \Big (x_1, x_2, \dots, x_{10} \Big) \end{equation*} $$

mod

Returns the remainder of the division between the first argument \( a \) and the second \( b \). Both arguments may be non-integral.

Usage

mod(a, b)

$$ \begin{equation*} \displaystyle y = a - \left\lfloor \frac{a}{b} \right\rfloor \cdot b \end{equation*} $$

not

Returns one if the first argument \( x \) is zero and zero otherwise. The second optional argument \( \epsilon \) gives the precision of the "zero" evaluation. If not given, default is \( \epsilon = 10^{-16} \).

Usage

not(x, [eps])

$$ \begin{equation*} \begin{cases}0 &\text{if $|x| < \epsilon$} \\ 1 &\text{otherwise} \end{cases} \end{equation*} $$

random

Returns a random real number uniformly distributed between the first real argument \( x_1 \) and the second one \( x_2 \). If the third integer argument \( s \) is given, it is used as the seed and thus repetitive sequences can be obtained. If no seed is provided, the current time (in seconds) plus the internal address of the expression is used. Therefore, two successive calls to the function without seed (hopefully) do not give the same result. This function uses a second-order multiple recursive generator described by Knuth in Seminumerical Algorithms, 3rd Ed., Section 3.6.

Usage

random(x1, x2, [s])

$$ \begin{equation*} x_1 + r \cdot (x_2-x_1) \quad \quad 0 \leq r < 1 \end{equation*} $$

random_gauss

Returns a random real number with a Gaussian distribution with a mean equal to the first argument \( x_1 \) and a standard deviation equatl to the second one \( x_2 \). If the third integer argument \( s \) is given, it is used as the seed and thus repetitive sequences can be obtained. If no seed is provided, the current time (in seconds) plus the internal address of the expression is used. Therefore, two successive calls to the function without seed (hopefully) do not give the same result. This function uses a second-order multiple recursive generator described by Knuth in Seminumerical Algorithms, 3rd Ed., Section 3.6.

Usage

random_gauss(x1, x2, [s])

round

Rounds the argument \( x \) to the nearest integer. Halfway cases are rounded away from zero.

Usage

round(x)

$$ \begin{equation*} \begin{cases} \lceil x \rceil & \text{if $\lceil x \rceil - x < 0.5$} \\ \lceil x \rceil & \text{if $\lceil x \rceil - x = 0.5 \wedge x > 0$} \\ \lfloor x \rfloor & \text{if $x-\lfloor x \rfloor < 0.5$} \\ \lfloor x \rfloor & \text{if $x-\lfloor x \rfloor = 0.5 \wedge x < 0$} \end{cases} \end{equation*} $$

sawtooth_wave

Computes a sawtooth wave betwen zero and one with a period equal to one. As with the sine wave, a sawtooh wave can be generated by passing as the argument \( x \) a linear function of time such as \( \omega t+\phi \), where \( \omega \) controls the frequency of the wave and \( \phi \) controls its phase.

Usage

sawtooth_wave(x)

$$ \begin{equation*} x - \lfloor x \rfloor \end{equation*} $$

Example #1, sawtooth_wave.was

end_time = 10
dt = 1e-2

r = 2*sawtooth_wave(0.2*t + 0.5) - 1
y = lag(r, 0.5)

PRINT t r y

sgn

Returns minus one, zero or plus one depending on the sign of the first argument \( x \). The second optional argument \( \epsilon \) gives the precision of the "zero" evaluation. If not given, default is \( \epsilon = 10^{-16} \).

Usage

sgn(x, [eps])

$$ \begin{equation*} \begin{cases}-1 &\text{if $x \le -\epsilon$} \\ 0 &\text{if $|x| < \epsilon$} \\ +1 &\text{if $x \ge +\epsilon$} \end{cases} \end{equation*} $$

sin

Computes the sine of the argument \( x \), where \( x \) is in radians. A sine wave can be generated by passing as the argument \( x \) a linear function of time such as \( \omega t+\phi \), where \( \omega \) controls the frequency of the wave and \( \phi \) controls its phase.

Usage

sin(x)

$$ \begin{equation*} \sin(x) \end{equation*} $$

sinh

Computes the hyperbolic sine of the argument \( x \), where \( x \) is in radians.

Usage

sinh(x)

$$ \begin{equation*} \sinh(x) \end{equation*} $$

sqrt

Computes the positive square root of the argument \( x \). If \( x \) is negative, a NaN error is issued.

Usage

sqrt(x)

$$ \begin{equation*} \sqrt{x} \end{equation*} $$

square_wave

Computes a square function betwen zero and one with a period equal to one. The output is one for \( 0 < x < 1/2 \) and goes to zero for \( 1/2 < x < 1 \). As with the sine wave, a square wave can be generated by passing as the argument \( x \) a linear function of time such as \( \omega t+\phi \), where \( \omega \) controls the frequency of the wave and \( \phi \) controls its phase.

Usage

square_wave(x)

$$ \begin{equation*} \begin{cases} 1 & \text{if $x - \lfloor x \rfloor < 0.5$} \\ 0 & \text{otherwise} \end{cases} \end{equation*} $$

Example #1, square_wave.was

end_time = 10
dt = 1e-2

r = 2*square_wave(0.2*t - 0.1) - 1
y = lag(r, 0.5)

PRINT t r y

tan

Computes the tangent of the argument \( x \), where \( x \) is in radians.

Usage

tan(x)

$$ \begin{equation*} \tan(x) \end{equation*} $$

tanh

Computes the hyperbolic tangent of the argument \( x \), where \( x \) is in radians.

Usage

tanh(x)

$$ \begin{equation*} \tanh(x) \end{equation*} $$

threshold_max

Returns one if the first argument \( x \) is greater than the threshold given by the second argument \( a \), and \textit{exactly} zero otherwise. If the optional third argument \( b \) is provided, an hysteresis of width \( b \) is needed in order to reset the function value. Default is no hysteresis, i.e. \( b=0 \).

Usage

threshold_max(x, a, [b])

$$ \begin{equation*} \begin{cases} 1 & \text{if $x > a$} \\ 0 & \text{if $x < a-b$} \\ \text{last value of $y$} & \text{otherwise} \end{cases} \end{equation*} $$

threshold_min

Returns one if the first argument \( x \) is less than the threshold given by the second argument \( a \), and \textit{exactly} zero otherwise. If the optional third argument \( b \) is provided, an hysteresis of width \( b \) is needed in order to reset the function value. Default is no hysteresis, i.e. \( b=0 \).

Usage

threshold_min(x, a, [b])

$$ \begin{equation*} \begin{cases} 1 & \text{if $x < a$} \\ 0 & \text{if $x > a+b$} \\ \text{last value of $y$} & \text{otherwise} \end{cases} \end{equation*} $$

triangular_wave

Computes a triangular wave betwen zero and one with a period equal to one. As with the sine wave, a triangular wave can be generated by passing as the argument \( x \) a linear function of time such as \( \omega t+\phi \), where \( \omega \) controls the frequency of the wave and \( \phi \) controls its phase.

Usage

triangular_wave(x)

$$ \begin{equation*} \begin{cases} 2 (x - \lfloor x \rfloor) & \text{if $x - \lfloor x \rfloor < 0.5$} \\ 2 [1-(x - \lfloor x \rfloor)] & \text{otherwise} \end{cases} \end{equation*} $$

Built-in functionals

derivative

Computes the derivative of the expression \( f(x) \) given in the first argument with respect to the variable \( x \) given in the second argument at the point \( x=a \) given in the third argument using an adaptive scheme. The fourth optional argument \( h \) is the initial width of the range the adaptive derivation method starts with. The fifth optional argument \( p \) is a flag that indicates whether a backward (\( p < 0 \)), centered (\( p = 0 \)) or forward (\( p > 0 \)) stencil is to be used. This functional calls the GSL functions gsl_deriv_central or gsl_deriv_forward according to the indicated flag \( p \). Defaults are \( h = (1/2)^{-10} \approx 9.8 \times 10^{-4} \) and \( p = 0 \).

Usage

derivative(f(x), x, a, [h], [p])

$$ \begin{equation*} \left. \frac{d}{dx} \Big[ f(x) \Big] \right|_{x = a} \end{equation*} $$

Example #1, derivative.was

VAR x
numeric = derivative(log(x^2),x,3)
exact(x) := 2/x 
PRINT numeric exact(3) numeric-exact(3)

# excercise: write a functions to compute the numerical
# derivative of log(x^2) and compare it to the exact one
# for a certain range of x

func_min

Finds the value of the variable \( x \) given in the second argument which makes the expression \( f(x) \) given in the first argument to take local a minimum in the in the range \( [a,b] \) given by the third and fourth arguments. If there are many local minima, the one that is closest to \( (a+b)/2 \) is returned. The optional fifth argument \( \epsilon \) gives a relative tolerance for testing convergence, corresponding to GSL epsrel (note that epsabs is set also to \( \epsilon) \). The sixth optional argument is an integer which indicates the algorithm to use: 0 (default) is quad_golden, 1 is brent and 2 is goldensection. See the GSL documentation for further information on the algorithms. The seventh optional argument \( p \) is a flag that indicates how to proceed if there is no local minimum in the range \( [a,b] \). If \( p = 0 \) (default), \( a \) is returned if \( f(a) < f(b) \) and \( b \) otherwise. If \( p = 1 \) then the local minimum algorimth is tried nevertheless. Default is \( \epsilon = (1/2)^{-20} \approx 9.6\times 10^{-7} \).

Usage

y = func_min(f(x), x, a, b, [eps], [alg], [p])

$$ \begin{equation*} y = \left\{ x \in [a,b] / f(x) = \min_{[a,b]} f(x) \right \} \end{equation*} $$

Example #1, func_min.was

FUNCTION f(x) INTERPOLATION spline DATA {
0   1
0.1 0.5
0.3 0.4
0.5 0.5
0.7 0.8
1   1
}

PRINT func_min(f(x),x,f_a,f_b)

# exercise: plot the interpolated f(x) in the range [0:1]
# and check that func_min returned the correct value

gauss_kronrod

Computes the integral of the expression \( f(x) \) given in the first argument with respect to variable \( x \) given in the second argument over the interval \( [a,b] \) given in the third and fourth arguments respectively using a non-adaptive procedure which uses fixed Gauss-Kronrod-Patterson abscissae to sample the integrand at a maximum of 87 points. It is provided for fast integration of smooth functions. The algorithm applies the Gauss-Kronrod 10-point, 21-point, 43-point and 87-point integration rules in succession until an estimate of the integral is achieved within the relative tolerance given in the fifth optional argument \( \epsilon \) It correspondes to GSL's epsrel parameter (epsabs is set to zero). The rules are designed in such a way that each rule uses all the results of its predecessors, in order to minimize the total number of function evaluations. Defaults are \( \epsilon = (1/2)^{-10} \approx 10^{-3} \). See GSL reference for further information.

Usage

gauss_kronrod(f(x), x, a, b, [eps])

$$ \begin{equation*} \int_a^b f(x) \, dx \end{equation*} $$

Example #1, integral3.was

f(x) := exp(-x^2/2)
eps = 1e-3

a = sqrt(2*pi)
b = integral(f(x), x, -10, 10, eps)
c = gauss_kronrod(f(x), x, -10, 10, eps)
d = gauss_legendre(f(x), x, -10, 10, 24)

PRINT %.20f a %e a-a
PRINT %.20f b %e b-a
PRINT %.20f c %e c-a
PRINT %.20f d %e d-a

# exercise: study how the errors change with eps.
# Hint: define thre functions of eps

gauss_legendre

Computes the integral of the expression \( f(x) \) given in the first argument with respect to variable \( x \) given in the second argument over the interval \( [a,b] \) given in the third and fourth arguments respectively using the \( n \)-point Gauss-Legendre rule, where \( n \) is given in the optional fourth argument. It is provided for fast integration of smooth functions with known polynomic order (it is exact for polynomials of order \( 2n-1 \)). This functional calls GSL function gsl_integration_glfixedp. Default is \( n = 12 \). See GSL reference for further information.

Usage

gauss_legendre(f(x), x, a, b, [n])

$$ \begin{equation*} \int_a^b f(x) \, dx \end{equation*} $$

Example #1, integral3.was

f(x) := exp(-x^2/2)
eps = 1e-3

a = sqrt(2*pi)
b = integral(f(x), x, -10, 10, eps)
c = gauss_kronrod(f(x), x, -10, 10, eps)
d = gauss_legendre(f(x), x, -10, 10, 24)

PRINT %.20f a %e a-a
PRINT %.20f b %e b-a
PRINT %.20f c %e c-a
PRINT %.20f d %e d-a

# exercise: study how the errors change with eps.
# Hint: define thre functions of eps

integral

Computes the integral of the expression \( f(x) \) given in the first argument with respect to variable \( x \) given in the second argument over the interval \( [a,b] \) given in the third and fourth arguments respectively using an adaptive scheme, in which the domain is divided into a number of maximum number of subintervals and a fixed-point Gauss-Kronrod-Patterson scheme is applied to each quadrature subinterval. Based on an estimation of the error commited, one or more of these subintervals may be split to repeat the numerical integration alogorithm with a refined division. The fifth optional argument \( \epsilon \) is is a relative tolerance used to check for convergence. It correspondes to GSL's epsrel parameter (epsabs is set to zero). The sixth optional argument \( 1\leq k \le 6 \) is an integer key that indicates the integration rule to apply in each interval. It corresponds to GSL's parameter key. The seventh optional argument gives the maximum number of subdivisions, which defaults to 1024. If the integration interval \( [a,b] \) if finite, this functional calls the GSL function gsl_integration_qag. If \( a \) is less that minus the internal variable infinite, \( b \) is greater that infinite or both conditions hold, GSL functions gsl_integration_qagil, gsl_integration_qagiu or gsl_integration_qagi are called. The condition of finiteness of a fixed range \( [a,b] \) can thus be changed by modifying the internal variable infinite. Defaults are \( \epsilon = (1/2)^{-10} \approx 10^{-3} \) and \( k=3 \). The maximum numbers of subintervals is limited to 1024. Due to the adaptivity nature of the integration method, this function gives good results with arbitrary integrands, even for infinite and semi-infinite integration ranges. However, for certain integrands, the adaptive algorithm may be too expensive or even fail to converge. In these cases, non-adaptive quadrature functionals ought to be used instead. See GSL reference for further information.

Usage

integral(f(x), x, a, b, [eps], [k], [max_subdivisions])

$$ \begin{equation*} \int_a^b f(x) \, dx \end{equation*} $$

Example #1, integral1.was

VAR x
PRINT integral(x^2,x,0,1)

Example #2, integral2.was

VAR x
intpi = 4 * integral(integral(1, y, 0, sqrt(1-x^2)), x, 0, 1)
PRINT intpi

Example #3, integral3.was

f(x) := exp(-x^2/2)
eps = 1e-3

a = sqrt(2*pi)
b = integral(f(x), x, -10, 10, eps)
c = gauss_kronrod(f(x), x, -10, 10, eps)
d = gauss_legendre(f(x), x, -10, 10, 24)

PRINT %.20f a %e a-a
PRINT %.20f b %e b-a
PRINT %.20f c %e c-a
PRINT %.20f d %e d-a

# exercise: study how the errors change with eps.
# Hint: define thre functions of eps

prod

Computes product of the \( N=b-a \) expressions \( f(i) \) given in the first argument by varying the variable \( i \) given in the second argument between \( a \) given in the third argument and \( b \) given in the fourth argument,~\( i = a, a+1, \dots ,b-1,b \).

Usage

prod(f(i), i, a, b)

$$ \begin{equation*} \prod_{i=a}^b f_i \end{equation*} $$

root

Computes the value of the variable \( x \) given in the second argument which makes the expression \( f(x) \) given in the first argument to be equal to zero by using a root bracketing algorithm. The root should be in the range \( [a,b] \) given by the third and fourth arguments. The optional fifth argument \( \epsilon \) gives a relative tolerance for testing convergence, corresponding to GSL epsrel (note that epsabs is set also to \( \epsilon) \). The sixth optional argument is an integer which indicates the algorithm to use: 0 (default) is brent, 1 is falsepos and 2 is bisection. See the GSL documentation for further information on the algorithms. The seventh optional argument \( p \) is a flag that indicates how to proceed if the sign of \( f(a) \) is equal to the sign of \( f(b) \). If \( p=0 \) (default) an error is raised, otherwise it is not. If more than one root is contained in the specified range, the first one to be found is returned. The initial guess is \( x_0 = (a+b)/2 \). If no roots are contained in the range and \( p \neq 0 \), the returned value can be any value. Default is \( \epsilon = (1/2)^{-10} \approx 10^{3} \).

Usage

root(f(x), x, a, b, [eps], [alg], [p])

$$ \begin{equation*} \left\{ x \in [a,b] / f(x) = 0 \right \} \end{equation*} $$

Example #1, root1.was

VAR x
PRINT "nu0 / j0(nu0) = 0 is equal to " %.6f root(j0(x),x,2,3) NOSEP

a = 2
PRINT "cos(a*x) = x with a = " %g a " holds for x = " %.6f root(cos(a*x)-x,x,0,2*pi) NOSEP

# exercise: try to find the roots of x^2 + x + 1 and explain what happens

Example #2, root2.was

VAR x'

cdf(x) := 2/sqrt(2*pi) * integral(exp(-x'^2/2), x', 0, x)
sigma(x) := root(cdf(x')-x, x', 0, 5)


PRINT "within one standard deviation one has " %.2f 100*cdf(1) " percent of the samples" NOSEP
PRINT "within two standard deviations one has " %.2f 100*cdf(2) " percent of the samples" NOSEP 
PRINT "to take into account 99% of cases for one needs " %.1f sigma(0.99) " standard deviations" NOSEP

# exercise: plot both cdf(x) and sigma(x) in the same figure

Example #3, root3.was

f(x) := sin(x)-1/2

PRINT pi/6-root(f(x),x,0,1,1e-2,2)
PRINT pi/6-root(f(x),x,0,1,1e-4,2)
PRINT pi/6-root(f(x),x,0,1,1e-6,2)
PRINT
PRINT pi/6-root(f(x),x,0,1,1e-2,1)
PRINT pi/6-root(f(x),x,0,1,1e-4,1)
PRINT pi/6-root(f(x),x,0,1,1e-6,1)
PRINT
PRINT pi/6-root(f(x),x,0,1,1e-2,0)
PRINT pi/6-root(f(x),x,0,1,1e-4,0)
PRINT pi/6-root(f(x),x,0,1,1e-6,0)


# exercice: try other combinations of tolerances and say something
# about the number of steps needed by each method to converge

Example #4, root4.was

FUNCTION f(x) DATA {
0    1
0.3 -1
1    1
}

PRINT root(f(x),x,0,1,,,1)

# exercise: see what happens if one sets p=1. How can one find
# the other root of f(x) located at x=0.65?

sum

Computes sum of the \( N=b-a \) expressions \( f_i \) given in the first argument by varying the variable \( i \) given in the second argument between \( a \) given in the third argument and \( b \) given in the fourth argument, \( i=a,a+1,\dots,b-1,b \).

Usage

sum(f_i, i, a, b)

$$ \begin{equation*} \sum_{i=a}^b f_i \end{equation*} $$

Example #1, sum1.was

f(n) := sum(i, i, 1, n)

PRINT TEXT "n" TEXT "sum" TEXT "formula"
PRINT_FUNCTION f (n*(n+1))/2 MIN 1 MAX 10 STEP 1 FORMAT %g

# exercise: do the same with the sum of the squares of
# the first n natural numbers

Example #2, sum2.was

n = 1e5
pisum = 4*sum((-1)^i * 1/(2*i+1), i, 0, n)

PRINT "exact = " %.10f pi NOSEP
PRINT "sum   = " %.10f pisum " (" %g n " terms)" NOSEP
PRINT "diff  = " pi-pisum NOSEP

# exercise: investigate the rate of convergence of pisum with n.

Example #3, sum3.was

NUMBER N 3
MATRIX A ROWS N COLS N
VECTOR b SIZE N

A(i,j) = i + 0.1*j

tr = sum(A(i,i), i, 1, N)
b(i) = sum(A(i,j), j, 1, N)

PRINT a
PRINT
PRINT tr
PRINT
PRINT_VECTOR b

# exercise: compute the matrix-product Ab

Buiilt-in vector funtions

vecdot

Computes the dot product between vectors \( \vec{a} \) and \( \vec{b} \), which should have the same size.

Usage

vecdot(a,b)

$$ \begin{equation*} \vec{a} \cdot \vec{b} = \sum_{i=1}^{\text{vecsize}(\vec{a})} a_i \cdot b_i \end{equation*} $$

Example #1, vecdot.was

NUMBER N 3
VECTOR a SIZE N DATA 0.1234 0.98765 0.5555
VECTOR b SIZE N

b(i) = 1-0.2*i

PRINT vecdot(a,b)

vecmax

Returns the biggest element of vector \( \vec{b} \), taking into account its sign (i.e. \( 1 > -2 \)).

Usage

vecmax(b)

$$ \begin{equation*} \max_i b_i \end{equation*} $$

Example #1, vecmax.was

VECTOR x SIZE 5

x(i) = (i-1.2345)^2 - i - 5.4321

PRINT %g x
PRINT "maximum is " vecmax(x)

vecmaxindex

Returns the index of the biggest element of vector \( \vec{b} \), taking into account its sign (i.e. \( 2 > -1 \)).

Usage

vecmaxindex(b)

$$ \begin{equation*} i / b_i = \max_i b_i \end{equation*} $$

Example #1, vecminindex.was

VECTOR x SIZE 5

x(i) = (i-1.2345)^2 - i - 5.4321

PRINT %g x
PRINT "minimum is element number" %g vecminindex(x)

vecmin

Returns the smallest element of vector \( \vec{b} \), taking into account its sign (i.e. \( -2 < 1 \)).

Usage

vecmin(b)

$$ \begin{equation*} \min_i b_i \end{equation*} $$

Example #1, vecmin.was

VECTOR x SIZE 5

x(i) = (i-1.2345)^2 - i - 5.4321

PRINT %g x
PRINT "minimum is " vecmin(x)

vecminindex

Returns the index of the smallest element of vector \( \vec{b} \), taking into account its sign (i.e. \( -2 < 1 \)).

Usage

vecminindex(b)

$$ \begin{equation*} i / b_i = \min_i b_i \end{equation*} $$

Example #1, vecminindex.was

VECTOR x SIZE 5

x(i) = (i-1.2345)^2 - i - 5.4321

PRINT %g x
PRINT "minimum is element number" %g vecminindex(x)

vecnorm

Computes euclidean norm of vector \( \vec{b} \). Other norms can be computed explicitly using the sum functional, as illustrated in the example.

Usage

vecnorm(b)

$$ \begin{equation*} \sqrt{\sum_{i=1}^{\text{vecsize}(\vec{b})} b^2_i} \end{equation*} $$

Example #1, vecnorm.was

VECTOR x SIZE 10

x(i) = 1/(i+1)

PRINT %g x

PRINT "euclidean norm  with vecnorm =" vecnorm(x)
PRINT "euclidean norm with sum =" sqrt(sum(x(i)^2,i,1,vecsize(x)))
PRINT "absolute value norm with sum = " sum(abs(x(i)),i,1,vecsize(x))

vecsize

Returns the size of vector \( \vec{b} \).

Usage

vecsize(b)

Example #1, vecsize.was

NUMBER N 6
VECTOR x SIZE 1+2*N
PRINT %g vecsize(x)

vecsum

Computes the sum of all the components of vector \( \vec{b} \).

Usage

vecsum(b)

$$ \begin{equation*} \sum_{i=1}^{\text{vecsize}(\vec{b})} b_i \end{equation*} $$

Example #1, vecsum.was

NUMBER N 100
VECTOR x SIZE 100

x(i) = 1/i

PRINT vecsum(x) vecsum(x)+1/(N+1)