## 31 December 2009

### Small gotcha when combining Boost.Array, Assign, and Test

When attempting to use Boost.Assign's list_of in expressions like BOOST_CHECK_EQUAL(somearray, list_of(x)(y)(z)), where somearray has a type like boost::array<T,N>, I kept running into funky errors that there was no operator<< defined with the appropriate types. So I'd define one at global scope, but the errors kept arising from the depths of BOOST_CHECK_EQUAL. It turns out that I needed to define such an operator<< in the boost namespace:

namespace boost {

template< typename charT, typename traits, typename T, ::std::size_t N >
::std::basic_ostream& operator<<(
::std::basic_ostream &os, const ::boost::array &array)
{
os << '[' << N << "]{ ";
::std::copy(array.begin(),
array.end(),
::std::ostream_iterator(os, " "));
os << '}';
return os;
}

}

## 24 December 2009

### Lit search

I finally got around to doing some lit search towards both my dissertation proposal and a poster that I need to present in February. CiteULike's been a nice way to organize the information, especially combined with SyncUThink.

The following is a snapshot of the author's that I'll be wading through:

## 22 December 2009

...the gift to yourself that just keeps on giving.

## 17 December 2009

### Blue Diamond Mine

Weird linkage stemming from the shuffle tonight. "Blue Diamond Mine" by the Texas Rubies sounds insanely like "Where Did You Sleep Last Night?" by Nirvana. Including all the lyrical structure. This isn't too crazy considering the former's genre and the known folk origin of the later, but it is odd when from nowhere a song you've never heard before strikes you as this uncannily familiar. I leave finding an MP3 of "Blue Diamond Mine" as an exercise for the consumer. It appears on Down to the Promised Land.

## 01 November 2009

### Getting 32-bit libstdc++.so.5 in {Karmic Koala,Lucid Lynx} on a 64-bit system

The Intel compilers require a 32-bit version of libstdc++.so.5 to function. Getting a copy of that build of that library requires a couple of steps in the latest 64-bit Ubuntu {9.10,10.04}. These have been alluded to in other places.  Just in case someone needs the details, here they are:

2. Unpack the .deb archive using ar vx ~/Desktop/libstdc++5_3.3.6-17ubuntu1_i386.deb
3. Unpack the resulting data.tar.gz using tar xzvf data.tar.gz
4. Confirm that you got the 32-bit version using file usr/lib/libstdc++.so.5.0.7
5. Install the library into /usr/lib32 using sudo install usr/lib/libstdc++.so.5.0.7 /usr/lib32
6. Change to /usr/lib32 using cd /usr/lib32
7. Create a symlink to finish the task via sudo ln -s libstdc++.so.5.0.7 libstdc++.so.5
Many thanks to everyone who provided the source material:

Updated 24 April 2010: Appears that this procedure also works on the Lucid Lynx release candidate.

## 28 October 2009

### Sugar Plum Plug

Milady got the Nutcracker casting she's talked about wanting for several years. Go hit up the show on one of December 6, 12, 18, 19 @ 7:30pm, 21, or 23 to see her grinning from ear to ear.

## 26 October 2009

uBLAS has a shallow_array_adaptor that allows you to wrap an existing block of data with a uBLAS vector. This is useful if you want to wrap raw data provided by someone else. Exposing this functionality is questionable in terms of encapsulation and ownership, and so it isn't available by default. Consequently the documentation is pretty scarce. Here's an example of it's use in the context of a Boost.Test test case.

#define BOOST_TEST_MODULE $Id: test_complex.cc 1817 2009-03-18 19:01:25Z rhys$

// Before ublas #include, enable boost::numeric::ublas::shallow_array_adaptor<T>

#include <algorithm>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/test/included/unit_test.hpp>
#include <boost/foreach.hpp>
#include <complex>

namespace ublas = boost::numeric::ublas;

typedef std::complex<double>                            complex;

// Ensure we can use std::complex<double> as two consecutive doubles
BOOST_AUTO_TEST_CASE( shared_c_array )
{
// Assumption must hold true for any of this scheme to work
BOOST_REQUIRE_EQUAL( sizeof(complex), 2*sizeof(double) );

const std::size_t N = 6;
double carray_double[N] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
complex *carray_complex = reinterpret_cast<complex *>(carray_double);

for (std::size_t i = 0; i < N/2; ++i)
{
BOOST_CHECK_EQUAL(carray_double[2*i],   carray_complex[i].real());
BOOST_CHECK_EQUAL(carray_double[2*i+1], carray_complex[i].imag());
}

for (std::size_t i = 0; i < N/2; ++i)
{
carray_complex[i] += carray_complex[0];
}

for (std::size_t i = 0; i < N/2; ++i)
{
BOOST_CHECK_EQUAL(carray_double[2*i],   carray_complex[i].real());
BOOST_CHECK_EQUAL(carray_double[2*i+1], carray_complex[i].imag());
}
}

// Ensure we can use a C-array of doubles as a ublas::vector.
{
const std::size_t N = 3;
double raw[N];

BOOST_CHECK_EQUAL( vec.size(), N );

std::fill(&raw[0], &raw[N], 1.0);
BOOST_CHECK_EQUAL_COLLECTIONS(&raw[0], &raw[N], vec.begin(), vec.end());

std::fill(vec.begin(), vec.end(), 2.0);
BOOST_CHECK_EQUAL_COLLECTIONS(&raw[0], &raw[N], vec.begin(), vec.end());
}

// Ensure we can use a C-array of std::complex<double> as a ublas::vector.
{
const std::size_t N = 3;
complex raw[N];

BOOST_CHECK_EQUAL( vec.size(), N );

std::fill(&raw[0], &raw[N], complex(1.0, -1.0));
BOOST_CHECK_EQUAL_COLLECTIONS(&raw[0], &raw[N], vec.begin(), vec.end());

std::fill(vec.begin(), vec.end(), complex(2.0, -2.0));
BOOST_CHECK_EQUAL_COLLECTIONS(&raw[0], &raw[N], vec.begin(), vec.end());
}

// Ensure we can use the same data as either double or complex ublas::vector
{
const std::size_t N = 6;
double carray_double[N] = { 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 };
complex *carray_complex = reinterpret_cast<complex *>(carray_double);

for (std::size_t i = 0; i < N/2; ++i)
{
BOOST_CHECK_EQUAL(vec_double[2*i],   vec_complex[i].real());
BOOST_CHECK_EQUAL(vec_double[2*i+1], vec_complex[i].imag());
}

for (std::size_t i = 0; i < N/2; ++i)
{
vec_complex[i] += vec_complex[0];
}

for (std::size_t i = 0; i < N/2; ++i)
{
BOOST_CHECK_EQUAL(vec_double[2*i],   vec_complex[i].real());
BOOST_CHECK_EQUAL(vec_double[2*i+1], vec_complex[i].imag());
}

for (std::size_t i = 0; i < N; ++i)
{
vec_double[i] += vec_double[N-1];
}

for (std::size_t i = 0; i < N/2; ++i)
{
BOOST_CHECK_EQUAL(vec_double[2*i],   vec_complex[i].real());
BOOST_CHECK_EQUAL(vec_double[2*i+1], vec_complex[i].imag());
}
}