Content-type: text/html
Man page of yacts
yacts
Section: (1)
Updated: 12 July 2015
Index
Return to Main Contents
NAME
yacts - yet another continuous time simulator
SYNOPSIS
yacts [-h] [-V]
yacts [-v] [-i]
yacts [-o out] [-v] <script file>
yacts [-s] [-v] <script file>
yacts [-p] [-v] [-f] [-c nc] [-j nj] [-n fn] [-o out] <script file>
DESCRIPTION
This program solves a system of ordinary differential equations,
specified by the yacts script, given to it as an argument. The
script must define several special variables, but is otherwise free
to make any additional computations. It may also contain more
definitions, which are parsed, but not evaluated if they do not
participate in defining values of special variables.
The yacts script is a J+ program (and, at the same time, a valid J
program, see J language documentation on www.jsoftware.com), subject
to lazy evaluation by yacts interpreter. It consists of series of
(possibly functional) assignments, like a bunch of mathematical
formulae written on a sheet of paper. Continuing this similarity, J+
language is not imperative in the sense that it does not prescribe
that the assignments will be executed sequentially in order of
specification. Rather, the program is reinterpreted each time a
driver (yacts in this case) asks J+ interpreter for the value of a
specific variable. The interpreter then performs minimum necessary
calculations to compute the requested value, while keeping track of
changed variables (the driver program can change them too) and their
dependencies. In short, J+ is J, supplemented by lazy execution and
aggressive dead code elimination.
J PLUS LANGUAGE
Consider the following J+ script, which (as all J+ scripts) is a valid
J program:
a =: 1
b =: (a =: a + 2) + (a =: a + 1)
When it is loaded into J+ interpreter, it is first converted into the static
single assignment (SSA) form.
a =: 1
b =: (a2 =: a1 + 2) + (a1 =: a + 1)
Suppose now the driver program asks J+ interpreter for the value of "a". The
interpreter finds the latest version of the requested variable and executes
the code, necessary to compute it. In this case
a =: 1
a1 =: a + 1
a2 =: a1 + 2
and the driver will receive 4. The interpreter keeps track of all the
computed values, so, if the driver subsequently requests "b", only the
following statement will be evaluated
b =: a2 + a1
returning 6. The driver may also set the values of the variables, but,
in contrast to requesting the values, the _first_ version of the variable
gets modified. So, for example, if interpreter sets the value of "a" to 5 and
then requests "a" again, the following code will be executed
a1 =: a + 1
a2 =: a1 + 2
returning 8. That's, basically, all the J+ language in a nutshell,
it is really that simple. But, coupled with J's concise array
operations and the yacts numerical library, it is powerful enough to
eloquently express a number of complex mathematical simulations and
process them efficiently in single-CPU and cluster environment.
YACTS VARIABLES
YACTS is a program, which drives the J+ interpreter to solve the problems,
expressed as systems of coupled ordinary differential equations. In fact,
it is an example program, using J+ interpreter, you can (and encouraged to)
write your own similar drivers for other problems.
Striving for simplicity, YACTS defines only three "special" variables, defining
the simulation itself, and an arbitrary number of "output" variables for
rendering (in textual or graphical form) various derived quantities. The
output variables are not part of simulation and do not take part in trajectory
file name hashing (more on this later).
The variables are:
- T
-
time, scalar. Initial, current and time of the next frame to compute.
- S
-
state, array. The initial and current state of the simulation.
- dSdT
-
state change. Change of state in time, used to compute the future state.
- OUT
-
literal, vector. The default output variable. its value is computed
and printed to standard output stream when the current frame is
processed. It is used to render the results in textual and graphical
(with the help of external utilities) form.
The user may define additional, arbitrarily named, output variables for
alternative kinds of output. The names of these variables can be specified
via the "-o" option to yacts.
Consider, for example, a trivial YACTS script, outputting the constant value:
T=:0
S=:1
dSdT=:0
OUT=: ": T, S
T=:T+0.5
The time starts at 0 and the state, initially, is 1. The time derivative
is 0 (that's why the initial value will never change). The time between
frames is 0.5 units. That is, the ODE will be integrated (possibly evaluating
dSdT many times) until the time is increased by 0.5 and then the frame will
be written to disk (in trajectory file) and processed (the "OUT" variable will
be computed and its result is printed to stdout). Running this script will
produce
$yacts constant
0 1
0.5 1
1 1
1.5 1
2 1
...
...
etc on standard output, indefinitely, very fast, and also write the
trajectory file named
constant_<some_seemingly_random_hex_number>.trj . The output shows
the current time and state at each frame (just as requested in the
variable OUT) and the "random" number is the sha1 hash of the
"meaningful" part of the YACTS script. The word "meaningful" in this
context means "all the statements, influencing the trajectory". That
is "T", "S" and "dSdT". Changes in the "OUT" variable definition, as
well as code, that influences "OUT" (but not "T", "S", "dSdT") will
not contribute to the trajectory hash. Thus, the purpose of the hash
is to help keep track of various simulation parameters (however many
the user will define) and never mix them up in the same trajectory.
Now for something a little more complex. Pendulum. :-) The pendulum equation
is a second order differential equation, which can be written as system of
two ODEs:
T =: 0
S =: 0 0.1 NB. position and velocity
sin =: 1&o.
dSdT =: ({: , (_0.1 * sin)@{.) S
OUT =: 100 gnuplot {. S
T =: T+0.3
the magic of "gnuplot" function is that when output of this yacts script
is piped through "gnuplot" program, like this
$ yacts pendulum | gnuplot
the user will see the sliding graphical plot of the last 100 points of
the pendulum position as function of time.
There are more visualization and numerical computation functions,
defined in the YACTS library.
YACTS LIBRARY
J is a very powerful language with a long history. However, it is
not the only programming language. There are other languages, in
which, historically, a number of very useful and efficient numerical
algorithms were implemented. J+ provides (and YACTS makes use of) an
efficient interface between C++ (or, potentially, any other
compiled language) and J. This interface makes it easy to "plug in"
additional well tested numerical code to be used seamlessly within
J+ environment.
For now, the following functions are defined:
- fft
-
(monad, dyad) multidimensional Fast Fourier Transform
(FFT) with FFTW library, monadic case makes the forward
transform, while the dyadic case with the left argument
of "1" the backward transform. The transform is
unnormalized: forward transform, followed by the backward
one, will multiply data by the number of elements in the
original array.
- fftr2c
-
(monad) multidimensional real-to-complex forward FFT.
- fftc2r
-
(dyad) multidimensional complex-to-real backward FFT. The
left argument is the shape of the resulting real array (this
information is not fully preserved by fftr2c).
- int
-
(adverb). The right argument of the resulting verb specifies
the integration limits, while the optional left argument the
requested error tolerances. This adverb can handle one-dimensional
integrals with infinite limits and mild singularities on
endpoints (or at specified points in the middle of interval)
using quadvav pure J integrator (it uses essentially the same
algorithm as "quadgk" function in MATLAB, but, additionally,
supports vector integrands) and will use cuhre algorithm from
the Cuba library for higher-dimensional (also, possibly
vector) integrals.
- memo
-
(adverb) similar to J memoization adverb "M.", memo caches
the computed results of a verb, so that repeated invocation
of the same verb on the same arguments does not cause the
result to be recalculated. Unlike "M.", memo stores the cache
permanently on disk, preserving it between invocations
of yacts.
- loadtrj
-
(dyad) Loads the last frame from the YACTS trajectory file,
specified by its right argument. The left argument specifies the
shape of the resulting array (the number of equations in the
loaded trajectory must fit exactly into the specified shape
for this operation to succeed). Useful for chaining several
simulations together.
- gnuplot
-
(monad,dyad) Displays a set of graphs in a sliding window when
its output is piped via "gnuplot" program. The left
argument is the number of points to accumulate in the window
(default 50), the right argument is a vector of values, each
value (when accumulated via several invocations) will produce
a separate line graph in the plot window.
- rasterplot
-
(dyad) Interpolates and plots scalar or vector fields in a
grayscale raster. The left argument is a vector of two values,
specifying the dimension of the final raster, the right argument
is either rank 2 array (in which case rasterplot performs
bilinear interpolation of its values to cover the whole
specified raster dimension) or rank 3 array with the last
dimension equal to 2 (this specifies the two-dimensional
vector field of two-dimensional vectors, which is interpolated
and rendered using the Line Integral Convolution, LIC, method,
producing a grayscale image, showing the vector field flow).
In both cases the result is 2-dimensional array with the
dimensions, specified as left argument to the rasterplot,
additionally, in the case of vector field plot, the values
lie in the range [0,1].
- pnmplot
-
(monad, dyad) renders grayscale or color raster in Portable
Anymap (PNM) format. The left argument specifies the number of
color gradations (255 by default) in the resulting image. The
right argument is either grayscale raster (2-dimensional array)
or color raster (rank 3 array with the last dimension of 3,
corresponding to RGB components of color). In both cases
the elements of arrays are assumed to lie in the interval [0,1].
The following dialog in YACTS interactive mode (available via "-i"
option) illustrates the behavior of some of these library functions:
| fft 1 2 3 4 5
|15 _2.5j3.44095 _2.5j0.812299 _2.5j_0.812299 _2.5j_3.44095
| 1 fft fft 1 2 3 4 5
|5 10 15 20 25
| (# %~ 1 fft fft) 1 2 3 4 5
|1 2 3 4 5
| (# %~ # fftc2r fftr2c) 1 2 3 4 5
|1 2 3 4 5
| fft 1 2 3 4 ,: 5 6 7 8
| 36 _4j4 _4 _4j_4
|_16 0 0 0
| ([: % *:) int 1 _
|1
| ^. int 0 1
|_1
| ([: +/ *:) int 0 1 ,: 0 1
|0.666667
| ([: +/ *:) int 0 1 , 0 1 ,: 0 1
|1
| *: int 0 1 , 1 2 ,: 2 3
|0.333333 2.33333 6.33333
| a =: 3 : '(2&((1!:2)~) ''cache miss'') ] y'
| a 3
|cache miss
|3
| a 3
|cache miss
|3
| a memo 3
|cache miss
|3
| a memo 3
|3
Vertical line on the left denotes the left boundary of the terminal window.
INTEGRATING AND PROCESSING
While integration of the ODE is inherently sequential, processing
the frames (provided they are already calculated and stored in the
trajectory file) is inherently parallel. yacts provides a number of
options to make use of this fact. In particular, it has an option "-s" to
disable frame processing (making the current instance of yacts
dedicated to integrating the ODE and saving the trajectory frames,
without processing the OUT block).
While the first instance of yacts does that, another one may be
launched (with the same problem definition, but different command
line options), which would not compute trajectory at all, but,
instead, read the frames from the trajectory file (written out by
the first instance in parallel) and process _only_ the OUT block on
each frame. There is also "-f" option, making this second instance
to hang at the end of the trajectory file, when it reaches it,
waiting for and processing the new frames as they are being appended
(much like "tail -f"). Even better, with the help of "-o" option,
several instances of "process only" YACTS may be used to display
various aspects of simulation in different windows.
Another useful options are "-c" and "-j", they make it easy to
submit array jobs on computing clusters, processing the trajectory
frames in parallel (all the while the first instance continues the
integration, as facilitated by the "-n" option). This may be useful
if processing of the frames is computationally intensive
(e.g. involves sophisticated rendering like LIC).
OPTIONS
- -h
-
The option -h or invocation with no arguments displays help.
- -V
-
Display versions of yacts and of the libraries used.
- -i
-
Interactive mode, enters read-eval-print loop with all the
yacts library functions defined. Similar in function to
jconsole, useful for developing and testing individual sentences.
- -s
-
Simulation only, disable processing of OUT blocks.
- -p
-
Processing only, disable simulation.
- -v
-
Display progress of some long running verbs. Progress reports
are printed to stderr as a running percentage. Currently
int and rasterplot (when computing LIC) will do this.
- -c nc
-
Job number of the current instance in the parallel job
array. Must be 0<=nc<nj. Default: 0.
- -j nj
-
Total number of jobs in the parallel job array. Default: 1.
- -n fn
-
Maximum number of frames to process. Processing stops, after
processing this many frames. Default: number of frames
in the trajectory file.
- -f
-
Follow. Wait and follow past the end of the trajectory file
(like "tail -f"). In case of parallel processing the -f
option applies to the last job in the array (with nc=nj-1).
Please note that it is absolutely necessary to give -n option
in this case.
- -o out
-
The name of output variable to gather output from.
Default: OUT
SEE ALSO
yacts-trj(1), gnuplot(1), display(1), convert(1).
ACKNOWLEDGMENTS
Most of the power of YACTS comes from the fact that it uses J
programming language, developed by Kenneth E. Iverson and Roger
K.W. Hui under umbrella of JSoftware, Inc and released recently
under the terms of GNU General Public License. The ODE integration
is done via SUNDIALS library, developed by Nonlinear Solvers and
Differential Equations Project at Center for Applied Scientific
Computing in Lawrence Livermore National Laboratory. The Fastest
Fourier Transform in the West (FFTW) library was developed at MIT by
Matteo Frigo and Steven G. Johnson. The Cuba library is being
developed at the Max Planck Institute for Physics in Munich by
Thomas Hahn, in there the Cuhre algorithm (used by yacts) is
by J. Berntsen, T. Espelid and A. Genz. The algorithm,
implemented and extended by quadvav numerical integrator, is
originally by Lawrence F. Shampine, professor emeritus at
Southern Methodist University.
BUGS
Probably many. Most annoying, as of current alpha version, is poor error
handling. In many cases, instead of giving error message and continuing,
yacts verbs, when facing wrong arguments or other user-provoked error
conditions, will fail assertions and make yacts quit. The error handling
will be reworked in future versions.
AUTHOR
Konstantin L. Metlov <metlov@fti.dn.ua>
Index
- NAME
-
- SYNOPSIS
-
- DESCRIPTION
-
- J PLUS LANGUAGE
-
- YACTS VARIABLES
-
- YACTS LIBRARY
-
- INTEGRATING AND PROCESSING
-
- OPTIONS
-
- SEE ALSO
-
- ACKNOWLEDGMENTS
-
- BUGS
-
- AUTHOR
-
This document was created by
man2html,
using the manual pages.
Time: 18:43:10 GMT, July 12, 2015