Home » Developing U++ » UppHub » Added Eigen
Added Eigen [message #32762] |
Tue, 07 June 2011 07:37  |
 |
koldo
Messages: 3432 Registered: August 2008
|
Senior Veteran |
|
|
Hello all
Eigen library has been included to Bazaar. See here for details.
It includes matrix algebra and math algorithms.
In addition to the Eigen package, there is an Eigen_demo package with many demos from very simple ones to non-linear equations systems solving and optimization.
U++ Bazaar Eigen packages have been cooked by Honza (dolik.rce) and koldo (me).
Best regards
Iñaki
|
|
|
|
|
Re: Added Eigen [message #37031 is a reply to message #32762] |
Fri, 10 August 2012 08:42   |
 |
forlano
Messages: 1207 Registered: March 2006 Location: Italy
|
Senior Contributor |
|
|
koldo wrote on Tue, 07 June 2011 07:37 | Hello all
Eigen library has been included to Bazaar. See here for details.
It includes matrix algebra and math algorithms.
In addition to the Eigen package, there is an Eigen_demo package with many demos from very simple ones to non-linear equations systems solving and optimization.
U++ Bazaar Eigen packages have been cooked by Honza (dolik.rce) and koldo (me).
|
Hello,
in the last week I needed a robust non linear fitting algorithm. I looked for it on the net and downloaded several. Unfortunately they do not compile on my windows machine or needed other libraries.
I was giving up when I realized it was already in my computer since one year... and the best one!
Thanks for providing this excellent package.
I have modified it for my need and of course it work as expected. Here my demo for a logistic fit:
#include <Core/Core.h>
using namespace Upp;
#include <plugin/Eigen/Eigen.h>
#include <plugin/Eigen/unsupported/Eigen/NonLinearOptimization>
using namespace Eigen;
// Generic functor
template<typename _Scalar, int nx = Dynamic, int ny = Dynamic>
struct Functor {
typedef _Scalar Scalar;
enum {
InputsAtCompileTime = nx,
ValuesAtCompileTime = ny
};
typedef Matrix<Scalar,InputsAtCompileTime,1> InputType;
typedef Matrix<Scalar,ValuesAtCompileTime,1> ValueType;
typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType;
const int m_inputs, m_values;
Functor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}
Functor(int inputs, int values) : m_inputs(inputs), m_values(values) {}
int inputs() const {return m_inputs;}
int values() const {return m_values;}
// you should define that in the subclass :
virtual void operator() (const InputType& x, ValueType* v, JacobianType* _j=0) const {};
};
struct LogisticA_functor : Functor<double> {
LogisticA_functor() : Functor<double>(3,15) {}
static const double x[15];
static const double y[15];
int operator()(const VectorXd &b, VectorXd &fvec) const {
ASSERT(b.size()==3);
ASSERT(fvec.size()==15);
for(int i=0; i<15; i++)
fvec[i] = b[0] / (1.0 + b[1]*exp(-1.0 * b[2] * x[i])) - y[i];
return 0;
}
};
const double LogisticA_functor::x[15] = {-280.0, -240.0, -200.0, -160.0, -120.0, -80.0, -40.0, 0.0, 40.0, 80.0, 120.0, 160.0, 200.0, 240.0, 280.0};
const double LogisticA_functor::y[15] = {0.061276, 0.071429, 0.091574, 0.112821, 0.132959, 0.131597, 0.167887, 0.198380, 0.221380, 0.292292, 0.351831, 0.445803, 0.497754 , 0.609337,0.632353};
void NonLinearOptimization() {
VectorXd x(3);
x << 5., 5., 0.01; // Initial values
//first run
LogisticA_functor functor;
NumericalDiff<LogisticA_functor> numDiff(functor);
LevenbergMarquardt<NumericalDiff<LogisticA_functor> > lm(numDiff);
int ret = lm.minimize(x);
if (ret == LevenbergMarquardtSpace::ImproperInputParameters ||
ret == LevenbergMarquardtSpace::TooManyFunctionEvaluation)
Cout() << "\nNo convergence!: " << ret;
else {
for (int i=0; i<3; i++) Cout() << "Parameter: "<< i << " = " << x[i] << "\n";
}
//second run with new data of different length and same curve to fit
//
// x[13] = {-280.0, -240.0, -200.0, -160.0, -120.0, -80.0, -40.0, 0.0, 40.0, 80.0, 120.0, 160.0, 200.0};
// y[13] = {0.061276, 0.071429, 0.091574, 0.112821, 0.132959, 0.131597, 0.167887, 0.198380, 0.221380, 0.292292, 0.351831, 0.445803, 0.497754};
// ..... ??? .....
}
CONSOLE_APP_MAIN
{ NonLinearOptimization();
}
Now, and here comes the problems, I would like to use the same curve, with the same number of parameters, but with a NEW dataset [X,Y] of different size.
I can duplicate the code (new functor and new drive) and it should work. But I need to do it up to 16 different dataset and my way is very, very silly.
It should be a way to modify the template of the functor to permit to feed at request a data set [X,Y] of N values.
Unfortunately the template structure and the operator() scary me and I do not know where to put my hands.
Can I ask a more easy way to drive the same functor with different dataset leaving unchanged the fitting curve?
Thanks a lot for your patience.
Luigi
|
|
|
Re: Added Eigen [message #37033 is a reply to message #37031] |
Fri, 10 August 2012 12:45   |
Sender Ghost
Messages: 301 Registered: November 2008
|
Senior Member |
|
|
Hello, Luigi.
forlano wrote on Fri, 10 August 2012 08:42 | Now, and here comes the problems, I would like to use the same curve, with the same number of parameters, but with a NEW dataset [X,Y] of different size.
|
Following is a possible implementation:
Toggle Spoiler
#include <Core/Core.h>
using namespace Upp;
#include <plugin/Eigen/Eigen.h>
#include <plugin/Eigen/unsupported/Eigen/NonLinearOptimization>
using namespace Eigen;
// Generic functor
template<typename _Scalar, int nx = Dynamic, int ny = Dynamic>
struct Functor {
typedef _Scalar Scalar;
enum {
InputsAtCompileTime = nx,
ValuesAtCompileTime = ny
};
typedef Matrix<Scalar,InputsAtCompileTime,1> InputType;
typedef Matrix<Scalar,ValuesAtCompileTime,1> ValueType;
typedef Matrix<Scalar,ValuesAtCompileTime,InputsAtCompileTime> JacobianType;
int m_inputs, m_values;
void SetInputsCount(int count) { m_inputs = count; }
void SetValuesCount(int count) { m_values = count; }
Functor() : m_inputs(InputsAtCompileTime), m_values(ValuesAtCompileTime) {}
Functor(int inputs, int values) : m_inputs(inputs), m_values(values) {}
int inputs() const {return m_inputs;}
int values() const {return m_values;}
// you should define that in the subclass :
virtual void operator() (const InputType& x, ValueType* v, JacobianType* _j=0) const {};
};
class LogisticA_functor : public Functor<double> {
protected:
double *vx;
double *vy;
public:
void Set(double *x, double *y) { vx = x; vy = y; }
int operator()(const VectorXd &b, VectorXd &fvec) const {
ASSERT(b.size()==m_inputs);
ASSERT(fvec.size()==m_values);
for(int i=0; i<m_values; i++)
fvec[i] = b[0] / (1.0 + b[1]*exp(-1.0 * b[2] * vx[i])) - vy[i];
return 0;
}
};
void DoLevenbergMarquardt(LogisticA_functor& functor, VectorXd& x, double *j, double *k, int inputs, int values)
{
functor.Set(j, k);
functor.SetInputsCount(inputs);
functor.SetValuesCount(values);
NumericalDiff<LogisticA_functor> numDiff(functor);
LevenbergMarquardt<NumericalDiff<LogisticA_functor> > lm(numDiff);
int ret = lm.minimize(x);
if (ret == LevenbergMarquardtSpace::ImproperInputParameters ||
ret == LevenbergMarquardtSpace::TooManyFunctionEvaluation)
Cout() << "\nNo convergence!: " << ret << '\n';
else
for (int i = 0; i < inputs; ++i)
Cout() << "Parameter: " << i << " = " << x[i] << '\n';
}
void NonLinearOptimization() {
const int inputs = 3;
VectorXd x(inputs);
x << 5., 5., 0.01; // Initial values
LogisticA_functor functor;
Cout() << "First run\n";
double jx[13] = {-280.0, -240.0, -200.0, -160.0, -120.0, -80.0, -40.0, 0.0, 40.0, 80.0, 120.0, 160.0, 200.0},
jy[13] = {0.061276, 0.071429, 0.091574, 0.112821, 0.132959, 0.131597, 0.167887, 0.198380, 0.221380, 0.292292, 0.351831, 0.445803, 0.497754};
VectorXd j = x;
DoLevenbergMarquardt(functor, j, jx, jy, inputs, 13);
Cout() << "Second run with new data of different length and same curve to fit\n";
double kx[15] = {-280.0, -240.0, -200.0, -160.0, -120.0, -80.0, -40.0, 0.0, 40.0, 80.0, 120.0, 160.0, 200.0, 240.0, 280.0},
ky[15] = {0.061276, 0.071429, 0.091574, 0.112821, 0.132959, 0.131597, 0.167887, 0.198380, 0.221380, 0.292292, 0.351831, 0.445803, 0.497754 , 0.609337,0.632353};
VectorXd k = x;
DoLevenbergMarquardt(functor, k, kx, ky, inputs, 15);
}
CONSOLE_APP_MAIN
{
NonLinearOptimization();
}
|
|
|
|
|
|
|
|
|
Goto Forum:
Current Time: Sat Apr 26 20:37:38 CEST 2025
Total time taken to generate the page: 0.00680 seconds
|