Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
alta
alta
Commits
f34c162d
Commit
f34c162d
authored
Sep 03, 2013
by
Laurent Belcour
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Adding the NLopt solver, but it is not working right now
parent
9ab966c2
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
303 additions
and
8 deletions
+303
-8
sources/plugins/nonlinear_fitter_ceres/fitter.cpp
sources/plugins/nonlinear_fitter_ceres/fitter.cpp
+0
-6
sources/plugins/nonlinear_fitter_ceres/fitter.h
sources/plugins/nonlinear_fitter_ceres/fitter.h
+34
-2
sources/plugins/nonlinear_fitter_nlopt/fitter.cpp
sources/plugins/nonlinear_fitter_nlopt/fitter.cpp
+191
-0
sources/plugins/nonlinear_fitter_nlopt/fitter.h
sources/plugins/nonlinear_fitter_nlopt/fitter.h
+59
-0
sources/plugins/nonlinear_fitter_nlopt/nonlinear_fitter_nlopt.pro
...plugins/nonlinear_fitter_nlopt/nonlinear_fitter_nlopt.pro
+18
-0
sources/plugins/plugins.pro
sources/plugins/plugins.pro
+1
-0
No files found.
sources/plugins/nonlinear_fitter_ceres/fitter.cpp
View file @
f34c162d
...
...
@@ -120,18 +120,12 @@ bool nonlinear_fitter_ceres::fit_data(const data* d, function* fit, const argume
// Create the problem
ceres
::
Problem
problem
;
for
(
int
i
=
0
;
i
<
d
->
size
();
++
i
)
{
vec
xi
=
d
->
get
(
i
);
problem
.
AddResidualBlock
(
new
CeresFunctor
(
nf
,
xi
),
NULL
,
&
p
[
0
]);
}
std
::
cout
<<
"<<INFO>> Nb parameters blocks = "
<<
problem
.
NumParameterBlocks
()
<<
std
::
endl
;
std
::
cout
<<
"<<INFO>> Nb residuals blocks = "
<<
problem
.
NumResidualBlocks
()
<<
std
::
endl
;
std
::
cout
<<
"<<INFO>> Nb residuals = "
<<
problem
.
NumResiduals
()
<<
std
::
endl
;
// Solver's options
ceres
::
Solver
::
Options
options
;
if
(
args
.
is_defined
(
"ceres-max-num-iterations"
))
...
...
sources/plugins/nonlinear_fitter_ceres/fitter.h
View file @
f34c162d
...
...
@@ -11,9 +11,41 @@
#include <core/args.h>
#include <core/vertical_segment.h>
/*! \brief A fitter for non-linear BRDF models that uses Eigen's
* Levenberg-Marquardt solver.
/*! \brief A non-linear fitter using the CERES solver
* \ingroup plugins
*
* \details
* <h3>Third party requirements</h3>
*
* You will need three external libraries to compile this plugin:
* <ul>
* <li><a href="https://ceres-solver.googlesource.com/ceres-solver">CERES</a>
* library, version 1.5.0</li>
* <li><a href="http://code.google.com/p/google-glog">Google glog</a> library
* version 0.3.1</li>
* <li><a href="http://eigen.tuxfamily.org/">Eigen library</a> version 3</li>
* </ul>
*
* The last two dependencies are required to compile CERES and this plugin
* must be linked against Google glog to run.
*
* You need to provide your own ceres.prf file for qmake to generate the correct
* Makefile or Visual Studio solution. In particular this configuration file
* should provide:
*
* <pre>
* INCLUDEPATH += [path-to-ceres-include]
* LIBS += -L[path-to-ceres-lib] -lceres -L[path-to-glog-lib] -lglog -lgomp
* </pre>
*
*
* <h3>Plugin parameters</h3>
*
* We provide the following command line arguments to manipulate this plugin:
* <ul>
* <li><b>--ceres-max-num-iterations</b> <em>[int]</em> to control the number
* of iterations the non linear solver will take before returning a solution</li>
* </ul>
*/
class
nonlinear_fitter_ceres
:
public
fitter
{
...
...
sources/plugins/nonlinear_fitter_nlopt/fitter.cpp
0 → 100644
View file @
f34c162d
#include "fitter.h"
#include <nlopt.h>
#include <string>
#include <iostream>
#include <fstream>
#include <limits>
#include <algorithm>
#include <cmath>
#include <QTime>
#include <core/common.h>
ALTA_DLL_EXPORT
fitter
*
provide_fitter
()
{
return
new
nonlinear_fitter_nlopt
();
}
void
print_nlopt_error
(
nlopt_result
res
,
char
*
string
)
{
if
(
res
==
NLOPT_FAILURE
)
{
std
::
cerr
<<
"<<ERROR>> generic failure for
\"
"
<<
string
<<
"
\"
"
<<
std
::
endl
;
}
else
if
(
res
==
NLOPT_INVALID_ARGS
)
{
std
::
cerr
<<
"<<ERROR>> invalid arguments for
\"
"
<<
string
<<
"
\"
"
<<
std
::
endl
;
}
else
if
(
res
==
NLOPT_OUT_OF_MEMORY
)
{
std
::
cerr
<<
"<<ERROR>> not enough memory for
\"
"
<<
string
<<
"
\"
"
<<
std
::
endl
;
}
}
// The parameter of the function _f should be set prior to this function
// call. If not it will produce undesirable results.
void
df
(
double
*
fjac
,
const
nonlinear_function
*
f
,
const
data
*
d
)
{
// Each constraint is of the form data point * color channel
for
(
int
s
=
0
;
s
<
d
->
size
();
++
s
)
{
vec
xi
=
d
->
get
(
s
);
// Get the jacobian of the function at position x_i for the current
// set of parameters (set prior to function call)
vec
_jac
=
f
->
parametersJacobian
(
xi
);
vec
_di
=
vec
(
f
->
dimY
());
for
(
int
i
=
0
;
i
<
f
->
dimY
();
++
i
)
{
_di
[
i
]
=
xi
[
f
->
dimX
()
+
i
];
}
// Should add the resulting vector completely
vec
_y
=
(
*
f
)(
xi
)
-
_di
;
// For each output channel, update the subpart of the
// vector row
for
(
int
i
=
0
;
i
<
f
->
dimY
();
++
i
)
{
// Fill the columns of the matrix
for
(
int
j
=
0
;
j
<
f
->
nbParameters
();
++
j
)
{
fjac
[
j
]
-=
2
*
_y
[
i
]
*
_jac
[
i
*
f
->
nbParameters
()
+
j
];
}
}
}
}
double
f
(
unsigned
n
,
const
double
*
x
,
double
*
dy
,
void
*
dat
)
{
nonlinear_function
*
_f
=
(
nonlinear_function
*
)(((
void
**
)
dat
)[
0
]);
const
data
*
_d
=
(
const
data
*
)(((
void
**
)
dat
)[
1
]);
// Update the parameters vector
vec
_p
(
_f
->
nbParameters
());
for
(
int
i
=
0
;
i
<
_f
->
nbParameters
();
++
i
)
{
_p
[
i
]
=
x
[
i
];
}
_f
->
setParameters
(
_p
);
// Create the result vector
double
y
=
0.0
;
// Each constraint is of the form data point * color channel
for
(
int
s
=
0
;
s
<
_d
->
size
();
++
s
)
{
vec
xi
=
_d
->
get
(
s
);
vec
_di
=
vec
(
_f
->
dimY
());
for
(
int
i
=
0
;
i
<
_f
->
dimY
();
++
i
)
{
_di
[
i
]
=
xi
[
_f
->
dimX
()
+
i
];
}
// Should add the resulting vector completely
vec
_y
=
(
*
_f
)(
xi
)
-
_di
;
for
(
int
i
=
0
;
i
<
_f
->
dimY
();
++
i
)
{
y
+=
pow
(
_y
[
i
],
2
);
}
}
if
(
dy
!=
NULL
)
{
df
(
dy
,
_f
,
_d
);
}
return
y
;
}
nonlinear_fitter_nlopt
::
nonlinear_fitter_nlopt
()
{
}
nonlinear_fitter_nlopt
::~
nonlinear_fitter_nlopt
()
{
}
bool
nonlinear_fitter_nlopt
::
fit_data
(
const
data
*
d
,
function
*
fit
,
const
arguments
&
args
)
{
// I need to set the dimension of the resulting function to be equal
// to the dimension of my fitting problem
fit
->
setDimX
(
d
->
dimX
())
;
fit
->
setDimY
(
d
->
dimY
())
;
fit
->
setMin
(
d
->
min
())
;
fit
->
setMax
(
d
->
max
())
;
// Convert the function and bootstrap it with the data
if
(
dynamic_cast
<
nonlinear_function
*>
(
fit
)
==
NULL
)
{
std
::
cerr
<<
"<<ERROR>> the function is not a non-linear function"
<<
std
::
endl
;
return
false
;
}
nonlinear_function
*
nf
=
dynamic_cast
<
nonlinear_function
*>
(
fit
);
nf
->
bootstrap
(
d
,
args
);
#ifndef DEBUG
std
::
cout
<<
"<<DEBUG>> number of parameters: "
<<
nf
->
nbParameters
()
<<
std
::
endl
;
#endif
if
(
nf
->
nbParameters
()
==
0
)
{
return
true
;
}
// the following starting values provide a rough fit is the bootstrap flag is
// enabled
vec
p
=
nf
->
parameters
();
// Create the optimizer
nlopt_opt
opt
=
nlopt_create
(
NLOPT_GD_STOGO
,
nf
->
nbParameters
());
if
(
opt
==
NULL
)
{
std
::
cerr
<<
"<<ERROR>> unable to create the optimizer"
<<
std
::
endl
;
return
false
;
}
// Create the problem
void
*
dat
[
2
];
dat
[
0
]
=
(
void
*
)
nf
;
dat
[
1
]
=
(
void
*
)
d
;
nlopt_result
res
=
nlopt_set_min_objective
(
opt
,
f
,
dat
);
if
(
res
<
0
)
{
print_nlopt_error
(
res
,
"nlopt_set_min_objective"
);
return
false
;
}
// Set the stopping criterion to a maximum number of evaluation
res
=
nlopt_set_maxeval
(
opt
,
50
);
if
(
res
<
0
)
{
print_nlopt_error
(
res
,
"nlopt_set_maxeval"
);
}
// Launch minimization
double
f_end
;
res
=
nlopt_optimize
(
opt
,
&
p
[
0
],
&
f_end
);
if
(
res
>
0
)
{
std
::
cout
<<
"<<INFO>> found parameters: "
<<
p
<<
std
::
endl
;
nf
->
setParameters
(
p
);
}
else
{
print_nlopt_error
(
res
,
"nlopt_optimize"
);
}
nlopt_destroy
(
opt
);
return
res
>
0
;
}
void
nonlinear_fitter_nlopt
::
set_parameters
(
const
arguments
&
args
)
{
}
sources/plugins/nonlinear_fitter_nlopt/fitter.h
0 → 100644
View file @
f34c162d
#pragma once
// Include STL
#include <vector>
#include <string>
// Interface
#include <core/function.h>
#include <core/data.h>
#include <core/fitter.h>
#include <core/args.h>
#include <core/vertical_segment.h>
/*! \brief A non-linear fitter using the NLOpt solver
* \ingroup plugins
*
* \details
* <h3>Third party requirements</h3>
*
* You will need three external libraries to compile this plugin:
* <ul>
* <li><a href="http://ab-initio.mit.edu/wiki/index.php/NLopt">NLopt</a>
* library, version 2.3</li>
* </ul>
*
* You need to provide your own nlopt.prf file for qmake to generate the correct
* Makefile or Visual Studio solution. In particular this configuration file
* should provide:
*
* <pre>
* INCLUDEPATH += [path-to-nlopt-include]
* LIBS += -L[path-to-nlopt-lib] -lnlopt -lm
* </pre>
*
*
* <h3>Plugin parameters</h3>
*
*/
class
nonlinear_fitter_nlopt
:
public
fitter
{
public:
// methods
nonlinear_fitter_nlopt
()
;
virtual
~
nonlinear_fitter_nlopt
()
;
// Fitting a data object
//
virtual
bool
fit_data
(
const
data
*
d
,
function
*
fit
,
const
arguments
&
args
)
;
// Provide user parameters to the fitter
//
virtual
void
set_parameters
(
const
arguments
&
args
)
;
protected:
// function
protected:
// data
}
;
sources/plugins/nonlinear_fitter_nlopt/nonlinear_fitter_nlopt.pro
0 → 100644
View file @
f34c162d
TARGET
=
nonlinear_fitter_nlopt
TEMPLATE
=
lib
CONFIG
*=
qt
\
plugin
\
nlopt
\
eigen
DESTDIR
=
..
/../
build
INCLUDEPATH
+=
..
/..
HEADERS
=
fitter
.
h
SOURCES
=
fitter
.
cpp
LIBS
+=
-
L
..
/../
build
\
-
lcore
sources/plugins/plugins.pro
View file @
f34c162d
...
...
@@ -11,6 +11,7 @@ SUBDIRS = \
#
rational_fitter_dca
\
nonlinear_levenberg_eigen
\
nonlinear_fitter_ceres
\
nonlinear_fitter_nlopt
\
nonlinear_fresnel_schlick
\
nonlinear_function_diffuse
\
nonlinear_function_phong
\
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment