Tuesday, 23 September 2014

Variadic print_log function

The c++11 standard allows the easy implementation of functions with variadic arguments. This ability can be exploited to build a user friendly log printing function that can take a variable number of arguments of different types:
    ...   
    // armadillo linear algebra library - http://goo.gl/5UmGY  
    arma::vec v = arma::randu<vec>(4);                                                                              
                                                                              
    print_log("this is the ",1,"-st example." );
    print_log("\u03C0 = ", pi, " and \u03C0/2 =",pi/2.0 );
    print_log();
    print_log("a vector: ",v.t());
    ...
Output:
this is the 1-st example.
π = 3.14159 and π/2 =1.5708

a vector:    0.8402   0.3944   0.7831   0.7984


First we provide the atomic versions of the function print_log defined respectivelly for zero and one arguments. Then we overload them with a variadic version taking a simple argument plus a variadic argument. Within the variadic print_log the one-argument print_log  is first called on the simple argument. Then the variadic print_log itself is called on the variadic argument which it will split again into a single argument plus a variadic argument. Thus all arguments will be printed one by one throught the one-argument print_log.

We also define a terminator function calling the one-argument print_log with the line-feed string as the argument. This function will be always called at the end of the recursion in the variadic print_log.  A pre-processor condition allows to choose at compile time if logs are to be printed or not. This is done by implementing an empty one-argument print_log  if the macro NOLOG is defined.
#include <iostream>

using namespace std;

#ifdef NOLOG

// empty one-argument version
template<typename T>
inline void print_log(T&& t) {  }

// empty one-argument-no-endline version
template<typename T>
inline void print_log_not_ended(T&& t ) { }

#else

// one-argument version
template<typename T>
inline void print_log(T&& t ) { cout << t << endl;  }

// one-argument-no-endline version
template<typename T>
inline void print_log_not_ended(T&& t ) { cout << t; }

#endif

// termination version
inline void print_log() {  cout << endl;  }

// variadic version
template<typename Arg, typename... Args>
inline void print_log(Arg&& arg1, Args&&... args)
{
    print_log_not_ended(arg1);
    print_log(args...);
    if( sizeof...(args) < 1  )
        print_log();
}

Friday, 13 January 2012

Finding the diagonal of a non-square matrix with matlab.

Sometime you need to find something similar to a diagonal in a non-square matrix. For instance, in neural networks, when you have an x layer of m units to be topologically connected to an y layer of n units, you could simply fill the diagonal elements of the matrix W of weights. so that the activations given by the weighted sum W*x would be topologically spread on the y layer.

The following matlab function returns a mask with the diagonal elements (plus a given neiborourhood)  for any matrix dimentionality.

function m = gendiag(N,M,slope)
  x=1:N;  y=1:M;
  [Y X]=meshgrid(y/M,x/N);
  M = 1-abs(X-Y);
  m = exp(-(M-1).^2/(2*(slope^2)));
end


example:

octave:12> imagesc(gendiag(70,30, 0.2))

gives



while
octave:12> imagesc(gendiag(40,75, 0.05))
gives






Wednesday, 27 January 2010

How to convert a matrix from a NxM to a X-Y-Z format

Somtimes a matrix need to be converted from the standard NxM format to a vector of X-Y-Z triplets (row-index, column-index, value).
Here you have a simple way to convert a 2D array in a X-Y-Z format in python:


from pylab import *

def mat2triplet(mat):

    rows = arange(mat.shape[0]*mat.shape[1])/mat.shape[1]
    # a vector of row indices

    cols = arange(mat.shape[0]*mat.shape[1])%mat.shape[1]
    # a vector of column indices

    values = mat.flatten()
    # a vector of values

    triplet = dstack((rows,cols,values))
    triplet = squeeze(triplet)

    return triplet


A matrix:
[[ 0  1  2]
 [ 3  4  5]
 [ 6  7  8]
 [ 9 10 11]]


is converted into:
[[ 0  0  0]
 [ 0  1  1]
 [ 0  2  2]
 [ 1  0  3]
 [ 1  1  4]
 [ 1  2  5]
 [ 2  0  6]
 [ 2  1  7]
 [ 2  2  8]
 [ 3  0  9]
 [ 3  1 10]
 [ 3  2 11]]

Monday, 18 January 2010

fscanf with python

Python does not have a fscanf function like c. Regular expressions can be used efficently to do the job. Here it is an example of how a filestream can be scanned row-by-row returning a list of all numbers encountered for each row.
First, a regex object is created with this pattern:
regex = re.compile("(\d+\.*\d*|\d*\.\d+)((e|E)(\+|\-)(\d+))*")

then it is used to find all matches within a string:
nums = regex.findall(line)

finally the list of found items is scanned in order to fill a list of numbers:
for num in nums:
    res.append(eval("%s%s" % (num[0],num[1])))

Here it is the complete function:

  import re

  regex = re.compile("(\d+\.*\d*|\d*\.\d+)((e|E)(\+|\-)(\d+))*")
  # this object will find numbers within a string
  # usage: regex.findall()

  def numscan(fstream):
      '''
      Scan a row of a given filestream 
      searching for numbers
      '''
      res = []
      # initialize an empty string

      line = fstream.readline()
      # read a line from fstream

      nums = regex.findall(line)
      # find numbers in line

      for num in nums:
          res.append(eval("%s%s" % (num[0],num[1])))
          # format the number output
          # and append it to the res list

      return res