Mostrando las entradas con la etiqueta tnt macros. Mostrar todas las entradas
Mostrando las entradas con la etiqueta tnt macros. Mostrar todas las entradas

viernes, octubre 23, 2009

TNT macros: Variables (2)


In a previous entry I wrote about variable declaration under TNT macro language, in this post I show the most important aspect of variables: their access.

Variables can be accessed in two ways, for reading, in which the value stored on the variable is retrieved. The second access way is for writing, in which a value is assigned to a variable.

General variables

In TNT general variables (variables declared with var keyword) are accessed by its name inside single quotations (').
quote The number stored on variable is 'value' ;
hold 'number' ;
In this example, the number stored on value is printed and the number stored in number is used as the maximum tree hold. This is an important feature of the language: you can replace any command parameter by the value of variables. This gives an extraordinary flexibility to TNT's macros.

Sometimes, specially at linux version, it is necessary to use parenthesis to read successfully the variable:
hold ('numero') ;
To access arrays, the same format is used, with an index inside squared brackets ([]).
quote the value of the fourth element is  'vector [4]' ;
It can be a more complex (and useful) way for this example
quote the value of the 'i' element is 'vector ['i']' ;
Note that the variable i is also inside quotations. If you are somewhat familiar with some computer programming language, you note that quotations are a way to "dereference" of a variable.

This is an example for a multidimensional array
quote the value of the element 'i' , 'j' is 'mat ['i' , 'j']' ;
Using parenthesis (()) you can use math operations as index values. Here is an example with a two dimensional array, but that is exactly equal with any kind of array:
quote the value of the element 4, 'j' is 'mat [ (2 + 2 ) , 'j' ]' ;
Another option is the use of series
quote the value of the elements 3 to 8 is 'list [ 3 - 8 ]' ;
In this case, note that there are no parenthesis limiting the scope! If you put parenthesis, TNT interpret it as a mathematical operation.

To write values on general variables, the keword set is used with the name of the variable to assing, without quotations, and followed with the assigned value
set val 4 ;           /* Assigns 4 to val */
set res (3 + 4) ; /* Assigns a math operation */
set num 'val' ; /* Assigns the content of val to num */
Note that as is the value of the variable that is assigned to num, then val must be inside quotations. To assign arrays, it is possible to use the same format, just using one element at time.
set vec [4] 5 ;                 /* Assigns 5 to the 4th element of the array*/
set arreglo [ (2 + 3) ] 8 ; /* Assigns 8 to the 5th element of the array */
set arreglo ['i'] 10 ; /* Assigns 10 to the i-element of the array */
set arreglo [ ('j' + 'k') ] 7 ; /* Assigns 7 to the element j + k of the array */
Note that indexes must be dereferenced!

Many times, an operation to a variable is just a modification of its value, for example increase its value by one
set val 'val' + 1 ;
It is more clear and intuitive, modifying directly the variable without dereference it, this can be done using a C-like sintaxys
set val ++ ;              /* increase by 1 */
set arr [3] -- ; /* decrease the content of element 3 in 1 */
set mat [2, 4] += 'val' ; /* adds the value of val to the element 2, 4 of mat */
set num *= (3 + 'j') ; /* multiplies the content of num by (3 plus j)-times */
set arr [2] /= 3 ; /* divides the content of element 2 of arr by 3 */
set val -= 4 ; /* decreases the content of val in 4 */
In some cases, you want to store all array elements at the same time. This can be done with the keyword setarray. It is important that array dimensions coincide with the dimensions used in the declaration. The format of setarray is the name of the array followed by the name of the array an the elements.
var:
lista [5, 4]
;
setarray 5, 4 lista 0 1 1 1 1 0 1 1 1 1 0 1 1 1 1 0 2 2 2 2 ;
In this example, the following matrix is assigned to a 5x4 array
0 1 1 1
1 0 1 1
1 1 1 0
2 2 2 2
The order of the elements follows the dimensions from left to right, then the first four elements assigned to the array are the array elements [0, 0], [0, 1], [0, 2] and [0, 3].

Variables in loops

Usually, loop variables are control variables, so the best option is not modifying them. So in principle, write the code as if loop variables are read-only. If a loop variable needs to be modified TNT can do it, but that usually shows a design problem, and it is not a good practice to make that modifications.

Loop variables can be accessed using using names or number. Is a good practice to use names to identify loop variables.

To read a loop variable the number or name of the cicle must be preceded by number character (#). For example to save a simple search of several k values using implied weights [1]
loop =kval 1 10
keep 0 ;
piwe = #kval ;
mult ;
tsave* resu#kval.tre ; save; tsave /;
stop
As #kval is the name of the first cicle, then is possible to use #1, then to save the tree it would be
tsave* resu#1..tre ;
Note the double point after #1, that is because a point is interpreted by TNT as a decimal fraction, and assumes that the point is part of the name. In any case, it is better to use names ;). The numbering of loops is assigned in relation with its nestedness, starting with #1.

To modify a loop variable the keyword setloop is used, that change the most nested loop (i.e. the loop in which the instruction is used). As changing the value of loops distorts their sequence, you must be aware of infinite-loops. This is the reason that makes the change of loop variables unsafe and unrecommended. But, some times it is necessary a non-stop loop that finish only when a specified condition is meet. In that case, using endloop coupled with setloop can be very useful
var:
i
;

set i 0 ;
loop =non 0 1
/* several instructions */
if ('i' == 1)
endloop ;
else
setloop 0 ;
end ;
stop
It is assumed that somewhere inside the loop, the value of i is changed to 1.

Command line variables

Variables from command line are read-only. Then, we only can access their value. To access a command line variable it is used the percent sign (%).
set j %1 ;
Assigns j to the first parameter from the command line (by the way, %0 is the name of the macro). Trying to read more parameters than parameters actually provided, is an error and stops the execution. When you write a macro, keep in mind that command line parameters is the only way to communicate with the user, so it is necessary to do a good choice of reading order and default values.

As always, do not forgive to keep your TNT copy updated. And check the TNT wiki or join the TNT google group to deal with any question!

References
[1] Goloboff, P.A. 1993. Estimating character weights during tree search. Cladistics 9: 83-91. DOI: 10.1111/j.1096-0031.1993.tb00209.x

Previous post on TNT's macros

lunes, octubre 19, 2009

The behemot! for free! / El behemot gratuito!

Santí noted that the "behemot"'s paper [1] is now available for free from Wiley/Blackwell web-page, this is the link:


Or you can jump directly to the paper abstract and download the pdf:


If you want to look the results, Pablo post a quick guide to manage the trees and extract info from them. If you want to check you favorite group, or just play for a moment, there are no excuses ;)!

And the best of it, as they are macros, you can use for your own trees! and don't forget to check out the TNT wiki!


Santí me hizo notar que el paper donde el "behemot" vio la luz [1] se encuentra disponible de manera gratuita en el sitio de blackwell. El enlace es este:


O pueden ir directamente a la pagina del artículo y descargar el pdf:

Para quienes quieran jugar con los resultados, Pablo publicó una guía rápida para manejar los árboles y poder extraer info de ellos. Así que si tienen curiosidad por ver como quedo el grupo que ustedes trabajan, o simplemente quieren pasar un rato, ya no hay excusas ;)

Y lo mejor de todo, como son macros, se pueden usar en sus propios resultados :D! No se olviden de consultar la wiki de TNT ;)

[1] Goloboff, P.A. et al. 2009. Phylogenetic analysis of 73 060 taxa corroborates major eukaryotic groups. Cladistics 25: 211-230. DOI: 10.1111/j.1096-0031.2009.00255.x

sábado, agosto 29, 2009

TNT macros: variables (1)


I forget an important feature. The commentaries.

TNT's macro language support the same multiline comment style of C (but not the single line comment style), enclosing comments within /* and */. Comments has no effect on the script, but are very useful to document the code!

/* This is a comment */

Comments are really important, no only to made code legible to other people, but also to our own understanding (specially, if it is code written long time away!).

Comments are valid after the macro mode is open (using macro =).

Following a well knew tradition I put this simple macro ;)

macro =;
/* My first TNT macro */

quote Hello world! ;
p/ ;

Now, we can enter on the subject of variables...

Variables are objects that the program manipulates by an specific objective given by the user. Variables store values, that can be modified or read. Usually we are interested in that value. In other circumstances the variable value is useful for controlling the program flow. Also they are used to store values given by the user.

When macro mode is open, TNT sets a default number of variables (1000). They can be accessed by a number, starting with 0. It is possible to change the amount of variables using macro* N K ; where N is the number of loops, and K the number of variables.

General variables

Using numbers to access variables can be useful for small scripts, but with more complex macros, the management of code can be very difficult. Then, is a good practice to use names for variables. Variables can be named in any part of the code. It is a good practice naming it just after starting the macro's file (just after macro = ). Variables names are declared using the keyword var.

There are two ways to name variables, the first is explicit, that is useful to backward compatibility with scripts written in old versions of TNT.

Var =
0 variable1
1 variable2
5 variable 3
;

In this format, using var =, each variable is declared using the internal number of TNT. The declaration finish with a semi colon. The principal problem with this style, is that it is an invitation to use the numbers instead of the names. This can be dangerous when parts of the code change (for example, adding more variables).

A more elegant way, and more secure (protects against usage of unnamed variables), is declaring directly the names, using var : instead of var =

var :
variable1
variable2
variable3
;

Here, I always use this style, that produce a more legible code.

TNT variables can be simple, that is, just with one value, or can be arrays, a vector of several consecutive values. TNT arrays are static, that is, they cannot be resized in running time. Then declare them only after you know the size of the array. For example, just after reading the data, and we known the number of nodes in a tree.

An array declaration is simple, just as a normal variable, but dimensions inside brackets ([]), if it is a multidimensional matrix, use a comma (,) to separate the values, in a similar way that arrays are declared in pascal.

Var:
anArray [25]
aMatrix [3, 4]
;

Variables in loops

In TNT loop variables are independent from general variables. This variables are managed by TNT and not directly by the programmer. As general variables they can be named, o accessed using a number that start from 1, and increase in each nesting level. I generally use numbers. Maybe a better practice is to use names, as that freed the loop from its nesting level, an that's the only way to access some variables (for example, if you access it from another file).

Loop variables are declared using an equal before the name:

loop =cicle 1 10

Variables in the command line

When a macro is called, it is possible to assign some initial values from the command line associated with the script. This variables are sometimes known as arguments or parameters. For example, a macro called dojac can receive as parameters the number of replicates and the number of iterations per replicate

dojac 1000 20 ;

Then, dojac receives 1000 replicates and each replicate with 20 iterations.

As TNT's scripts are not interactive, this is the only way to the final user to modify the behavior of the scripts. Then, if the idea is to distribute the macro, calling the macro without parameters shows a help screen explaining the objective, the parameters, and the conditions necessary for using the macro in a correct way.

The function argnumber returns the number of arguments used when calling the macro.

Not forget to check out for TNT updates, and of course, several scripts and useful documentation at the TNT wiki :D

miércoles, mayo 06, 2009

TNT macros: Intro


One of the most powerful utilities of TNT is its macro's language. This language allows access to TNT internal variables, and tree and data manipulation. This coupled with the computer power of TNT makes a terrific combination.

Unfortunatelly, maybe because of a lack of an extensive manual, or because there are few papers that explicitly use TNT macros (but they are growing!), then this capability is ignored for several users. In this series of posts, I want to give an introduction of the many possibilities allowed by the usage of macros.

Part of this idea born after I see the book "phylogenetics with R" [1], and the constant exchange with Santi Catalano about the TNT's wiki. I hope to post part of this series on the TNT's wiki, but for the moment, just to get the writing feeling, I post it first on my blog ;).

The style is somewhat orientated to programming--I'm powerfully influenced by Kenighan and Ritchie :)--because I think it is the best way to learn the language.

Notation

The TNT macro language is an interpreted language, this is, each instruction is executed as it is readed, then it is possible to “write” the programs in real time (just like the old BASIC, lisp, or the fashionable python).

This can be very nice, for example, to make some simple mathematical operations directly on TNT.

An example:
> macro = ;
Macro language is ON
> var: dest ;
> set dest 4 + 5 ;
> quote 'dest' ;
9
This simple calculator can introduce us in some particularities of the language.

To activate macros, the command macro = ; must be invoked, macro - ; deactivates the macros.

Each instruction finish with a semi colon (;). Although not necessary, for clarity, an space before the semicolon is a good practice.

The keyword var is used to declare variables.

The keyword set assigns a value to a variable. In the example it is a sum. Set accepts the four basic operations, as well as more complex combinations using parenthesis.

The command quote prints on the screen. In TNT to access the value stored into a variable, the name of the variable must be between simple quotes ('). Note that set assigns a value, so the name is written without quotations, but if the value assigned is stored into a variable, then that values must be in quotations:
set dest 'first' * 'second' ;
This operation assigns to dest the value of first times second.

But more important, is that TNT macros can be written on separate file, and executing like any commando of the program.

If the macro is saved with the ".run" extention, and is on the same working directory of the program (for example c:\bin\tnt) it is possible to call the macro just typing the name of the file. For example, TNT is distributed with the macro stats.run, that calculates consistency and retention index of the trees in memory. To execute it, only is necessary to type:
> stats ;
in the program command line, and the macro runs automatically.

As any file of TNT it can be accessed using proc command (but you lost the parameter list) of the macro. It is better to use the command run (or just write the macro's name). As any command macros can be accessed trough the OS command line.

Exercises

As exercises try to use the different ways to call a macro, as well as accessing values with the commands, think on scripts like this:
macro = ;
var:
numIts
numTrees
itTrees;

set numIts 100 ;
set itTrees 10 ;
set numTrees 'numIts' * 'itTrees' ;

rseed 0;
hold 'numTrees' ;
mult = replic 'numIts' hold 'itTrees' ;
nel * ;
p/ ;
That does noting that you can do more easily by hand, but allows you to get familiarity with the notation.

References
[1] Paradis, E. 2006. Analysis of phylogenetics and evolution with R. Springer