2013/04/14

The trickery that is std::numeric_limits::min()

Pop quiz: what is wrong with the following C++ code:

#include <limits>
#include <algorithm>

template<typename T>
class MaxValue
{
 public:
  MaxValue():
   val(std::numeric_limits<T>::min())
  {
  }

  void operator()(const T& v)
  {
   val = std::max(val, v);
  }
 
  T get() const
  {
   return val; 
  }
 private:
  T val;
};

template<typename T>
class MinValue
{
 public:
  MinValue():
   val(std::numeric_limits<T>::max())
  {
  }

  void operator()(const T& v)
  {
   val = std::min(val, v);
  }
 
  T get() const
  {
   return val; 
  }
 private:
  T val;
};

It seems okay right, initialise to the lowest possible value (or highest) and then always take the maximum of the current value and the new value (or minimum). Well, enter the mess that is std::numeric_limits<T>::min(). The description on cplusplus.com reads as follows:

Minimum finite value.
For floating types with denormalization (variable number of exponent bits): minimum positive normalized value.

Read that again, it does say minimum positive (normalized) value. That's right, if you use double's numeric limits, the value min() returns is 2.22507e-308 on my machine, which is pretty close to zero. On the other hand, if you call the same function but with the also-signed int as template parameter, it returns the expected value of -2147483648. Who thought it was a good idea for a function called "min" to return something other than the minimum?

Instead of using min(), you should either use the lowest() function defined on the same class if you're lucky enough to be using C++11, or use minus std::numeric_limits<T>::max() and pray your underlying floating point type is symmetrical as not to cause an underflow...

2011/08/17

On the performance of forward (linear) iterators of std::vector and std::list

The Experiment

I've been wondering for a while; when iterating linearly over an ordered collection of values; what's faster, an std::list or an std::vector. Today I set up the following C++ experiment:

(univhac.h is an extremely minor project of mine which can be found on http://univhac.googlecode.com/svn/trunk/univhac.h).

I'm only using the last two runs, the first two runs are just to warm up the cache.

The Result

This is with time on the y-axis and the 2-logarithm of the size linear access was tested on on the x-axis. The little disturbances for x < 10 are measurement errors and not repeatable.

Conclusion

Although std::list is slightly faster than std::vector for linear access, the difference on my laptop is maybe 1-2%. So, when all you care about is speed, and all you need is linear access, it really doesn't matter if you pick an std::list or an std::vector. I'd probably go for an std::vector, in case I ever need random access. Now, memory usage is another story, more on that later...

2011/07/12

A CMake module for finding librsync: Findrsync.cmake

I realize this isn't very hard to write, but if I can save one person five minutes, it's worth it. The latest version of the code can be found at https://gist.github.com/1077849.

# Written by Ives van der Flaas , 2011
#
# License: Public domain.
#
# Defines
#
#  RSYNC_INCLUDE_DIRS
#     which contains the include directory for librsync.h
#
#  RSYNC_LIBRARIES
#     which contains the library directory for librsync.a

set( SEARCHPATH /usr /usr/local /opt /opt/local $ENV{HOME}/opt)
   
find_path( RSYNC_INCLUDE_DIRS librsync.h
    PATHS ${SEARCHPATH}  
    PATH_SUFFIXES include 
)  

find_library( RSYNC_LIBRARIES rsync
    PATHS ${SEARCHPATH}  
    PATH_SUFFIXES lib 
)

unset( SEARCHPATH )

include( FindPackageHandleStandardArgs )
FIND_PACKAGE_HANDLE_STANDARD_ARGS(rsync DEFAULT_MSG RSYNC_LIBRARIES RSYNC_INCLUDE_DIRS)

2011/06/25

Installing the Auto 1 fonts in MikTex

(This is mainly for my own reference when re-installing).

From here on, if I'm talking about a "root", this will mean the directory C:\Program Files (x86)\MiKTeX 2.9 or equivalent (this directory should contain the folders "fonts" and "tex").

First, download Nico Schlömer's Auto1 package at CTAN. Also find some way to get the actual TTF Auto 1 files as sold by Underware.

Copy the files from

  • enc/ in the zipfile to root/fonts/enc/dvips/auto1
  • map/ in the zipfile to root/fonts/map/dvips/auto1
  • tfm/ in the zipfile to root/fonts/tfm/underware
  • vf/ in the zipfile to root/fonts/vf/underware
Also copy the TTF auto 1 font files to root/fonts/truetype/underware, and make sure they're named
Auto1-BoldSmCp.ttf
Auto1-Bold.ttf
Auto1-BlackItalicLF.ttf
Auto1-LightSmCp.ttf
Auto1-ItalicLF.ttf
Auto1-BoldItalicSmCp.ttf
Auto1-LightItalic.ttf
Auto1-Regular.ttf
Auto1-BoldItalic.ttf
Auto1-LightLF.ttf
Auto1-LightItalicSmCp.ttf
Auto1-BlackSmCp.ttf
Auto1-BoldLF.ttf
Auto1-BlackItalic.ttf
Auto1-BoldItalicLF.ttf
Auto1-Light.ttf
Auto1-BlackLF.ttf
Auto1-RegularLF.ttf
Auto1-Black.ttf
Auto1-ItalicSmCp.ttf
Auto1-LightItalicLF.ttf
Auto1-RegularSmCp.ttf
Auto1-Italic.ttf
Auto1-BlackItalicSmCp.ttf

Now the LaTeX part: enter the doc/ directory in the zip file and execute pdflatex Auto1.ins. This will generate an STY file and some FD files. Copy both the STY and all of the FD files to root/tex/latex/auto1.

Now register the new map file by executing the following command (as administrator):initexmf --edit-config-file updmap. Then add the line Map Auto1.map to the bottom of that file and execute initexmf --mkmaps. Open the MikTex Maintenance Settings (as Administrator) thingie and refresh FNDB and Update Formats.

I think that it might work now...

Aren't fonts in LaTeX fun?

2010/12/30

A Simple and Clean Singleton in C++

I've seen lots and lots of examples of bad singleton implemenations in C++, including this one on the Dutch Wikipedia.

There's a number of things the Wikipedia implementation does badly (or could at least have been done better)

  • getInstance() returns a pointer. There's no reason whatsoever for this.
  • The assignment m_pSingleton = new CSingleton; can be forgotten without a compile-time warning, resulting in a runtime segfault
  • The conditional if(m_pSingleton == NULL) (which should have been written as if(!m_pSingleton) or if(m_pSingleton == 0) anyway, read "The C++ Programming Language" by Stroustrup and realise that C and C++ are two different languages) can be forgotten resulting in confusing behavior

A much better solution looks like this:

#include 

class SomeClass
{
 private:
  SomeClass(){ /* Do whatever */ };

 public:
  static SomeClass& get()
  {
   static SomeClass instance;
   return instance;
  }

  void doStuff()
  { std::cout << "stuff\n"; } 
};

int main()
{
 SomeClass::get().doStuff();
 SomeClass::get().doStuff();
 return 0;
}

Let's see if my earlier comments on the Wikpedia example still apply:

  • get() (the getInstance() equivalent, feel free to name this function getInstance()) returns a reference, not a pointer.
  • If the initialisation (static SomeClass instance;) is forgotten, this will result in a compile-time error
  • There is no check, the code that makes sure the instance is only instantiated once is generated automatically by the C++ compiler
Also, by choosing my implementation over the Wikipedia one, the amount of code needed to return an instance is halved from 4 lines of code in the Wikipedia example (excluding all lines of code that are equivalent) to 2 lines of code in my example.

2010/11/25

Setting a dashed line style on a PDF terminal in gnuplot

Everyone who's tried to include a gnuplot graph with several curves on the same graph in a B&W printed report has noticed that by default, all linestyles for the pdf terminal type look the same in black and white.

You can check for yourself by giving gnuplot the commands

gnuplot> set terminal pdf monochrome
gnuplot> set output "graph.pdf"
gnuplot> test
gnuplot> unset output

This will create a new file called graph.pdf containing all possible linestyles on the right. You'll notice they all look exactly the same.

The solution for this is kind of obvious but pretty much impossible to find unless you know what you're looking for. It's possible to enable the use of dashed lines by giving an extra parameter to the set terminal pdf command. Try the commands

gnuplot> set terminal pdf monochrome dashed
gnuplot> set output "graph.pdf"
gnuplot> test
gnuplot> unset output

and you'll see dashed lines suddenly appearing on the right. You can use them like this:
gnuplot> set terminal pdf monochrome dashed
gnuplot> set output "graph.pdf"
gnuplot> plot x^2 ls 1, x^3 ls 2, x^4 ls 3
gnuplot> unset output

To set linestyle 1 (look at the test output to see what linestyle one looks like) for x^2, linestyle two for x^3 and finally linestyle three for x^4.

2010/11/10

gnuplot for people who have no interest in learning gnuplot

A really quick tutorial to get you started with gnuplot. Just start the gnuplot executable to enter the gnuplot CLI.

Plotting a basic function

gnuplot> plot x**3-4*x**2+sin(x)/x 
will plot the function x3-4x2+sin(x)/x.

Disabling the function label/legend on the top right

gnuplot> unset key
gnuplot> replot  
Will remove the label in the top right corner of the output and redraw the graph.

Outputting to pdf

gnuplot> set terminal pdf
Terminal type set to 'pdfcairo'
Options are ' size 5.00in, 3.00in '
gnuplot> set output "somefile.pdf"
gnuplot> replot
gnuplot> unset output 
Will create a new file called somefile.pdf, write it's output to it (that's what the replot command is for) and finally close the file so you can open it (unset output).

If you prefer outputting to png or jpg, just use set terminal png and set the output accordingly.

Restoring the output to standard after writing to pdf

gnuplot> set terminal pop
   restored terminal is wxt 0 

Only plotting a certain domain

gnuplot> plot [x=-1:1] x**3

Drawing the x-axis

gnuplot> set xzeroaxis
gnuplot> replot         

Setting the axis labels

gnuplot> set ylabel "data"
gnuplot> set xlabel "time"
gnuplot> replot    

That should be enough to get you started. If you'd like to know more, just check out the documentation for gnuplot.

2010/09/27

Deleting files that start with a dash in UNIX

Today I inadvertently ended up with a file that started with a dash and I tried to rm it.

The Bad Way

Ives ~ $ rm --something
rm: unknown option -- something
Try `rm ./--something' to remove the file `--something'.
Try `rm --help' for more information.
Ives ~ $ rm '--something'
rm: unknown option -- something
Try `rm ./--something' to remove the file `--something'.
Try `rm --help' for more information.
Ives ~ $ # HELP!!!
That clearly doesn't work.

The Good Way

The answer is quite simple: address the file in such a way that it no longer has a dash as the first character. In fact, carefully reading the rm error message will tell you this:

Try `rm ./--something' to remove the file `--something'.

So the solution is simple:

Ives ~ $ rm ./--something
Ives ~ $

The Good Way 2

Another way by Nathan Samson...
Ives ~ $ rm -- --something
Ives ~ $
This works because -- signals the end of option processing in a lot of Unix utilities, including touch, rm, ... and also all programs that use getopt(3) for their option processing.

2010/09/19

A Google Calendar For The University Of Antwerp Academic Calendar 2010-2011

I wasn't able to find a Google Calendar for this year's Academic Calendar on the university website, so I did what every slightly bored student would do: make my own.

You can view the calendar here and click the "+ Google Agenda" button on the bottom right to add this calendar to your Google Calendar.

The usual disclaimer: By viewing the Google Calendar referenced above and displayed below, you agree that although I checked all appointments, I cannot be held responsible in any way for possible errors in the Google Calendar.