Commit 5574a878 authored by Laurent Belcour's avatar Laurent Belcour

Merge branch 'gforge-master'

parents 896f5832 5d1b434b
...@@ -21,7 +21,6 @@ sys.path += [ top_srcdir + '/external' ] ...@@ -21,7 +21,6 @@ sys.path += [ top_srcdir + '/external' ]
## Add ALTA custom cmd configurations ## Add ALTA custom cmd configurations
## ##
AddOption('--cfg', help='Specify a configuration file') AddOption('--cfg', help='Specify a configuration file')
AddOption('--no-externals', action="store_false", dest="obtain_externals", default=True, help='Do not download and build externals')
## Import configuration from a config file ## Import configuration from a config file
...@@ -134,7 +133,6 @@ if len(envVars['PKG_CONFIG_PATH']) > 0: ...@@ -134,7 +133,6 @@ if len(envVars['PKG_CONFIG_PATH']) > 0:
envVars['PKG_CONFIG_PATH'] += ':' envVars['PKG_CONFIG_PATH'] += ':'
envVars['PKG_CONFIG_PATH'] += os.path.abspath('external' + os.sep + 'build' + os.sep + 'lib' + os.sep + 'pkgconfig') envVars['PKG_CONFIG_PATH'] += os.path.abspath('external' + os.sep + 'build' + os.sep + 'lib' + os.sep + 'pkgconfig')
env = Environment(variables = vars, ENV = envVars) env = Environment(variables = vars, ENV = envVars)
env['DL_EXTERNALS'] = GetOption('obtain_externals')
# Generate help text for the build variables. # Generate help text for the build variables.
......
...@@ -54,10 +54,6 @@ Optional dependencies that will allow more plugins to be built include: ...@@ -54,10 +54,6 @@ Optional dependencies that will allow more plugins to be built include:
+ [MATLAB][matlab] with the Engine library, for some plugins. + [MATLAB][matlab] with the Engine library, for some plugins.
For your convenience, some of these dependencies are shipped with ALTA,
as noted above. Others are automatically downloaded unless
<tt>--no-externals</tt> is passed to <tt>scons</tt> (see below.)
#### Note for Ceres installation for Debian/Ubuntu distribution #### Note for Ceres installation for Debian/Ubuntu distribution
To improve the numerical stability of the different solvers, it is highly recommended to install the following packages: To improve the numerical stability of the different solvers, it is highly recommended to install the following packages:
+ <tt>libatlas-base-dev</tt> + <tt>libatlas-base-dev</tt>
...@@ -88,9 +84,9 @@ dependencies are met, and which of the optional dependencies are ...@@ -88,9 +84,9 @@ dependencies are met, and which of the optional dependencies are
available. All the compilation byproducts go to the available. All the compilation byproducts go to the
<tt>sources/build</tt> sub-directory. <tt>sources/build</tt> sub-directory.
Some of the missing dependencies, such as NlOpt, IpOpt, and CERES, are If Eigen could not be found, it is
automatically downloaded from upstream when they are not found. The automatically downloaded from upstream. The
downloaded files are integrity-checked, and then the software is built downloaded file is integrity-checked, and then the software is built
and installed under the <tt>external/build</tt> sub-directory of the and installed under the <tt>external/build</tt> sub-directory of the
source tree. source tree.
......
# ALTA --- Analysis of Bidirectional Reflectance Distribution Functions # ALTA --- Analysis of Bidirectional Reflectance Distribution Functions
# #
# Copyright (C) 2014, 2015 CNRS # Copyright (C) 2014, 2015 CNRS
# Copyright (C) 2013, 2014, 2015 Inria # Copyright (C) 2013, 2014, 2015, 2016 Inria
# Copyright (C) 2015 Universite de Montreal # Copyright (C) 2015 Universite de Montreal
# #
# This file is part of ALTA. # This file is part of ALTA.
...@@ -25,11 +25,7 @@ if env.GetOption('clean'): ...@@ -25,11 +25,7 @@ if env.GetOption('clean'):
#shutil.rmtree('build', True) #shutil.rmtree('build', True)
# Removing the TP directories # Removing the TP directories
#shutil.rmtree('ceres-solver-1.7.0', True)
#shutil.rmtree('eigen-eigen-ffa86ffb5570', True) #shutil.rmtree('eigen-eigen-ffa86ffb5570', True)
#shutil.rmtree('glog-0.3.3', True)
#shutil.rmtree('Ipopt-3.11.8', True)
#shutil.rmtree('nlopt-2.4.1', True)
else: else:
## ##
...@@ -45,47 +41,6 @@ else: ...@@ -45,47 +41,6 @@ else:
env['EIGEN_INC'] = [Dir('#external/build/include').abspath] env['EIGEN_INC'] = [Dir('#external/build/include').abspath]
env = conf.Finish() env = conf.Finish()
##
# The env variable is cloned for IpOpt, NlOpt and CERES to avoid
# propagating the link flags for them in the main build script.
##
##
# Check for optional dependencies, downloading them if they
# are not already available in the user's environment.
#
# At this point CCFLAGS and LINKFLAGS already contain the
# right flags if those dependencies if they found via
# 'pkg-config'. Check whether they are usable, and download
# them if not.
#
##
##
# IpOpt dependencies
##
env2 = env.Clone()
if not on_windows and not library_available(env2, pkgspec='ipopt', inc_var='IPOPT_INC', lib_var='IPOPT_DIR', lib='IPOPT_LIB', header='coin/IpTNLP.hpp') and env['DL_EXTERNALS']:
execfile('obtain_ipopt.py')
##
# NlOpt dependencies
##
env2 = env.Clone()
if not library_available(env2, pkgspec='nlopt', inc_var='NLOPT_INC', lib_var='NLOPT_DIR', lib='NLOPT_LIB', header='nlopt.h') and env['DL_EXTERNALS']:
execfile('obtain_nlopt.py')
##
# CERES dependencies
##
env2 = env.Clone()
if not library_available(env2, pkgspec='ceres', inc_var='CERES_INC', lib_var='CERES_DIR', lib='CERES_LIB', header='ceres/ceres.h') and env['DL_EXTERNALS']:
execfile('obtain_ceres.py')
C.progress_display("external libraries are built as shared libraries")
C.progress_display("please adjust the shared library search path \
before running ALTA")
## ##
# QuadProg++ # QuadProg++
# TODO: Change to the QuadProg v2 code # TODO: Change to the QuadProg v2 code
......
import obtain
import os
import sys
import shutil
import subprocess
import SCons.Warnings as W
import SCons.SConf as C
# Download GLOG
version = '0.3.3'
base = 'glog'
name = 'GLOG v' + version
directory = base + '-' + version
url = 'http://google-glog.googlecode.com/files/glog-' + version + '.tar.gz'
filename = 'glog-' + version + '.tar.gz'
sha256 = 'fbf90c2285ba0561db7a40f8a4eefb9aa963e7d399bd450363e959929fe849d0'
glog_obtained = False
glog_compiled = False
if os.name != 'nt':
glog_obtained = obtain.obtain(name, directory, url, filename, sha256)
glog_compiled = os.path.exists('.' + os.sep + 'build' + os.sep + 'include' + os.sep + 'glog')
if glog_obtained and not glog_compiled:
if sys.platform == 'darwin':
obtain.patch('glog-0.3.3/src/glog/stl_logging.h.in', 'glog.patch')
C.progress_display('configuring and building GLOG for CERES')
glog_compiled = obtain.configure_build(directory,
['--disable-shared',
'--enable-static', '--with-pic'])
# Download CERES. Assume Eigen is already available.
version = '1.9.0'
base = 'ceres-solver'
name = 'CERES v' + version
directory = base + '-' + version
url = 'http://ceres-solver.org/ceres-solver-' + version + '.tar.gz'
filename = 'ceres-solver-' + version + '.tar.gz'
sha256 = '30ac0729249f908afe80cb6fd06ae6d037f25a60d9fac54f61344389adab9c1a'
obtained = obtain.obtain(name, directory, url, filename, sha256)
## Test for the presence of already compiled ceres version in
## the $ALTA/external/build directory. Then test for the
## presence of cmake.
compile_test = not os.path.exists('.' + os.sep + 'build' + os.sep + 'include' + os.sep + 'ceres')
if obtained and compile_test:
C.progress_display('configuring and building ' + name)
# Build cmake script
build_dir = os.pardir + os.sep + 'build' + os.sep
options = ''
if glog_compiled:
options = '-DGLOG_LIBRARY=' + build_dir + 'lib' + os.sep + 'libglog.a' + ' -DGLOG_INCLUDE_DIR=' + build_dir + 'include' + ' -DMINIGLOG=OFF'
else:
options = '-DMINIGLOG=ON'
options = options + ' include -DGFLAGS=OFF -DBUILD_EXAMPLES=OFF -DBUILD_TESTING=OFF'
# When Eigen was not found by pkg-config (i.e., it was built
# locally under externals/, or the user specified 'EIGEN_INC' in
# the config file), then we need to tell CMake where to find it.
if env['EIGEN_INC']:
options += '-DEIGEN_INCLUDE_DIR=' + env['EIGEN_INC'][0] + '/include'
if not sys.platform.startswith('win'):
# Build PIC so we can link it into our DSOs.
options = options + ' -DCMAKE_CXX_FLAGS=-fPIC'
if obtain.cmake_build(directory, options):
if not glog_compiled:
# When CERES builds miniglog, it installs its headers under
# $includedir/ceres/internal/miniglog. Move it to the right
# place.
includedir = Dir('#external/build/include').abspath
os.rename(includedir + '/ceres/internal/miniglog/glog',
includedir + '/glog')
# CERES's CMakeLists.txt chooses to install to lib64/ or lib/
# depending on the phase of the moon. Rectify that by moving
# things to lib/ if need be.
libdir = Dir('#external/build/lib').abspath
lib64dir = Dir('#external/build/lib64').abspath
if os.access(lib64dir, os.R_OK):
os.rename(lib64dir + '/libceres.a', libdir + '/libceres.a')
if not glog_compiled:
os.rename(lib64dir + '/libminiglog.a', libdir + '/libminiglog.a')
os.rmdir(lib64dir)
# When building miniglog, rename it to libglog.a, which is what the
# rest of the build system expects.
if not glog_compiled:
if not sys.platform.startswith('win'):
os.rename(libdir + '/libminiglog.a', libdir + '/libglog.a')
else:
os.rename(libdir + '/miniglog.lib', libdir + '/libglog.lib')
#end ifelse
#end if
#end if
else:
W.warn(obtain.AltaDependencyWarning,
'CERES already installed or cannot be installed automatically')
import obtain
import os
import sys
import shutil
import subprocess
import SCons.Warnings as W
import SCons.SConf as C
from subprocess import Popen, PIPE
def getThirdParty(name) :
path = os.getcwd()
third = path + os.sep + directory + os.sep + 'ThirdParty' + os.sep
os.chdir(third + name)
ret = Popen(['./get.' + name]).wait()
if(ret != 0):
C.progress_display('Failed to get IpOpt third party \'' + name + '\'')
os.chdir(path)
# Download IpOpt.
version = '3.12.4'
base = 'Ipopt'
name = 'IpOpt v' + version
directory = base + '-' + version
url = 'http://www.coin-or.org/download/source/Ipopt/Ipopt-' + version + '.tgz'
filename = 'Ipopt-' + version + '.tgz'
sha256 = '292afd952c25ec9fe6225041683dcbd3cb76e15a128764671927dbaf881c2e89'
obtained = obtain.obtain(name, directory, url, filename, sha256)
compiled = os.path.exists('.' + os.sep + 'build' + os.sep + 'include' + os.sep + 'coin/IpIpoptNLP.hpp')
if obtained and not compiled:
if os.name == 'nt':
W.warn(obtain.AltaDependencyWarning, 'sorry, no automatic installation of IpOpt')
else:
C.progress_display('configuring and building ' + name + ' and its dependencies')
getThirdParty('Blas')
getThirdParty('Lapack')
getThirdParty('ASL')
getThirdParty('Mumps')
obtain.configure_build(directory,
['--enable-static', '--with-pic',
'--enable-dependency-linking'])
else:
C.progress_display('IpOpt is already installed')
C.progress_display('if the plugins using IpOpt fail to build, check its installation')
import obtain
import os
import sys
import shutil
import SCons.SConf as C
# Download NlOpt.
version = '2.4.1'
base = 'nlopt'
name = 'NlOpt v' + version
directory = base + '-' + version
baseurl = 'http://ab-initio.mit.edu/nlopt/'
url = baseurl + 'nlopt-' + version + '.tar.gz'
filename = 'nlopt-' + version + '.tar.gz'
sha256 = 'fe9ade54ed79c87f682540c34ad4e610ff32c9a43c52c6ea78cef6adcd5c1319'
obtained = obtain.obtain(name, directory, url, filename, sha256)
compiled = os.path.exists('.' + os.sep + 'build' + os.sep + 'include' + os.sep + 'nlopt.hpp')
if obtained and not compiled:
C.progress_display('configuring and building ' + name)
if os.name == 'nt':
# Get the CMakeList file
obtain.download(baseurl + 'CMakeLists.txt', directory+os.sep+'CMakeLists.txt')
# Get the Additional CMake script
obtain.download(baseurl + 'config.cmake.h.in', directory+os.sep+'config.cmake.h.in')
# Build cmake script
obtain.cmake_build(directory)
else:
obtain.configure_build(directory,
['--enable-static', '--with-pic',
'--without-matlab',
'--without-octave', '--without-python',
'--without-guile'])
else:
print '<<INSTALL>> NlOpt already installed'
...@@ -10,15 +10,30 @@ ...@@ -10,15 +10,30 @@
:: This script can be launch using Administrator rights. In :: This script can be launch using Administrator rights. In
:: this case, the different PATHS will be permanent. :: this case, the different PATHS will be permanent.
:: ::
:: It can happens that the PATH variable contain directory
:: with parenthesis in them. In that case, we cannot use
:: a parenthesis for the IF ELSE statement. I use goto instead.
::
:: Source:
:: http://www.blinnov.com/en/2010/06/04/microsoft-was-unexpected-at-this-time/
net session >nul 2>&1 net session >nul 2>&1
if %ERRORLEVEL% equ 0 ( IF %ERRORLEVEL% EQU 0 GOTO superuser
setx ALTA_DIR "%~dp0sources" /M
setx ALTA_PLUGIN_PATH "%~dp0build\plugins" /M set ALTA_DIR=%~dp0sources
setx PATH "%PATH%;%~dp0build\softs" /M set ALTA_PLUGIN_PATH=%~dp0build\plugins
setx PYTHONPATH "%PYTHONPATH%;%~dp0build\python" /M set PATH=%PATH%;%~dp0build\softs
) else ( set PYTHONPATH=%PYTHONPATH%;%~dp0build\python
set ALTA_DIR=%~dp0sources REM set ALTA_DIR=%CD%\sources
set ALTA_PLUGIN_PATH=%~dp0build\plugins REM set ALTA_PLUGIN_PATH=%CD%\build\plugins
set PATH=%PATH%;%~dp0build\softs REM set PATH=%PATH%;%CD%\build\softs
set PYTHONPATH=%PYTHONPATH%;%~dp0build\python REM set PYTHONPATH=%PYTHONPATH%;%CD%\build\python
) GOTO:eof
:superuser
setx ALTA_DIR "%~dp0sources" /M
setx ALTA_PLUGIN_PATH "%~dp0build\plugins" /M
setx PATH "%PATH%;%~dp0build\softs" /M
setx PYTHONPATH "%PYTHONPATH%;%~dp0build\python" /M
GOTO:eof
/* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions /* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions
Copyright (C) 2014 CNRS Copyright (C) 2014 CNRS
Copyright (C) 2013, 2014, 2015 Inria Copyright (C) 2013, 2014, 2015, 2016 Inria
This file is part of ALTA. This file is part of ALTA.
...@@ -36,6 +36,8 @@ ...@@ -36,6 +36,8 @@
#include <Eigen/Core> #include <Eigen/Core>
typedef Eigen::VectorXd vec; typedef Eigen::VectorXd vec;
typedef Eigen::Ref<vec> vecref;
typedef Eigen::Ref<const vec> const_vecref;
// Convenience functions. // Convenience functions.
static inline double norm(const vec& v) static inline double norm(const vec& v)
...@@ -103,6 +105,13 @@ static bool close_to(const T a, const T b, const T epsilon = 1E-7) ...@@ -103,6 +105,13 @@ static bool close_to(const T a, const T b, const T epsilon = 1E-7)
} }
/* Mark a type, class, method, function, or variable as deprecated. */
#ifdef __GNUC__
# define ALTA_DEPRECATED __attribute__((__deprecated__))
#else
# define ALTA_DEPRECATED
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
#define NOT_IMPLEMENTED() \ #define NOT_IMPLEMENTED() \
std::cerr << "<<ERROR>> not implemented " << __FUNCDNAME__ << " in file " << __FILE__ \ std::cerr << "<<ERROR>> not implemented " << __FUNCDNAME__ << " in file " << __FILE__ \
......
/* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions /* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions
Copyright (C) 2013, 2014, 2015 Inria Copyright (C) 2013, 2014, 2015, 2016 Inria
This file is part of ALTA. This file is part of ALTA.
...@@ -17,41 +17,43 @@ using namespace alta; ...@@ -17,41 +17,43 @@ using namespace alta;
void data::save(const std::string& filename) const void data::save(const std::string& filename) const
{ {
std::ofstream file; std::ofstream file;
file.exceptions(std::ios_base::failbit); file.exceptions(std::ios_base::failbit);
file.open(filename.c_str(), std::ios_base::trunc); file.open(filename.c_str(), std::ios_base::trunc);
file.exceptions(std::ios_base::goodbit); file.exceptions(std::ios_base::goodbit);
alta::save_data_as_text(file, *this); alta::save_data_as_text(file, *this);
file.close(); file.close();
} }
bool data::equals(const data& data, double epsilon) bool data::equals(const data& data, double epsilon)
{ {
if (size() != data.size() if (size() != data.size()
|| dimX() != data.dimX() || dimY() != data.dimY() || _parameters.dimX() != data.parametrization().dimX()
|| input_parametrization() != data.input_parametrization() || _parameters.dimY() != data.parametrization().dimY()
|| output_parametrization() != data.output_parametrization()) || (_parameters.input_parametrization()
return false; != data.parametrization().input_parametrization())
|| (_parameters.output_parametrization()
for(int i = 0; i < data.size(); i++) != data.parametrization().output_parametrization()))
{ return false;
vec other = data.get(i);
vec self = get(i); for(int i = 0; i < data.size(); i++)
{
if (self.size() != other.size()) // should not happen vec other = data.get(i);
return false; vec self = get(i);
for (int j = 0; j < self.size(); j++) if (self.size() != other.size()) // should not happen
{ return false;
double diff = std::abs(self[j] - other[j]);
if (diff > epsilon) for (int j = 0; j < self.size(); j++)
return false; {
} double diff = std::abs(self[j] - other[j]);
} if (diff > epsilon)
return false;
return true; }
}
return true;
} }
/* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions /* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions
Copyright (C) 2013, 2014, 2015 Inria Copyright (C) 2013, 2014, 2015, 2016 Inria
This file is part of ALTA. This file is part of ALTA.
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <limits> #include <limits>
#include <fstream> #include <fstream>
#include <cmath> #include <cmath>
#include <cassert>
#include "common.h" #include "common.h"
#include "args.h" #include "args.h"
...@@ -24,46 +25,43 @@ ...@@ -24,46 +25,43 @@
#include "ptr.h" #include "ptr.h"
//namespace alta {
// class data;
//}
//void load_data_from_binary(std::istream& in, const alta::arguments& header, alta::data& data);
namespace alta { namespace alta {
/*! \brief A data object. Allows to load data from files. /*! \brief A data object. Allows to load data from files.
* \ingroup core * \ingroup core
*/ */
class data : public parametrized class data
{ {
public: // methods public: // methods
data() : parametrized()
{}
data( unsigned int dim_X, unsigned int dim_Y) data(const parameters &p, int size)
: parametrized( dim_X, dim_Y ) : _parameters(p), _size(size) {}
{
}
data(params::input in_param, params::output out_param) data(const parameters& p, int size, const vec& min, const vec& max)
: parametrized( in_param, out_param) : _parameters(p), _size(size), _min(min), _max(max)
{ {
assert(min.size() == p.dimX());
assert(max.size() == p.dimX());
}
} /* TODO: Eventually mark the following constructors as deprecated. */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
data() {}
// Virtual destructor data(unsigned int dim_X, unsigned int dim_Y)
virtual ~data() {} : _parameters(dim_X, dim_Y)
{}
#pragma GCC diagnostic pop
// Load data from a file // Virtual destructor
virtual void load(const std::string& filename) = 0 ; virtual ~data() {}
virtual void load(const std::string& filename, const arguments& args) = 0 ;
// Save the data to a file // Save the data to a file
virtual void save(const std::string& filename) const; virtual void save(const std::string& filename) const;
// Acces to data // Acces to data
virtual vec get(int i) const = 0 ; virtual vec get(int i) const = 0 ;
//! \brief Provide an evaluation of the data using interpolation. If //! \brief Provide an evaluation of the data using interpolation. If
//! the data object does not provide an interpolation mechanism, it //! the data object does not provide an interpolation mechanism, it
...@@ -74,23 +72,41 @@ class data : public parametrized ...@@ -74,23 +72,41 @@ class data : public parametrized
//! match the total dimension: dimX + dimY. //! match the total dimension: dimX + dimY.
virtual vec value(const vec& in) const = 0; virtual vec value(const vec& in) const = 0;
//! \brief Put the sample inside the data //! \brief Put the sample inside the data at index I.
virtual void set(const vec& x) = 0; virtual void set(int i, const vec& x) = 0;
virtual void set(int i, const vec& x) = 0;
// Get data size, e.g. the number of samples to fit // Get data size, e.g. the number of samples to fit
virtual int size() const = 0 ; int size() const { return _size; };
//! \brief Return true if this object is equal to DATA ±ε. //! \brief Return true if this object is equal to DATA ±ε.
virtual bool equals(const data& data, virtual bool equals(const data& data,
double epsilon = double epsilon =
std::pow(1.0, -int(std::numeric_limits<double>::digits10 - 1))); std::pow(1.0, -int(std::numeric_limits<double>::digits10 - 1)));
friend void load_data_from_binary(std::istream& in, const alta::arguments& header,
alta::data& data);