Install Ipopt on Mac OS 10.6 for Matlab

Ipopt is a very good software package and library for large-scale nonlinear optimization (NLP solver). I wanted to install it, particularly its Matlab interface, to improve the performance of some of my code which currently uses fmincon. The Matlab’s default solver is good enough for many instances, but according to many reviews, the free Ipopt is better, especially for large and complex problems. With my very own experience in compiling and installing open-source code, and after reading many reviews and complaints on the Internet, I knew that installing Ipopt on Mac OS would be a tough task. Indeed, it was so difficult that it made me very frustrated and almost give up. I tried a few instructions on the web, but they did not work, partly because they are for older versions of Ipopt and partly because the compiling process is very machine-dependent. Last night, I gave it a last chance, and fortunately made it. Below are the steps that I used, for my own record and hopefully for others who are trying to do the same thing.

(A side note: personally, I think that if we total the amount of time people around the world spending frustratedly to install and make open-source software work for them, it would be equal to the age of the universe. I know I am exaggerating too much but honestly, that total wasted amount of time would be HUGE. Kudos to the people and companies that make software so easy to install and use: Apple, Ubuntu, and many others.)

The machine I am using is a MacBook Pro with Intel Core 2 Duo, Snow Leopard (10.6.8), Matlab R2009b. An important resource is the current issue list.

  1. You need to download Ipopt. I downloaded version 3.10.1 (released on September 21, 2011 – my birthday FYI). Other versions may not work because as I said, the installation is very tricky.
  2. You need to have a (good) Fortran compiler. The bad news is that not all Fortran compilers work. The good news: gfortran works. You can download gfortran for MacOS X from its website or from here. Install it as instructed on those websites.
  3. Of course, you need to have XCode installed so that you can compile C/C++ source files. I am too lazy to check the version of XCode on my machine, but I guess the latest version will work.
  4. Extract Ipopt source to a directory, say Ipopt.
  5. Download third party packages: you will need at least one linear solver for Ipopt to work.
    • Download MA27 and MC19 solvers from this website. Extract the archives and copy the Fortran source files (extension .f) to the directory Ipopt/ThirdParty/HSL. Somehow the name of the source files were changed, so you need to rename ma27d.f to ma27ad.f and mc19d.f to mc19ad.f.
    • Go to directory Ipopt/ThirdParty/ASL and run get.ASL to download ASL.
    • Go to directory Ipopt/ThirdParty/Metis and run get.Metis to download Metis.
    • DO NOT download MUMPS because for some reason, MUMPS caused errors on my machine. It compiled successfully and all tests were passed, but some code (particularly the Matlab interface and the Python interface) failed due to some problem with MPI. As instructed on the Ipopt website, you will have to modify the source code of MUMPS to make it work, but they did not tell you how. So I skipped it.
  6. Go to the directory of Ipopt and configure it by the following command:
    /configure --without-mumps --prefix=/usr/local --enable-static
    --disable-shared \
    --with-blas="-framework vecLib"
    --with-lapack="-framework vecLib" \
    F77=gfortran \
    ADD_CFLAGS="-fno-common -fexceptions -no-cpp-precomp -fPIC -m64" \
    ADD_CXXFLAGS="-fno-common -fexceptions -no-cpp-precomp -fPIC -m64" \
    ADD_FFLAGS="-mmacosx-version-min=10.4 -m64" \
    LDFLAGS="-L/usr/local/lib -flat_namespace"
    

    As you can see, I skipped MUMPS, set the installation directory (prefix), disabled building shared libraries (the Ipopt website suggests doing that on MacOS), used the Apple’s vector library for BLAS and LAPACK, set to build 64-bit binaries (if you want to build 32-bit binaries, use flag -m32), and set some (important) flags to make Ipopt work with Matlab.

  7. Compile the library by issuing the command make (will take a while to finish), then test it by make test. If everything is fine (I hope so), you can install Ipopt by sudo make install.
  8. Go to Ipopt/Ipopt/contrib/MatlabInterface/src. Edit Makefile and set the correct paths and settings. You really need to change LDFLAGS and LIBS to make it compile, otherwise mex will give an error. Below is what I used:
    MATLAB_HOME = /Applications/MATLAB_R2009b.app
    MEXSUFFIX   = mexmaci64
    

    then move (i.e. cut and paste) the line after LIBS to the end of the line LDFLAGS, so that LIBS will become empty and LDFLAGS will contain the switch for Ipopt.

  9. Build the interface by make. I hope that it will compile successfully. Then copy the output file ipopt.mexmaci64 and the M-file ipopt.m in the parent directory to some directory in your Matlab’s path.
  10. Try running the Matlab example file. It should work (hopefully). You can download Yalmip to use with Ipopt.

Happy solving NLP!

Advertisements
This entry was posted in Computer and tagged , , . Bookmark the permalink.

3 Responses to Install Ipopt on Mac OS 10.6 for Matlab

  1. Lori says:

    Hi, thank for your blog. I am installing Ipopt on my Mac following your instruction. The configuration step is ok, I get the successful message. If i run the make, i always get the message Nothing to be done for `all’. I don’t know if this is fine or not.But the main problem is when I try my make test. Here I get the message “ld: library not found for -lstdc++”. Do you have some experience with that?
    Thanks a lot for any help!

  2. Venkat says:

    Hi,
    I am trying to interface matlab and ipopt in Ubuntu 11.10 in 64-bit machine. I am able to configure using the below command successfully.
    ../configure –prefix=$HOME/CoinIpopt/build –without-mumps CXX=’g++-4.6 -m64′ CC=’gcc-4.6 -m64′ F77=’gfortran-4.6 -m64′ ADD_CXXFLAGS=”fPIC -fexceptions” ADD_CFLAGS=”-fPIC -fexceptions” ADD_FFLAGS=”-fPIC -fexceptions”

    But I am getting the below error when I run make command. Does anybody have similar and know how to resolve?

    Making all in Ipopt
    make[1]: Entering directory `/home/venkat/CoinIpopt/build/Ipopt’
    Making all in src/Common
    make[2]: Entering directory `/home/venkat/CoinIpopt/build/Ipopt/src/Common’
    if /bin/bash ../../../libtool –tag=CXX –mode=compile g++-4.6 -m64 -DHAVE_CONFIG_H -I. -I`echo ../../../../Ipopt/src/Common` -I../../inc -O -MT IpDebug.lo -MD -MP -MF “.deps/IpDebug.Tpo” -c -o IpDebug.lo ../../../../Ipopt/src/Common/IpDebug.cpp; \
    then mv -f “.deps/IpDebug.Tpo” “.deps/IpDebug.Plo”; else rm -f “.deps/IpDebug.Tpo”; exit 1; fi
    if /bin/bash ../../../libtool –tag=CXX –mode=compile g++-4.6 -m64 -DHAVE_CONFIG_H -I. -I`echo ../../../../Ipopt/src/Common` -I../../inc -O -MT IpJournalist.lo -MD -MP -MF “.deps/IpJournalist.Tpo” -c -o IpJournalist.lo ../../../../Ipopt/src/Common/IpJournalist.cpp; \
    then mv -f “.deps/IpJournalist.Tpo” “.deps/IpJournalist.Plo”; else rm -f “.deps/IpJournalist.Tpo”; exit 1; fi
    mkdir .libs
    g++-4.6 -m64 -DHAVE_CONFIG_H -I. -I../../../../Ipopt/src/Common -I../../inc -O -MT IpJournalist.lo -MD -MP -MF .deps/IpJournalist.Tpo -c ../../../../Ipopt/src/Common/IpJournalist.cpp -fPIC -DPIC -o .libs/IpJournalist.o
    g++-4.6 -m64 -DHAVE_CONFIG_H -I. -I../../../../Ipopt/src/Common -I../../inc -O -MT IpDebug.lo -MD -MP -MF .deps/IpDebug.Tpo -c ../../../../Ipopt/src/Common/IpDebug.cpp -fPIC -DPIC -o .libs/IpDebug.o
    In file included from ../../../../Ipopt/src/Common/IpJournalist.hpp:15:0,
    from ../../../../Ipopt/src/Common/IpJournalist.cpp:10:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In constructor ‘Ipopt::SmartPtr::SmartPtr()’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:340:12: error: ‘NULL’ was not declared in this scope
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In copy constructor ‘Ipopt::SmartPtr::SmartPtr(const Ipopt::SmartPtr&)’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:359:12: error: ‘NULL’ was not declared in this scope
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In constructor ‘Ipopt::SmartPtr::SmartPtr(T*)’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:379:12: error: ‘NULL’ was not declared in this scope
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In member function ‘Ipopt::SmartPtr& Ipopt::SmartPtr::SetFromRawPtr_(T*)’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:475:16: error: ‘NULL’ was not declared in this scope
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In member function ‘void Ipopt::SmartPtr::ReleasePointer_()’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:518:14: error: ‘NULL’ was not declared in this scope
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In function ‘bool Ipopt::IsNull(const Ipopt::SmartPtr&)’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:557:31: error: ‘NULL’ was not declared in this scope
    In file included from ../../../../Ipopt/src/Common/IpJournalist.hpp:15:0,
    from ../../../../Ipopt/src/Common/IpDebug.cpp:12:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In constructor ‘Ipopt::SmartPtr::SmartPtr()’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:340:12: error: ‘NULL’ was not declared in this scope
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In copy constructor ‘Ipopt::SmartPtr::SmartPtr(const Ipopt::SmartPtr&)’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:359:12: error: ‘NULL’ was not declared in this scope
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In constructor ‘Ipopt::SmartPtr::SmartPtr(T*)’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:379:12: error: ‘NULL’ was not declared in this scope
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In member function ‘Ipopt::SmartPtr& Ipopt::SmartPtr::SetFromRawPtr_(T*)’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:475:16: error: ‘NULL’ was not declared in this scope
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In member function ‘void Ipopt::SmartPtr::ReleasePointer_()’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:518:14: error: ‘NULL’ was not declared in this scope
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp: In function ‘bool Ipopt::IsNull(const Ipopt::SmartPtr&)’:
    ../../../../Ipopt/src/Common/IpSmartPtr.hpp:557:31: error: ‘NULL’ was not declared in this scope
    ../../../../Ipopt/src/Common/IpJournalist.cpp: In member function ‘virtual void Ipopt::FileJournal::PrintImpl(Ipopt::EJournalCategory, Ipopt::EJournalLevel, const char*)’:
    ../../../../Ipopt/src/Common/IpJournalist.cpp:405:25: warning: format not a string literal and no format arguments [-Wformat-security]
    make[2]: *** [IpDebug.lo] Error 1
    make[2]: *** Waiting for unfinished jobs….
    make[2]: *** [IpJournalist.lo] Error 1
    make[2]: Leaving directory `/home/venkat/CoinIpopt/build/Ipopt/src/Common’
    make[1]: *** [all-recursive] Error 1
    make[1]: Leaving directory `/home/venkat/CoinIpopt/build/Ipopt’
    make: *** [all-recursive] Error 1

  3. Venkat says:

    any help would be appreciated. Thanks.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s