Installing MPB

I wanted to try MPB also, it’s a photonic bandgap simulator by MIT. So I downloaded the package and tried to install in my office workstation. The config stage couldn’t pass since it didn’t find the FFTW library, though I have one installed. It turns out that mine is fftw3 while MPB is not compatible with fftw3 yet. So I have to installed fftw2 into my local directory. The installation for fftw2 is pretty straightforward. Now I need to specify both fftw2, libctl and HDF5 location into the configure of MPB (you may want to refer to Meep installation also, it’s quite similar). This is what I typed to configure MPB.


./configure --prefix=/scratch/kurniawano/local LDFLAGS="-L/scratch/kurniawano/local/fftw2/lib -L/scratch/kurniawano/Download/hdf5/lib" CPPFLAGS="-I/scratch/kurniawano/local/fftw2/include -I/scratch/kurniawano/Download/hdf5/include" --with-libctl=/scratch/kurniawano/local/share/libctl

However, when I typed make, it gives me an error, from this page, I found out that the problem is that I am using HDF5 version 1.8, so I needed to pass through the option -DH5_USE_16_API=1 in the CPPFLAGS. After adding this, my installation works fine 🙂

Advertisements

Installing Meep 1.1.1

I tried to install Meep 1.1.1 in my CentOS workstation. It turns out that it needs some more packages to be installed. First Meep requires guile and libctl, So after downloading them, I tried to install guile. But it failed since guile requires GNU MP (sigh). So I downloaded GNU MP 4.3.1 and did configure, make, make install. I successfully installed in in a local folder. Then in configure guile, I need to specify the location of the GNU MP as well as the libltdl, so I typed:

./configure --prefix=/scratch/kurniawano/local LDFLAGS="-L/scratch/kurniawano/local/lib/" CPPFLAGS="-I/usr/share/libtool/libltdl/ -I/scratch/kurniawano/local/include"

I also need to specify the gmp.h location using CPPFLAGS. Otherwise, I will get an error “At least GNU MP 4.1 is required, see README”. After that I successfully installed guile 1.8.7. Once this is done I configure libctl and specifying the location of guile using LDFLAGS in the configure command. libctl was successfully installed also 🙂

During configure, a warning message shows that I didn’t have hdf5.h in my system. So I downloaded hdf5 and included the header files in the CPPFLAGS when installing meep 1.1.1. Before installing hdf5, I need to install SZIP library first. The installation for SZIP library is pretty simple and no problem encountered. However, it requires me to rebuild libctl again. After I installed hdf5, meep configure gives no error. But when I did make, it gives me error undefined reference to some hdf5 libraries. The problem is that some interface has changed in hdf5 1.8.x version. In one of the forum, it was suggested to install h5utils version 1.11.1.

To overcome this problem, I installed h5utils version 1.12.1 from MIT website, and configure it as follows:

./configure --prefix=/scratch/kurniawano/local LDFLAGS="-L/scratch/kurniawano/Download/hdf5/lib -L/scratch/kurniawano/local/lib" CPPFLAGS="-I/scratch/kurniawano/Download/hdf5/include -I/scratch/kurniawano/local/include" LIBS="-lhdf5"

If you use the shared library, you need to add the hdf5/lib into your LD_LIBRARY_PATH to make the configure successful. Besides that to create png, jpg image from hdf5 output of Meep, you need to install libpng, libjpeg. Another library that is required by h5utils is matheval.

To configure meep 1.1.1, I typed:

./configure --prefix=/scratch/kurniawano/local LDFLAGS="-L/scratch/kurniawano/Download/hdf5/lib -L/scratch/kurniawano/local/lib" CPPFLAGS="-I/scratch/kurniawano/Download/hdf5/include" LIBS="-lhdf5" --with-libctl=/scratch/kurniawano/local/share/libctl

This configures fine, but when I run make, it gives me this error:


libtool: link: warning: library `/scratch/kurniawano/Download/hdf5/lib/libhdf5.l
a' was moved.
grep: /mnt/hdf/packages/szip/shared/encoder/Linux2.6-x86_64-gcc/lib/libsz.la: No
such file or directory
/bin/sed: can't read /mnt/hdf/packages/szip/shared/encoder/Linux2.6-x86_64-gcc/l
ib/libsz.la: No such file or directory
libtool: link: `/mnt/hdf/packages/szip/shared/encoder/Linux2.6-x86_64-gcc/lib/li
bsz.la' is not a valid libtool archive

though, I have installed szip library, it seems that hdf5 looks at a different location. So I needed to edit the libhdf5.la file under the hdf5/lib folder, and comment the line for dependency_libs then add the line for szip lib location:


# Libraries that this one depends upon.
#dependency_libs=' -L/mnt/hdf/packages/szip/shared/encoder/Linux2.6-x86_64-gcc/l
ib /mnt/hdf/packages/szip/shared/encoder/Linux2.6-x86_64-gcc/lib/libsz.la -lz -l
m'
dependency_libs='/scratch/kurniawano/local/lib/libsz.la -lz -lm'

After this, the make and make install runs fine.

If you want to build Meep with MPI enabled for parallel computation, add –with-mpi during the configure stage.

Adding Generalized Eigenvalue functions to IT++

I have added a functions call to lapack DGGEV and ZGGEV functions to solve generalized eigenvalue problem. There are three files to modify: lapack.h, eigen.h, and eigen.cpp. The diff files can be obtained from this link.

To test the code, I ran an example for generalized complex eigenvalue problem found in the NAG site. The test program is shown below:

#include 

using namespace itpp;

//These lines are needed for use of cout and endl
using std::cout;
using std::endl;

int main()
{

  cmat cA,cB;
  cA="-21.10-22.50i 53.50-50.50i -34.50+127.50i 7.50+0.50i; 
        -0.46-7.78i -3.50-37.50i -15.50+58.50i -10.50-1.50i; 
        4.30-5.50i 39.70-17.10i -68.50+12.50i -7.50-3.50i; 
        5.50+4.40i 14.40+43.30i -32.50-46.00i -19.00-32.50i";

  cB="1.00-5.00i 1.60+1.20i -3.00+0.00i 0.00-1.00i; 
        0.80-0.60i 3.00-5.00i -4.00+3.00i -2.40-3.20i;  
        1.00+0.00i  2.40+1.80i -4.00-5.00i 0.00-3.00i;  
        0.00+1.00i -1.80+2.40i  0.00-4.00i  4.00-5.00i";

  cout<< "cA = " << cA<<endl;
  cout<< "cB = " << cB<<endl;

  cvec lambda;
  cmat evecs;
  eig(cA,cB,lambda,evecs);
  cout<< "eig(cA,cB)\n";
  cout << "lambda = "<<lambda<<endl;
  cout << "evecs = "<<evecs<<endl;

  //Exit program:
  return 0;

}

And the output is:

cA = [[-21.1-22.5i 53.5-50.5i -34.5+127.5i 7.5+0.5i]
 [-0.46-7.78i -3.5-37.5i -15.5+58.5i -10.5-1.5i]
 [4.3-5.5i 39.7-17.1i -68.5+12.5i -7.5-3.5i]
 [5.5+4.4i 14.4+43.3i -32.5-46i -19-32.5i]]
cB = [[1-5i 1.6+1.2i -3+0i 0-1i]
 [0.8-0.6i 3-5i -4+3i -2.4-3.2i]
 [1+0i 2.4+1.8i -4-5i 0-3i]
 [0+1i -1.8+2.4i 0-4i 4-5i]]
eig(cA,cB)
lambda = [3-9i 2-5i 3-1i 4-5i]
evecs = [[-0.823768-0.176232i 0.639741+0.360259i 
                  0.977535+0.0224645i -0.906234+0.0937662i]
 [-0.152951+0.0706552i 0.0041597-0.000546503i 
                  0.159101-0.11371i -0.0074303+0.00687504i]
 [-0.0706552-0.152951i 0.0402123+0.0226448i 
                  0.120899-0.15371i 0.0302078-0.00312554i]
 [0.152951-0.0706552i -0.0226448+0.0402123i 
                  0.15371+0.120899i -0.0145859-0.14097i]]

Calling lapack functions from C++ codes

I have been using IT++ for my C++ class matrix and vectors. It is a great libraries. However, it lacks the function to solve generalized eigenvalue problem. so I need to link directly to lapack to do this. I follow the wrapper used in eigen.cpp to link to ZGGEV function of lapack. I tested the code with the problem shown in NAG website for ZGGEV examples.

To use IT++ matrix and vector classes, we need to include:
#include <itpp/base.h>

Then we need to declare the ZGGEV function prototype. Refer to this page for details on ZGGEV parameters. We can then define

extern "C"{
void zggev_(char *jobvl, char *jobvr, int *n, std::complex *a,
            int *lda, std::complex *b, int *ldb, std::complex *alpha,
            std::complex *beta, std::complex *vl,
            int *ldvl, std::complex *vr, int *ldvr,
            std::complex *work, int *lwork, double *rwork, int *info);
}

To call the functions, we simply type:

zggev_(&jobvl, &jobvr, &n, cA._data(), &lda, 
           cB._data(), &ldb, alpha._data(),  beta._data(), vl._data(), 
           &ldvl, vr._data(), &ldvr, work._data(), &lwork, 
           rwork._data(), &info);

and then we need to compile and link. These are the command:

gcc -I$HOME/local/include -I$HOME/Download/boost_1_36_0 \
     -L$HOME/local/lib testzlapack.cpp -o tzlapack \
     -llapack -lcblas -lf77blas -latlas -litpp -g


Note that I use a modified IT++ library that uses Boost libraries to compute complex function acos.

The complete source code is:

//file:testzlapack.cpp
#include &lt itpp/base.h &gt

using namespace itpp;

//These lines are needed for use of cout and endl
using std::cout;
using std::endl;

extern "C"{
void zggev_(char *jobvl, char *jobvr, int *n, std::complex *a,
            int *lda, std::complex *b, int *ldb, std::complex *alpha,
            std::complex *beta, std::complex *vl,
            int *ldvl, std::complex *vr, int *ldvr,
            std::complex *work, int *lwork, double *rwork, int *info);
}

int main()
{

  cmat cA,cB;
  cA="-21.10-22.50i 53.50-50.50i -34.50+127.50i 7.50+0.50i; 
    -0.46-7.78i -3.50-37.50i -15.50+58.50i -10.50-1.50i; 
    4.30-5.50i 39.70-17.10i -68.50+12.50i -7.50-3.50i; 
    5.50+4.40i 14.40+43.30i -32.50-46.00i -19.00-32.50i";

 cB="1.00-5.00i 1.60+1.20i -3.00+0.00i 0.00-1.00i; 
   0.80-0.60i 3.00-5.00i -4.00+3.00i -2.40-3.20i;  
   1.00+0.00i  2.40+1.80i -4.00-5.00i 0.00-3.00i;  
   0.00+1.00i -1.80+2.40i  0.00-4.00i  4.00-5.00i";

  cout<< "cA = " << cA<<endl;
  cout<< "cB = " << cB<<endl;

  cvec lambda;
  cmat evecs;
//  eig(cA,lambda,evecs);
  char jobvl = 'N', jobvr = 'V';
  int n, lda, ldb, ldvl, ldvr, lwork, info;
  n=lda=cA.rows();
  ldb = cB.rows();
  ldvl = 1;
  ldvr = n;
  lwork = std::max(1,  n*n+64); // This may be choosen better!

  cvec work(lwork);
  vec rwork(8*n); // This may be choosen better
  cvec alpha(n), beta(n);
  cmat vl(1,1), vr(n, n);
  zggev_(&jobvl, &jobvr, &n, cA._data(), &lda, 
       cB._data(), &ldb, alpha._data(),  beta._data(), vl._data(), 
       &ldvl, vr._data(), &ldvr, work._data(), &lwork, 
       rwork._data(), &info);
  lambda=elem_div(alpha,beta);
  evecs=vr;
  cout<<endl;
  cout<< "eig(cA,cB)= \n";
  cout << "lambda = "<<lambda<<endl;
  cout << "evecs = "<<evecs<<endl;

  //Exit program:
  return 0;

}


And we get the output:

cA = [[-21.1-22.5i 53.5-50.5i -34.5+127.5i 7.5+0.5i]
 [-0.46-7.78i -3.5-37.5i -15.5+58.5i -10.5-1.5i]
 [4.3-5.5i 39.7-17.1i -68.5+12.5i -7.5-3.5i]
 [5.5+4.4i 14.4+43.3i -32.5-46i -19-32.5i]]
cB = [[1-5i 1.6+1.2i -3+0i 0-1i]
 [0.8-0.6i 3-5i -4+3i -2.4-3.2i]
 [1+0i 2.4+1.8i -4-5i 0-3i]
 [0+1i -1.8+2.4i 0-4i 4-5i]]

 eig(cA,cB)=
lambda = [3-9i 2-5i 3-1i 4-5i]
evecs = [[-0.823768-0.176232i 0.639741+0.360259i 
                     0.977535+0.0224645i -0.906234+0.0937662i]
 [-0.152951+0.0706552i 0.0041597-0.000546503i 
                     0.159101-0.11371i -0.0074303+0.00687504i]
 [-0.0706552-0.152951i 0.0402123+0.0226448i 
                     0.120899-0.15371i 0.0302078-0.00312554i]
 [0.152951-0.0706552i -0.0226448+0.0402123i 
                     0.15371+0.120899i -0.0145859-0.14097i]]

which agrees with the results shown in NAG site.

Compiling ATLAS with -fPIC

in the configure , type
./configure -Fa acg ‘-fPIC’

Installing Octave’s binding for ARPACK in Kubuntu Hardy for Sparse Matrix Calculation

Octave Forge provided an octave binding to Arpack to solve large scale sparse matrix. So first download from octave forge packages.

And to install the package, you need to have the header files for suitesparse and libarpack. So type this in console:
sudo apt-get install libsuitesparse-dev libarpack2-dev
after that go to the download folder of Octave’s arpack and run Octave
octave:\> pkg install arpack-1.0.6.tar.gz

EDIT: thanks Andrew, I previously typed wrongly suitesparse-dev, it should be libsuitesparse-dev.