wasora

wasora's an advanced suite for optimization & reactor analysis

wasora

logo wasora is a free computational tool designed to aid a cognizant expert—i.e. you, whether an engineer, scientist, technician, geek, etc.—to analyze complex systems by solving mathematical problems by means of a high-level plain-text input file containing algebraic expressions, data for function interpolation, differential equations and output instructions amongst other facilities. At a first glance, it may look as another high-level interpreted programming language, but—hopefully—it is not: wasora should be seen as a syntactically-sweetened way to ask a computer to perform a certain mathematical calculation. For example, see below to find how the famous Lorenz system may be solved by writing the three differential equations into a plain-text input file as humanly-friendly as possible.

Although its ultimate subject is optimization, it may hopefully help you with the tough calculations that usually appear when working with problems that have some kind of complexity, allowing the user to focus on what humans perform best—expert judgment and reaching conclusions. Some of its main features include

  • evaluation of algebraic expressions
  • one and multi-dimensional function interpolation
  • scalars, vectors and matrices operations
  • numerical integration, differentiation and root finding of functions
  • possibility to solve iterative and/or time-dependent problems
  • adaptive integration of systems of differential-algebraic equations
  • I/O from files and shared-memory objects (with optional synchronization using semaphores)
  • execution of arbitrary code provided as shared object files
  • parametric runs using quasi-random sequence numbers to efficiently sweep a sub-space of parameter space
  • non-linear fit of scattered data to one or multi-dimensional functions
  • non-linear multidimensional optimization

Almost any single feature included in the code was needed at least once by the author during his career in the nuclear industry. Nevertheless, wasora is aimed at solving general mathematical problems (see below for a description of the wasora Real Book). Should a particular calculation be needed, wasora's features may be extended by the implementation of dynamically-loaded plugins.

Explaining what a certain piece of software does—especially if it is a technical one—is very hard, as shown by the cryptic description most scientific software package present at their web pages, version control system logs, README files and repository sources. This is by no means an exception, so please before flying away take the time to look at this page and at wasora's README for a brief description and some practical examples to see. Maybe after all wasora can help you.

Last modification: Wed, 01 Oct 2014 19:05:27 -0300.

news

01-Oct-2014
Version 0.3.17 tarballs are available. Update to this version if you plan to load recent plugins such as milonga.
18-Aug-2014
Version 0.3.8 tarballs (with complete README and INSTALL) are available.
17-Aug-2014
New version 0.3.x series is now hosted on Bitbucket using Mercurial. The old 0.2.x repository on Launchpad is not used anymore.

download

The recommended way to get wasora is to download the latest (0.3.17) source tarball and compile wasora from scratch. However, libraries may be tricky to get running so binary versions are also provided:

mercurial repository

Bitbucket If you plan to contribute to wasora, modify its sources or just want to get updated versions easily, you will need to clone the development tree of wasora, which is hosted at Bitbucket using Mercurial a the version control system (note that series 0.2.x used to be hosted at Launchpad using bazaar). The wasora tree can be browsed online or cloned into a local copy with

If you use hg to get the development version, you will need automake, autoconf, libtool and m4. See details in the README file contained in the tree. Regular users just downloading the tarballs listed above will not need such advanced tools.

Feel free to ask whatever question you may have in the mailing list.

quickstart

Download the source code, uncompress, configure, make, check and install:

$ wget http://www.talador.com.ar/jeremy/wasora/downloads/wasora-0.3.17.tar.gz
$ tar xvzf wasora-0.3.17.tar.gz
$ cd wasora-0.3.17
$ ./configure --enable-download-gsl
$ make
$ make check
$ su
# make install
# exit
$

Please note that the GNU Scientific Library (both the library and the headers) is mandatory to compile the source code. The --enable-download-gsl option may be used to have configure to automatically download and compile the library. In Debian-based GNU/Linux boxes, it may be installed with

$ apt-get install libgsl0-dev
instead of using the --enable-download-gsl option in configure. Other non-standard libraries such as SUNDIALS or Readline are optional. See the projects wasora relies on, and the INSTALL file in the distribution for details.

See a description of the compilation instructions in the INSTALL file contained in the distribution. If configure runs into trouble with the required libraries, try to download the binary tarball that better suits your architecture. See also the README file.

test suite

The the test suite executed in the make check step above consists of ten examples of application that use different kind of the features provided by wasora. They work both as examples of usage and as a suite of tests that check that wasora implements correctly the functionalities that are expected. A more detailed set of examples that illustrate real applications of wasora in a wide variety of fields—ranging from classical mechanical systems up to analysis of blackjack strategies—can be found in The wasora Real Book. Some of the cases in the test suite generate graphical data which is shown on the screen using gnuplot, provided it is installed.

Each individual test may be repeated by executing the test-*.sh scripts located in the examples subdirectory. A brief description of the ten cases follows.

the fibonacci sequence

Compute the first fifteen numbers of the Fibonacci sequence by building a vector and setting the individual elements as the sum of the previous two with fibonacci.was:
# compute the first 15 numbers of the fibonacci sequence
VECTOR f SIZE 15

f(i)<1:2> = 1
f(i)<3:vecsize(f)> = f(i-2) + f(i-1)

PRINT_VECTOR f FORMAT %g

# exercise: increase the size of vector f
$ wasora fibonacci.was
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
$

See The Fibonacci sequence at the wasora Real Book for two other ways of computing the same sequence.

estimating π

Compute an estimation of π using seven different ways and compare them to the exact value (up to double-precision floating-point binary representation):
# computing pi in eight different ways
VECTOR piapprox SIZE 8
VAR x y

# the double-precision internal representation of pi (M_PI)
piapprox(1) = pi

# four times the arc-tangent of the unity
piapprox(2) = 4*atan(1)

# the abscissae x where tan(x) = 0 in the range [3:3.5]
piapprox(3) = root(tan(x), x, 3, 3.5)

# the square of the numerical integral of the guassian curve 
piapprox(4) = integral(exp(-x^2), x, -10, 10)^2

# the numerical integral of a circle inscribed in a unit square
piapprox(5) = integral(integral((x^2+y^2) < 1, y, -1, 1), x, -1, 1)

# the numerical integral of a circle parametrized with sqrt(1-x^2)
piapprox(6) = integral(integral(1, y, -sqrt(1-x^2), sqrt(1-x^2)), x, -1, 1)

# the gregory-leibniz sum (one hundred thousand terms)
piapprox(7) = 4*sum((-1)^(i+1)/(2*i-1), i, 1, 1e5)

# the abraham sharp sum (twenty-one terms)
piapprox(8) = sum(2*(-1)^i * 3^(1/2-i)/(2*i+1), i, 0, 20)


PRINT_VECTOR FORMAT "% .20f" piapprox piapprox(i)-pi
$ wasora pi.was 
 3.14159265358979311600  0.00000000000000000000
 3.14159265358979311600  0.00000000000000000000
 3.14159265358979356009  0.00000000000000044409
 3.14159265358991079964  0.00000000000011768364
 3.14176053328579962809  0.00016787969600651209
 3.14159565486785119504  0.00000300127805807904
 3.14158265358971977577 -0.00001000000007334023
 3.14159265359563510955  0.00000000000584199356
$

one-dimensional interpolation

First generate some (x, y) pairs with a random component using gendata1d.was:
# generate pairs of (x,y) data to be used with interp1.was

CONST static_steps
static_steps = round(random_gauss(10,2))
x = step_static/static_steps

PRINT x+random(-0.04,0.04) 1-x+random(-0.2,0.2)+random_gauss(0,0.2)
$ wasora gendata1d.was > f.dat
$

Then read the generated data and define two functions, one using linear interpolation and another one using akima interpolation:

# read file f.dat and define two one-dimensional functions,
# one using linear interpolation (default) and another with akima
FUNCTION f(x) FILE_PATH f.dat INTERPOLATION linear
FUNCTION g(x) FILE_PATH f.dat INTERPOLATION akima

OUTPUT_FILE out f-interp.dat
PRINT_FUNCTION f g FILE out MIN f_a MAX f_b STEP 2e-3
$ wasora interp1d.was 
$ gnuplot -p -e "plot 'f.dat' pt 2 ti 'data',\
                      'f-interp.dat' w l lt 3 ti 'linear',\
                      'f-interp.dat' u 1:3 w l lw 2 lt 7 ti 'akima'"
$

One-dimensional interpolation

building an histogram

Take a file with three hundred values of measurements taken with a digital chronometer of the period of a simple pendulum (assignment part of an experimental physics course back in 2004), and build an histogram to see what the distribution of the samples is:
# compute an histogram representation of individual samples
# call this input as
# wasora histogram.was histogramdata 300 15 2.25 2.55 | qdp --with histeps
# wasora histogram.was histogramdata 300 15 2.25 2.55 | gnuplot -p -e "plot '< cat' with histeps"

NUMBER N $2    # number of samples
NUMBER n $3    # number of bins
NUMBER a $4    # lower end of range
NUMBER b $5    # upper end of range

VECTOR x SIZE N     # vector with the actual data
VECTOR hist SIZE n  # histogram bins

# either read data from a file 
READ x ASCII_FILE_PATH $1
# or generate some random data
# x(i) = random_gauss(0.5,0.2)

s = (b-a)/n
hist(i) = sum(is_in_interval(x(j), a+(i-1)*s, a+i*s), j, 1, N)

PRINT_VECTOR FORMAT %g a+(i-1/2)*s hist 

The input file expects five extra arguments that should be provided in the command line. The output wasora gives can be directly piped to gnuplot:

$ wasora histogram.was histogram-samples.dat 300 15 2.25 2.55 | gnuplot -p -e "plot '< cat' with histeps"
$

Histogram of experimental data

the logistic map

Build a classical chaotic attractor by parametrically and iteratively solving the logistic map for different values of the parameter r within a certain range:
# compute the logistic map for a range of the parameter r

DEFAULT_ARGUMENT_VALUE 1 2.6  # by default compute r in [2.6:4]
DEFAULT_ARGUMENT_VALUE 2 4

# sweep the parameter r between the arguments given in the commandline
# sample 1000 values from a halton quasi-random number sequence
PARAMETRIC r MIN $1 MAX $2 OUTER_STEPS 1000 TYPE halton

static_steps = 800     # for each r compute 800 steps
x_init = 0.5           # start at x = 0.5
x = r*x*(1-x)          # apply the map

# only print x for the last 50 steps to obtain the asymptotic behaviour
IF step_static>static_steps-50
 PRINT %g r x 
ENDIF

Even though logistic.was expects the range of the parameter r to be given in the command line, it defaults to [2.6:4] which shows the characteristic period-doubling route to chaos:

$ wasora logistic.was | gnuplot -p -e "plot '< cat' pt 0 lt 3 ti ''"
$

The logistic map

Click on the image to access a mouseable vector figure generated with gnuplot's HTML5 canvas terminal out of wasora's output.

the lorenz chaotic system

Build your own version of the famous Lorenz attractor that introduced for the first time the idea of what nowadays we call chaotic attractor in a humanly-friendly way. First, state which variables belong to the phase space and choose the final integration time. Then define the constant parameters and set the initial conditions. Finally write down the differential equations as naturally as it is possible to do so in a plain-text computer file:
# lorenz' seminal dynamical system
PHASE_SPACE x y z
end_time = 40

CONST sigma r b  
sigma = 10            # parameters
r = 28
b = 8/3

x_0 = -11             # initial conditions
y_0 = -16
z_0 = 22.5

# the dynamical system
x_dot .= sigma*(y - x)
y_dot .= x*(r - z) - y
z_dot .= x*y - b*z

PRINT t x y z HEADER

# exercise: play with the system! change
# the parameters and plot, plot plot!
$ wasora lorenz.was | gnuplot -p -e "splot '< cat' u 2:3:4 w l lt 2 ti ''"
$

Lorenz' chaotic attractor

Click on the image to see an SVG version of the attractor. This example illustrates the kind of syntactic sugar wasora tries to provide. See also the section about The Lorenz chaotic system and The chaotic Lorenzian waterwheel amongst other further examples in The wasora Real Book.

mathace: the plot thickens

Donald Knuth introduced this mystery equation in one of his books. What does it represent? Find out by solving it parametrically sweeping the xy plane with a Sobol quasi-random number sequence (do not scroll down until trying to understand the equation shown in the input):
# Knuth's mystery equation
f(x,y) := {
 ( abs(abs(3-abs(x)) - 3 + abs(x)) + abs(abs(sqrt(abs(9-x^2)) - abs(y-2/3*abs(x))) - sqrt(abs(9-x^2)) + abs(y - 2/3*abs(x)))) *
 ( abs(abs(x*y) + x*y) +
   ( abs(abs(2 - abs(33-3*abs(x))) - 2 + abs(33-3*abs(x))) + abs(14 - abs(y)) ) *
   ( abs(16 - abs(y) - 3*abs(11 - abs(x))) *
      abs(abs(sqrt(abs(1 - (11 - abs(x))^2)) - abs(11 - abs(y) + 2/3*abs(11 - abs(x)))) - sqrt(abs(1 - (11 - abs(x))^2)) + abs(11 - abs(y) + 2/3*abs(11 - abs(x))))
      + abs(abs(1 - abs(11 - abs(x))) - 1 + abs(11 - abs(x))) )
 )
}

DEFAULT_ARGUMENT_VALUE 1 sobol
DEFAULT_ARGUMENT_VALUE 2 2e5

# the range to sweep
PARAMETRIC x y MIN -13 -18 MAX 13 18 TYPE $1 OUTER_STEPS $2
                 
IF abs(f(x,y))<1
 PRINT %f x y
ENDIF
$ wasora mathace.was  | gnuplot -p -e "plot '< cat' pt 0 ti ''"
$

Knuth's mystery equation

fitting the semi-empirical mass formula

See how wasora can be used to fit multidimensional data sets by finding the the empirical coefficients of Weiszäcker's formula for the binding energy of atomic nuclei:
# fit the six parameters of the semi-empirical mass formula to
# experimental binding energy per nucleon data

# initial guess
a1 = 1
a2 = 1
a3 = 1
a4 = 1
a5 = 1
gamma = 1.5

# the functional form of weiszacker's formula
delta(A,Z) := if(is_odd(A), 0, if(is_even(Z), +1, -1))
W(A,Z) := a1 - a2*A^(-1/3) - a3*Z^2*A^(-4/3) - a4*(A-2*Z)^2*A^(-2) + delta(A,Z) * a5*A^(-gamma)

# the experimental data
FUNCTION D(A,Z) FILE_PATH binding_per_A.dat

# fit W to D using the six parameters
FIT W TO D VIA a1 a2 a3 a4 a5 gamma

IF done_outer
 PRINT_FUNCTION D W D(A,Z)-W(A,Z)
ENDIF
$ wasora fsm.was | gnuplot -p -e "set cbrange [0:9]; set view map; \
                                  set xlabel 'A'; set ylabel 'Z'; \
                                  splot '< cat' u 1:2:4 w p pt 57 palette ti ''"
$

Weizsäcker's semi-empirical mass formula

See also the section about Semi-empirical mass formula fit at the wasora Real Book for a comparison between the ftting method proposed by wasora and other approaches.

checking wasora's coupling mechanisms

This test checks that wasora can read data from ASCII files, and that the coupling mechanism through semaphore-synchronized shared-memory objects (whose actual type is be OS-dependent) is able to correctly exchange information amongst two instances of wasora. First, an ASCII file with numerical data is created:
$ echo 1e-1 1.23456 0.999999999999999 -9.876543210987654321e2 > data.dat
$

One input file, io-readfile-writeshm.was, reads the file and writes the data into a shared-memory segment:

# read a scalar and a vector of size three from a file and
# send them  to another wasora instance through shared memory
VAR a
VECTOR b SIZE 3

FILE data data.dat MODE r   # define a file id
READ ASCII_FILE data a b    # read data from the file

WRITE SHM_OBJECT data a b   # output a & b to a shm-object called "data"
SEM data-written POST       # post a shared semaphore called "data-written"
SEM data-read    WAIT       # wait until the other end reads the data

PRINT %g a b SEP " "

Another input, io-readshm.was, waits until the data is ready to be read from the shared-memory object and writes the data to the standard output:

# read a scalar and a vector from a shared-memory object
VAR a
VECTOR b SIZE 3

SEM data-written WAIT       # wait for a semaphore called "data-written" to be posted
READ SHM_OBJECT data a b    # read from a shm-object called "data" a & b
SEM data-read    POST       # post a semaphore called "data-read" to inform the other end

PRINT %g a b SEP " "

These two inputs may be executed concurrently in separate terminals, or the first may be executed in background using Bash's ampersand & control operator:

$ wasora io-readfile-writeshm.was & 
[4] 16201
$ wasora io-readshm.was
0.1 1.23456 1 -987.654
0.1 1.23456 1 -987.654
[4]+  Done                    wasora io-readfile-writeshm.was
$

sending the Rössler attractor through shared memory

A further illustration of the coupling scheme wasora proposes—which may be used to couple wasora to other arbitrary codes—is obtained by solving a problem in one input and generating the output in another one. The first one solves the Rössler system:
# solve roessler attractor and write the instantenoeus state
# to a shared memory object
end_time = 100

VECTOR x SIZE 3
PHASE_SPACE x

CONST a b c            # system parameters
a = 0.2
b = 0.2
c = 5.7

x_0(i) = i+0.123456    # initial conditions as a function of i

# system of equations written in implicit form
0 = -x_dot(1) - x(2) - x(3)
0 = -x_dot(2) + x(1) + a*x(2)
0 = -x_dot(3) + b + x(3)*(x(1) - c)

# write t, dt, done and vector x to shared object "state"
WRITE SHM_OBJECT state t dt done x

# tell the receiver the data is ready through a "sender_ready" semaphore
SEM sender_ready   POST  

# wait until the other read the data end before advancing another step
# if we are on the first step, we write a message to remind the user
# that the other instance of wasora is to be executed at the same time
IF in_static
 PRINT "\# waiting for other end to read my data..." NONEWLINE
ENDIF

SEM receiver_ready WAIT  

IF in_static
 PRINT "ok!"
ENDIF

# note that this input does not produce any output

The second input just reads the data generated by the first and writes the status to the standard output at each time step:

# receive a 3d phase-space trajectory data from shared memory
# and write the ascii data into the standard output

# we do not know where the data comes, but it should
# be a three-dimensional phase-space trajectory
VAR x y z 
# we do not know the end time either, so we start assuming
# we run through infinite but actually end when done is true
end_time = infinite

# print a message to remind the user that another wasora
# sending the data is to be executed
IF in_static
 PRINT "\# waiting for data..." NONEWLINE
ENDIF

SEM sender_ready WAIT

IF in_static
 PRINT "ok!"
ENDIF

# read t, dt, done, x, y and z from shm-object "state"
# note that roessler-sender defines x as a vector of size 3
# we defined x as a scalar, and read x, y and z
# this is a perfectly valid coupling schme!
READ SHM_OBJECT state t dt done x y z
SEM receiver_ready POST

# print the data so it can be finally plotted
PRINT %f t x y z

Again, both inputs may be run in different terminals or in the same one using the & operator. Only the second should be used to plot the result:

$ wasora roessler-sender.was &
[4] 16672
$ wasora roessler-receiver.was | gnuplot -p -e "splot '< cat' u 2:3:4 w l lt 1 ti ''"
# waiting for other end to read my data...      ok!
[4]+  Done                    wasora roessler-sender.was
$

Rössler attractor

documentation

Currently, wasora's full documentation is still incomplete. Nevertheless, it contains a reference section that lists all the

that the wasora parser understands. The following files also contain some useful information:

the wasora real book

As with jazz, wasora is best mastered when played. Visit The wasora Real Book which, as the original, will guide you through wasora with fully-usable examples of increasing complexity and difficulty. The examples come with introductions, wasora inputs, terminal mimics, figures, videos and discussions. realbook This book—that is not a book—is a living document that is eager to be fed by users willing to share experiences.

Noteworthy sections include:

The sources and scripts that generate the Real Book examples are included in the wasora repository in the subdirectory realbook.

plugins

As illustrated in the Finding prime numbers section of the wasora real book, wasora's capabilities can be extended by loading user-provided routines in the form of shared-object files. However, if the desired extension is fairly complex, the best choice is to use the plugins mechanism, which consist of ad-hoc libraries that interact with some sort of API wasora provides (and of course is not yet documented). The two most useful plugins are besssugo and milonga, although more are being developed:

  • besssugo plugin to generate scientific videos
  • milonga free nuclear reactor core analysis code
  • waspy interface to execute Python code within wasora

Clone a plugin skeleton that can be used as a template to write a plugin for wasora from scratch:

wasora and its plugins are sometimes called the wasora suite.

mailing list

There exist a mailing list < wasora @ talador.com.ar > where questions can be posted about any aspect of the code, including intallation, usage and development. Besides suscribing and directly asking a question, you can also browse the archives. Bugs reports are also welcome.

plaforms

wasora is free software, and as such it is developed under a free operating system, namely Debian GNU/Linux. The distribution tarball is based on GNU Autoconf & friends, so wasora should build in any POSIX-compliant environment. However, wasora is a fairly complex piece of software, so portability is not guaranteed (but improvements are welcome). Running wasora in non-free operating systems is discouraged, and such topic is not of the interest of the author of wasora. However, contributions and experiences may be well received if discussed in the mailing list.

license

wasora is released under the terms of the GNU General Public License version 3, or at your option, any later version. Bottomline is, you get the four software freedoms

  • The freedom to run the program, for any purpose (freedom 0).
  • The freedom to study how the program works, and change it so it does your computing as you wish (freedom 1). Access to the source code is a precondition for this.
  • The freedom to redistribute copies so you can help your neighbor (freedom 2).
  • The freedom to distribute copies of your modified versions to others (freedom 3). By doing this you can give the whole community a chance to benefit from your changes. Access to the source code is a precondition for this.
The condition is that if you modify the code and/or include it in a larger package and you want to distribute it, you have to release it under the same terms of the GPLv3+. That is to say, you cannot turn any derivative work based on wasora into a privative software. However, private modifications not intended for distribution may be produced and, if desired, never undisclosed at all. See the GPL FAQs or contact the mailing list for further details.

projects wasora relies on

Following good practices in UNIX programming, by design wasora tries to reuse as much as possible already-available high-quality free software (especially regarding numerical methods, which are better analyzed by mathematicians and better coded by professional programmers than by myself).

required libraries

GNU Scientific Library
wasora extensively relies on the GSL to provide numerical integration, differentiation, vectors & matrices, interpolation, root-finding, random number generation, multidimensional optimization, etc. See the GNU Scientific Library examples rewritten section of The wasora Real Book for some particular examples.

Therefore, this library (and its development headers) is mandatory to compile wasora. In Debian-based systems, the needed components can be installed with

$ apt-get install libgsl0-dev

 

optional libraries

SUite of Nonlinear and DIfferential/ALgebraic equation Solvers
In order for wasora to be able to solve systems of Differential-Algebraic-Equations (DAEs) such as the The Lorenz chaotic system, the IDA library (and its development headers) has to be installed. Again, the needed components can be installed with
$ apt-get install libsundials-serial-dev
GNU Readline Library
This library is needed if interactive debugging facilities are desired in wasora (i.e. ability to stop a transient calculation at arbitrary breakpoints and to query values of variables, vectors or matrices). Install it with
$ apt-get install libreadline-dev

 

other useful packages

Pyxplot
Scientific Scripting Language, Graph Plotting Tool and Vector Graphics Suite
quick & dirty plot
a wrapper around pyxplot to generate figures from the commandline
Gnuplot
Gnuplot is a portable command-line driven graphing utility for Linux, OS/2, MS Windows, OSX, VMS, and many other platforms.
Gmsh
A three-dimensional finite element mesh generator with built-in pre- and post-processing facilities
Doconce
Document once, include anywhere

publications

The following technical papers have directly or indirectly used wasora to perform different kinds of computations:

© jeremy theler 2004—2014