Tuesday, November 8, 2011

Tune your ViM

ViM (Vi iMproved) is a standard text editor for UNIX like systems. However, in its default configuration it may be difficult to work with. Below are some of the options that I use in my configuration file to tune it for more comfortable work. The ViM configuration file is ~/.vimrc. To enable any of the options listed below place the command marked in blue in your ~/.vimrc file or copy the whole file that I use to enable them all (whole file is listed at the bottom of this page).

If you are not a long term Vi user and prefer the more flexible ViM you should turn off the Vi compatibility. In this way ViM will behave more like a standard text editor.
set nocompatible
Turn on the syntax highlighting/coloring and pick the color code used by default for all files including syntax recognized by ViM (e.g. c/c++/fortran/tex/html/python).
syntax on
colorscheme default
Turn on highlighting of the searched phrase. You can search your file forward and backward using / and ? respectively. Searched phrase may be highlighting in the whole file after enabling it.
set hlsearch
Set a limit at which lines will be broken instead of wrapped. I use 150 columns which works well for all coding that I do.
set textwidth=150
Use spaces instead of tabs. Every time you use tab ViM can expand it and replace it with spaces. From my experience, replacing tabs to spaces makes the code source more portable between programmers and avoid confusion with indentation. The following options enable replacing and set two spaces per tab limit.
set expandtab
set tabstop=2
Show the more that ViM is currently in. ViM has two main modes that you will be using most often. The insert mode will be marked by showing -- INSERT -- at the bottom left corner.
set showmode
One of the most useful options of ViM is its capability to reopen the file keeping the editing position at which the file was closed. This is the most useful if you are working with very long files. I have experienced problems with this option by default and found a command that always ensures the mentioned behaviour.
set viminfo='10,\"100,:20,%,n~/.viminfo
    au BufReadPost * if line("'\"") > 0|if line("'\"") <= line("$")|exe("norm '\"")|else|exe "norm $"|endif|endif
ViM will make a backup copy of every file you will be editing. Most of the time this option may be rather disturbing since ViM will create file foo~ when you edit file foo. However, the backup copy may safe a lot of work when you accidentally save unwanted changes of delete something.
set backup
Default ViM coloring may not always work for all languages that you may work with. One can define a different syntax coloring scheme for certain file types. The following option will use desert color code for TeX files and default color code for all other file types.
autocmd FileType tex colorscheme desert
Whenever you start a new file ViM may automatically switch to the insert mode by enabling the following.
autocmd BufNewFile * startinsert
Editing a plain text file ViM will try to align the following lines based on the alignment of the previous lines. For example, if you start a line with 5 spaces, type a word and hit enter, the next line will also start with 5 spaced. To prevent ViM to auto-align the next line use the following command.
set noautoindent
Although the indentation for plain text file may be not comfortable to work with, working with various source codes makes the indentation specific for a given language very desirable. One may enable a language specific indentation using ViM syntax definitions using the following command.
filetype plugin indent on
ViM is able to show you what commands and key combinations have you just used. The bottom right corner will show you any combinations like ^w in case you hit ctrl+w. The option may be enabled by the following command.
set showcmd
ViM may display the actual cursor position in the file you are editing by giving you a row and column number in the bottom right corner. To enable a ruler put the following command in your .vimrc file.
set ruler
One may enable an incremental search in ViM allowing to see the results while you are typing the phrase to be found. Otherwise the search will start after putting a whole phrase and hitting enter.
set incsearch
If you want to have a case insensitive search treating equally phrases ABC, abc or aBc.
set ignorecase
Set the limit for command history. In command line arrows up and down will show you a history of the commands you have recently used.
set history=100
A status line with the name of the currently edited file will be always displayed after setting laststatus=2. Giving option 0 will result with never displaying and 1 with displaying it only if two or more files are open.
set laststatus=2
ViM differs from most text editors and some keys default action may be different from their action in WYSIWYG editors. Backspace is one of them. To ensure a classic action of backspace enable the following command.
set backspace=indent,eol,start
My full .vimrc looks like this:
syntax on
colorscheme default
set hlsearch
set textwidth=150
set tabstop=2
set expandtab
set noautoindent
set incsearch
set ruler
set history=100
set nocompatible
set backspace=indent,eol,start
set showmode
set showcmd
set laststatus=2
filetype plugin indent on
autocmd BufNewFile * startinsert
autocmd FileType tex colorscheme desert
set backup

set viminfo='10,\"100,:20,%,n~/.viminfo
    au BufReadPost * if line("'\"") > 0|if line("'\"") <= line("$")|exe("norm '\"")|else|exe "norm $"|endif|endif

Monday, November 7, 2011

Multiple output files with Gnuplot

Making figures with Gnuplot one may want to generate more than one figure using a one script. For example if you are analyzing data you may want to present parts of your data in different figures. One can prepare more than one figure using Gnuplot in two ways. The first one is to prepare a multiplot figure where one physical file contains more than one figure. Second option is to prepare multiple files with separate figures using a one Gnuplot script. The script below shows how to organize the Gnuplot script to prepare three different files with sine cosine and tangent functions plotted in separate files.
#!/usr/bin/gnuplot 
set terminal postscript eps enhanced color "Helvetica" 24

# change the line styles 
set style line 1 lt 1 lw 2 pt 5 ps 1 lc rgb "#d61818"
set style line 2 lt 2 lw 2 pt 9 ps 1 lc rgb "#072c76"

# set labels and ranges for axes
set xlabel "x"
set ylabel "y"
set xrange [-pi:pi]
set yrange [-1:1]

# plot 1
set output "plot1.eps"
plot sin(x) ls 1

# plot 2
set output "plot2.eps"
plot cos(x) ls 1

# plot 3
set output "plot3.eps"
plot tan(x) ls 1, sin(x)/cos(x)+pi ls 2
The crux is to set a different output file before the plot command. The script above has three plot calls for sine, cosine and tangent functions separately and all of them are preceded by the output file statements. The script prepares three different postscript files named plot1.eps, plot2.eps and plot3.eps having the plots mentioned before. All definitions common for the three plots, like the axes labels and ranges or the line styles definitions are given at the top of the script and are carried down the script by default.

Sunday, November 6, 2011

Masking a matrix in c/c++

In numerical operations on matrices one sometimes faces an issue of reducing the original size of the matrix by removing certain columns and rows. The problem may be formulated differently when remaining elements are a subblock of the original matrix or the remaining elements are scattered. The more general function would collect the scattered elements. To fully define such a procedure we must pass a vector of elements defining which columns and rows should be keept and which to be removed (for example 1 for retaining and 0 for removing). Generating of a new matrix by masking the original one is shown schematically on the figure below. 

A representation of a matrix with columns and rows that are to be removed marked in white. All blue elements will be kept and new matrix of a reduced size will be formed after removing marked columns and rows.
For symmetric masking the matrix with respect to the columns and rows we only need to pass one vector defining columns and rows to be removed. An example of such a function is presented below.
double *sm_mat_mask(int dim, int *mask, double *data){

  // count non-zero elements in mask vector
  int num = 0;
  for(int i=0; i<dim; i++){
    if(mask[i] == 1) num++;
  }

  // number of non-screened elements 
  // (number of elements in the masked matrix)
  int nelements = num*num;

  // allocate space 
  double *masked_data = new double [nelements];
  memset(masked_data,0,nelements*sizeof(double));

  // collect elements
  int offset, idx;

  int elem = 0;
  // rows
  for(int i=0; i<dim; i++){
    // only if row is not to be screened
    if(mask[i] != 0){
      offset = i*dim;
      // columns
      for(int j=0; j<dim; j++){
        // only if column is not to be masked
        if(mask[j] != 0){
          idx = offset + j;
          
          masked_data[elem] = data[idx];

          elem++;
        }
      }
    }
  }

  // return masked matrix
  return masked_data;

}
The above function takes a vector of number representing a matrix (in a row major order), its dimension and vector of 0,1 elements of the same dimension representing columns / rows to be removed. The matrix is assumed to be symmetric and the masking will also be done in a symmetric fashion. The function returns a new matrix that is a reduction of the original matrix.

Saturday, November 5, 2011

Multiplot mode in Gnuplot

Preparing figures with multiple plots is very easy with Gnuplot. First one has to specify a size of the whole figure and then enter the multiplot mode. After that every single component of the total figure is done using the usual plot function. However, every component has to be preceded by definition of its size and origin with respect to the full page (specified before entering the multiplot mode). Let us consider an example when we need to prepare a figure with 5 smaller plots. Figure 1 shows the desired structure of the plot. 

Figure 1. A block diagram of the Gnuplot multiplot mode. Blocks A,B, ... , E represent individual parts of the multi figure picture to be prepared in Gnuplot. The dimensions of multi figure picture are presented as "page height" and "page width". Block D has explicitly shown position of its origin and its dimensions.  

We begin with specifying the size of the page with height equal 4 and width equal 5. After that we enter the muliplot mode.
set size 5.0,4.0
set multiplot
One has to remember that all parameters after setting are carried down the script until the parameter is changed. In this example I will plot the same function in all parts of the plot so the labels and ranges and tics for axes may be specified only once at the beginning.
set xlabel "x"
set ylabel "y"
set ytics 0.5
After that we may proceed with plotting individual components remembering that we need to manually change all parameter that differ for individual plots. Every plot has to be started with definition of the size and origin. 
# plot A
set origin 0.0,2.0
set size 2.0,2.0
plot sin(x) ls 1
All other components may be plotted in the same way changing the origin and adjusting the size of the plot. Plot displayed on the scheme in Figure 1 may be done using the following script. 
#!/usr/bin/gnuplot 
set terminal postscript eps enhanced color "Helvetica" 50
set output "results.eps"

set style line 1 lt 1 lw 15 pt 5 ps 1 lc rgb "#d61818"
set style line 2 lt 2 lw 15 pt 9 ps 1 lc rgb "#072c76"
set style line 3 lt 3 lw 15 pt 9 ps 1 lc rgb "#072c76"
set style line 4 lt 4 lw 15 pt 7 ps 1 lc rgb "#208418"
set style line 5 lt 5 lw 15 pt 11 ps 1 lc rgb "#d97c19"

set size 5.0,4.0
set multiplot

set xlabel "x"
set ylabel "y"

set ytics 0.5

# plot A
set origin 0.0,2.0
set size 2.0,2.0

plot sin(x) ls 1

# plot B
set origin 0.0,1.0
set size 2.0,1.0

plot sin(x) ls 2

# plot C
set origin 0.0,0.0
set size 3.0,1.0

plot sin(x) ls 3

# plot D
set origin 2.0,1.0
set size 3.0,3.0

plot sin(x) ls 4

# plot E
set origin 3.0,0.0
set size 2.0,1.0

plot sin(x) ls 5
The result of the script should look as follows.

Figure 2. Gnuplot generated figure based on the scheme from the figure above and presented script.